diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index e1228b1506c4..52f595380821 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -51,6 +51,7 @@
#define ROLE_VAMPIRICACCIDENT "Vampiric Accident"
#define ROLE_BLOODSUCKERBREAKOUT "Bloodsucker Breakout"
#define ROLE_MONSTERHUNTER "Monster Hunter"
+#define ROLE_SINFULDEMON "Demon of Sin"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
@@ -91,6 +92,7 @@ GLOBAL_LIST_INIT(special_roles, list(
ROLE_FUGITIVE,
ROLE_BLOODSUCKER = /datum/game_mode/bloodsucker,
ROLE_MONSTERHUNTER,
+ ROLE_SINFULDEMON
))
//Job defines for what happens when you fail to qualify for any job during job selection
diff --git a/code/__DEFINES/{yogs_defines}/antagonists.dm b/code/__DEFINES/{yogs_defines}/antagonists.dm
index 0cfa66b79b1c..7afc8ce41334 100644
--- a/code/__DEFINES/{yogs_defines}/antagonists.dm
+++ b/code/__DEFINES/{yogs_defines}/antagonists.dm
@@ -5,6 +5,7 @@
#define ANTAG_DATUM_VEIL /datum/antagonist/veil
#define ANTAG_DATUM_INFILTRATOR /datum/antagonist/infiltrator
#define ANTAG_DATUM_HIJACKEDAI /datum/antagonist/hijacked_ai
+#define ANTAG_DATUM_SINFULDEMON /datum/antagonist/sinfuldemon
#define NOT_DOMINATING -1
#define MAX_LEADERS_GANG 3
diff --git a/code/__DEFINES/{yogs_defines}/is_helpers.dm b/code/__DEFINES/{yogs_defines}/is_helpers.dm
index c694ceab2ea0..2d0791cb8c73 100644
--- a/code/__DEFINES/{yogs_defines}/is_helpers.dm
+++ b/code/__DEFINES/{yogs_defines}/is_helpers.dm
@@ -8,6 +8,8 @@
#define is_clockcult(M) (istype(M, /mob/living) && M.mind && M.mind.has_antag_datum(/datum/antagonist/clockcult))
+#define is_sinfuldemon(M) (M.mind && M.mind.has_antag_datum(/datum/antagonist/sinfuldemon))
+
#define is_mindslaved(M) (istype(M, /mob/living) && M.mind && M.mind.has_antag_datum(/datum/antagonist/mindslave))
#define is_traitor(M) (istype(M, /mob/living) && M.mind && M.mind.has_antag_datum(/datum/antagonist/traitor) || is_mindslaved(M))
#define is_blood_brother(M) (istype(M, /mob/living) && M.mind && M.mind.has_antag_datum(/datum/antagonist/brother))
diff --git a/code/modules/antagonists/demon/demons.dm b/code/modules/antagonists/demon/demons.dm
new file mode 100644
index 000000000000..98955d468ae1
--- /dev/null
+++ b/code/modules/antagonists/demon/demons.dm
@@ -0,0 +1,173 @@
+#define SIN_GLUTTONY "gluttony"
+#define SIN_GREED "greed"
+#define SIN_SLOTH "sloth"
+#define SIN_WRATH "wrath"
+#define SIN_ENVY "envy"
+#define SIN_PRIDE "pride"
+
+/mob/living/carbon/human/Life()
+ . = ..()
+ if(is_sinfuldemon(src))
+ var/datum/antagonist/sinfuldemon/demon = mind.has_antag_datum(/datum/antagonist/sinfuldemon)
+ demon.sinfuldemon_life()
+
+/datum/antagonist/sinfuldemon
+ name = "Sinful Demon"
+ roundend_category = "demons of sin"
+ antagpanel_category = "Demon"
+ job_rank = ROLE_SINFULDEMON
+ show_to_ghosts = TRUE
+ ///The sin a specific demon is assigned to. Defines what objectives and powers they'll receive.
+ var/demonsin
+ ///The list of choosable sins for demons. One will be assigned to a demon when spawned naturally.
+ var/static/list/demonsins = list(SIN_GLUTTONY, SIN_GREED, SIN_WRATH, SIN_ENVY, SIN_PRIDE)
+ var/static/list/demon_spells = typecacheof(list(
+ /obj/effect/proc_holder/spell/targeted/shapeshift/demon,
+ /obj/effect/proc_holder/spell/targeted/shapeshift/demon/gluttony,
+ /obj/effect/proc_holder/spell/targeted/shapeshift/demon/wrath,
+ /obj/effect/proc_holder/spell/targeted/forcewall/gluttony,
+ /obj/effect/proc_holder/spell/aoe_turf/conjure/summon_greedslots,
+ /obj/effect/proc_holder/spell/targeted/inflict_handler/ignite,
+ /obj/effect/proc_holder/spell/targeted/touch/envy,
+ /obj/effect/proc_holder/spell/aoe_turf/conjure/summon_mirror))
+
+/datum/antagonist/sinfuldemon/proc/sinfuldemon_life()
+ var/mob/living/carbon/C = owner.current
+ if(!C)
+ return
+ if(istype(get_area(C), /area/chapel))
+ demon_burn()
+
+///Handles burning and hurting sinful demons while they're in the chapel.
+/datum/antagonist/sinfuldemon/proc/demon_burn() //sinful demons are even more vulnerable to the chapel than vampires, but can turn into their true form to negate this.
+ var/mob/living/L = owner.current
+ if(!L)
+ return
+ if(L.stat != DEAD) //demons however wont dust from the chapel so this needs to be a check to avoid spam while they're already dead
+ if(prob(50) && L.health >= 50)
+ switch(L.health)
+ if(85 to 100)
+ L.visible_message(span_warning("[L]'s skin begins to heat up and darken!"), span_danger("Your flesh begins to sear..."))
+ if(60 to 85)
+ L.visible_message(span_warning("[L]'s skin begins to melt apart!"), span_danger("Your skin is melting!"), "You hear sizzling.")
+ L.adjustFireLoss(5)
+ else if(L.health < 60)
+ if(!L.on_fire)
+ L.visible_message(span_warning("[L] lights up in a holy blaze!"), span_danger("Your skin catches fire!"))
+ L.emote("scream")
+ else
+ L.visible_message(span_warning("[L] continues to burn!"), span_danger("You continue to burn!"))
+ L.adjust_fire_stacks(5)
+ L.IgniteMob()
+ return
+
+/datum/antagonist/sinfuldemon/New()
+ . = ..()
+ demonsin = pick(demonsins)
+
+/datum/antagonist/sinfuldemon/proc/forge_objectives()
+ var/datum/objective/demon/O
+ switch(demonsin)//the 5 most interesting of the 8 sins. Left out sloth because it sounds boring, couldn't think of a good enough objective/power for acedia, and lust for obvious reasons.
+ if(SIN_GLUTTONY)
+ O = new /datum/objective/demon/gluttony
+ if(SIN_GREED)
+ O = new /datum/objective/demon/greed
+ if(SIN_WRATH)
+ O = new /datum/objective/demon/wrath
+ if(prob(50))
+ var/N = pick(/datum/objective/assassinate, /datum/objective/assassinate/cloned, /datum/objective/assassinate/once)
+ var/datum/objective/assassinate/kill_objective = new N
+ kill_objective.owner = owner
+ kill_objective.find_target()
+ objectives += kill_objective
+ if(SIN_ENVY)
+ O = new /datum/objective/demon/envy
+ if(prob(50))
+ var/datum/objective/escape/escape_with_identity/identity_theft = new
+ identity_theft.owner = owner
+ identity_theft.find_target()
+ identity_theft.update_explanation_text()
+ objectives += identity_theft
+ if(SIN_PRIDE)
+ O = new /datum/objective/demon/pride
+ objectives += O
+
+/datum/antagonist/sinfuldemon/can_be_owned(datum/mind/new_owner)
+ . = ..()
+ return . && (ishuman(new_owner.current) || iscyborg(new_owner.current))
+
+/datum/antagonist/sinfuldemon/admin_add(datum/mind/new_owner,mob/admin)
+ var/choices = demonsins + "Random"
+ var/chosen_sin = input(admin,"What kind ?","Sin kind") as null|anything in choices
+ if(!chosen_sin)
+ return
+ if(chosen_sin in demonsins)
+ demonsin = chosen_sin
+ new_owner.add_antag_datum(src)
+ message_admins("[key_name_admin(admin)] has demonized [key_name_admin(new_owner)].")
+ log_admin("[key_name(admin)] has demonized [key_name(new_owner)].")
+
+/datum/antagonist/sinfuldemon/antag_listing_name()
+ return ..() + "(, demon of [demonsin])" // Boris Smith, demon of Wrath
+
+/datum/antagonist/sinfuldemon/greet()
+ to_chat(owner.current, span_warning("You remember your link to the infernal. You are a demon of [demonsin] released from hell to spread sin amongst the living."))
+ to_chat(owner.current, span_warning("However, your infernal form is not without weaknesses."))
+ to_chat(owner.current, "You are incredibly vulnerable to holy artifacts and influence.")
+ to_chat(owner.current, "While blessed with the unholy ability to transform into your true form, this form is extremely obvious and vulnerable to holy weapons.")
+ to_chat(owner.current, "[span_warning("Do your best to complete your objectives without unnessecary death, unless you are a wrathful demon.")]
")
+ owner.announce_objectives()
+ SEND_SOUND(owner.current, sound('sound/magic/ethereal_exit.ogg'))
+ .=..()
+
+/datum/antagonist/sinfuldemon/on_gain()
+ forge_objectives()
+ owner.special_role = "sinfuldemon"
+ owner.current.faction += "hell"
+ if(owner.assigned_role == "Clown" && ishuman(owner.current))
+ var/mob/living/carbon/human/S = owner.current
+ to_chat(S, span_notice("Your infernal nature has allowed you to overcome your clownishness."))
+ S.dna.remove_mutation(CLOWNMUT)
+ switch(demonsin)
+ if(SIN_GLUTTONY)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/shapeshift/demon/gluttony)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall/gluttony)
+ if(SIN_GREED)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/shapeshift/demon)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/summon_greedslots)
+ if(SIN_WRATH)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/shapeshift/demon/wrath)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/inflict_handler/ignite)
+ if(SIN_ENVY)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/shapeshift/demon)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/touch/envy)
+ if(SIN_PRIDE)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/shapeshift/demon)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/summon_mirror)
+ .=..()
+
+/datum/antagonist/sinfuldemon/on_removal()
+ owner.special_role = null
+ owner.current.faction -= "hell"
+ remove_spells()
+ to_chat(owner.current, span_userdanger("Your infernal link has been severed! You are no longer a demon!"))
+ .=..()
+
+/datum/antagonist/sinfuldemon/proc/remove_spells()
+ for(var/X in owner.spell_list)
+ var/obj/effect/proc_holder/spell/S = X
+ if(is_type_in_typecache(S, demon_spells))
+ owner.RemoveSpell(S)
+
+/datum/antagonist/sinfuldemon/roundend_report()
+ var/list/parts = list()
+ parts += printplayer(owner)
+ parts += printobjectives(objectives)
+ return parts.Join("
")
+
+#undef SIN_ENVY
+#undef SIN_GLUTTONY
+#undef SIN_GREED
+#undef SIN_PRIDE
+#undef SIN_SLOTH
+#undef SIN_WRATH
diff --git a/code/modules/antagonists/demon/general_powers.dm b/code/modules/antagonists/demon/general_powers.dm
new file mode 100644
index 000000000000..78702ac67410
--- /dev/null
+++ b/code/modules/antagonists/demon/general_powers.dm
@@ -0,0 +1,68 @@
+/obj/effect/proc_holder/spell/targeted/shapeshift/demon //emergency get out of jail card.
+ name = "Lesser Demon Form"
+ desc = "Take on your true demon form. This form is strong but very obvious, and especially weak to holy influence. \
+ Also, note that damage taken in this form can transform into your normal body. Heal by attacking living creatures before transforming back if gravely wounded!"
+ invocation = "COWER, MORTALS!!"
+ shapeshift_type = /mob/living/simple_animal/lesserdemon
+ action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
+ action_icon_state = "daemontransform"
+ action_background_icon_state = "bg_demon"
+
+/mob/living/simple_animal/lesserdemon
+ name = "demon"
+ real_name = "demon"
+ desc = "A large, menacing creature covered in armored red scales."
+ speak_emote = list("cackles")
+ emote_hear = list("cackles","screeches")
+ response_help = "thinks better of touching"
+ response_disarm = "flails at"
+ response_harm = "punches"
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "lesserdaemon"
+ icon_living = "lesserdaemon"
+ mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ speed = 0.33
+ a_intent = INTENT_HARM
+ stop_automated_movement = 1
+ status_flags = CANPUSH
+ attack_sound = 'sound/magic/demon_attack1.ogg'
+ deathsound = 'sound/magic/demon_dies.ogg'
+ deathmessage = "wails in anger and fear as it collapses in defeat!"
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 250 //Weak to cold
+ maxbodytemp = INFINITY
+ faction = list("hell")
+ attacktext = "wildly tears into"
+ maxHealth = 200
+ health = 200
+ environment_smash = ENVIRONMENT_SMASH_STRUCTURES
+ obj_damage = 40
+ melee_damage_lower = 24
+ melee_damage_upper = 24
+ wound_bonus = -15
+ see_in_dark = 8
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
+ loot = (/obj/effect/decal/cleanable/blood)
+ del_on_death = 1
+
+/mob/living/simple_animal/lesserdemon/attackby(obj/item/W, mob/living/user, params)
+ . = ..()
+ if(istype(W, /obj/item/nullrod))
+ visible_message(span_warning("[src] screams in unholy pain from the blow!"), \
+ span_cult("As \the [W] hits you, you feel holy power blast through your form, tearing it apart!"))
+ adjustBruteLoss(22) //22 extra damage from the nullrod while in your true form. On average this means 40 damage is taken now.
+
+/mob/living/simple_animal/lesserdemon/UnarmedAttack(mob/living/L, proximity)//10 hp healed from landing a hit.
+ if(isliving(L))
+ if(L.stat != DEAD && !L.anti_magic_check(TRUE, TRUE)) //demons do not gain succor from the dead or holy
+ adjustHealth(-maxHealth * 0.05)
+ return ..()
+
+/mob/living/simple_animal/lesserdemon/Life()
+ . = ..()
+ if(!src)
+ return
+ if(istype(get_area(src.loc), /area/chapel)) //being a non-carbon will not save you!
+ if(src.stat != DEAD) //being dead, however, will save you
+ src.visible_message(span_warning("[src] begins to melt apart!"), span_danger("Your very soul melts from the holy room!"), "You hear sizzling.")
+ adjustHealth(20) //20 damage every ~2 seconds. About 20 seconds for a full HP demon to melt apart in the chapel.
diff --git a/code/modules/antagonists/demon/objectives.dm b/code/modules/antagonists/demon/objectives.dm
new file mode 100644
index 000000000000..3540bbfe3842
--- /dev/null
+++ b/code/modules/antagonists/demon/objectives.dm
@@ -0,0 +1,17 @@
+/datum/objective/demon
+ completed = TRUE
+
+/datum/objective/demon/gluttony
+ explanation_text = "Devour as much food as possible."
+
+/datum/objective/demon/greed
+ explanation_text = "Acquire as much wealth as possible."
+
+/datum/objective/demon/wrath
+ explanation_text = "Inflict as much pain as possible."
+
+/datum/objective/demon/envy
+ explanation_text = "Do not allow anyone to become more popular than you."
+
+/datum/objective/demon/pride
+ explanation_text = "Become as popular, powerful, and influential to as many people possible."
diff --git a/code/modules/antagonists/demon/sins/envy.dm b/code/modules/antagonists/demon/sins/envy.dm
new file mode 100644
index 000000000000..66cfbdc7a46e
--- /dev/null
+++ b/code/modules/antagonists/demon/sins/envy.dm
@@ -0,0 +1,40 @@
+/obj/effect/proc_holder/spell/targeted/touch/envy
+ name = "Vanity Steal"
+ desc = "Engulfs your arm in a jealous might, allowing you to steal the look of the first human-like struck with it. Note, the form change is not reversible."
+ hand_path = /obj/item/melee/touch_attack/envy
+ school = "evocation"
+ charge_max = 150
+ clothes_req = FALSE
+ invocation = "ETERNAL FLAMES"
+ invocation_type = "whisper"
+ action_icon = 'icons/mob/actions/actions_changeling.dmi'
+ action_icon_state = "transform"
+ action_background_icon_state = "bg_demon"
+
+/obj/item/melee/touch_attack/envy
+ name = "Envious Hand"
+ desc = "A writhing, burning aura of jealousy, ready to be unleashed."
+ icon_state = "flagellation"
+ item_state = "hivemind"
+ catchphrase = "I'M BETTER THAN YOU!!"
+
+/obj/item/melee/touch_attack/envy/afterattack(atom/target, mob/living/carbon/human/user, proximity_flag, click_parameters)
+ if(!proximity_flag)
+ return
+ var/mob/living/M = target
+ if(M.anti_magic_check())
+ to_chat(user, span_warning("[M] resists your unholy jealousy!"))
+ to_chat(M, span_warning("A creeping feeling of jealousy dances around your mind before being suddenly dispelled."))
+ ..()
+ return
+ playsound(user, 'sound/magic/demon_attack1.ogg', 75, TRUE)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(user.real_name != H.dna.real_name)
+ user.real_name = H.dna.real_name
+ H.dna.transfer_identity(user, transfer_SE=1)
+ user.updateappearance(mutcolor_update=1)
+ user.domutcheck()
+ user.visible_message(span_warning("[user]'s appearance shifts into [H]'s!"), \
+ span_boldannounce("[H.p_they(TRUE)] think[H.p_s()] [H.p_theyre()] sooo much better than you. Not anymore, [H.p_they()] won't."))
+ return ..()
diff --git a/code/modules/antagonists/demon/sins/gluttony.dm b/code/modules/antagonists/demon/sins/gluttony.dm
new file mode 100644
index 000000000000..7720b8f9ac48
--- /dev/null
+++ b/code/modules/antagonists/demon/sins/gluttony.dm
@@ -0,0 +1,56 @@
+/obj/effect/proc_holder/spell/targeted/forcewall/gluttony
+ name = "Gluttonous Wall"
+ desc = "Create a magical barrier that only allows fat people to pass through."
+ school = "transmutation"
+ charge_max = 150
+ clothes_req = FALSE
+ invocation = "INDULGE"
+ invocation_type = "shout"
+ sound = 'sound/magic/forcewall.ogg'
+ action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
+ action_icon_state = "blob"
+ action_background_icon_state = "bg_demon"
+ range = -1
+ include_user = TRUE
+ cooldown_min = 50 //12 deciseconds reduction per rank
+ wall_type = /obj/effect/gluttony/timed
+
+/obj/effect/proc_holder/spell/targeted/shapeshift/demon/gluttony //emergency get out of jail card, but better. It also eats everything.
+ name = "Gluttony Demon Form"
+ desc = "Take on your true demon form. This form is strong but very obvious and especially weak to holy influence. \
+ Also, note that damage taken in this form can transform into your normal body. Heal by attacking living creatures before transforming back if gravely wounded! \
+ Your unique form as a demon of gluttony also allows you to eat corpses to heal yourself."
+ shapeshift_type = /mob/living/simple_animal/lesserdemon/gluttony
+
+/mob/living/simple_animal/lesserdemon/gluttony //capable of devouring corpses for health
+ name = "gluttonous demon"
+ real_name = "gluttonous demon"
+ icon_state = "lesserdaemon_gluttony"
+ icon_living = "lesserdaemon_gluttony"
+
+/mob/living/simple_animal/lesserdemon/gluttony/UnarmedAttack(mob/living/L)
+ if(isliving(L)) //Eat Corpses to regen health
+ if(L.stat == DEAD)
+ if(do_after(src, 3 SECONDS, target = L))
+ devour(L)
+ return
+ return ..()
+
+/mob/living/simple_animal/lesserdemon/gluttony/proc/devour(mob/living/L)
+ if(!L)
+ return FALSE
+ visible_message(
+ span_danger("[src] devours [L]!"),
+ span_userdanger("You feast on [L], restoring your health!"))
+ adjustBruteLoss(-50)
+ L.gib()
+ return TRUE
+
+/obj/effect/gluttony/timed
+ ///Time in deciseconds before it deletes itself.
+ var/timeleft = 150
+
+/obj/effect/gluttony/timed/Initialize()
+ . = ..()
+ if(timeleft)
+ QDEL_IN(src, timeleft)
diff --git a/code/modules/antagonists/demon/sins/greed.dm b/code/modules/antagonists/demon/sins/greed.dm
new file mode 100644
index 000000000000..248f88b7119d
--- /dev/null
+++ b/code/modules/antagonists/demon/sins/greed.dm
@@ -0,0 +1,17 @@
+/obj/effect/proc_holder/spell/aoe_turf/conjure/summon_greedslots
+ name = "Summon Slotmachine"
+ desc = "Summon forth a temporary slot machine of greed, allowing you to offer patrons a deadly game where the price is their life (and some money if you'd like) and the possible prize is a one use die of fate."
+ invocation = "Just one game?"
+ invocation_type = "whisper"
+ clothes_req = FALSE
+ charge_max = 600
+ cooldown_min = 200
+ summon_type = list(/obj/structure/cursed_slot_machine/betterchance)
+ summon_lifespan = 600
+ summon_amt = 1
+ range = 1
+ action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
+ action_icon_state = "slots"
+ action_background_icon_state = "bg_demon"
+
+
diff --git a/code/modules/antagonists/demon/sins/pride.dm b/code/modules/antagonists/demon/sins/pride.dm
new file mode 100644
index 000000000000..1bde7d4bb18a
--- /dev/null
+++ b/code/modules/antagonists/demon/sins/pride.dm
@@ -0,0 +1,17 @@
+/obj/effect/proc_holder/spell/aoe_turf/conjure/summon_mirror
+ name = "Summon Mirror"
+ desc = "Summon forth a temporary mirror of sin that will allow you and others to change anything they want about themselves."
+ invocation = "Aren't I so amazing?"
+ invocation_type = "whisper"
+ clothes_req = FALSE
+ charge_max = 600
+ cooldown_min = 200
+ summon_type = list(/obj/structure/mirror/magic/lesser)
+ summon_lifespan = 60 SECONDS
+ range = 1
+ action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
+ action_icon_state = "magic_mirror"
+ action_background_icon_state = "bg_demon"
+
+
+
diff --git a/code/modules/antagonists/demon/sins/wrath.dm b/code/modules/antagonists/demon/sins/wrath.dm
new file mode 100644
index 000000000000..48974d3d3937
--- /dev/null
+++ b/code/modules/antagonists/demon/sins/wrath.dm
@@ -0,0 +1,41 @@
+/obj/effect/proc_holder/spell/targeted/shapeshift/demon/wrath //emergency get out of jail card, but better.
+ name = "Wrath Demon Form"
+ shapeshift_type = /mob/living/simple_animal/lesserdemon/wrath
+
+/mob/living/simple_animal/lesserdemon/wrath //slightly more damage.
+ name = "wrathful demon"
+ real_name = "wrathful demon"
+ melee_damage_lower = 28
+ melee_damage_upper = 28
+ icon_state = "lesserdaemon_wrath"
+ icon_living = "lesserdaemon_wrath"
+
+/obj/effect/proc_holder/spell/pointed/trigger/ignite
+ name = "Ignite"
+ desc = "This ranged spell sets a person on fire."
+ school = "transmutation"
+ charge_max = 600
+ clothes_req = FALSE
+ invocation = "BURN IN HELL!!"
+ invocation_type = "shout"
+ message = span_notice("You ignite in a flash of hellfire!")
+ cooldown_min = 75
+ ranged_mousepointer = 'icons/effects/mouse_pointers/throw_target.dmi'
+ action_icon = 'icons/mob/actions/humble/actions_humble.dmi'
+ action_icon_state = "sacredflame"
+ active_msg = "You prepare to ignite a target..."
+
+/obj/effect/proc_holder/spell/targeted/inflict_handler/ignite
+ name = "Ignite"
+ desc = "This spell sets a person on fire from range."
+ school = "transmutation"
+ invocation = "BURN IN HELL!!"
+ invocation_type = "shout"
+ charge_max = 600
+ clothes_req = FALSE
+ action_icon = 'icons/mob/actions/humble/actions_humble.dmi'
+ action_icon_state = "sacredflame"
+ amt_firestacks = 5
+ ignites = TRUE
+ sound = 'sound/magic/fireball.ogg'
+
diff --git a/code/modules/events/sinfuldemon.dm b/code/modules/events/sinfuldemon.dm
new file mode 100644
index 000000000000..dd1c8c3515fb
--- /dev/null
+++ b/code/modules/events/sinfuldemon.dm
@@ -0,0 +1,61 @@
+/datum/round_event_control/sinfuldemon
+ name = "Create Demon of Sin"
+ typepath = /datum/round_event/ghost_role/sinfuldemon
+ max_occurrences = 2 //misery loves company
+ min_players = 15
+ earliest_start = 20 MINUTES
+
+/datum/round_event/ghost_role/sinfuldemon
+ var/success_spawn = 0
+ minimum_required = 1
+ role_name = "demon of sin"
+ fakeable = FALSE
+
+/datum/round_event/ghost_role/sinfuldemon/kill()
+ if(!success_spawn && control)
+ control.occurrences--
+ return ..()
+
+/datum/round_event/ghost_role/sinfuldemon/spawn_role()
+ //selecting a spawn_loc
+ if(!SSjob.latejoin_trackers.len)
+ return MAP_ERROR
+
+ //selecting a candidate player
+ var/list/candidates = get_candidates(ROLE_SINFULDEMON, null, ROLE_SINFULDEMON)
+ if(!candidates.len)
+ return NOT_ENOUGH_PLAYERS
+
+ var/mob/dead/selected_candidate = pick_n_take(candidates)
+ var/key = selected_candidate.key
+
+ var/datum/mind/Mind = create_sinfuldemon_mind(key)
+ Mind.active = TRUE
+
+ var/mob/living/carbon/human/sinfuldemon = create_event_sinfuldemon()
+ Mind.transfer_to(sinfuldemon)
+ Mind.add_antag_datum(/datum/antagonist/sinfuldemon)
+
+ spawned_mobs += sinfuldemon
+ message_admins("[ADMIN_LOOKUPFLW(sinfuldemon)] has been made into a demon of sin by an event.")
+ log_game("[key_name(sinfuldemon)] was spawned as a demon of sin by an event.")
+ var/datum/job/jobdatum = SSjob.GetJob("Assistant")
+ sinfuldemon.job = jobdatum.title
+ jobdatum.equip(sinfuldemon)
+ return SUCCESSFUL_SPAWN
+
+
+/proc/create_event_sinfuldemon(spawn_loc)
+ var/mob/living/carbon/human/new_sinfuldemon = new(spawn_loc)
+ if(!spawn_loc)
+ SSjob.SendToLateJoin(new_sinfuldemon)
+ var/datum/preferences/A = new() //Randomize appearance for the demon.
+ A.copy_to(new_sinfuldemon)
+ new_sinfuldemon.dna.update_dna_identity()
+ return new_sinfuldemon
+
+/proc/create_sinfuldemon_mind(key)
+ var/datum/mind/Mind = new /datum/mind(key)
+ Mind.assigned_role = ROLE_SINFULDEMON
+ Mind.special_role = ROLE_SINFULDEMON
+ return Mind
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 02771207decf..e21a9523c3ea 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -268,6 +268,23 @@
M.adjust_fire_stacks(3)
M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire
M.adjustFireLoss(3) //Hence the other damages... ain't I a bastard? // Yogs End
+ if(ishuman(M) && is_sinfuldemon(M) && prob(80))
+ switch(data)
+ if(1 to 4)
+ to_chat(M, span_warning("Your unholy blood begins to burn as holy power creeps through you."))
+ M.adjustFireLoss(1)
+ if(5 to 10)
+ to_chat(M, span_danger("The burning deepens and strengthens!"))
+ M.adjustFireLoss(2)
+ if(11 to 12)
+ to_chat(M, span_danger("Your flesh itself begins to melt apart in agony!"))
+ M.adjustFireLoss(3)
+ M.emote("scream")
+ if(13 to INFINITY)
+ M.visible_message("[M] suddenly ignites in a brilliant flash of white!", span_userdanger("You suddenly ignite in a holy fire!"))
+ M.adjust_fire_stacks(3)
+ M.IgniteMob()
+ M.adjustFireLoss(4)
holder.remove_reagent(type, 0.4) //fixed consumption to prevent balancing going out of whack
/datum/reagent/water/holywater/reaction_turf(turf/T, reac_volume)
@@ -936,6 +953,8 @@
/datum/reagent/silver/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(M.has_bane(BANE_SILVER))
M.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
+ if(ishuman(M) && is_sinfuldemon(M) && prob(80)) //sinful demons have a lesser reaction to silver
+ M.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
..()
/datum/reagent/uranium
diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
index 63234595ced1..b4d8834df172 100644
--- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm
+++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
@@ -14,6 +14,9 @@
return
if(obj_flags & IN_USE)
return
+ if(is_sinfuldemon(user)) //this is probably a snowflake way of doing it but sure. Demons of Greed don't need to farm this.
+ to_chat(user,"Reserve this foolish game for mortals.")
+ return
obj_flags |= IN_USE
user.health -= 20
user.maxHealth -= 20
@@ -41,6 +44,8 @@
if(user)
to_chat(user, span_boldwarning("Fucking machine! Must be rigged. Still... one more try couldn't hurt, right?"))
+/obj/structure/cursed_slot_machine/betterchance //doubled chance of winnning.
+ win_prob = 10
/obj/structure/cursed_money
name = "bag of money"
diff --git a/code/modules/spells/spell_types/inflict_handler.dm b/code/modules/spells/spell_types/inflict_handler.dm
index 2ad9a5ed169b..f590d3b72a07 100644
--- a/code/modules/spells/spell_types/inflict_handler.dm
+++ b/code/modules/spells/spell_types/inflict_handler.dm
@@ -1,6 +1,6 @@
/obj/effect/proc_holder/spell/targeted/inflict_handler
name = "Inflict Handler"
- desc = "This spell blinds and/or destroys/damages/heals and/or knockdowns/stuns the target."
+ desc = "This spell blinds and/or destroys/damages/heals/ignites and/or knockdowns/stuns the target."
var/amt_paralyze = 0
var/amt_unconscious = 0
@@ -18,6 +18,9 @@
var/amt_eye_blind = 0
var/amt_eye_blurry = 0
+ var/amt_firestacks = 0
+ var/ignites = FALSE
+
var/destroys = "none" //can be "none", "gib" or "disintegrate"
var/summon_type = null //this will put an obj at the target's location
@@ -50,6 +53,7 @@
target.blind_eyes(amt_eye_blind)
target.blur_eyes(amt_eye_blurry)
+ target.adjust_fire_stacks(amt_firestacks)
//summoning
if(summon_type)
new summon_type(target.loc, target)
@@ -58,3 +62,6 @@
var/list/stat_args = status_params.Copy()
stat_args.Insert(1,inflict_status)
target.apply_status_effect(arglist(stat_args))
+
+ if(ignites)
+ target.IgniteMob()
diff --git a/icons/mob/actions/actions_minor_antag.dmi b/icons/mob/actions/actions_minor_antag.dmi
index 3b9fe54577e6..9e4da8f6524b 100644
Binary files a/icons/mob/actions/actions_minor_antag.dmi and b/icons/mob/actions/actions_minor_antag.dmi differ
diff --git a/icons/mob/actions/actions_spells.dmi b/icons/mob/actions/actions_spells.dmi
index ca84f29d4a2e..82ba375a4fe8 100644
Binary files a/icons/mob/actions/actions_spells.dmi and b/icons/mob/actions/actions_spells.dmi differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index b8792a8eab26..ba2ee1ee3df7 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index 1e2fa42d973e..3f1756ca8c37 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/yogstation.dme b/yogstation.dme
index 863334705385..efc99a907b20 100644
--- a/yogstation.dme
+++ b/yogstation.dme
@@ -1513,6 +1513,14 @@
#include "code\modules\antagonists\cult\ritual.dm"
#include "code\modules\antagonists\cult\rune_spawn_action.dm"
#include "code\modules\antagonists\cult\runes.dm"
+#include "code\modules\antagonists\demon\demons.dm"
+#include "code\modules\antagonists\demon\general_powers.dm"
+#include "code\modules\antagonists\demon\objectives.dm"
+#include "code\modules\antagonists\demon\sins\envy.dm"
+#include "code\modules\antagonists\demon\sins\gluttony.dm"
+#include "code\modules\antagonists\demon\sins\greed.dm"
+#include "code\modules\antagonists\demon\sins\pride.dm"
+#include "code\modules\antagonists\demon\sins\wrath.dm"
#include "code\modules\antagonists\devil\devil.dm"
#include "code\modules\antagonists\devil\devil_helpers.dm"
#include "code\modules\antagonists\devil\imp\imp.dm"
@@ -1913,6 +1921,7 @@
#include "code\modules\events\sentience.dm"
#include "code\modules\events\shuttle_catastrophe.dm"
#include "code\modules\events\shuttle_loan.dm"
+#include "code\modules\events\sinfuldemon.dm"
#include "code\modules\events\space_dragon.dm"
#include "code\modules\events\spacevine.dm"
#include "code\modules\events\spider_infestation.dm"