diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index 7e3d8d8a440b..6968b4a57d9e 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -79,6 +79,7 @@ #define SPAN_COMMAND "command_headset" #define SPAN_CLOWN "clown" #define SPAN_SINGING "singing" +#define SPAN_CULTLARGE "cultlarge" //bitflag #defines for return value of the radio() proc. #define ITALICS (1<<0) diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 83853192f03a..f94f6de03fe1 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -3,6 +3,7 @@ * Fork * Kitchen knives * Ritual Knife + * Holy Ritual Knife * Bloodletter * Butcher's cleaver * Combat Knife @@ -123,6 +124,11 @@ righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' w_class = WEIGHT_CLASS_NORMAL +/obj/item/kitchen/knife/ritual/holy + name = "ruinous knife" + desc = "The runes inscribed on the knife radiate a strange power." + force = 12 + /obj/item/kitchen/knife/bloodletter name = "bloodletter" desc = "An occult looking dagger that is cold to the touch. Somehow, the flawless orb on the pommel is made entirely of liquid blood." diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index eb371ae472ed..c240c09f42ab 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -759,3 +759,25 @@ GLOBAL_LIST_INIT(cheese_recipes, list ( /obj/item/stack/sheet/cheese/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.cheese_recipes . = ..() + +/obj/item/stack/sheet/ruinous_metal + name = "ruinous metal" + desc = "Metal with a strange aura surrounding it, along with various inscriptions etched onto the surface.." + icon_state = "sheet-runed" + item_state = "sheet-rune" + icon = 'icons/obj/stack_objects.dmi' + singular_name = "ruinous metal sheet" + sheettype = null + max_amount = 20 + novariants = TRUE + grind_results = list(/datum/reagent/iron = 5, /datum/reagent/blood = 15) + merge_type = /obj/item/stack/sheet/ruinous_metal + +GLOBAL_LIST_INIT(ruinous_metal_recipes, list ( + new/datum/stack_recipe("holy fountain", /obj/structure/holyfountain, 3, one_per_turf = 1, on_floor = 1, time = 40), \ + new/datum/stack_recipe("altar of the gods", /obj/structure/altar_of_gods, 6, one_per_turf = 1, on_floor = 1, time = 40 ))) + +/obj/item/stack/sheet/ruinous_metal/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.ruinous_metal_recipes + . = ..() + diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm index 08afc0318aaa..6a40e83c9691 100644 --- a/code/modules/food_and_drinks/food/snacks/meat.dm +++ b/code/modules/food_and_drinks/food/snacks/meat.dm @@ -295,6 +295,23 @@ filling_color = "#B22222" tastes = list("beef" = 1, "cod fish" = 1) +/obj/item/reagent_containers/food/snacks/meat/slab/blessed + name = "blessed meat" + icon_state = "shadowmeat" + desc = "It is covered in a strange darkness." + bitesize = 2 + list_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 3) //pretty healthy, chap could start a cult diner. + slice_path = null //its perfect as it is, why would you want to defile it + cooked_type = null + filling_color = "#202020" + tastes = list("holyness" = 1, "meat" = 1, "dread" = 1) + foodtype = MEAT | RAW | GROSS //they just don't understand how tasty it really is + +/obj/item/reagent_containers/food/snacks/meat/slab/blessed/weak + name = "lesser blessed meat" + icon_state = "shadowmeat" + desc = "It is covered in a strange darkness. This slab's magical properties appear to be drastically weakened due to the synthetic nature of the meat." + ////////////////////////////////////// MEAT STEAKS /////////////////////////////////////////////////////////// diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 9a602b5011e5..eed2ec6d2d74 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -1344,3 +1344,43 @@ remove_ranged_ability("Something nullifies any teleports in the local area...") return FALSE return TRUE + +/datum/species/golem/ruinous //slightly weaker and faster,gets telepathy,speaks louder, and their text is cult colored + name = "Ruinous Golem" + id = "ruinous golem" + //limbs_id = "ruingolem" //i cant get it to work, if someone else finds out what the problem is later on, be my guest, and please fix it. + //sexes = FALSE + armor = 40 //down from 55 + //species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES) //no mutcolors or eyesprites + speedmod = 1.5 //inbetween gold golem and iron + meat = /obj/item/reagent_containers/food/snacks/meat/slab/blessed + fixed_mut_color = "333" + info_text = "As an Ruinous Golem, you are made of an ancient powerful metal. While not particularly tough, you have a connection with the old gods that grants you a selection of abilities." + prefix = "Ruinous" + special_names = list("One", "Elder", "Watcher", "Walker") //ominous + var/obj/effect/proc_holder/spell/targeted/telepathy/eldritch/ruinoustelepathy + var/obj/effect/proc_holder/spell/targeted/touch/flagellate/flagellate + +/datum/species/golem/ruinous/on_species_loss(mob/living/carbon/C) + ..() + UnregisterSignal(C, COMSIG_MOB_SAY) + REMOVE_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT) + if(ruinoustelepathy) + C.RemoveSpell(ruinoustelepathy) + if(flagellate) + C.RemoveSpell(flagellate) + +/datum/species/golem/ruinous/on_species_gain(mob/living/carbon/C, datum/species/old_species) + ..() + RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) + ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT) + ruinoustelepathy = new + ruinoustelepathy.charge_counter = 0 + C.AddSpell(ruinoustelepathy) + flagellate = new + flagellate.charge_counter = 0 + C.AddSpell(flagellate) + +/datum/species/golem/ruinous/proc/handle_speech(datum/source, list/speech_args) + speech_args[SPEECH_SPANS] |= SPAN_CULTLARGE + playsound(source, 'sound/effects/curseattack.ogg', 100, 1, 1) diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm index bc846048e743..82be7e47c6a4 100644 --- a/code/modules/religion/religion_sects.dm +++ b/code/modules/religion/religion_sects.dm @@ -291,3 +291,31 @@ to_chat(L, "[GLOB.deity] happily accepts your offering, and brings the crop to a new home.") qdel(I) return TRUE + +/**** Gathering of the Old Ones sect, bless flesh and sacrifice it to gain favor for fancy runes. ****/ +// Blessed meat slabs are the currency of this sect, they use it in order to make fancy structures and runes. + +/datum/religion_sect/oldgods + name = "Gathering of the Old Ones" + desc = "A sect dedicated to the Old Gods." + convert_opener = "The great gods of old welcome you to their gathering, acolyte.
Bless slabs of meat on your altar and then sacrifice it in the name of the Old Gods." + alignment = ALIGNMENT_EVIL //kind of evil? + max_favor = 3000 + desired_items = list(/obj/item/reagent_containers/food/snacks/meat/slab/blessed) + rites_list = list(/datum/religion_rites/meatbless, /datum/religion_rites/ruinousknife, /datum/religion_rites/ruinousmetal, /datum/religion_rites/bodybless) + altar_icon_state = "convertaltar-black" + +//old ones sect bibles don't heal or do anything special apart from the standard holy water blessings +/datum/religion_sect/oldgods/sect_bless(mob/living/blessed, mob/living/user) + return TRUE + +/datum/religion_sect/oldgods/on_sacrifice(obj/item/reagent_containers/food/snacks/meat/slab/blessed/offering, mob/living/user) + if(!istype(offering)) + return + to_chat(user, " An image of [GLOB.deity] flashes in your mind. They look pleased.") + if(istype(offering, /obj/item/reagent_containers/food/snacks/meat/slab/blessed/weak)) + adjust_favor(10, user) + else + adjust_favor(75, user) + qdel(offering) + return TRUE diff --git a/code/modules/religion/religion_structures.dm b/code/modules/religion/religion_structures.dm index 15dbc80e1cef..96bbc4c4338a 100644 --- a/code/modules/religion/religion_structures.dm +++ b/code/modules/religion/religion_structures.dm @@ -42,4 +42,37 @@ if(sect_to_altar.altar_icon) icon = sect_to_altar.altar_icon if(sect_to_altar.altar_icon_state) - icon_state = sect_to_altar.altar_icon_state \ No newline at end of file + icon_state = sect_to_altar.altar_icon_state + +//****Old Gods sect structures****// + +/obj/structure/holyfountain //reskinned healing fountain, but different enough i guess + name = "blessed fountain" + desc = "A dark fountain filled with some kind of strange liquid." + icon = 'icons/obj/hand_of_god_structures.dmi' + icon_state = "fountain-black" + anchored = TRUE + density = TRUE + var/time_between_uses = 1800 + var/last_process = 0 + +/obj/structure/holyfountain/attack_hand(mob/living/user) + . = ..() + if(.) + return + if(last_process + time_between_uses > world.time) + to_chat(user, "The fountain appears to be empty.") + return + last_process = world.time + to_chat(user, "The liquid feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.") + user.reagents.add_reagent(/datum/reagent/medicine/omnizine/godblood,10) //Hurts your brain and makes you go insane + user.reagents.add_reagent(/datum/reagent/toxin/mindbreaker,10) //However, it gives rather potent healing. + update_icon() + addtimer(CALLBACK(src, .proc/update_icon), time_between_uses) + + +/obj/structure/holyfountain/update_icon() + if(last_process + time_between_uses > world.time) + icon_state = "fountain" + else + icon_state = "fountain-black" diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm index 3f5b71dd1a02..ebe96e506ef2 100644 --- a/code/modules/religion/rites.dm +++ b/code/modules/religion/rites.dm @@ -378,3 +378,108 @@ var/altar_turf = get_turf(religious_tool) new /obj/effect/mob_spawn/photogeist(altar_turf) return TRUE + +/*********Old Ones**********/ + +/datum/religion_rites/ruinousknife + name = "Ruinous Knife" + desc = "Creates a knife that is mostly cosmetic, but is also a weapon." + ritual_length = 5 SECONDS + invoke_msg = "please, old ones, lend us a tool of holy creation." + favor_cost = 50 + +/datum/religion_rites/ruinousknife/invoke_effect(mob/living/user, atom/movable/religious_tool) + var/altar_turf = get_turf(religious_tool) + new /obj/item/kitchen/knife/ritual/holy(altar_turf) + playsound(altar_turf, 'sound/magic/enter_blood.ogg', 50, TRUE) + return TRUE + +/datum/religion_rites/meatbless + name = "Meat Blessing" + desc = "Bless a piece of meat. Preps it for sacrifice" + ritual_length = 2 SECONDS + //no invoke message, this does a custom one down below in invoke_effect + ///the piece of meat that will be blessed, only one per rite + var/obj/item/reagent_containers/food/snacks/meat/slab/chosen_meat + +/datum/religion_rites/meatbless/perform_rite(mob/living/user, atom/religious_tool) + for(var/obj/item/reagent_containers/food/snacks/meat/slab/offering in get_turf(religious_tool)) + if(istype(offering, /obj/item/reagent_containers/food/snacks/meat/slab/blessed)) + continue //we ignore anything that is already blessed + chosen_meat = offering //the meat has been chosen by our lord and savior + return ..() + return FALSE + +/datum/religion_rites/meatbless/invoke_effect(mob/living/user, atom/religious_tool) + if(!QDELETED(chosen_meat) && get_turf(religious_tool) == chosen_meat.loc) //check if the same meat is still there + var/altar_turf = get_turf(religious_tool) + playsound(get_turf(religious_tool), 'sound/magic/enter_blood.ogg', 50, TRUE) + if(istype(chosen_meat, /obj/item/reagent_containers/food/snacks/meat/slab/synthmeat)) + new /obj/item/reagent_containers/food/snacks/meat/slab/blessed/weak(altar_turf) + else + new /obj/item/reagent_containers/food/snacks/meat/slab/blessed(altar_turf) + qdel(chosen_meat) + chosen_meat = null //our lord and savior no longer cares about this meat + var/mb_message = pick("old ones, I bless this meat for you!", "old ones, I bless this flesh in your name", "old ones, I empower this flesh in your name.") + user.say(mb_message, forced = "ritual") //chooses one of three invoke messages to say in order to avoid auto mute and add variety. + return TRUE + chosen_meat = null + to_chat(user, "The meat that was chosen for the rite is no longer on the altar!") + return FALSE + +/datum/religion_rites/ruinousmetal + name = "Ruinous Metal" + desc = "Creates a piece of metal that can create various holy structures." + ritual_length = 5 SECONDS + invoke_msg = "please, old ones, lend us some of your holy material." + favor_cost = 150 + +/datum/religion_rites/ruinousmetal/invoke_effect(mob/living/user, atom/movable/religious_tool) + var/altar_turf = get_turf(religious_tool) + new /obj/item/stack/sheet/ruinous_metal(altar_turf) + playsound(altar_turf, 'sound/magic/enter_blood.ogg', 50, TRUE) + return TRUE + +/datum/religion_rites/bodybless + name = "Body Blessing" + desc = "Convert a human-esque individual into a being of ruinous metal." + ritual_length = 1 MINUTES + ritual_invocations = list( + "Let us call upon the blessings of the old gods...", + "... Show them one that is worthy of greatness...", + "... And allow them to bless this one with a great power..." + ) + invoke_msg = "... Become one with the blessings of our gods, arise great one!!" + favor_cost = 2000 // 27 slabs of blessed meat/200 blessed synthetic meat, more expensive than working with xenobio. + +/datum/religion_rites/bodybless/perform_rite(mob/living/user, atom/religious_tool) + if(!ismovable(religious_tool)) + to_chat(user, "This rite requires a religious device that individuals can be buckled to.") + return FALSE + var/atom/movable/movable_reltool = religious_tool + if(!movable_reltool) + return FALSE + if(!LAZYLEN(movable_reltool.buckled_mobs)) + . = FALSE + if(!movable_reltool.can_buckle) //yes, if you have somehow managed to have someone buckled to something that now cannot buckle, we will still let you perform the rite! + to_chat(user, "This rite requires a religious device that individuals can be buckled to.") + return + to_chat(user, "This rite requires an individual to be buckled to [movable_reltool].") + return + return ..() + +/datum/religion_rites/bodybless/invoke_effect(mob/living/user, atom/religious_tool) + if(!ismovable(religious_tool)) + CRASH("[name]'s perform_rite had a movable atom that has somehow turned into a non-movable!") + var/atom/movable/movable_reltool = religious_tool + if(!movable_reltool?.buckled_mobs?.len) + return FALSE + var/mob/living/carbon/human/human2ruinous + for(var/i in movable_reltool.buckled_mobs) + if(istype(i,/mob/living/carbon/human)) + human2ruinous = i + break + if(!human2ruinous) + return FALSE + human2ruinous.set_species(/datum/species/golem/ruinous) + human2ruinous.visible_message("[human2ruinous] has been converted by the rite of [name]!") diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index 5477e1cdf970..d5b2be39e4a5 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -83,7 +83,8 @@ /obj/item/stack/sheet/cheese = /datum/species/golem/cheese, /obj/item/stack/telecrystal = /datum/species/golem/telecrystal, /obj/item/stack/telecrystal/five = /datum/species/golem/telecrystal, - /obj/item/stack/telecrystal/twenty = /datum/species/golem/telecrystal) + /obj/item/stack/telecrystal/twenty = /datum/species/golem/telecrystal, + /obj/item/stack/sheet/ruinous_metal = /datum/species/golem/ruinous) if(istype(I, /obj/item/stack)) var/obj/item/stack/O = I diff --git a/code/modules/spells/spell_types/godhand.dm b/code/modules/spells/spell_types/godhand.dm index 927bef94ba3b..c6890ded697b 100644 --- a/code/modules/spells/spell_types/godhand.dm +++ b/code/modules/spells/spell_types/godhand.dm @@ -107,3 +107,34 @@ M.Stun(40) M.petrify() return ..() + +/obj/item/melee/touch_attack/flagellate + name = "\improper flagellating touch" + desc = "I'd like to see them greytide me now." + catchphrase = "RETRIBUTION!!" + on_use_sound = 'sound/magic/wandodeath.ogg' + icon_state = "flagellation" + item_state = "hivehand" + +/obj/item/melee/touch_attack/flagellate/afterattack(atom/target, mob/living/carbon/user, proximity) + if(!proximity || target == user || !isliving(target) || !iscarbon(user)) //flagellating your own mind painfully wouldn't be THAT bad but still bad + return + if(!(user.mobility_flags & MOBILITY_USE)) + to_chat(user, "You can't reach out!") + return + if(!user.can_speak_vocal()) + to_chat(user, "You can't get the words out!") + return + var/mob/living/M = target + if(M.anti_magic_check()) + to_chat(user, "The spell can't seem to affect [M]!") + to_chat(M, "You feel faint energies trying to get into your head, before they suddenly vanish!") + ..() + return + M.adjustBruteLoss(18) //same as nullrod, but with a large cooldown, so it should be fine + M.blur_eyes(10) + M.confused = max(M.confused, 6) + M.visible_message("[M] cringes in pain as they hold their head for a second!") + M.emote("scream") + to_chat(M, "You feel an explosion of pain erupt in your mind!") + return ..() diff --git a/code/modules/spells/spell_types/touch_attacks.dm b/code/modules/spells/spell_types/touch_attacks.dm index 4618c78b8a50..b931b6524473 100644 --- a/code/modules/spells/spell_types/touch_attacks.dm +++ b/code/modules/spells/spell_types/touch_attacks.dm @@ -76,3 +76,16 @@ action_icon_state = "statue" sound = 'sound/magic/fleshtostone.ogg' + +/obj/effect/proc_holder/spell/targeted/touch/flagellate //doesn't do much, mostly cosmetic punishment tool for chaplains + name = "Flagellate" + desc = "This spell charges your hand with the power of the old gods, allowing you to flagellate heathens." + hand_path = /obj/item/melee/touch_attack/flagellate + clothes_req = FALSE + + charge_max = 300 //its very weak so it doesn't need a super long cooldown. 30 second cooldown + + action_icon = 'icons/mob/actions/actions_cult.dmi' + action_icon_state = "horror" + action_background_icon_state = "bg_ecult" + sound = 'sound/magic/fleshtostone.ogg' diff --git a/code/modules/spells/spell_types/voice_of_god.dm b/code/modules/spells/spell_types/voice_of_god.dm index 1552278189bb..da3256350e57 100644 --- a/code/modules/spells/spell_types/voice_of_god.dm +++ b/code/modules/spells/spell_types/voice_of_god.dm @@ -42,4 +42,4 @@ power_mod = 0.1 cooldown_mod = 0.5 spans = list("clown") - speech_sound = 'sound/spookoween/scary_horn2.ogg' \ No newline at end of file + speech_sound = 'sound/spookoween/scary_horn2.ogg' diff --git a/icons/mob/human_parts.dmi b/icons/mob/human_parts.dmi index b0beb21017c9..45b66bef44dd 100644 Binary files a/icons/mob/human_parts.dmi and b/icons/mob/human_parts.dmi differ diff --git a/icons/obj/hand_of_god_structures.dmi b/icons/obj/hand_of_god_structures.dmi index 4b908e5453f5..7fb5c00a8844 100644 Binary files a/icons/obj/hand_of_god_structures.dmi and b/icons/obj/hand_of_god_structures.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 30e942c9bbe5..2f1eed026b4b 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ