From b69d87a76e5b9dcd885c360c39ddc4a3d9bd39e7 Mon Sep 17 00:00:00 2001 From: tralezab <40974010+tralezab@users.noreply.github.com> Date: Fri, 17 Sep 2021 13:04:47 -0700 Subject: [PATCH] Sparring Sect! (#61316) Adds the sparring god. Your deity wants you to go out and spar people for self improvement. Sparring You can create contracts from paper as the chaplain. The contracts come with a set of conditions for the battle. You can set which weapons are allowed. You can set what you earn from winning. You can set where you fight. BOTH participants in the sparring match must agree to the terms for the fight to begin. Changing the terms will remove any other signatures on the contract, requiring them to review and willingly sign again. Setting the stakes to be holy will give you favor for winning the fight. You can only do this once per person, so you can't farm points. You can use points on declaring new areas as arenas, or if you save up enough, buff your heart to keep fighting in dangerous conditions. --- code/__DEFINES/dcs/signals.dm | 4 + code/__DEFINES/misc.dm | 12 - code/__DEFINES/religion.dm | 50 +++ code/__DEFINES/traits.dm | 8 + code/datums/components/unbreakable.dm | 31 ++ code/datums/elements/tenacious.dm | 33 ++ .../config_types/greyscale_configs.dm | 15 + .../json_configs/items/ceremonial_blade.json | 15 + .../items/ceremonial_blade_lefthand.json | 10 + .../items/ceremonial_blade_righthand.json | 10 + code/datums/helper_datums/teleport.dm | 2 + .../mutations/holy_mutation/honorbound.dm | 9 - code/datums/wounds/burns.dm | 7 + .../objects/items/grenades/atmos_grenades.dm | 2 + code/modules/admin/smites/lightning.dm | 18 +- code/modules/antagonists/monkey/monkey.dm | 4 +- .../antagonists/wizard/equipment/soulstone.dm | 12 +- .../modules/movespeed/modifiers/components.dm | 4 + code/modules/religion/religion_sects.dm | 29 ++ code/modules/religion/rites.dm | 139 +++++++- .../religion/sparring/ceremonial_gear.dm | 56 ++++ .../religion/sparring/sparring_contract.dm | 145 +++++++++ .../religion/sparring/sparring_datum.dm | 304 ++++++++++++++++++ code/modules/surgery/organs/heart.dm | 3 - icons/obj/hand_of_god_structures.dmi | Bin 31605 -> 31756 bytes icons/obj/items/ritual_weapon.dmi | Bin 0 -> 1728 bytes tgstation.dme | 6 + .../tgui/interfaces/SparringContract.tsx | 235 ++++++++++++++ 28 files changed, 1128 insertions(+), 35 deletions(-) create mode 100644 code/__DEFINES/religion.dm create mode 100644 code/datums/components/unbreakable.dm create mode 100644 code/datums/elements/tenacious.dm create mode 100644 code/datums/greyscale/json_configs/items/ceremonial_blade.json create mode 100644 code/datums/greyscale/json_configs/items/ceremonial_blade_lefthand.json create mode 100644 code/datums/greyscale/json_configs/items/ceremonial_blade_righthand.json create mode 100644 code/modules/religion/sparring/ceremonial_gear.dm create mode 100644 code/modules/religion/sparring/sparring_contract.dm create mode 100644 code/modules/religion/sparring/sparring_datum.dm create mode 100644 icons/obj/items/ritual_weapon.dmi create mode 100644 tgui/packages/tgui/interfaces/SparringContract.tsx diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 6ae1dd3c00c..14f2e01d81c 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -501,6 +501,8 @@ #define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size" ///Called when a movable is hit by a plunger in layer mode, from /obj/item/plunger/attack_atom() #define COMSIG_MOVABLE_CHANGE_DUCT_LAYER "movable_change_duct_layer" +///Called when a movable is teleported from `do_teleport()`: (destination, channel) +#define COMSIG_MOVABLE_TELEPORTED "movable_teleported" // /mob signals @@ -1015,6 +1017,8 @@ ///called in /obj/item/gun/process_fire (user, target, params, zone_override) #define COMSIG_GRENADE_DETONATE "grenade_prime" +//called from many places in grenade code (armed_by, nade, det_time, delayoverride) +#define COMSIG_MOB_GRENADE_ARMED "grenade_mob_armed" ///called in /obj/item/gun/process_fire (user, target, params, zone_override) #define COMSIG_GRENADE_ARMED "grenade_armed" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 269af6146aa..cafed708aab 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -485,18 +485,6 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE))) #define FALL_NO_MESSAGE (1<<1) //Used to suppress the "[A] falls through [old_turf]" messages where it'd make little sense at all, like going downstairs. #define FALL_STOP_INTERCEPTING (1<<2) //Used in situations where halting the whole "intercept" loop would be better, like supermatter dusting (and thus deleting) the atom. -//Religion -///role below priests, for losing most powers of priests but still being holy. -#define HOLY_ROLE_DEACON 1 -///default priestly role -#define HOLY_ROLE_PRIEST 2 -///the one who designates the religion -#define HOLY_ROLE_HIGHPRIEST 3 - -#define ALIGNMENT_GOOD "good" -#define ALIGNMENT_NEUT "neutral" -#define ALIGNMENT_EVIL "evil" - // Play time / EXP #define PLAYTIME_HARDCORE_RANDOM 120 diff --git a/code/__DEFINES/religion.dm b/code/__DEFINES/religion.dm new file mode 100644 index 00000000000..0db0961c12d --- /dev/null +++ b/code/__DEFINES/religion.dm @@ -0,0 +1,50 @@ +///role below priests, for losing most powers of priests but still being holy. +#define HOLY_ROLE_DEACON 1 +///default priestly role +#define HOLY_ROLE_PRIEST 2 +///the one who designates the religion +#define HOLY_ROLE_HIGHPRIEST 3 + +#define ALIGNMENT_GOOD "good" +#define ALIGNMENT_NEUT "neutral" +#define ALIGNMENT_EVIL "evil" + +//## which weapons should we use? + +// unused but for clarity +#define CONDITION_FIST_FIGHT 1 +///can only use the ritual weapons the sparring chaplain makes. +#define CONDITION_CEREMONIAL_ONLY 2 +///melee weapon condition, default sparring condition. +#define CONDITION_MELEE_ONLY 3 +///any weapon is cool... probably a terrible idea against security +#define CONDITION_ANY_WEAPON 4 + +// +///must use weapons the chaplain makes from their sect. no fist fighting, even! it ensures a fair fight. +// #define RITUAL_WEAPONS 2 + +//## where should we fight? + +// default value - /area/service/chapel + +//## what are the stakes? people you've beaten before can only fight in no stakes battles, to prevent farming + +///just for fun +#define STAKES_NONE 1 +///standard stakes, winning gets you a point. losing counts towards standard excommunication. +#define STAKES_HOLY_MATCH 2 +///no stakes god wise, but whomever wins gets all the money of the other +#define STAKES_MONEY_MATCH 3 +///the winner gets the other's soul. you said this was a neutral sect, right? +#define STAKES_YOUR_SOUL 4 + +///the left signing part of the contract +#define CONTRACT_LEFT_FIELD "left" + +///curses the sinner +#define PUNISHMENT_OMEN "omen" +///smites the sinner +#define PUNISHMENT_LIGHTNING "lightningbolt" +///brands the sinner +#define PUNISHMENT_BRAND "brand" diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index a6e9fdc1b29..70f7bf2a700 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -325,6 +325,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_BYPASS_MEASURES "bypass_lagswitch_measures" /// Someone can safely be attacked with honorbound with ONLY a combat mode check, the trait is assuring holding a weapon and hitting won't hurt them.. #define TRAIT_ALLOWED_HONORBOUND_ATTACK "allowed_honorbound_attack" +/// The user is sparring +#define TRAIT_SPARRING "sparring" #define TRAIT_NOBLEED "nobleed" //This carbon doesn't bleed /// This atom can ignore the "is on a turf" check for simple AI datum attacks, allowing them to attack from bags or lockers as long as any other conditions are met @@ -526,6 +528,12 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// If present on a [/mob/living/carbon], will make them appear to have a medium level disease on health HUDs. #define TRAIT_DISEASELIKE_SEVERITY_MEDIUM "diseaselike_severity_medium" +/// trait denoting someone will crawl faster in soft crit +#define TRAIT_TENACIOUS "tenacious" + +/// trait denoting someone will sometimes recover out of crit +#define TRAIT_UNBREAKABLE "unbreakable" + //Medical Categories for quirks #define CAT_QUIRK_ALL 0 #define CAT_QUIRK_NOTES 1 diff --git a/code/datums/components/unbreakable.dm b/code/datums/components/unbreakable.dm new file mode 100644 index 00000000000..8d75c563d57 --- /dev/null +++ b/code/datums/components/unbreakable.dm @@ -0,0 +1,31 @@ +/datum/component/unbreakable + COOLDOWN_DECLARE(surge_cooldown) + +/datum/component/unbreakable/Initialize() + if(!ishuman(parent)) + return COMPONENT_INCOMPATIBLE + ADD_TRAIT(parent, TRAIT_UNBREAKABLE, INNATE_TRAIT) + +/datum/component/unbreakable/Destroy(force, silent) + . = ..() + REMOVE_TRAIT(parent, TRAIT_UNBREAKABLE, INNATE_TRAIT) + +/datum/component/unbreakable/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOB_STATCHANGE, .proc/surge) + +/datum/component/unbreakable/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_MOB_STATCHANGE) + +/datum/component/unbreakable/proc/surge(mob/living/carbon/human/surged, new_stat) + SIGNAL_HANDLER + if(new_stat < SOFT_CRIT || new_stat >= DEAD) + return + if(!COOLDOWN_FINISHED(src, surge_cooldown)) + return + COOLDOWN_START(src, surge_cooldown, 1 MINUTES) + surged.balloon_alert(surged, "you refuse to give up!")//breaks balloon alert conventions by using a "!" for a fail message but that's okay because it's a pretty awesome moment + surged.heal_overall_damage(15, 15, 0, BODYPART_ORGANIC) + if(surged.reagents.get_reagent_amount(/datum/reagent/medicine/ephedrine) < 20) + surged.reagents.add_reagent(/datum/reagent/medicine/ephedrine, 10) + if(surged.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine) < 20) + surged.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 10) diff --git a/code/datums/elements/tenacious.dm b/code/datums/elements/tenacious.dm new file mode 100644 index 00000000000..c917dc7518a --- /dev/null +++ b/code/datums/elements/tenacious.dm @@ -0,0 +1,33 @@ +/** + * tenacious element; which makes the parent move faster while crawling + * + * Used by sparring sect! + */ +/datum/element/tenacious + element_flags = ELEMENT_DETACH + +/datum/element/tenacious/Attach(datum/target) + . = ..() + + if(!ishuman(target)) + return COMPONENT_INCOMPATIBLE + var/mob/living/carbon/human/valid_target = target + on_stat_change(valid_target, new_stat = valid_target.stat) //immediately try adding movement bonus if they're in soft crit + RegisterSignal(target, COMSIG_MOB_STATCHANGE, .proc/on_stat_change) + ADD_TRAIT(target, TRAIT_TENACIOUS, INNATE_TRAIT) + +/datum/element/tenacious/Detach(datum/target) + . = ..() + UnregisterSignal(target, COMSIG_MOB_STATCHANGE) + REMOVE_TRAIT(target, TRAIT_TENACIOUS, INNATE_TRAIT) + +///signal called by the stat of the target changing +/datum/element/tenacious/proc/on_stat_change(mob/living/carbon/human/target, new_stat) + SIGNAL_HANDLER + + if(new_stat == SOFT_CRIT) + target.balloon_alert(target, "your tenacity kicks in") + target.add_movespeed_modifier(/datum/movespeed_modifier/tenacious) + else + target.balloon_alert(target, "your tenacity wears off") + target.remove_movespeed_modifier(/datum/movespeed_modifier/tenacious) diff --git a/code/datums/greyscale/config_types/greyscale_configs.dm b/code/datums/greyscale/config_types/greyscale_configs.dm index 7d1759b99ea..4d94dc6a7c9 100644 --- a/code/datums/greyscale/config_types/greyscale_configs.dm +++ b/code/datums/greyscale/config_types/greyscale_configs.dm @@ -283,6 +283,21 @@ icon_file = 'icons/obj/items/cleric_mace.dmi' json_config = 'code/datums/greyscale/json_configs/items/cleric_mace_worn_gold.json' +/datum/greyscale_config/ceremonial_blade + name = "Base Ceremonial Blade" + icon_file = 'icons/obj/items/ritual_weapon.dmi' + json_config = 'code/datums/greyscale/json_configs/items/ceremonial_blade.json' + +/datum/greyscale_config/ceremonial_blade_lefthand + name = "Base Held Ceremonial Blade, Left" + icon_file = 'icons/obj/items/ritual_weapon.dmi' + json_config = 'code/datums/greyscale/json_configs/items/ceremonial_blade_lefthand.json' + +/datum/greyscale_config/ceremonial_blade_righthand + name = "Base Held Ceremonial Blade, Right" + icon_file = 'icons/obj/items/ritual_weapon.dmi' + json_config = 'code/datums/greyscale/json_configs/items/ceremonial_blade_righthand.json' + /datum/greyscale_config/beret name = "Beret" icon_file = 'icons/obj/clothing/head/beret.dmi' diff --git a/code/datums/greyscale/json_configs/items/ceremonial_blade.json b/code/datums/greyscale/json_configs/items/ceremonial_blade.json new file mode 100644 index 00000000000..16360a5e889 --- /dev/null +++ b/code/datums/greyscale/json_configs/items/ceremonial_blade.json @@ -0,0 +1,15 @@ +{ + "default": [ + { + "type": "icon_state", + "icon_state": "base", + "blend_mode": "overlay", + "color_ids": [ 1 ] + }, + { + "type": "icon_state", + "icon_state": "handle", + "blend_mode": "overlay" + } + ] +} diff --git a/code/datums/greyscale/json_configs/items/ceremonial_blade_lefthand.json b/code/datums/greyscale/json_configs/items/ceremonial_blade_lefthand.json new file mode 100644 index 00000000000..aafdb2d897e --- /dev/null +++ b/code/datums/greyscale/json_configs/items/ceremonial_blade_lefthand.json @@ -0,0 +1,10 @@ +{ + "default": [ + { + "type": "icon_state", + "icon_state": "inhand_left", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/code/datums/greyscale/json_configs/items/ceremonial_blade_righthand.json b/code/datums/greyscale/json_configs/items/ceremonial_blade_righthand.json new file mode 100644 index 00000000000..d80b0c49a25 --- /dev/null +++ b/code/datums/greyscale/json_configs/items/ceremonial_blade_righthand.json @@ -0,0 +1,10 @@ +{ + "default": [ + { + "type": "icon_state", + "icon_state": "inhand_right", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index b35000f9b94..b07a28a07e8 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -26,6 +26,8 @@ if (isnull(precision)) precision = 0 + SEND_SIGNAL(teleatom, COMSIG_MOVABLE_TELEPORTED, destination, channel) + switch(channel) if(TELEPORT_CHANNEL_BLUESPACE) if(istype(teleatom, /obj/item/storage/backpack/holding)) diff --git a/code/datums/mutations/holy_mutation/honorbound.dm b/code/datums/mutations/holy_mutation/honorbound.dm index 18746918961..0b97be7e468 100644 --- a/code/datums/mutations/holy_mutation/honorbound.dm +++ b/code/datums/mutations/holy_mutation/honorbound.dm @@ -199,15 +199,6 @@ lightningbolt(user) SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "honorbound", /datum/mood_event/holy_smite)//permanently lose your moodlet after this -/datum/mutation/human/honorbound/proc/lightningbolt(mob/living/user) - var/turf/lightning_source = get_step(get_step(user, NORTH), NORTH) - lightning_source.Beam(user, icon_state="lightning[rand(1,12)]", time = 5) - user.adjustFireLoss(LIGHTNING_BOLT_DAMAGE) - playsound(get_turf(user), 'sound/magic/lightningbolt.ogg', 50, TRUE) - if(ishuman(user)) - var/mob/living/carbon/human/human_target = user - human_target.electrocution_animation(LIGHTNING_BOLT_ELECTROCUTION_ANIMATION_LENGTH) - /obj/effect/proc_holder/spell/pointed/declare_evil name = "Declare Evil" desc = "If someone is so obviously an evil of this world you can spend a huge amount of favor to declare them guilty." diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index bc25484ac6b..18bca49b06b 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -299,3 +299,10 @@ infestation_rate = 0.075 // appx 4.33 minutes to reach sepsis without any treatment flesh_damage = 20 scar_keyword = "burncritical" + +///special severe wound caused by sparring interference or other god related punishments. +/datum/wound/burn/severe/brand + name = "Holy Brand" + desc = "Patient is suffering extreme burns from a strange brand marking, creating serious risk of infection and greatly reduced limb integrity." + examine_desc = "appears to have holy symbols painfully branded into their flesh, leaving severe burns." + occur_text = "chars rapidly into a strange pattern of holy symbols, burned into the flesh." diff --git a/code/game/objects/items/grenades/atmos_grenades.dm b/code/game/objects/items/grenades/atmos_grenades.dm index cb0e90515f8..2a4ff608b8d 100644 --- a/code/game/objects/items/grenades/atmos_grenades.dm +++ b/code/game/objects/items/grenades/atmos_grenades.dm @@ -19,6 +19,8 @@ icon_state = initial(icon_state) + "_active" playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', volume, TRUE) SEND_SIGNAL(src, COMSIG_GRENADE_ARMED, det_time, delayoverride) + if(user) + SEND_SIGNAL(src, COMSIG_MOB_GRENADE_ARMED, user, src, det_time, delayoverride) addtimer(CALLBACK(src, .proc/detonate), isnull(delayoverride)? det_time : delayoverride) /obj/item/grenade/gas_crystal/healium_crystal diff --git a/code/modules/admin/smites/lightning.dm b/code/modules/admin/smites/lightning.dm index 27cab44e2d0..660af779f9b 100644 --- a/code/modules/admin/smites/lightning.dm +++ b/code/modules/admin/smites/lightning.dm @@ -4,11 +4,15 @@ /datum/smite/lightning/effect(client/user, mob/living/target) . = ..() - var/turf/lightning_source = get_step(get_step(target, NORTH), NORTH) - lightning_source.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) - target.adjustFireLoss(LIGHTNING_BOLT_DAMAGE) - playsound(get_turf(user), 'sound/magic/lightningbolt.ogg', 50, TRUE) - if(ishuman(target)) - var/mob/living/carbon/human/human_target = target - human_target.electrocution_animation(LIGHTNING_BOLT_ELECTROCUTION_ANIMATION_LENGTH) + lightningbolt(target) to_chat(target, span_userdanger("The gods have punished you for your sins!"), confidential = TRUE) + +///this is the actual bolt effect and damage, made into its own proc because it is used elsewhere +/proc/lightningbolt(mob/living/user) + var/turf/lightning_source = get_step(get_step(user, NORTH), NORTH) + lightning_source.Beam(user, icon_state="lightning[rand(1,12)]", time = 5) + user.adjustFireLoss(LIGHTNING_BOLT_DAMAGE) + playsound(get_turf(user), 'sound/magic/lightningbolt.ogg', 50, TRUE) + if(ishuman(user)) + var/mob/living/carbon/human/human_target = user + human_target.electrocution_animation(LIGHTNING_BOLT_ELECTROCUTION_ANIMATION_LENGTH) diff --git a/code/modules/antagonists/monkey/monkey.dm b/code/modules/antagonists/monkey/monkey.dm index 8e60c761550..6132ab4d202 100644 --- a/code/modules/antagonists/monkey/monkey.dm +++ b/code/modules/antagonists/monkey/monkey.dm @@ -123,8 +123,8 @@ /datum/antagonist/monkey/leader/on_gain() . = ..() - var/obj/item/organ/heart/freedom/F = new - F.Insert(owner.current, drop_if_replaced = FALSE) + var/obj/item/organ/heart/freedom/super_heart = new + super_heart.Insert(owner.current, drop_if_replaced = FALSE) owner.special_role = "Monkey Leader" /datum/antagonist/monkey/leader/on_removal() diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm index 9e993608f09..52e4872c39e 100644 --- a/code/modules/antagonists/wizard/equipment/soulstone.dm +++ b/code/modules/antagonists/wizard/equipment/soulstone.dm @@ -88,6 +88,15 @@ one_use = TRUE grab_sleeping = FALSE +/obj/item/soulstone/anybody/chaplain/sparring + icon_state = "purified_soulstone" + theme = THEME_HOLY + +/obj/item/soulstone/anybody/sparring/Initialize(mapload) + . = ..() + name = "[GLOB.deity]'s punishment" + desc = "A prison for those who lost [GLOB.deity]'s game." + /obj/item/soulstone/anybody/mining grab_sleeping = FALSE @@ -260,7 +269,8 @@ return TRUE else to_chat(user, "[span_userdanger("Capture failed!")]: The soul has already fled its mortal frame. You attempt to bring it back...") - return getCultGhost(victim,user) + INVOKE_ASYNC(src, .proc/getCultGhost, victim, user) + return TRUE //it'll probably get someone ;) ///captures a shade that was previously released from a soulstone. /obj/item/soulstone/proc/capture_shade(mob/living/simple_animal/shade/shade, mob/user) diff --git a/code/modules/movespeed/modifiers/components.dm b/code/modules/movespeed/modifiers/components.dm index 1a7aff3e0f8..30b41e89152 100644 --- a/code/modules/movespeed/modifiers/components.dm +++ b/code/modules/movespeed/modifiers/components.dm @@ -7,6 +7,10 @@ multiplicative_slowdown = -7 movetypes = GROUND +/datum/movespeed_modifier/tenacious + multiplicative_slowdown = -0.7 + movetypes = GROUND + /datum/movespeed_modifier/sanity id = MOVESPEED_ID_SANITY movetypes = (~FLYING) diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm index 8a891c3483d..f241c5c4e45 100644 --- a/code/modules/religion/religion_sects.dm +++ b/code/modules/religion/religion_sects.dm @@ -377,3 +377,32 @@ return TRUE #undef MINIMUM_YUCK_REQUIRED + +/datum/religion_sect/spar + name = "Sparring God" + quote = "Your next swing must be faster, neophyte. Steel your heart." + desc = "Spar other crewmembers to gain favor or other rewards. Exchange favor to steel yourself against real battles." + tgui_icon = "fist-raised" + altar_icon_state = "convertaltar-orange" + alignment = ALIGNMENT_NEUT + rites_list = list( + /datum/religion_rites/sparring_contract, + /datum/religion_rites/ceremonial_weapon, + /datum/religion_rites/declare_arena, + /datum/religion_rites/tenacious, + /datum/religion_rites/unbreakable, + ) + ///the one allowed contract. making a new contract dusts the old one + var/obj/item/sparring_contract/existing_contract + ///places you can spar in. rites can be used to expand this list with new arenas! + var/list/arenas = list( + "Recreation Area" = /area/commons/fitness/recreation, + "Chapel" = /area/service/chapel + ) + ///how many matches you've lost with holy stakes. 3 = excommunication + var/matches_lost = 0 + ///past opponents who you've beaten in holy battles. You can't fight them again to prevent favor farming + var/list/past_opponents = list() + +/datum/religion_sect/spar/tool_examine(mob/living/holy_creature) + return "You have [round(favor)] sparring matches won in [GLOB.deity]'s name to redeem. You have lost [matches_lost] holy matches. You will be excommunicated after losing three matches." diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm index 9e0d22ce6e8..f639bd43a6d 100644 --- a/code/modules/religion/rites.dm +++ b/code/modules/religion/rites.dm @@ -117,7 +117,7 @@ ritual_invocations =list( "Let your will power our forges.", "...Help us in our great conquest!") invoke_msg = "The end of flesh is near!" - favor_cost = 2000 + favor_cost = 2000 /datum/religion_rites/machine_blessing/invoke_effect(mob/living/user, atom/movable/religious_tool) ..() @@ -603,4 +603,141 @@ new /obj/item/ritual_totem(altar_turf) return TRUE +///sparring god rites +/datum/religion_rites/sparring_contract + name = "Summon Sparring Contract" + desc = "Turns some paper into a sparring contract." + invoke_msg = "I will train in the name of my god." + ///paper to turn into a sparring contract + var/obj/item/paper/contract_target + +/datum/religion_rites/sparring_contract/perform_rite(mob/living/user, atom/religious_tool) + for(var/obj/item/paper/could_contract in get_turf(religious_tool)) + if(could_contract.info) //blank paper pls + continue + contract_target = could_contract + return ..() + to_chat(user, span_warning("You need to place blank paper on [religious_tool] to do this!")) + return FALSE + +/datum/religion_rites/sparring_contract/invoke_effect(mob/living/user, atom/movable/religious_tool) + ..() + var/obj/item/paper/blank_paper = contract_target + var/turf/tool_turf = get_turf(religious_tool) + contract_target = null + if(QDELETED(blank_paper) || !(tool_turf == blank_paper.loc)) //check if the same paper is still there + to_chat(user, span_warning("Your target left the altar!")) + return FALSE + blank_paper.visible_message(span_notice("words magically form on [blank_paper]!")) + playsound(tool_turf, 'sound/effects/pray.ogg', 50, TRUE) + var/datum/religion_sect/spar/sect = GLOB.religious_sect + if(sect.existing_contract) + sect.existing_contract.visible_message(span_warning("[src] fizzles into nothing!")) + qdel(sect.existing_contract) + sect.existing_contract = new /obj/item/sparring_contract(tool_turf) + qdel(blank_paper) + return TRUE + +/datum/religion_rites/declare_arena + name = "Declare Arena" + desc = "Declare a new area as fit for sparring. You'll be able to select it in contracts." + ritual_length = 6 SECONDS + ritual_invocations = list("I seek new horizons ...") + invoke_msg = "... may my climb be steep." + favor_cost = 1 //only costs one holy battle for a new area + var/area/area_instance + +/datum/religion_rites/declare_arena/perform_rite(mob/living/user, atom/religious_tool) + var/list/filtered = list() + for(var/area/unfiltered_area as anything in GLOB.sortedAreas) + if(istype(unfiltered_area, /area/centcom)) //youuu dont need thaaat + continue + if(!(unfiltered_area.area_flags & HIDDEN_AREA)) + filtered += unfiltered_area + area_instance = tgui_input_list(user, "Choose an area to mark as an arena!", "Arena Declaration", filtered) + if(!area_instance) + return FALSE + . = ..() + +/datum/religion_rites/declare_arena/invoke_effect(mob/living/user, atom/movable/religious_tool) + . = ..() + var/datum/religion_sect/spar/sect = GLOB.religious_sect + sect.arenas[area_instance.name] = area_instance.type + to_chat(user, span_warning("[area_instance] is a now an option to select on sparring contracts.")) + +/datum/religion_rites/ceremonial_weapon + name = "Forge Ceremonial Gear" + desc = "Turn some material into ceremonial gear. Ceremonial blades are weak outside of sparring, and are quite heavy to lug around." + ritual_length = 10 SECONDS + invoke_msg = "Weapons in your name! Battles with your blood!" + favor_cost = 0 + ///the material that will be attempted to be forged into a weapon + var/obj/item/stack/sheet/converted + +/datum/religion_rites/ceremonial_weapon/perform_rite(mob/living/user, atom/religious_tool) + for(var/obj/item/stack/sheet/could_blade in get_turf(religious_tool)) + if(!(GET_MATERIAL_REF(could_blade.material_type) in SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL])) + continue + if(could_blade.amount < 5) + continue + converted = could_blade + return ..() + to_chat(user, span_warning("You need at least 5 sheets of a material that can be made into items!")) + return FALSE + +/datum/religion_rites/ceremonial_weapon/invoke_effect(mob/living/user, atom/movable/religious_tool) + ..() + var/altar_turf = get_turf(religious_tool) + var/obj/item/stack/sheet/used_for_blade = converted + converted = null + if(QDELETED(used_for_blade) || !(get_turf(religious_tool) == used_for_blade.loc) || used_for_blade.amount < 5) //check if the same food is still there + to_chat(user, span_warning("Your target left the altar!")) + return FALSE + var/material_used = used_for_blade.material_type + to_chat(user, span_warning("[used_for_blade] reshapes into a ceremonial blade!")) + if(!used_for_blade.use(5))//use 5 of the material + return + var/obj/item/ceremonial_blade/blade = new(altar_turf) + blade.set_custom_materials(list(GET_MATERIAL_REF(material_used) = MINERAL_MATERIAL_AMOUNT * 5)) + return TRUE + +/datum/religion_rites/unbreakable + name = "Become Unbreakable" + desc = "Your training has made you unbreakable. In times of crisis, you will attempt to keep fighting on." + ritual_length = 10 SECONDS + invoke_msg = "My will must be unbreakable. Grant me this boon!" + favor_cost = 4 //4 duels won + +/datum/religion_rites/unbreakable/perform_rite(mob/living/carbon/human/user, atom/religious_tool) + if(!ishuman(user)) + return FALSE + if(HAS_TRAIT_FROM(user, TRAIT_UNBREAKABLE, INNATE_TRAIT)) + to_chat(user, span_warning("Your spirit is already unbreakable!")) + return FALSE + return ..() + +/datum/religion_rites/unbreakable/invoke_effect(mob/living/carbon/human/user, atom/movable/religious_tool) + ..() + to_chat(user, span_nicegreen("You feel [GLOB.deity]'s will to keep fighting pouring into you!")) + user.AddComponent(/datum/component/unbreakable) + +/datum/religion_rites/tenacious + name = "Become Tenacious" + desc = "Your training has made you tenacious. In times of crisis, you will be able to crawl faster." + ritual_length = 10 SECONDS + invoke_msg = "Grant me your tenacity! I have proven myself!" + favor_cost = 3 //3 duels won + +/datum/religion_rites/tenacious/perform_rite(mob/living/carbon/human/user, atom/religious_tool) + if(!ishuman(user)) + return FALSE + if(HAS_TRAIT_FROM(user, TRAIT_TENACIOUS, INNATE_TRAIT)) + to_chat(user, span_warning("Your spirit is already tenacious!")) + return FALSE + return ..() + +/datum/religion_rites/tenacious/invoke_effect(mob/living/carbon/human/user, atom/movable/religious_tool) + ..() + to_chat(user, span_nicegreen("You feel [GLOB.deity]'s tenacity pouring into you!")) + user.AddElement(/datum/element/tenacious) diff --git a/code/modules/religion/sparring/ceremonial_gear.dm b/code/modules/religion/sparring/ceremonial_gear.dm new file mode 100644 index 00000000000..7814bc24017 --- /dev/null +++ b/code/modules/religion/sparring/ceremonial_gear.dm @@ -0,0 +1,56 @@ +///ritual weapons. they're really bad, but they become normal weapons when sparring. +/obj/item/ceremonial_blade + name = "ceremonial blade" + desc = "A blade created to spar with. It seems weak, but if you spar with it...?" + icon_state = "default" + inhand_icon_state = "default" + icon = 'icons/obj/items/ritual_weapon.dmi' + + //does the exact thing we want so heck why not + greyscale_config = /datum/greyscale_config/ceremonial_blade + greyscale_config_inhand_left = /datum/greyscale_config/ceremonial_blade_lefthand + greyscale_config_inhand_right = /datum/greyscale_config/ceremonial_blade_righthand + greyscale_colors = "#FFFFFF" + + hitsound = 'sound/weapons/bladeslice.ogg' + custom_materials = list(/datum/material/iron = 12000) //Defaults to an Iron blade. + force = 2 //20 + throwforce = 1 //10 + w_class = WEIGHT_CLASS_NORMAL + attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") + attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") + block_chance = 3 //30 + sharpness = SHARP_EDGED + max_integrity = 200 + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE //doesn't affect stats of the weapon as to avoid gamering your opponent with a dope weapon + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) + resistance_flags = FIRE_PROOF + +/obj/item/ceremonial_blade/Initialize() + . = ..() + AddComponent(/datum/component/butchering, 40, 105) + RegisterSignal(src, COMSIG_ITEM_SHARPEN_ACT, .proc/block_sharpening) + +/obj/item/ceremonial_blade/melee_attack_chain(mob/user, atom/target, params) + if(!HAS_TRAIT(target, TRAIT_SPARRING)) + return ..() + var/old_force = force + var/old_throwforce = throwforce + force *= 10 + throwforce *= 10 + . = ..() + force = old_force + throwforce = old_throwforce + +/obj/item/ceremonial_blade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(attack_type != MELEE_ATTACK || !ishuman(hitby.loc)) + return ..() + if(HAS_TRAIT(hitby.loc, TRAIT_SPARRING)) + //becomes 30 block + final_block_chance *= 10 + . = ..() + +/obj/item/ceremonial_blade/proc/block_sharpening(datum/source, increment, max) + SIGNAL_HANDLER + //this breaks it + return COMPONENT_BLOCK_SHARPEN_BLOCKED diff --git a/code/modules/religion/sparring/sparring_contract.dm b/code/modules/religion/sparring/sparring_contract.dm new file mode 100644 index 00000000000..0b7a4d05f2f --- /dev/null +++ b/code/modules/religion/sparring/sparring_contract.dm @@ -0,0 +1,145 @@ +/obj/item/sparring_contract + desc = "A contract for setting up sparring matches. Both sparring partners must agree with the terms to begin." + icon = 'icons/obj/wizard.dmi' + icon_state = "scroll" + drop_sound = 'sound/items/handling/paper_drop.ogg' + pickup_sound = 'sound/items/handling/paper_pickup.ogg' + throw_range = 1 + throw_speed = 1 + w_class = WEIGHT_CLASS_TINY + ///what weapons will be allowed during the sparring match + var/weapons_condition = CONDITION_MELEE_ONLY + ///what arena the fight will take place in + var/arena_condition = /area/service/chapel + ///what stakes the fight will have + var/stakes_condition = STAKES_NONE + ///who has signed this contract. fills itself with WEAKREFS, to prevent hanging references + var/list/datum/weakref/signed_by = list(null, null) + +/obj/item/sparring_contract/Initialize() + . = ..() + name = "[GLOB.deity]'s sparring contract" + +/obj/item/sparring_contract/Destroy() + QDEL_NULL(signed_by) + var/datum/religion_sect/spar/sect = GLOB.religious_sect + sect?.existing_contract = null + . = ..() + +/obj/item/sparring_contract/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SparringContract", name) + ui.open() + +/obj/item/sparring_contract/ui_static_data(mob/user) + var/list/data = list() + var/area/arena = GLOB.areas_by_type[arena_condition] + data["set_weapon"] = weapons_condition + data["set_area"] = arena?.name + data["set_stakes"] = stakes_condition + data["possible_areas"] = get_possible_areas() + + return data + +/obj/item/sparring_contract/ui_data(mob/user) + var/list/data = list() + var/area/arena = GLOB.areas_by_type[arena_condition] + var/mob/living/carbon/human/left_partner + if(signed_by[1]) + left_partner = signed_by[1].resolve() + var/mob/living/carbon/human/right_partner + if(signed_by[2]) + right_partner = signed_by[2].resolve() + data["in_area"] = ((left_partner && right_partner && arena) && (left_partner in arena.contents) && (right_partner in arena.contents)) + data["no_chaplains"] = (!left_partner?.mind?.holy_role && !right_partner?.mind?.holy_role) + data["left_sign"] = left_partner ? left_partner.real_name : "none" + data["right_sign"] = right_partner ? right_partner.real_name : "none" + return data + +/obj/item/sparring_contract/proc/get_possible_areas() + var/list/area_names = list() + var/datum/religion_sect/spar/sect = GLOB.religious_sect + for(var/key in sect.arenas) + area_names += key + return area_names + +/obj/item/sparring_contract/ui_act(action, list/params) + . = ..() + if(.) + return + + var/mob/user = usr + + if(!ishuman(user)) + to_chat(user, span_warning("This contract refuses to be signed by a lesser creature such as yourself.")) + return + + var/datum/religion_sect/spar/sect = GLOB.religious_sect + + var/list/resolved_opponents = list() + for(var/datum/weakref/resolve_me as anything in sect.past_opponents) + var/resolved = resolve_me.resolve() + if(!isnull(resolved)) + resolved_opponents += resolved + + if(user in resolved_opponents && params["stakes"] == STAKES_HOLY_MATCH) + to_chat(user, span_warning("This contract refuses to be signed up for a holy match by a previous holy match loser. Pick a different stake!")) + + //any updating of the terms should update the UI to display new terms + . = TRUE + + var/mob/living/carbon/human/left_partner + if(signed_by[1]) + left_partner = signed_by[1].resolve() + var/mob/living/carbon/human/right_partner + if(signed_by[2]) + right_partner = signed_by[2].resolve() + + switch(action) + if("clear") + signed_by = list(null, null)//remove weakrefs + if("fight") + if(!left_partner || !right_partner || !left_partner.mind || !right_partner.mind) + return + if(HAS_TRAIT(left_partner, TRAIT_SPARRING) || HAS_TRAIT(right_partner, TRAIT_SPARRING)) + to_chat(user, span_warning("One participant is already sparring!")) + return + var/chaplain = left_partner.mind.holy_role ? left_partner : right_partner + var/opponent = left_partner.mind.holy_role ? right_partner : left_partner + new /datum/sparring_match(weapons_condition, GLOB.areas_by_type[arena_condition], stakes_condition, chaplain, opponent) + qdel(src) + if("sign") + if(user == left_partner || user == right_partner) + to_chat(user, span_warning("You've already signed one side of the contract.")) + return + var/area/arena_condition_name = GLOB.areas_by_type[arena_condition] + arena_condition_name = format_text(arena_condition_name.name) + //setting/checking for terms changed + var/terms_changed = FALSE + if(params["weapon"] != weapons_condition) + if(!params["weapon"]) + return //they hit f5 to clear data then submitted + terms_changed = TRUE + weapons_condition = params["weapon"] + if(params["area"] != arena_condition_name) + if(!params["area"]) + return //they hit f5 to clear data then submitted + terms_changed = TRUE + var/new_area_condition = sect.arenas[params["area"]] + arena_condition = new_area_condition + if(params["stakes"] != stakes_condition) + if(!params["stakes"]) + return //they hit f5 to clear data then submitted + terms_changed = TRUE + stakes_condition = params["stakes"] + //if you change the terms you have to get the other person to sign again. + if(terms_changed && (left_partner || right_partner)) + signed_by = list(null, null)//remove weakrefs + to_chat(user, span_warning("You will need to get your sparring partner to sign again under these new terms you've set.")) + //fluff and signing + var/datum/weakref/user_ref = WEAKREF(user) + if(params["sign_position"] == CONTRACT_LEFT_FIELD) + signed_by[1] = user_ref + else + signed_by[2] = user_ref diff --git a/code/modules/religion/sparring/sparring_datum.dm b/code/modules/religion/sparring/sparring_datum.dm new file mode 100644 index 00000000000..391b8378e16 --- /dev/null +++ b/code/modules/religion/sparring/sparring_datum.dm @@ -0,0 +1,304 @@ +/datum/sparring_match + ///the chaplain. it isn't actually a chaplain all the time, but in the cases where the chaplain is needed this will always be them. + var/mob/living/carbon/human/chaplain + ///the other fighter + var/mob/living/carbon/human/opponent + ///what weapons will be allowed during the sparring match + var/weapons_condition + ///area instance the participants must stay in + var/area/arena_condition + ///what stakes the fight will have + var/stakes_condition + ///cheats from the chaplain + var/chaplain_violations_allowed = 2 + ///cheats from the non-chaplain + var/opponent_violations_allowed = 2 + ///outside interventions that ruin the match + var/flubs = 2 + +/datum/sparring_match/New(weapons_condition, arena_condition, stakes_condition, mob/living/carbon/human/chaplain, mob/living/carbon/human/opponent) + . = ..() + src.weapons_condition = weapons_condition + src.arena_condition = arena_condition + src.stakes_condition = stakes_condition + src.chaplain = chaplain + src.opponent = opponent + ADD_TRAIT(chaplain, TRAIT_SPARRING, TRAIT_GENERIC) + ADD_TRAIT(opponent, TRAIT_SPARRING, TRAIT_GENERIC) + hook_signals(chaplain) + hook_signals(opponent) + chaplain.add_filter("sparring_outline", 9, list("type" = "outline", "color" = "#e02200")) + opponent.add_filter("sparring_outline", 9, list("type" = "outline", "color" = "#004ee0")) + +/datum/sparring_match/proc/hook_signals(mob/living/carbon/human/sparring) + //weapon conditions + if(weapons_condition < CONDITION_ANY_WEAPON) + RegisterSignal(sparring, COMSIG_MOB_FIRED_GUN, .proc/gun_violation) + RegisterSignal(sparring, COMSIG_MOB_GRENADE_ARMED, .proc/grenade_violation) + if(weapons_condition <= CONDITION_CEREMONIAL_ONLY) + RegisterSignal(sparring, COMSIG_PARENT_ATTACKBY, .proc/melee_violation) + //arena conditions + RegisterSignal(sparring, COMSIG_MOVABLE_MOVED, .proc/arena_violation) + //severe violations (insta violation win for other party) conditions + RegisterSignal(sparring, COMSIG_MOVABLE_TELEPORTED, .proc/teleport_violation) + //win conditions + RegisterSignal(sparring, COMSIG_MOB_STATCHANGE, .proc/check_for_victory) + //flub conditions + RegisterSignal(sparring, COMSIG_PARENT_ATTACKBY, .proc/outsider_interference) + RegisterSignal(sparring, COMSIG_ATOM_HULK_ATTACK, .proc/hulk_interference) + RegisterSignal(sparring, COMSIG_ATOM_ATTACK_HAND, .proc/hand_interference) + RegisterSignal(sparring, COMSIG_ATOM_ATTACK_PAW, .proc/paw_interference) + RegisterSignal(sparring, COMSIG_ATOM_HITBY, .proc/thrown_interference) + RegisterSignal(sparring, COMSIG_ATOM_BULLET_ACT, .proc/projectile_interference) + //severe flubs (insta match ender, no winners) conditions + RegisterSignal(sparring, COMSIG_LIVING_DEATH, .proc/death_flub) + RegisterSignal(sparring, COMSIG_PARENT_QDELETING, .proc/deletion_flub) + +/datum/sparring_match/proc/unhook_signals(mob/living/carbon/human/sparring) + if(!sparring) + return + UnregisterSignal(sparring, list( + COMSIG_MOB_FIRED_GUN, + COMSIG_MOB_GRENADE_ARMED, + COMSIG_MOB_ITEM_ATTACK, + COMSIG_MOVABLE_MOVED, + COMSIG_MOVABLE_TELEPORTED, + COMSIG_MOB_STATCHANGE, + COMSIG_PARENT_ATTACKBY, + COMSIG_ATOM_HULK_ATTACK, + COMSIG_ATOM_ATTACK_HAND, + COMSIG_ATOM_ATTACK_PAW, + COMSIG_ATOM_HITBY, + COMSIG_ATOM_BULLET_ACT, + COMSIG_LIVING_DEATH, + COMSIG_PARENT_QDELETING, + )) + +///someone is changing health state, end the fight in crit +/datum/sparring_match/proc/check_for_victory(datum/participant, new_stat) + SIGNAL_HANDLER + + //death needs to be a flub, conscious means they haven't won + if(new_stat == CONSCIOUS || new_stat == DEAD) + return + if(participant == chaplain) + end_match(opponent, chaplain) + else + end_match(chaplain, opponent) + +// SIGNALS THAT ARE FOR BEING ATTACKED FIRST (GUILTY) +/datum/sparring_match/proc/outsider_interference(datum/source, obj/item/I, mob/attacker) + SIGNAL_HANDLER + if(attacker == chaplain || attacker == opponent) + return + INVOKE_ASYNC(src, .proc/flub, attacker) + +/datum/sparring_match/proc/hulk_interference(datum/source, mob/attacker) + SIGNAL_HANDLER + if((attacker == chaplain || attacker == opponent)) + // fist fighting a hulk is so dumb. i can't fathom why you would do this. + return + INVOKE_ASYNC(src, .proc/flub, attacker) + +/datum/sparring_match/proc/hand_interference(datum/source, mob/living/attacker) + SIGNAL_HANDLER + if(attacker == chaplain || attacker == opponent) + //you can pretty much always use fists as a participant + return + + INVOKE_ASYNC(src, .proc/flub, attacker) + +/datum/sparring_match/proc/paw_interference(datum/source, mob/living/attacker) + SIGNAL_HANDLER + + if(attacker == chaplain || attacker == opponent) + //you can pretty much always use paws as a participant + return + + INVOKE_ASYNC(src, .proc/flub, attacker) + +/datum/sparring_match/proc/thrown_interference(datum/source, atom/movable/thrown_movable, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) + SIGNAL_HANDLER + if(istype(thrown_movable, /obj/item)) + var/mob/living/honorbound = source + var/obj/item/thrown_item = thrown_movable + var/mob/thrown_by = thrown_item.thrownby?.resolve() + if(thrown_item.throwforce < honorbound.health && ishuman(thrown_by)) + INVOKE_ASYNC(src, .proc/flub, thrown_by) + +/datum/sparring_match/proc/projectile_interference(datum/participant, obj/projectile/proj) + SIGNAL_HANDLER + if(proj.firer == chaplain || proj.firer == opponent) + //oh, well that's allowed. or maybe it isn't. doesn't matter because firing the gun will trigger a violation, so no additional violation needed + return + var/mob/living/interfering + if(isliving(proj.firer)) + interfering = proj.firer + INVOKE_ASYNC(src, .proc/flub, interfering) + +///someone randomly fucking died +/datum/sparring_match/proc/death_flub(datum/deceased) + SIGNAL_HANDLER + + flubbed_match() + +///someone randomly fucking deleted +/datum/sparring_match/proc/deletion_flub(datum/qdeleting) + SIGNAL_HANDLER + + flubbed_match() + +///someone used a gun +/datum/sparring_match/proc/gun_violation(datum/offender) + SIGNAL_HANDLER + violation(offender, "using guns") + +///someone used a grenade +/datum/sparring_match/proc/grenade_violation(datum/offender) + SIGNAL_HANDLER + violation(offender, "using grenades") + +///someone used melee weapons +/datum/sparring_match/proc/melee_violation(datum/offender, obj/item/thing, mob/user, params) + SIGNAL_HANDLER + + if(weapons_condition != CONDITION_CEREMONIAL_ONLY) + violation(offender, "using melee weapons") + if(istype(thing, /obj/item/ceremonial_blade)) + return + violation(offender, "using non ceremonial weapons") + +/datum/sparring_match/proc/teleport_violation(datum/offender) + SIGNAL_HANDLER + if(offender == chaplain) + end_match(opponent, chaplain, violation_victory = TRUE) + else + end_match(chaplain, opponent, violation_victory = TRUE) + +///someone tried to leave +/datum/sparring_match/proc/arena_violation(atom/movable/mover, atom/oldloc, direction) + SIGNAL_HANDLER + + var/area/inhabited_area = get_area(mover) + if(inhabited_area == arena_condition) + return //still in the ring!! :) + + violation(mover, "leaving the arena") + var/atom/throw_target = get_edge_target_turf(mover, REVERSE_DIR(direction)) + mover.throw_at(throw_target, 6, 4) + +/datum/sparring_match/proc/violation(mob/living/carbon/human/offender, reason) + SIGNAL_HANDLER + + to_chat(offender, span_userdanger("Violation! No [reason]!")) + if(offender == chaplain) + chaplain_violations_allowed-- + if(!chaplain_violations_allowed) + end_match(opponent, chaplain, violation_victory = TRUE) + else + opponent_violations_allowed-- + if(!opponent_violations_allowed) + end_match(chaplain, opponent, violation_victory = TRUE) + +/datum/sparring_match/proc/flub(mob/living/interfering) + if(interfering) + var/list/possible_punishments = list(PUNISHMENT_OMEN, PUNISHMENT_LIGHTNING) + if(ishuman(interfering)) + possible_punishments += PUNISHMENT_BRAND + switch(pick(possible_punishments)) + if(PUNISHMENT_OMEN) + to_chat(interfering, span_warning("You get a bad feeling... for interfering with [chaplain]'s sparring match...")) + interfering.AddComponent(/datum/component/omen, TRUE, null, FALSE) + if(PUNISHMENT_LIGHTNING) + to_chat(interfering, span_warning("[GLOB.deity] has punished you for interfering with [chaplain]'s sparring match!")) + lightningbolt(interfering) + if(PUNISHMENT_BRAND) + var/mob/living/carbon/human/branded = interfering + to_chat(interfering, span_warning("[GLOB.deity] brands your flesh for interfering with [chaplain]'s sparring match!!")) + var/obj/item/bodypart/branded_limb = pick(branded.bodyparts) + branded_limb.force_wound_upwards(/datum/wound/burn/severe/brand) + branded.emote("scream") + + flubs-- + if(!flubs) //too many interferences + flubbed_match() + +///this match was interfered on, nobody wins or loses anything, just end +/datum/sparring_match/proc/flubbed_match() + cleanup_sparring_match() + + if(chaplain) //flubing means we don't know who is still standing + to_chat(chaplain, span_boldannounce("The match was flub'd! No winners, no losers. You may restart the match with another contract.")) + if(opponent) + to_chat(opponent, span_boldannounce("The match was flub'd! No winners, no losers.")) + qdel(src) + +///helper to remove all the effects after a match ends +/datum/sparring_match/proc/cleanup_sparring_match() + REMOVE_TRAIT(chaplain, TRAIT_SPARRING, TRAIT_GENERIC) + REMOVE_TRAIT(opponent, TRAIT_SPARRING, TRAIT_GENERIC) + unhook_signals(chaplain) + unhook_signals(opponent) + chaplain.remove_filter("sparring_outline") + opponent.remove_filter("sparring_outline") + +/datum/sparring_match/proc/end_match(mob/living/carbon/human/winner, mob/living/carbon/human/loser, violation_victory = FALSE) + cleanup_sparring_match() + to_chat(chaplain, span_boldannounce("[violation_victory ? "[loser] DISQUALIFIED!" : ""] [winner] HAS WON!")) + to_chat(opponent, span_boldannounce("[violation_victory ? "[loser] DISQUALIFIED!" : ""] [winner] HAS WON!")) + win(winner, loser, violation_victory) + lose(loser, winner) + if(stakes_condition != STAKES_YOUR_SOUL) + var/healing_message = "You may want to heal up the loser now." + if(winner == chaplain) + healing_message += " Your bible will heal the loser for awhile." + to_chat(winner, span_notice(healing_message)) + qdel(src) + +///most of the effects are handled on `lose()` instead. +/datum/sparring_match/proc/win(mob/living/carbon/human/winner, mob/living/carbon/human/loser, violation_victory) + switch(stakes_condition) + if(STAKES_HOLY_MATCH) + if(winner == chaplain) + if(violation_victory) + to_chat(winner, span_warning("[GLOB.deity] is not entertained from a matched decided by violations. No favor awarded...")) + else + to_chat(winner, span_nicegreen("You've won favor with [GLOB.deity]!")) + var/datum/religion_sect/spar/sect = GLOB.religious_sect + sect.adjust_favor(1, winner) + sect.past_opponents += WEAKREF(loser) + if(STAKES_MONEY_MATCH) + to_chat(winner, span_nicegreen("You've won all of [loser]'s money!")) + if(STAKES_YOUR_SOUL) + to_chat(winner, span_nicegreen("You've won [loser]'s SOUL!")) + +/datum/sparring_match/proc/lose(mob/living/carbon/human/loser, mob/living/carbon/human/winner) + if(!loser) //shit happened? + return + switch(stakes_condition) + if(STAKES_HOLY_MATCH) + if(loser == chaplain) + var/datum/religion_sect/spar/sect = GLOB.religious_sect + sect.matches_lost++ + if(sect.matches_lost < 3) + to_chat(loser, span_userdanger("[GLOB.deity] is angry you lost in their name!")) + return + to_chat(loser, span_userdanger("[GLOB.deity] is enraged by your lackluster sparring record!")) + lightningbolt(loser) + SEND_SIGNAL(loser, COMSIG_ADD_MOOD_EVENT, "sparring", /datum/mood_event/banished) + loser.mind.holy_role = NONE + to_chat(loser, span_userdanger("You have been excommunicated! You are no longer holy!")) + if(STAKES_MONEY_MATCH) + to_chat(loser, span_userdanger("You've lost all your money to [winner]!")) + var/datum/bank_account/loser_account = loser.get_bank_account() + var/datum/bank_account/winner_account = winner.get_bank_account() + if(!loser_account || !winner_account)//the winner is pretty owned in this case but whatever shoulda read the fine print of the contract + return + winner_account.transfer_money(loser_account, loser_account.account_balance) + if(STAKES_YOUR_SOUL) + var/turf/shard_turf = get_turf(loser) + if(!shard_turf) + return + to_chat(loser, span_userdanger("You've lost ownership over your soul to [winner]!")) + var/obj/item/soulstone/anybody/chaplain/sparring/shard = new(shard_turf) + shard.capture_soul(loser, winner, forced = TRUE) diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index f78bc77de47..83eefbc5fb6 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -253,9 +253,6 @@ if(owner.reagents.get_reagent_amount(/datum/reagent/medicine/ephedrine) < 20) owner.reagents.add_reagent(/datum/reagent/medicine/ephedrine, 10) - - - /obj/item/organ/heart/ethereal name = "crystal core" icon_state = "ethereal_heart" //Welp. At least it's more unique in functionaliy. diff --git a/icons/obj/hand_of_god_structures.dmi b/icons/obj/hand_of_god_structures.dmi index 25ef4c527bccb1359182d65d2bbcf77fc2c7acc8..4c19d560b22d36c3ee0037a51ba84889c79d3fae 100644 GIT binary patch literal 31756 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 R@N?QA9Zds`dNs$${{`cSS^WS2 diff --git a/icons/obj/items/ritual_weapon.dmi b/icons/obj/items/ritual_weapon.dmi new file mode 100644 index 0000000000000000000000000000000000000000..806f1014e7b0d0bc8f1c95b57ab7a8b22074a274 GIT binary patch literal 1728 zcmZuydoUa57Egi@Z;_@|TaT=eXjCp8Y&VpMN@x)jK~sH2-D;|+nl>u7R@Dk+lX}D^ zZINZYwoR?AT#1RUrIHQW={A(mcon6pMS}L~wljC{-22D*&isDA^L=yXH|LvkJuD>9 z#Biq}001x{5eea2`PNo24ZvGx;fdqcTdDCSD z1Ewc-H)aIl+G&0Pb^hx{9CFnV0ul}#TeT`Mx3u84q%U~W$20etS-w@@vSr_Uj@U8d z5!b{!Zge%Li@Mv9@@u30c8o4~XRzs_cyBC)WMw>mKNX_Ww0cdHAaH)Tqp9UY1yVOC zt&`Ctg<4hr;QgS*Nu+%}-@C2*bVE~{eXlgzxfHYUctDyod)roj6ZB~Ka@HVx(i;HK zQ;-OLk(pJmez;3lAAkk4z>}T`f-Uuk)ipE=yOa%!yx|T1AW!sQjoh=w#6y+PQmJ?6 zEnPXKAL;g6B`ErrmnB~37B0K5-Un~wF#`S1_dJLlQK|e5;ET_6%+LB;qzIM9h3(W? z;RCVweUD8S@jTG%nog@`UYm^T)rY}T+J?zoMYE!t%kcFBUKEY=UpP{qx-ctTLfM89 zJCl~%hF!Gcqnx_AS|4tN#>U3xN&;&VmIhSH6aP$9Q+zsOd^47n@06KkW?0yb5k^Lq z$LOSWne?FUNl*R}KI@`J&|sm|`wJY>{Rk+Z0Zb$4=ykLcee4DCNdF}C({1vkj+;Rb z-AClZ?Rf(<`dpl@Vd{bIee6^K)&R!7Lw@+;2E!QF=h?he+oKMqHFr zKGk-M7@a?g0mOwv_n7lj!a3n}JKGz3Mu~%mdPZK!U#le9I)IgR?^;cCboB11P0=uS zeA8AErV{WBrw@yRV>()0mKRoNYg6m4K!7T1ecKhSrcFTOJuOyMDy@Eg_q|HHR5o@P z7`I>3WSfnq!ah?I70f37#?xZSUOwcRwpSwRuxhuJfcvMG+`UHiLjP30*UYWHaLSI& z?x03ke;8LBy*Bv!{v*>3NfnbWK5=CpOux6Sh^m?iOasT zneEMI4&eJ_GimSJC^&8z%fDXza{Wr{2%UT5XEp<^xGyx?K^B+59Wb1md@Vkp)%8nE z#dS}v{Po&e{?MpwY3)%orw!E3+s$m`JE~4Z(#VI0!@j5Kl$MmZ-Cn% zr!TDTqTmIn*=ttjS+QGK^iBF!f%G6@4j7jxP4iJ!53o6=%cU{c5z3< z*`n~dqAXR*)4A3Q70DB9#Vpk4GK5DR!l{o93|o&Tic6GM{f{G9XweA0E-A;$3GU9B zG?C34&m8tqr~=P)X&1hFUj1v=I5u-5A-~U{%@n1XMN~0MTlPpHs98M7@c(*8^z{q) zFR8%LYqj8Fy{we@giTo+x(lGH4h5Fp-{QAv;vg*!4kgn& zIAZ6$8Mj4xc)iG5L!)zm0uWF1H6M9<8XSr&B>Xe>+X`mc0e|*QtQ50+-`++f=1ssUHr5HQEWBjjdOTGz z1V1m|4w-r9>6GiTMYcmMBGV!8zYX30826uf+>$1DjqSHD2sq@bx+JIJ{$P?bvN!@T z#5>X5M(^aS99I9B!3l>M`N7d6$b5gIPRftFd8Vu!pTCbM1C$&x`Xfsjj>Fw za=;Z2s#!dF`CCl+QUvfveH#*?JEofE?kFkjT&rj12fL}ugM(t6xdV5K*4vIDg1o}< z(w=F313SBf)t5qPYGaAGpvD~EnIA)p;WC)Idy#{Uay$rJ?NQG$L)D!I|NResw&R1& Yfc~DxfV-QOTPq1b3J4)I;}gF5H>CI}QUCw| literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index 66810c350a5..583b5140f76 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -122,6 +122,7 @@ #include "code\__DEFINES\reactions.dm" #include "code\__DEFINES\reagents.dm" #include "code\__DEFINES\reagents_specific_heat.dm" +#include "code\__DEFINES\religion.dm" #include "code\__DEFINES\research.dm" #include "code\__DEFINES\robots.dm" #include "code\__DEFINES\role_preferences.dm" @@ -629,6 +630,7 @@ #include "code\datums\components\trapdoor.dm" #include "code\datums\components\twohanded.dm" #include "code\datums\components\udder.dm" +#include "code\datums\components\unbreakable.dm" #include "code\datums\components\uplink.dm" #include "code\datums\components\usb_port.dm" #include "code\datums\components\vacuum.dm" @@ -790,6 +792,7 @@ #include "code\datums\elements\strippable.dm" #include "code\datums\elements\surgery_initiator.dm" #include "code\datums\elements\swabbable.dm" +#include "code\datums\elements\tenacious.dm" #include "code\datums\elements\tool_flash.dm" #include "code\datums\elements\turf_transparency.dm" #include "code\datums\elements\undertile.dm" @@ -3441,6 +3444,9 @@ #include "code\modules\religion\religion_sects.dm" #include "code\modules\religion\religion_structures.dm" #include "code\modules\religion\rites.dm" +#include "code\modules\religion\sparring\ceremonial_gear.dm" +#include "code\modules\religion\sparring\sparring_contract.dm" +#include "code\modules\religion\sparring\sparring_datum.dm" #include "code\modules\requests\request.dm" #include "code\modules\requests\request_manager.dm" #include "code\modules\research\bepis.dm" diff --git a/tgui/packages/tgui/interfaces/SparringContract.tsx b/tgui/packages/tgui/interfaces/SparringContract.tsx new file mode 100644 index 00000000000..21daf5dd824 --- /dev/null +++ b/tgui/packages/tgui/interfaces/SparringContract.tsx @@ -0,0 +1,235 @@ +import { BooleanLike } from 'common/react'; +import { multiline } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { BlockQuote, Button, Dropdown, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +// defined this so the code is more readable +const STAKES_HOLY_MATCH = 1; + +const weaponlist = [ + "Fist Fight", + "Ceremonial Weapons", + "Melee Only", + "Any Weapons", +]; + +const stakelist = [ + "No Stakes", + "Holy Match", + "Money Match", + "Your Soul", +]; + +const weaponblurb = [ + "You will fight with your fists only. Any weapons will be considered a violation.", + "You can only fight with ceremonial weapons. You will be at a severe disadvantage without one!", + "You can fight with weapons, or fists if you have none. Ranged weapons are a violation.", + "You can fight with any and all weapons as you please. Try not to kill them, okay?", +]; + +const stakesblurb = [ + "No stakes, just for fun. Who doesn't love some recreational sparring?", + "A match for the chaplain's deity. The Chaplain suffers large consequences for failure, but advances their sect by winning.", + "A match with money on the line. Whomever wins takes all the money of whomever loses.", + "A lethal match with the loser's soul becoming under ownership of the winner.", +]; + +type Info = { + set_weapon: number; + set_area: string; + set_stakes: number; + left_sign: string; + right_sign: string; + in_area: BooleanLike; + no_chaplains: BooleanLike; + possible_areas: Array; +}; + +export const SparringContract = (props, context) => { + const { data, act } = useBackend(context); + const { + set_weapon, + set_area, + set_stakes, + possible_areas, + left_sign, + right_sign, + in_area, + no_chaplains, + } = data; + const [weapon, setWeapon] = useLocalState(context, "weapon", set_weapon); + const [area, setArea] = useLocalState(context, "area", set_area); + const [stakes, setStakes] = useLocalState(context, "stakes", set_stakes); + return ( + + +
+ + + + + Weapons: + + + + setWeapon(weaponlist.findIndex(title => ( + title === value + ))+1)} /> + + +
+ {weaponblurb[weapon-1]} +
+
+
+
+ + + + Arena: + + + setArea(value)} /> + + +
+ This fight will take place in the {area}. + Leaving the arena mid-fight is a violation. +
+
+
+
+ + + + Stakes: + + + + setStakes(stakelist.findIndex(title => ( + title === value + ))+1)} /> + + +
+ {stakesblurb[stakes-1]} +
+
+
+
+ + + + {left_sign === 'none' && ( + + ) || ( + left_sign + )} + + + VS + + + {right_sign === "none" && ( + + ) || ( + right_sign + )} + + + + + + + + + + + + + + + + +
+
+
+
+ ); +};