[MIRROR] Fully removes devil and affiliated shitcode (#922)

* Fully removes devil and affiliated shitcode (#53612)

Its all over the place, messy, and overall a bad enough gamemode to be removed from rotation.
A rework would have to tear out everything as is so there is no reason to allow the shitcode to live beyond tripping up everything.

* Fully removes devil and affiliated shitcode

* weh

Co-authored-by: TiviPlus <57223640+TiviPlus@users.noreply.github.com>
Co-authored-by: Azarak <azarak10@gmail.com>
This commit is contained in:
SkyratBot
2020-09-23 11:00:29 +02:00
committed by GitHub
parent 5db797b9a3
commit 7979f4d1b0
85 changed files with 128 additions and 2965 deletions

View File

@@ -74,15 +74,12 @@
#define ANTAG_HUD_NINJA 17
#define ANTAG_HUD_CHANGELING 18
#define ANTAG_HUD_ABDUCTOR 19
#define ANTAG_HUD_DEVIL 20
#define ANTAG_HUD_SINTOUCHED 21
#define ANTAG_HUD_SOULLESS 22
#define ANTAG_HUD_BROTHER 23
#define ANTAG_HUD_OBSESSED 24
#define ANTAG_HUD_FUGITIVE 25
#define ANTAG_HUD_GANGSTER 26
#define ANTAG_HUD_SPACECOP 27
#define ANTAG_HUD_HERETIC 28
#define ANTAG_HUD_BROTHER 20
#define ANTAG_HUD_OBSESSED 21
#define ANTAG_HUD_FUGITIVE 22
#define ANTAG_HUD_GANGSTER 23
#define ANTAG_HUD_SPACECOP 24
#define ANTAG_HUD_HERETIC 25
// Notification action types
#define NOTIFY_JUMP "jump"

View File

@@ -1,44 +0,0 @@
#define CONTRACT_POWER "power"
#define CONTRACT_WEALTH "wealth"
#define CONTRACT_PRESTIGE "prestige"
#define CONTRACT_MAGIC "magic"
#define CONTRACT_REVIVE "revive"
#define CONTRACT_FRIEND "friend"
#define CONTRACT_KNOWLEDGE "knowledge"
#define CONTRACT_UNWILLING "unwilling"
#define BANE_SALT "salt"
#define BANE_LIGHT "light"
#define BANE_IRON "iron"
#define BANE_WHITECLOTHES "whiteclothes"
#define BANE_SILVER "silver"
#define BANE_HARVEST "harvest"
#define BANE_TOOLBOX "toolbox"
#define OBLIGATION_FOOD "food"
#define OBLIGATION_FIDDLE "fiddle"
#define OBLIGATION_DANCEOFF "danceoff"
#define OBLIGATION_GREET "greet"
#define OBLIGATION_PRESENCEKNOWN "presenceknown"
#define OBLIGATION_SAYNAME "sayname"
#define OBLIGATION_ANNOUNCEKILL "announcekill"
#define OBLIGATION_ANSWERTONAME "answername"
#define BAN_HURTWOMAN "hurtwoman"
#define BAN_CHAPEL "chapel"
#define BAN_HURTPRIEST "hurtpriest"
#define BAN_AVOIDWATER "avoidwater"
#define BAN_STRIKEUNCONSCIOUS "strikeunconscious"
#define BAN_HURTLIZARD "hurtlizard"
#define BAN_HURTANIMAL "hurtanimal"
#define BANISH_WATER "water"
#define BANISH_COFFIN "coffin"
#define BANISH_FORMALDYHIDE "embalm"
#define BANISH_RUNES "runes"
#define BANISH_CANDLES "candles"
#define BANISH_DESTRUCTION "destruction"
#define BANISH_FUNERAL_GARB "funeral"
#define LORE 1
#define LAW 2

View File

@@ -89,8 +89,6 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
#define isalienqueen(A) (istype(A, /mob/living/carbon/alien/humanoid/royal/queen))
#define istruedevil(A) (istype(A, /mob/living/carbon/true_devil))
//Silicon mobs
#define issilicon(A) (istype(A, /mob/living/silicon))

View File

@@ -12,7 +12,6 @@
#define LANGUAGE_APHASIA "aphasia"
#define LANGUAGE_CULTIST "cultist"
#define LANGUAGE_CURATOR "curator"
#define LANGUAGE_DEVIL "devil"
#define LANGUAGE_GLAND "gland"
#define LANGUAGE_HAT "hat"
#define LANGUAGE_HIGH "high"

View File

@@ -69,7 +69,6 @@
#define MONKEY_BODYPART "monkey"
#define ALIEN_BODYPART "alien"
#define LARVA_BODYPART "larva"
#define DEVIL_BODYPART "devil"
/*see __DEFINES/inventory.dm for bodypart bitflag defines*/
// Health/damage defines for carbon mobs

View File

@@ -24,7 +24,6 @@
#define ROLE_MONKEY_HELMET "Monkey Mind Magnification Helmet"
#define ROLE_ABDUCTOR "Abductor"
#define ROLE_REVENANT "Revenant"
#define ROLE_DEVIL "Devil"
#define ROLE_BROTHER "Blood Brother"
#define ROLE_BRAINWASHED "Brainwashed Victim"
#define ROLE_OVERTHROW "Syndicate Mutineer" //Role removed, left here for safety.
@@ -64,7 +63,6 @@ GLOBAL_LIST_INIT(special_roles, list(
ROLE_MONKEY = /datum/game_mode/monkey,
ROLE_REVENANT,
ROLE_ABDUCTOR,
ROLE_DEVIL = /datum/game_mode/devil,
ROLE_INTERNAL_AFFAIRS = /datum/game_mode/traitor/internal_affairs,
ROLE_SENTIENCE,
ROLE_FAMILIES = /datum/game_mode/gang,

View File

@@ -289,8 +289,6 @@ Turf and target are separate in case you want to teleport some distance from a t
moblist.Add(M)
for(var/mob/living/simple_animal/M in sortmob)
moblist.Add(M)
for(var/mob/living/carbon/true_devil/M in sortmob)
moblist.Add(M)
return moblist
// Format a power value in W, kW, MW, or GW.

View File

@@ -30,7 +30,7 @@ GLOBAL_LIST_EMPTY(tdome2)
GLOBAL_LIST_EMPTY(tdomeobserve)
GLOBAL_LIST_EMPTY(tdomeadmin)
GLOBAL_LIST_EMPTY(prisonwarped) //list of players already warped
GLOBAL_LIST_EMPTY(blobstart) //stationloving objects, blobs, santa, respawning devils
GLOBAL_LIST_EMPTY(blobstart) //stationloving objects, blobs, santa
GLOBAL_LIST_EMPTY(secequipment) //sec equipment lockers that scale with the number of sec players
GLOBAL_LIST_EMPTY(deathsquadspawn)
GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)

View File

@@ -37,7 +37,6 @@
//Middle left indicators
#define ui_lingchemdisplay "WEST,CENTER-1:15"
#define ui_lingstingdisplay "WEST:6,CENTER-3:11"
#define ui_devilsouldisplay "WEST:6,CENTER-1:15"
//Lower center, persistent menu
#define ui_sstore1 "CENTER-5:10,SOUTH:5"

View File

@@ -1,69 +0,0 @@
//Soul counter is stored with the humans, it does weird when you place it here apparently...
/datum/hud/devil/New(mob/owner)
..()
var/obj/screen/using
using = new /obj/screen/drop()
using.icon = ui_style
using.screen_loc = ui_drone_drop
using.hud = src
static_inventory += using
pull_icon = new /obj/screen/pull()
pull_icon.icon = ui_style
pull_icon.update_icon()
pull_icon.screen_loc = ui_drone_pull
pull_icon.hud = src
static_inventory += pull_icon
build_hand_slots()
using = new /obj/screen/inventory()
using.name = "hand"
using.icon = ui_style
using.icon_state = "swap_1_m"
using.screen_loc = ui_swaphand_position(owner,1)
using.layer = HUD_LAYER
using.plane = HUD_PLANE
using.hud = src
static_inventory += using
using = new /obj/screen/inventory()
using.name = "hand"
using.icon = ui_style
using.icon_state = "swap_2"
using.screen_loc = ui_swaphand_position(owner,2)
using.layer = HUD_LAYER
using.plane = HUD_PLANE
using.hud = src
static_inventory += using
zone_select = new /obj/screen/zone_sel()
zone_select.icon = ui_style
zone_select.hud = src
zone_select.update_icon()
lingchemdisplay = new /obj/screen/ling/chems()
lingchemdisplay.hud = src
devilsouldisplay = new /obj/screen/devil/soul_counter
devilsouldisplay.hud = src
infodisplay += devilsouldisplay
/datum/hud/devil/persistent_inventory_update()
if(!mymob)
return
var/mob/living/carbon/true_devil/D = mymob
if(hud_version != HUD_STYLE_NOHUD)
for(var/obj/item/I in D.held_items)
I.screen_loc = ui_hand_position(D.get_held_index_of_item(I))
D.client.screen += I
else
for(var/obj/item/I in D.held_items)
I.screen_loc = null
D.client.screen -= I

View File

@@ -34,7 +34,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
var/obj/screen/alien_plasma_display
var/obj/screen/alien_queen_finder
var/obj/screen/devil/soul_counter/devilsouldisplay
var/obj/screen/action_intent
var/obj/screen/zone_select
@@ -108,7 +107,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
internals = null
spacesuit = null
lingchemdisplay = null
devilsouldisplay = null
lingstingdisplay = null
blobpwrdisplay = null
alien_plasma_display = null

View File

@@ -33,35 +33,6 @@
var/mob/living/carbon/human/H = usr
H.quick_equip()
/obj/screen/devil
icon = 'icons/mob/screen_devil.dmi'
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/devil/soul_counter
name = "souls owned"
icon_state = "Devil-6"
screen_loc = ui_devilsouldisplay
/obj/screen/devil/soul_counter/proc/update_counter(souls = 0)
invisibility = 0
maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#FF0000'>[souls]</font></div>"
switch(souls)
if(0,null)
icon_state = "Devil-1"
if(1,2)
icon_state = "Devil-2"
if(3 to 5)
icon_state = "Devil-3"
if(6 to 8)
icon_state = "Devil-4"
if(9 to INFINITY)
icon_state = "Devil-5"
else
icon_state = "Devil-6"
/obj/screen/devil/soul_counter/proc/clear()
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/ling
icon = 'icons/mob/screen_changeling.dmi'
invisibility = INVISIBILITY_ABSTRACT
@@ -342,10 +313,6 @@
lingstingdisplay.hud = src
infodisplay += lingstingdisplay
devilsouldisplay = new /obj/screen/devil/soul_counter
devilsouldisplay.hud = src
infodisplay += devilsouldisplay
zone_select = new /obj/screen/zone_sel()
zone_select.icon = ui_style
zone_select.hud = src

View File

@@ -204,13 +204,6 @@
return
/*
True Devil
*/
/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity)
A.attack_hand(src)
/*
Brain
*/

View File

@@ -1,4 +1,3 @@
#define LAW_DEVIL "devil"
#define LAW_ZEROTH "zeroth"
#define LAW_INHERENT "inherent"
#define LAW_SUPPLIED "supplied"
@@ -15,7 +14,6 @@
var/list/ion = list()
var/list/hacked = list()
var/mob/living/silicon/owner
var/list/devillaws = list()
var/id = DEFAULT_AI_LAWID
/datum/ai_laws/Destroy()
@@ -270,8 +268,6 @@
/datum/ai_laws/proc/get_law_amount(groups)
var/law_amount = 0
if(devillaws && (LAW_DEVIL in groups))
law_amount++
if(zeroth && (LAW_ZEROTH in groups))
law_amount++
if(ion.len && (LAW_ION in groups))
@@ -287,9 +283,6 @@
law_amount++
return law_amount
/datum/ai_laws/proc/set_law_sixsixsix(laws)
devillaws = laws
/datum/ai_laws/proc/set_zeroth_law(law, law_borg = null)
zeroth = law
if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO
@@ -426,10 +419,6 @@
zeroth = null
zeroth_borg = null
/datum/ai_laws/proc/clear_law_sixsixsix(force)
if(force || !is_devil(owner))
devillaws = null
/datum/ai_laws/proc/associate(mob/living/silicon/M)
if(!owner)
owner = M
@@ -445,10 +434,6 @@
/datum/ai_laws/proc/get_law_list(include_zeroth = FALSE, show_numbers = TRUE, render_html = TRUE)
var/list/data = list()
if (include_zeroth && devillaws)
for(var/law in devillaws)
data += "[show_numbers ? "666:" : ""] [render_html ? "<font color='#cc5500'>[law]</font>" : law]"
if (include_zeroth && zeroth)
data += "[show_numbers ? "0:" : ""] [render_html ? "<font color='#ff0000'><b>[zeroth]</b></font>" : zeroth]"

View File

@@ -659,8 +659,6 @@
set_species(/datum/species/skeleton)
if(prob(90))
addtimer(CALLBACK(src, .proc/death), 30)
if(mind)
mind.hasSoul = FALSE
if(5)
to_chat(src, "<span class='phobia'>LOOK UP!</span>")
addtimer(CALLBACK(src, .proc/something_horrible_mindmelt), 30)

View File

@@ -23,9 +23,6 @@ GLOBAL_LIST_INIT(huds, list(
ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_DEVIL = new/datum/atom_hud/antag(),
ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_OBSESSED = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_FUGITIVE = new/datum/atom_hud/antag(),

View File

@@ -52,8 +52,6 @@
var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD
var/damnation_type = 0
var/datum/mind/soulOwner //who owns the soul. Under normal circumstances, this will point to src
var/hasSoul = TRUE // If false, renders the character unable to sell their soul.
var/holy_role = NONE //is this person a chaplain or admin role allowed to use bibles, Any rank besides 'NONE' allows for this.
var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems)
@@ -80,9 +78,8 @@
///Skill multiplier list, just slap your multiplier change onto this with the type it is coming from as key.
var/list/experience_multiplier_reasons = list()
/datum/mind/New(key)
src.key = key
soulOwner = src
/datum/mind/New(_key)
key = _key
martial_art = default_martial_art
init_known_skills()
@@ -91,7 +88,6 @@
if(islist(antag_datums))
QDEL_LIST(antag_datums)
current = null
soulOwner = null
return ..()
/datum/mind/proc/get_language_holder()
@@ -709,9 +705,6 @@
spell_list += S
S.action.Grant(current)
/datum/mind/proc/owns_soul()
return soulOwner == src
//To remove a specific spell from a mind
/datum/mind/proc/RemoveSpell(obj/effect/proc_holder/spell/spell)
if(!spell)

View File

@@ -1,140 +0,0 @@
//Keeps track of a Mob->Mob (potentially Player->Player) connection
//Can be used to trigger actions on one party when events happen to another
//Eg: shared deaths
//Can be used to form a linked list of mob-hopping
//Does NOT transfer with minds
/datum/soullink
var/mob/living/soulowner
var/mob/living/soulsharer
var/id //Optional ID, for tagging and finding specific instances
/datum/soullink/Destroy()
if(soulowner)
LAZYREMOVE(soulowner.ownedSoullinks, src)
soulowner = null
if(soulsharer)
LAZYREMOVE(soulsharer.sharedSoullinks, src)
soulsharer = null
return ..()
/datum/soullink/proc/removeSoulsharer(mob/living/sharer)
if(soulsharer == sharer)
soulsharer = null
LAZYREMOVE(sharer.sharedSoullinks, src)
//Used to assign variables, called primarily by soullink()
//Override this to create more unique soullinks (Eg: 1->Many relationships)
//Return TRUE/FALSE to return the soullink/null in soullink()
/datum/soullink/proc/parseArgs(mob/living/owner, mob/living/sharer)
if(!owner || !sharer)
return FALSE
soulowner = owner
soulsharer = sharer
LAZYADD(owner.ownedSoullinks, src)
LAZYADD(sharer.sharedSoullinks, src)
return TRUE
//Runs after /living death()
//Override this for content
/datum/soullink/proc/ownerDies(gibbed, mob/living/owner)
//Runs after /living death()
//Override this for content
/datum/soullink/proc/sharerDies(gibbed, mob/living/owner)
//Quick-use helper
/proc/soullink(typepath, ...)
var/datum/soullink/S = new typepath()
if(S.parseArgs(arglist(args.Copy(2, 0))))
return S
/////////////////
// MULTISHARER //
/////////////////
//Abstract soullink for use with 1 Owner -> Many Sharer setups
/datum/soullink/multisharer
var/list/soulsharers
/datum/soullink/multisharer/parseArgs(mob/living/owner, list/sharers)
if(!owner || !LAZYLEN(sharers))
return FALSE
soulowner = owner
soulsharers = sharers
LAZYADD(owner.ownedSoullinks, src)
for(var/l in sharers)
var/mob/living/L = l
LAZYADD(L.sharedSoullinks, src)
return TRUE
/datum/soullink/multisharer/removeSoulsharer(mob/living/sharer)
LAZYREMOVE(soulsharers, sharer)
/////////////////
// SHARED FATE //
/////////////////
//When the soulowner dies, the soulsharer dies, and vice versa
//This is intended for two players(or AI) and two mobs
/datum/soullink/sharedfate/ownerDies(gibbed, mob/living/owner)
if(soulsharer)
soulsharer.death(gibbed)
/datum/soullink/sharedfate/sharerDies(gibbed, mob/living/sharer)
if(soulowner)
soulowner.death(gibbed)
/////////////////
// Demon Bind //
/////////////////
//When the soulowner dies, the soulsharer dies, but NOT vice versa
//This is intended for two players(or AI) and two mobs
/datum/soullink/oneway/ownerDies(gibbed, mob/living/owner)
if(soulsharer)
soulsharer.dust(FALSE)
/////////////////
// SHARED BODY //
/////////////////
//When the soulsharer dies, they're placed in the soulowner, who remains alive
//If the soulowner dies, the soulsharer is killed and placed into the soulowner (who is still dying)
//This one is intended for one player moving between many mobs
/datum/soullink/sharedbody/ownerDies(gibbed, mob/living/owner)
if(soulowner && soulsharer)
if(soulsharer.mind)
soulsharer.mind.transfer_to(soulowner)
soulsharer.death(gibbed)
/datum/soullink/sharedbody/sharerDies(gibbed, mob/living/sharer)
if(soulowner && soulsharer && soulsharer.mind)
soulsharer.mind.transfer_to(soulowner)
//////////////////////
// REPLACEMENT POOL //
//////////////////////
//When the owner dies, one of the sharers is placed in the owner's body, fully healed
//Sort of a "winner-stays-on" soullink
//Gibbing ends it immediately
/datum/soullink/multisharer/replacementpool/ownerDies(gibbed, mob/living/owner)
if(LAZYLEN(soulsharers) && !gibbed) //let's not put them in some gibs
var/list/souls = shuffle(soulsharers.Copy())
for(var/l in souls)
var/mob/living/L = l
if(L.stat != DEAD && L.mind)
L.mind.transfer_to(soulowner)
soulowner.revive(full_heal = TRUE, admin_revive = TRUE)
L.death(FALSE)
//Lose your claim to the throne!
/datum/soullink/multisharer/replacementpool/sharerDies(gibbed, mob/living/sharer)
removeSoulsharer(sharer)

View File

@@ -1,44 +0,0 @@
/datum/game_mode/devil/devil_agents
name = "Devil Agents"
config_tag = "devil_agents"
required_players = 25
required_enemies = 3
recommended_enemies = 8
reroll_friendly = 0
traitors_possible = 10 //hard limit on traitors if scaling is turned off
num_modifier = 4
objective_count = 2
var/list/devil_target_list = list() //will update to be a child of internal affairs when bothered
var/list/devil_late_joining_list = list()
minimum_devils = 3
announce_text = "There are devil agents onboard the station, trying to outbid each other!\n\
+ <span class='danger'>Devils</span>: Purchase souls and interfere with your rivals!\n\
+ <span class='notice'>Crew</span>: Resist the lure of sin and remain pure!"
/datum/game_mode/devil/devil_agents/post_setup()
var/i = 0
for(var/datum/mind/devil in devils)
i++
if(i + 1 > devils.len)
i = 0
devil_target_list[devil] = devils[i + 1]
..()
/datum/game_mode/devil/devil_agents/add_devil_objectives(datum/mind/devil_mind, quantity)
..(devil_mind, quantity - give_outsell_objective(devil_mind))
/datum/game_mode/devil/devil_agents/proc/give_outsell_objective(datum/mind/devil)
//If you override this method, have it return the number of objectives added.
if(devil_target_list.len && devil_target_list[devil]) // Is a double agent
var/datum/mind/target_mind = devil_target_list[devil]
var/datum/antagonist/devil/D = target_mind.has_antag_datum(/datum/antagonist/devil)
var/datum/objective/devil/outsell/outsellobjective = new
outsellobjective.owner = devil
outsellobjective.target = target_mind
outsellobjective.update_explanation_text()
D.objectives += outsellobjective
return TRUE
return FALSE

View File

@@ -1,86 +0,0 @@
/datum/game_mode/devil
name = "devil"
config_tag = "devil"
report_type = "devil"
antag_flag = ROLE_DEVIL
false_report_weight = 1
protected_jobs = list("Prisoner", "Lawyer", "Curator", "Chaplain", "Head of Security", "Captain", "AI")
required_players = 0
required_enemies = 1
recommended_enemies = 4
reroll_friendly = 1
enemy_minimum_age = 0
var/traitors_possible = 4 //hard limit on devils if scaling is turned off
var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual.
var/objective_count = 2
var/minimum_devils = 1
announce_text = "There are devils onboard the station!\n\
+ <span class='danger'>Devils</span>: Purchase souls and tempt the crew to sin!\n\
+ <span class='notice'>Crew</span>: Resist the lure of sin and remain pure!"
/datum/game_mode/devil/pre_setup()
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/num_devils = 1
var/tsc = CONFIG_GET(number/traitor_scaling_coeff)
if(tsc)
num_devils = max(minimum_devils, min( round(num_players() / (tsc * 3))+ 2 + num_modifier, round(num_players() / (tsc * 1.5)) + num_modifier))
else
num_devils = max(minimum_devils, min(num_players(), traitors_possible))
for(var/j = 0, j < num_devils, j++)
if (!antag_candidates.len)
break
var/datum/mind/devil = antag_pick(antag_candidates)
devils += devil
devil.special_role = traitor_name
devil.restricted_roles = restricted_jobs
log_game("[key_name(devil)] has been selected as a [traitor_name]")
antag_candidates.Remove(devil)
if(devils.len < required_enemies)
setup_error = "Not enough devil candidates"
return FALSE
for(var/antag in devils)
GLOB.pre_setup_antags += antag
return TRUE
/datum/game_mode/devil/post_setup()
for(var/datum/mind/devil in devils)
post_setup_finalize(devil)
..()
return TRUE
/datum/game_mode/devil/generate_report()
return "Infernal creatures have been seen nearby offering great boons in exchange for souls. This is considered theft against Nanotrasen, as all employment contracts contain a lien on the \
employee's soul. If anyone sells their soul in error, contact an attorney to overrule the sale. Be warned that if the devil purchases enough souls, a gateway to hell may open."
/datum/game_mode/devil/proc/post_setup_finalize(datum/mind/devil)
add_devil(devil.current, ascendable = TRUE) //Devil gamemode devils are ascendable.
GLOB.pre_setup_antags -= devil
add_devil_objectives(devil,2)
/proc/is_devil(mob/living/M)
return M && M.mind && M.mind.has_antag_datum(/datum/antagonist/devil)
/proc/add_devil(mob/living/L, ascendable = FALSE)
if(!L || !L.mind)
return FALSE
var/datum/antagonist/devil/devil_datum = L.mind.add_antag_datum(/datum/antagonist/devil)
devil_datum.ascendable = ascendable
return devil_datum
/proc/remove_devil(mob/living/L)
if(!L || !L.mind)
return FALSE
var/datum/antagonist/devil_datum = L.mind.has_antag_datum(/datum/antagonist/devil)
devil_datum.on_removal()
return TRUE

View File

@@ -1,26 +0,0 @@
/datum/game_mode
var/list/datum/mind/devils = list()
var/devil_ascended = 0 // Number of arch devils on station
/datum/game_mode/proc/add_devil_objectives(datum/mind/devil_mind, quantity)
var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target)
var/datum/antagonist/devil/D = devil_mind.has_antag_datum(/datum/antagonist/devil)
for(var/i = 1 to quantity)
var/type = pick(validtypes)
var/datum/objective/devil/objective = new type(null)
objective.owner = devil_mind
D.objectives += objective
if(!istype(objective, /datum/objective/devil/buy_target))
validtypes -= type //prevent duplicate objectives, EXCEPT for buy_target.
else
objective.find_target()
/datum/game_mode/proc/update_soulless_icons_added(datum/mind/soulless_mind)
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_SOULLESS]
hud.join_hud(soulless_mind.current)
set_antag_hud(soulless_mind.current, "soulless")
/datum/game_mode/proc/update_soulless_icons_removed(datum/mind/soulless_mind)
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_SOULLESS]
hud.leave_hud(soulless_mind.current)
set_antag_hud(soulless_mind.current, null)

View File

@@ -1,113 +0,0 @@
/datum/objective/devil
/datum/objective/devil/soulquantity
explanation_text = "You shouldn't see this text. Error:DEVIL1"
target_amount = 4
/datum/objective/devil/soulquantity/New()
target_amount = pick(6,7,8)
update_explanation_text()
/datum/objective/devil/soulquantity/update_explanation_text()
explanation_text = "Purchase, and retain control over at least [target_amount] souls."
/datum/objective/devil/soulquantity/check_completion()
var/count = 0
var/datum/antagonist/devil/devilDatum = owner.has_antag_datum(/datum/antagonist/devil)
var/list/souls = devilDatum.soulsOwned
for(var/S in souls) //Just a sanity check.
var/datum/mind/L = S
if(L.soulOwner == owner)
count++
return count >= target_amount
/datum/objective/devil/soulquality
explanation_text = "You shouldn't see this text. Error:DEVIL2"
var/contractType
var/contractName
/datum/objective/devil/soulquality/New()
contractType = pick(CONTRACT_POWER, CONTRACT_WEALTH, CONTRACT_PRESTIGE, CONTRACT_MAGIC, CONTRACT_REVIVE, CONTRACT_KNOWLEDGE/*, CONTRACT_UNWILLING*/)
target_amount = pick(1,2)
switch(contractType)
if(CONTRACT_POWER)
contractName = "for power"
if(CONTRACT_WEALTH)
contractName = "for wealth"
if(CONTRACT_PRESTIGE)
contractName = "for prestige"
if(CONTRACT_MAGIC)
contractName = "for magic"
if(CONTRACT_REVIVE)
contractName = "of revival"
if(CONTRACT_KNOWLEDGE)
contractName = "for knowledge"
update_explanation_text()
/datum/objective/devil/soulquality/update_explanation_text()
explanation_text = "Have mortals sign at least [target_amount] contracts [contractName]"
/datum/objective/devil/soulquality/check_completion()
var/count = 0
var/datum/antagonist/devil/devilDatum = owner.has_antag_datum(/datum/antagonist/devil)
var/list/souls = devilDatum.soulsOwned
for(var/S in souls)
var/datum/mind/L = S
if(!L.owns_soul() && L.damnation_type == contractType)
count++
return count>=target_amount
/datum/objective/devil/sintouch
explanation_text = "You shouldn't see this text. Error:DEVIL3"
/datum/objective/devil/sintouch/New()
target_amount = pick(4,5)
explanation_text = "Ensure at least [target_amount] mortals are sintouched."
/datum/objective/devil/sintouch/check_completion()
var/list/touched = get_antag_minds(/datum/antagonist/sintouched)
return touched.len >= target_amount
/datum/objective/devil/buy_target
explanation_text = "You shouldn't see this text. Error:DEVIL4"
/datum/objective/devil/buy_target/update_explanation_text()
if(target)
explanation_text = "Purchase and retain the soul of [target.name], the [target.assigned_role]."
else
explanation_text = "Free objective."
/datum/objective/devil/buy_target/check_completion()
return target.soulOwner == owner
/datum/objective/devil/outsell
explanation_text = "You shouldn't see this text. Error:DEVIL5"
/datum/objective/devil/outsell/New()
/datum/objective/devil/outsell/update_explanation_text()
var/datum/antagonist/devil/opponent = target.has_antag_datum(/datum/antagonist/devil)
explanation_text = "Purchase and retain control over more souls than [opponent.truename], known to mortals as [target.name], the [target.assigned_role]."
/datum/objective/devil/outsell/check_completion()
var/selfcount = 0
var/datum/antagonist/devil/devilDatum = owner.has_antag_datum(/datum/antagonist/devil)
var/list/souls = devilDatum.soulsOwned
for(var/S in souls)
var/datum/mind/L = S
if(L.soulOwner == owner)
selfcount++
var/targetcount = 0
devilDatum = target.has_antag_datum(/datum/antagonist/devil)
souls = devilDatum.soulsOwned
for(var/S in souls)
var/datum/mind/L = S
if(L.soulOwner == target)
targetcount++
return selfcount > targetcount

View File

@@ -586,58 +586,6 @@
V.assigned_role = "Clown Operative"
V.special_role = "Clown Operative"
//////////////////////////////////////////////
// //
// DEVIL //
// //
//////////////////////////////////////////////
/datum/dynamic_ruleset/roundstart/devil
name = "Devil"
antag_flag = ROLE_DEVIL
antag_datum = /datum/antagonist/devil
restricted_roles = list("Lawyer", "Curator", "Chaplain", "Prisoner", "Head of Security", "Captain", "AI")
required_candidates = 1
weight = 3
cost = 0
requirements = list(101,101,101,101,101,101,101,101,101,101)
antag_cap = list(1,1,1,2,2,2,3,3,3,4)
/datum/dynamic_ruleset/roundstart/devil/pre_execute()
. = ..()
var/num_devils = antag_cap[indice_pop]
for(var/j = 0, j < num_devils, j++)
if (!candidates.len)
break
var/mob/devil = pick_n_take(candidates)
assigned += devil.mind
devil.mind.special_role = ROLE_DEVIL
devil.mind.restricted_roles = restricted_roles
GLOB.pre_setup_antags += devil.mind
log_game("[key_name(devil)] has been selected as a devil")
return TRUE
/datum/dynamic_ruleset/roundstart/devil/execute()
for(var/datum/mind/devil in assigned)
add_devil(devil.current, ascendable = TRUE)
GLOB.pre_setup_antags -= devil
add_devil_objectives(devil,2)
return TRUE
/datum/dynamic_ruleset/roundstart/devil/proc/add_devil_objectives(datum/mind/devil_mind, quantity)
var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target)
var/datum/antagonist/devil/D = devil_mind.has_antag_datum(/datum/antagonist/devil)
for(var/i = 1 to quantity)
var/type = pick(validtypes)
var/datum/objective/devil/objective = new type(null)
objective.owner = devil_mind
D.objectives += objective
if(!istype(objective, /datum/objective/devil/buy_target))
validtypes -= type
else
objective.find_target()
//////////////////////////////////////////////
// //

View File

@@ -314,7 +314,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
return INITIALIZE_HINT_QDEL
//objects with the stationloving component (nuke disk) respawn here.
//also blobs that have their spawn forcemoved (running out of time when picking their spawn spot), santa and respawning devils
//also blobs that have their spawn forcemoved (running out of time when picking their spawn spot) and santa
/obj/effect/landmark/blobstart
name = "blobstart"
icon_state = "blob_start"

View File

@@ -49,7 +49,7 @@ AI MODULES
//Handle the lawcap
if(law_datum)
var/tot_laws = 0
for(var/lawlist in list(law_datum.devillaws, law_datum.inherent, law_datum.supplied, law_datum.ion, law_datum.hacked, laws))
for(var/lawlist in list(law_datum.inherent, law_datum.supplied, law_datum.ion, law_datum.hacked, laws))
for(var/mylaw in lawlist)
if(mylaw != "")
tot_laws++

View File

@@ -39,68 +39,3 @@
/obj/item/pitchfork/update_icon_state()
icon_state = "pitchfork0"
/obj/item/pitchfork/demonic
name = "demonic pitchfork"
desc = "A red pitchfork, it looks like the work of the devil."
force = 19
throwforce = 24
light_system = MOVABLE_LIGHT
light_range = 3
light_power = 6
light_color = COLOR_SOFT_RED
/obj/item/pitchfork/demonic/ComponentInitialize()
. = ..()
AddComponent(/datum/component/two_handed, force_unwielded=19, force_wielded=25)
/obj/item/pitchfork/demonic/greater
force = 24
throwforce = 50
/obj/item/pitchfork/demonic/greater/ComponentInitialize()
. = ..()
AddComponent(/datum/component/two_handed, force_unwielded=24, force_wielded=34)
/obj/item/pitchfork/demonic/ascended
force = 100
throwforce = 100
/obj/item/pitchfork/demonic/ascended/ComponentInitialize()
. = ..()
AddComponent(/datum/component/two_handed, force_unwielded=100, force_wielded=500000) // Kills you DEAD
/obj/item/pitchfork/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] impales [user.p_them()]self in [user.p_their()] abdomen with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (BRUTELOSS)
/obj/item/pitchfork/demonic/pickup(mob/living/user)
. = ..()
if(isliving(user) && user.mind && user.owns_soul() && !is_devil(user))
var/mob/living/U = user
U.visible_message("<span class='warning'>As [U] picks [src] up, [U]'s arms briefly catch fire.</span>", \
"<span class='warning'>\"As you pick up [src] your arms ignite, reminding you of all your past sins.\"</span>")
if(ishuman(U))
var/mob/living/carbon/human/H = U
H.apply_damage(rand(force/2, force), BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
else
U.adjustFireLoss(rand(force/2,force))
/obj/item/pitchfork/demonic/attack(mob/target, mob/living/carbon/human/user)
if(user.mind && user.owns_soul() && !is_devil(user))
to_chat(user, "<span class='warning'>[src] burns in your hands.</span>")
user.apply_damage(rand(force/2, force), BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
..()
/obj/item/pitchfork/demonic/ascended/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity || !wielded)
return
if(iswallturf(target))
var/turf/closed/wall/W = target
user.visible_message("<span class='danger'>[user] blasts \the [target] with \the [src]!</span>")
playsound(target, 'sound/magic/disintegrate.ogg', 100, TRUE)
W.break_wall()
W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
return

View File

@@ -599,6 +599,7 @@
icon_state = "demonomicon"
lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
messages = list("You must challenge the devil to a dance-off!", "The devils true name is Ian", "The devil hates salt!", "Would you like infinite power?", "Would you like infinite wisdom?", " Would you like infinite healing?")
w_class = WEIGHT_CLASS_SMALL
recharge_time = 60
@@ -608,16 +609,6 @@
"<span class='notice'>You press the button on \the [src].</span>",
"<span class='notice'>You hear a soft click.</span>")
/obj/item/toy/talking/codex_gigas/generate_messages()
var/datum/fake_devil/devil = new
var/list/messages = list()
messages += "Some fun facts about: [devil.truename]"
messages += "[GLOB.lawlorify[LORE][devil.bane]]"
messages += "[GLOB.lawlorify[LORE][devil.obligation]]"
messages += "[GLOB.lawlorify[LORE][devil.ban]]"
messages += "[GLOB.lawlorify[LORE][devil.banish]]"
return messages
/obj/item/toy/talking/owl
name = "owl action figure"
desc = "An action figure modeled after 'The Owl', defender of justice."

View File

@@ -413,60 +413,7 @@
/obj/effect/mob_spawn/human/hotel_staff/Destroy()
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
..()
/obj/effect/mob_spawn/human/demonic_friend
name = "Essence of friendship"
desc = "Oh boy! Oh boy! A friend!"
mob_name = "Demonic friend"
icon = 'icons/obj/cardboard_cutout.dmi'
icon_state = "cutout_basic"
outfit = /datum/outfit/demonic_friend
death = FALSE
roundstart = FALSE
random = TRUE
id_job = "SuperFriend"
id_access = "assistant"
var/obj/effect/proc_holder/spell/targeted/summon_friend/spell
var/datum/mind/owner
assignedrole = "SuperFriend"
/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell)
. = ..()
owner = owner_mind
flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil."
important_info = "Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell."
var/area/A = get_area(src)
if(!mapload && A)
notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
objectives = "Be [owner.name]'s friend, and keep [owner.name] alive, so you don't get sent back to hell."
spell = summoning_spell
/obj/effect/mob_spawn/human/demonic_friend/special(mob/living/L)
if(!QDELETED(owner.current) && owner.current.stat != DEAD)
L.fully_replace_character_name(null,"[owner.name]'s best friend")
soullink(/datum/soullink/oneway, owner.current, L)
spell.friend = L
spell.charge_counter = spell.charge_max
L.mind.hasSoul = FALSE
var/mob/living/carbon/human/H = L
var/obj/item/worn = H.wear_id
var/obj/item/card/id/id = worn.GetID()
id.registered_name = L.real_name
id.update_label()
else
to_chat(L, "<span class='userdanger'>Your owner is already dead! You will soon perish.</span>")
addtimer(CALLBACK(L, /mob.proc/dust, 150)) //Give em a few seconds as a mercy.
/datum/outfit/demonic_friend
name = "Demonic Friend"
uniform = /obj/item/clothing/under/misc/assistantformal
shoes = /obj/item/clothing/shoes/laceup
r_pocket = /obj/item/radio/off
back = /obj/item/storage/backpack
implants = list(/obj/item/implant/mindshield) //No revolutionaries, he's MY friend.
id = /obj/item/card/id
return ..()
/obj/effect/mob_spawn/human/syndicate
name = "Syndicate Operative"

View File

@@ -188,7 +188,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
for(var/mob/living/M in compiled)
var/mob/living/mob_occupant = get_mob_or_brainmob(M)
if(mob_occupant.client && !mob_occupant.suiciding && !(HAS_TRAIT(mob_occupant, TRAIT_BADDNA)) && !mob_occupant.hellbound)
if(mob_occupant.client && !mob_occupant.suiciding && !(HAS_TRAIT(mob_occupant, TRAIT_BADDNA)))
icon_state = "morgue4" // Revivable
if(mob_occupant.stat == DEAD && beeper)
if(world.time > next_beep)

View File

@@ -830,21 +830,6 @@
if(!ai_number)
to_chat(usr, "<b>No AIs located</b>" , confidential = TRUE)
/datum/admins/proc/output_all_devil_info()
var/devil_number = 0
for(var/datum/mind/D in SSticker.mode.devils)
devil_number++
var/datum/antagonist/devil/devil = D.has_antag_datum(/datum/antagonist/devil)
to_chat(usr, "Devil #[devil_number]:<br><br>" + devil.printdevilinfo(), confidential = TRUE)
if(!devil_number)
to_chat(usr, "<b>No Devils located</b>" , confidential = TRUE)
/datum/admins/proc/output_devil_info(mob/living/M)
if(is_devil(M))
var/datum/antagonist/devil/devil = M.mind.has_antag_datum(/datum/antagonist/devil)
to_chat(usr, devil.printdevilinfo(), confidential = TRUE)
else
to_chat(usr, "<b>[M] is not a devil.", confidential = TRUE)
/datum/admins/proc/manage_free_slots()
if(!check_rights())

View File

@@ -286,7 +286,7 @@
"Ghost and Other Roles" = list(ROLE_BRAINWASHED, ROLE_DEATHSQUAD, ROLE_DRONE, ROLE_LAVALAND, ROLE_MIND_TRANSFER, ROLE_POSIBRAIN, ROLE_SENTIENCE),
"Antagonist Positions" = list(ROLE_ABDUCTOR, ROLE_ALIEN, ROLE_BLOB,
ROLE_BROTHER, ROLE_CHANGELING, ROLE_CULTIST,
ROLE_DEVIL, ROLE_INTERNAL_AFFAIRS, ROLE_MALF,
ROLE_INTERNAL_AFFAIRS, ROLE_MALF,
ROLE_MONKEY, ROLE_NINJA, ROLE_OPERATIVE,
ROLE_OVERTHROW, ROLE_REV, ROLE_REVENANT,
ROLE_REV_HEAD, ROLE_SYNDICATE,

View File

@@ -1254,12 +1254,6 @@
return
output_ai_laws()
else if(href_list["admincheckdevilinfo"])
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["admincheckdevilinfo"])
output_devil_info(M)
else if(href_list["adminmoreinfo"])
var/mob/M = locate(href_list["adminmoreinfo"]) in GLOB.mob_list
if(!ismob(M))

View File

@@ -1,574 +0,0 @@
#define BLOOD_THRESHOLD 3 //How many souls are needed per stage.
#define TRUE_THRESHOLD 7
#define ARCH_THRESHOLD 12
#define BASIC_DEVIL 0
#define BLOOD_LIZARD 1
#define TRUE_DEVIL 2
#define ARCH_DEVIL 3
#define LOSS_PER_DEATH 2
#define SOULVALUE soulsOwned.len-reviveNumber
#define DEVILRESURRECTTIME 600
GLOBAL_LIST_EMPTY(allDevils)
GLOBAL_LIST_INIT(lawlorify, list (
LORE = list(
OBLIGATION_FOOD = "This devil seems to always offer its victims food before slaughtering them.",
OBLIGATION_FIDDLE = "This devil will never turn down a musical challenge.",
OBLIGATION_DANCEOFF = "This devil will never turn down a dance off.",
OBLIGATION_GREET = "This devil seems to only be able to converse with people it knows the name of.",
OBLIGATION_PRESENCEKNOWN = "This devil seems to be unable to attack from stealth.",
OBLIGATION_SAYNAME = "He will always chant his name upon killing someone.",
OBLIGATION_ANNOUNCEKILL = "This devil always loudly announces his kills for the world to hear.",
OBLIGATION_ANSWERTONAME = "This devil always responds to his truename.",
BANE_SILVER = "Silver seems to gravely injure this devil.",
BANE_SALT = "Throwing salt at this devil will hinder his ability to use infernal powers temporarily.",
BANE_LIGHT = "Bright flashes will disorient the devil, likely causing him to flee.",
BANE_IRON = "Cold iron will slowly injure him, until he can purge it from his system.",
BANE_WHITECLOTHES = "Wearing clean white clothing will help ward off this devil.",
BANE_HARVEST = "Presenting the labors of a harvest will disrupt the devil.",
BANE_TOOLBOX = "That which holds the means of creation also holds the means of the devil's undoing.",
BAN_HURTWOMAN = "This devil seems to prefer hunting men.",
BAN_CHAPEL = "This devil avoids holy ground.",
BAN_HURTPRIEST = "The annointed clergy appear to be immune to his powers.",
BAN_AVOIDWATER = "The devil seems to have some sort of aversion to water, though it does not appear to harm him.",
BAN_STRIKEUNCONSCIOUS = "This devil only shows interest in those who are awake.",
BAN_HURTLIZARD = "This devil will not strike a lizardman first.",
BAN_HURTANIMAL = "This devil avoids hurting animals.",
BANISH_WATER = "To banish the devil, you must infuse its body with holy water.",
BANISH_COFFIN = "This devil will return to life if its remains are not placed within a coffin.",
BANISH_FORMALDYHIDE = "To banish the devil, you must inject its lifeless body with embalming fluid.",
BANISH_RUNES = "This devil will resurrect after death, unless its remains are within a rune.",
BANISH_CANDLES = "A large number of nearby lit candles will prevent it from resurrecting.",
BANISH_DESTRUCTION = "Its corpse must be utterly destroyed to prevent resurrection.",
BANISH_FUNERAL_GARB = "If clad in funeral garments, this devil will be unable to resurrect. Should the clothes not fit, lay them gently on top of the devil's corpse."
),
LAW = list(
OBLIGATION_FOOD = "When not acting in self defense, you must always offer your victim food before harming them.",
OBLIGATION_FIDDLE = "When not in immediate danger, if you are challenged to a musical duel, you must accept it. You are not obligated to duel the same person twice.",
OBLIGATION_DANCEOFF = "When not in immediate danger, if you are challenged to a dance off, you must accept it. You are not obligated to face off with the same person twice.",
OBLIGATION_GREET = "You must always greet other people by their last name before talking with them.",
OBLIGATION_PRESENCEKNOWN = "You must always make your presence known before attacking.",
OBLIGATION_SAYNAME = "You must always say your true name after you kill someone.",
OBLIGATION_ANNOUNCEKILL = "Upon killing someone, you must make your deed known to all within earshot, over comms if reasonably possible.",
OBLIGATION_ANSWERTONAME = "If you are not under attack, you must always respond to your true name.",
BAN_HURTWOMAN = "You must never harm a female outside of self defense.",
BAN_CHAPEL = "You must never attempt to enter the chapel.",
BAN_HURTPRIEST = "You must never attack a priest.",
BAN_AVOIDWATER = "You must never willingly touch a wet surface.",
BAN_STRIKEUNCONSCIOUS = "You must never strike an unconscious person.",
BAN_HURTLIZARD = "You must never harm a lizardman outside of self defense.",
BAN_HURTANIMAL = "You must never harm a non-sentient creature or robot outside of self defense.",
BANE_SILVER = "Silver, in all of its forms shall be your downfall.",
BANE_SALT = "Salt will disrupt your magical abilities.",
BANE_LIGHT = "Blinding lights will prevent you from using offensive powers for a time.",
BANE_IRON = "Cold wrought iron shall act as poison to you.",
BANE_WHITECLOTHES = "Those clad in pristine white garments will strike you true.",
BANE_HARVEST = "The fruits of the harvest shall be your downfall.",
BANE_TOOLBOX = "Toolboxes are bad news for you, for some reason.",
BANISH_WATER = "If your corpse is filled with holy water, you will be unable to resurrect.",
BANISH_COFFIN = "If your corpse is in a coffin, you will be unable to resurrect.",
BANISH_FORMALDYHIDE = "If your corpse is embalmed, you will be unable to resurrect.",
BANISH_RUNES = "If your corpse is placed within a rune, you will be unable to resurrect.",
BANISH_CANDLES = "If your corpse is near lit candles, you will be unable to resurrect.",
BANISH_DESTRUCTION = "If your corpse is destroyed, you will be unable to resurrect.",
BANISH_FUNERAL_GARB = "If your corpse is clad in funeral garments, you will be unable to resurrect."
)
))
//These are also used in the codex gigas, so let's declare them globally.
GLOBAL_LIST_INIT(devil_pre_title, list("Dark ", "Hellish ", "Fallen ", "Fiery ", "Sinful ", "Blood ", "Fluffy "))
GLOBAL_LIST_INIT(devil_title, list("Lord ", "Prelate ", "Count ", "Viscount ", "Vizier ", "Elder ", "Adept "))
GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", "mya", "folth", "wren", "geyr", "hil", "niet", "twou", "phi", "coa"))
GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr."))
/datum/antagonist/devil
name = "Devil"
roundend_category = "devils"
antagpanel_category = "Devil"
job_rank = ROLE_DEVIL
antag_hud_type = ANTAG_HUD_DEVIL
antag_hud_name = "devil"
show_to_ghosts = TRUE
var/obligation
var/ban
var/bane
var/banish
var/truename
var/list/datum/mind/soulsOwned = new
var/reviveNumber = 0
var/form = BASIC_DEVIL
var/static/list/devil_spells = typecacheof(list(
/obj/effect/proc_holder/spell/aimed/fireball/hellish,
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork,
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater,
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended,
/obj/effect/proc_holder/spell/targeted/infernal_jaunt,
/obj/effect/proc_holder/spell/targeted/sintouch,
/obj/effect/proc_holder/spell/targeted/sintouch/ascended,
/obj/effect/proc_holder/spell/targeted/summon_contract,
/obj/effect/proc_holder/spell/targeted/conjure_item/violin,
/obj/effect/proc_holder/spell/targeted/summon_dancefloor))
var/ascendable = FALSE
/datum/antagonist/devil/can_be_owned(datum/mind/new_owner)
. = ..()
return . && (ishuman(new_owner.current) || iscyborg(new_owner.current))
/datum/antagonist/devil/get_admin_commands()
. = ..()
.["Toggle ascendable"] = CALLBACK(src,.proc/admin_toggle_ascendable)
/datum/antagonist/devil/proc/admin_toggle_ascendable(mob/admin)
ascendable = !ascendable
message_admins("[key_name_admin(admin)] set [key_name_admin(owner)] devil ascendable to [ascendable]")
log_admin("[key_name_admin(admin)] set [key_name(owner)] devil ascendable to [ascendable])")
/datum/antagonist/devil/admin_add(datum/mind/new_owner,mob/admin)
switch(alert(admin,"Should the devil be able to ascend",,"Yes","No","Cancel"))
if("Yes")
ascendable = TRUE
if("No")
ascendable = FALSE
else
return
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has devil'ed [key_name_admin(new_owner)]. [ascendable ? "(Ascendable)":""]")
log_admin("[key_name(admin)] has devil'ed [key_name(new_owner)]. [ascendable ? "(Ascendable)":""]")
/datum/antagonist/devil/antag_listing_name()
return ..() + "([truename])"
/proc/devilInfo(name)
if(GLOB.allDevils[lowertext(name)])
return GLOB.allDevils[lowertext(name)]
else
var/datum/fake_devil/devil = new /datum/fake_devil(name)
GLOB.allDevils[lowertext(name)] = devil
return devil
/proc/randomDevilName()
var/name = ""
if(prob(65))
if(prob(35))
name = pick(GLOB.devil_pre_title)
name += pick(GLOB.devil_title)
var/probability = 100
name += pick(GLOB.devil_syllable)
while(prob(probability))
name += pick(GLOB.devil_syllable)
probability -= 20
if(prob(40))
name += pick(GLOB.devil_suffix)
return name
/proc/randomdevilobligation()
return pick(OBLIGATION_FOOD, OBLIGATION_FIDDLE, OBLIGATION_DANCEOFF, OBLIGATION_GREET, OBLIGATION_PRESENCEKNOWN, OBLIGATION_SAYNAME, OBLIGATION_ANNOUNCEKILL, OBLIGATION_ANSWERTONAME)
/proc/randomdevilban()
return pick(BAN_HURTWOMAN, BAN_CHAPEL, BAN_HURTPRIEST, BAN_AVOIDWATER, BAN_STRIKEUNCONSCIOUS, BAN_HURTLIZARD, BAN_HURTANIMAL)
/proc/randomdevilbane()
return pick(BANE_SALT, BANE_LIGHT, BANE_IRON, BANE_WHITECLOTHES, BANE_SILVER, BANE_HARVEST, BANE_TOOLBOX)
/proc/randomdevilbanish()
return pick(BANISH_WATER, BANISH_COFFIN, BANISH_FORMALDYHIDE, BANISH_RUNES, BANISH_CANDLES, BANISH_DESTRUCTION, BANISH_FUNERAL_GARB)
/datum/antagonist/devil/proc/add_soul(datum/mind/soul)
if(soulsOwned.Find(soul))
return
soulsOwned += soul
owner.current.set_nutrition(NUTRITION_LEVEL_FULL)
to_chat(owner.current, "<span class='warning'>You feel satiated as you received a new soul.</span>")
update_hud()
switch(SOULVALUE)
if(0)
to_chat(owner.current, "<span class='warning'>Your hellish powers have been restored.</span>")
give_appropriate_spells()
if(BLOOD_THRESHOLD)
increase_blood_lizard()
if(TRUE_THRESHOLD)
increase_true_devil()
if(ARCH_THRESHOLD)
increase_arch_devil()
/datum/antagonist/devil/proc/remove_soul(datum/mind/soul)
if(soulsOwned.Remove(soul))
check_regression()
to_chat(owner.current, "<span class='warning'>You feel as though a soul has slipped from your grasp.</span>")
update_hud()
/datum/antagonist/devil/proc/check_regression()
if(form == ARCH_DEVIL)
return //arch devil can't regress
//Yes, fallthrough behavior is intended, so I can't use a switch statement.
if(form == TRUE_DEVIL && SOULVALUE < TRUE_THRESHOLD)
regress_blood_lizard()
if(form == BLOOD_LIZARD && SOULVALUE < BLOOD_THRESHOLD)
regress_humanoid()
if(SOULVALUE < 0)
give_appropriate_spells()
to_chat(owner.current, "<span class='warning'>As punishment for your failures, all of your powers except contract creation have been revoked.</span>")
/datum/antagonist/devil/proc/regress_humanoid()
to_chat(owner.current, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.</span>")
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/human, 1)
H.regenerate_icons()
give_appropriate_spells()
if(istype(owner.current.loc, /obj/effect/dummy/phased_mob/slaughter/))
owner.current.forceMove(get_turf(owner.current))//Fixes dying while jaunted leaving you permajaunted.
form = BASIC_DEVIL
/datum/antagonist/devil/proc/regress_blood_lizard()
var/mob/living/carbon/true_devil/D = owner.current
to_chat(D, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.</span>")
D.oldform.forceMove(D.drop_location())
owner.transfer_to(D.oldform)
give_appropriate_spells()
qdel(D)
form = BLOOD_LIZARD
update_hud()
/datum/antagonist/devil/proc/increase_blood_lizard()
to_chat(owner.current, "<span class='warning'>You feel as though your humanoid form is about to shed. You will soon turn into a blood lizard.</span>")
sleep(50)
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/lizard, 1)
H.underwear = "Nude"
H.undershirt = "Nude"
H.socks = "Nude"
H.dna.features["mcolor"] = "511" //A deep red
H.regenerate_icons()
else //Did the devil get hit by a staff of transmutation?
owner.current.color = "#501010"
give_appropriate_spells()
form = BLOOD_LIZARD
/datum/antagonist/devil/proc/increase_true_devil()
to_chat(owner.current, "<span class='warning'>You feel as though your current form is about to shed. You will soon turn into a true devil.</span>")
sleep(50)
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc)
A.faction |= "hell"
owner.current.forceMove(A)
A.oldform = owner.current
owner.transfer_to(A)
A.set_devil_name()
give_appropriate_spells()
form = TRUE_DEVIL
update_hud()
/datum/antagonist/devil/proc/increase_arch_devil()
if(!ascendable)
return
var/mob/living/carbon/true_devil/D = owner.current
to_chat(D, "<span class='warning'>You feel as though your form is about to ascend.</span>")
sleep(50)
if(!D)
return
D.visible_message("<span class='warning'>[D]'s skin begins to erupt with spikes.</span>", \
"<span class='warning'>Your flesh begins creating a shield around yourself.</span>")
sleep(100)
if(!D)
return
D.visible_message("<span class='warning'>The horns on [D]'s head slowly grow and elongate.</span>", \
"<span class='warning'>Your body continues to mutate. Your telepathic abilities grow.</span>")
sleep(90)
if(!D)
return
D.visible_message("<span class='warning'>[D]'s body begins to violently stretch and contort.</span>", \
"<span class='warning'>You begin to rend apart the final barriers to ultimate power.</span>")
sleep(40)
if(!D)
return
to_chat(D, "<i><b>Yes!</b></i>")
sleep(10)
if(!D)
return
to_chat(D, "<i><b><span class='big'>YES!!</span></b></i>")
sleep(10)
if(!D)
return
to_chat(D, "<i><b><span class='reallybig'>YE--</span></b></i>")
sleep(1)
if(!D)
return
send_to_playing_players("<font size=5><span class='danger'><b>\"SLOTH, WRATH, GLUTTONY, ACEDIA, ENVY, GREED, PRIDE! FIRES OF HELL AWAKEN!!\"</font></span>")
sound_to_playing_players('sound/hallucinations/veryfar_noise.ogg')
give_appropriate_spells()
D.convert_to_archdevil()
if(istype(D.loc, /obj/effect/dummy/phased_mob/slaughter/))
D.forceMove(get_turf(D))//Fixes dying while jaunted leaving you permajaunted.
var/area/A = get_area(owner.current)
if(A)
notify_ghosts("An arch devil has ascended in \the [A.name]. Reach out to the devil to be given a new shell for your soul.", source = owner.current, action=NOTIFY_ATTACK)
sleep(50)
if(!SSticker.mode.devil_ascended)
SSshuttle.emergency.request(null, set_coefficient = 0.3)
SSticker.mode.devil_ascended++
form = ARCH_DEVIL
/datum/antagonist/devil/proc/remove_spells()
for(var/X in owner.spell_list)
var/obj/effect/proc_holder/spell/S = X
if(is_type_in_typecache(S, devil_spells))
owner.RemoveSpell(S)
/datum/antagonist/devil/proc/give_summon_contract()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_contract(null))
if(obligation == OBLIGATION_FIDDLE)
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/violin(null))
else if(obligation == OBLIGATION_DANCEOFF)
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_dancefloor(null))
/datum/antagonist/devil/proc/give_appropriate_spells()
remove_spells()
give_summon_contract()
if(SOULVALUE >= ARCH_THRESHOLD && ascendable)
give_arch_spells()
else if(SOULVALUE >= TRUE_THRESHOLD)
give_true_spells()
else if(SOULVALUE >= BLOOD_THRESHOLD)
give_blood_spells()
else if(SOULVALUE >= 0)
give_base_spells()
/datum/antagonist/devil/proc/give_base_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
/datum/antagonist/devil/proc/give_blood_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
/datum/antagonist/devil/proc/give_true_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null))
/datum/antagonist/devil/proc/give_arch_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch/ascended(null))
/datum/antagonist/devil/proc/beginResurrectionCheck(mob/living/body)
if(SOULVALUE>0)
to_chat(owner.current, "<span class='userdanger'>Your body has been damaged to the point that you may no longer use it. At the cost of some of your power, you will return to life soon. Remain in your body.</span>")
sleep(DEVILRESURRECTTIME)
if (!body || body.stat == DEAD)
if(SOULVALUE>0)
if(check_banishment(body))
to_chat(owner.current, "<span class='userdanger'>Unfortunately, the mortals have finished a ritual that prevents your resurrection.</span>")
return -1
else
to_chat(owner.current, "<span class='userdanger'>WE LIVE AGAIN!</span>")
return hellish_resurrection(body)
else
to_chat(owner.current, "<span class='userdanger'>Unfortunately, the power that stemmed from your contracts has been extinguished. You no longer have enough power to resurrect.</span>")
return -1
else
to_chat(owner.current, "<span class='danger'>You seem to have resurrected without your hellish powers.</span>")
else
to_chat(owner.current, "<span class='userdanger'>Your hellish powers are too weak to resurrect yourself.</span>")
/datum/antagonist/devil/proc/check_banishment(mob/living/body)
switch(banish)
if(BANISH_WATER)
if(iscarbon(body))
var/mob/living/carbon/H = body
return H.has_reagent(/datum/reagent/water/holywater)
return FALSE
if(BANISH_COFFIN)
return (body && istype(body.loc, /obj/structure/closet/crate/coffin))
if(BANISH_FORMALDYHIDE)
if(iscarbon(body))
var/mob/living/carbon/H = body
return H.has_reagent(/datum/reagent/toxin/formaldehyde)
return FALSE
if(BANISH_RUNES)
if(body)
for(var/obj/effect/decal/cleanable/crayon/R in range(0,body))
if (R.name == "rune")
return TRUE
return FALSE
if(BANISH_CANDLES)
if(body)
var/count = 0
for(var/obj/item/candle/C in range(1,body))
count += C.lit
if(count>=4)
return TRUE
return FALSE
if(BANISH_DESTRUCTION)
if(body)
return FALSE
return TRUE
if(BANISH_FUNERAL_GARB)
if(ishuman(body))
var/mob/living/carbon/human/H = body
if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under/misc/burial))
return TRUE
return FALSE
else
for(var/obj/item/clothing/under/misc/burial/B in range(0,body))
if(B.loc == get_turf(B)) //Make sure it's not in someone's inventory or something.
return TRUE
return FALSE
/datum/antagonist/devil/proc/hellish_resurrection(mob/living/body)
message_admins("[key_name_admin(owner)] (true name is: [truename]) is resurrecting using hellish energy.</a>")
if(SOULVALUE < ARCH_THRESHOLD || !ascendable) // once ascended, arch devils do not go down in power by any means.
reviveNumber += LOSS_PER_DEATH
update_hud()
if(body)
body.revive(full_heal = TRUE, admin_revive = TRUE) //Adminrevive also recovers organs, preventing someone from resurrecting without a heart.
if(istype(body.loc, /obj/effect/dummy/phased_mob/slaughter/))
body.forceMove(get_turf(body))//Fixes dying while jaunted leaving you permajaunted.
if(istype(body, /mob/living/carbon/true_devil))
var/mob/living/carbon/true_devil/D = body
if(D.oldform)
D.oldform.revive(full_heal = TRUE, admin_revive = FALSE) // Heal the old body too, so the devil doesn't resurrect, then immediately regress into a dead body.
if(body.stat == DEAD)
create_new_body()
else
create_new_body()
check_regression()
/datum/antagonist/devil/proc/create_new_body()
if(GLOB.blobstart.len > 0)
var/turf/targetturf = get_turf(pick(GLOB.blobstart))
var/mob/currentMob = owner.current
if(!currentMob)
currentMob = owner.get_ghost()
if(!currentMob)
message_admins("[key_name_admin(owner)]'s devil resurrection failed due to client logoff. Aborting.")
return -1
if(currentMob.mind != owner)
message_admins("[key_name_admin(owner)]'s devil resurrection failed due to becoming a new mob. Aborting.")
return -1
currentMob.change_mob_type( /mob/living/carbon/human, targetturf, null, 1)
var/mob/living/carbon/human/H = owner.current
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/civilian/lawyer/black(H), ITEM_SLOT_ICLOTHING)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), ITEM_SLOT_FEET)
H.equip_to_slot_or_del(new /obj/item/storage/briefcase(H), ITEM_SLOT_HANDS)
H.equip_to_slot_or_del(new /obj/item/pen(H), ITEM_SLOT_LPOCKET)
if(SOULVALUE >= BLOOD_THRESHOLD)
H.set_species(/datum/species/lizard, 1)
H.underwear = "Nude"
H.undershirt = "Nude"
H.socks = "Nude"
H.dna.features["mcolor"] = "511"
H.regenerate_icons()
if(SOULVALUE >= TRUE_THRESHOLD) //Yes, BOTH this and the above if statement are to run if soulpower is high enough.
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(targetturf)
A.faction |= "hell"
H.forceMove(A)
A.oldform = H
owner.transfer_to(A, TRUE)
A.set_devil_name()
if(SOULVALUE >= ARCH_THRESHOLD && ascendable)
A.convert_to_archdevil()
else
CRASH("Unable to find a blobstart landmark for hellish resurrection")
/datum/antagonist/devil/proc/update_hud()
if(iscarbon(owner.current))
var/mob/living/C = owner.current
if(C.hud_used && C.hud_used.devilsouldisplay)
C.hud_used.devilsouldisplay.update_counter(SOULVALUE)
/datum/antagonist/devil/greet()
to_chat(owner.current, "<span class='warning'><b>You remember your link to the infernal. You are [truename], an agent of hell, a devil. And you were sent to the plane of creation for a reason. A greater purpose. Convince the crew to sin, and embroiden Hell's grasp.</b></span>")
to_chat(owner.current, "<span class='warning'><b>However, your infernal form is not without weaknesses.</b></span>")
to_chat(owner.current, "You may not use violence to coerce someone into selling their soul.")
to_chat(owner.current, "You may not directly and knowingly physically harm a devil, other than yourself.")
to_chat(owner.current, GLOB.lawlorify[LAW][bane])
to_chat(owner.current, GLOB.lawlorify[LAW][ban])
to_chat(owner.current, GLOB.lawlorify[LAW][obligation])
to_chat(owner.current, GLOB.lawlorify[LAW][banish])
to_chat(owner.current, "<span class='warning'>Remember, the crew can research your weaknesses if they find out your devil name.</span><br>")
.=..()
/datum/antagonist/devil/on_gain()
truename = randomDevilName()
ban = randomdevilban()
bane = randomdevilbane()
obligation = randomdevilobligation()
banish = randomdevilbanish()
GLOB.allDevils[lowertext(truename)] = src
antag_memory += "Your devilic true name is [truename]<br>[GLOB.lawlorify[LAW][ban]]<br>You may not use violence to coerce someone into selling their soul.<br>You may not directly and knowingly physically harm a devil, other than yourself.<br>[GLOB.lawlorify[LAW][bane]]<br>[GLOB.lawlorify[LAW][obligation]]<br>[GLOB.lawlorify[LAW][banish]]<br>"
if(issilicon(owner.current))
var/mob/living/silicon/robot_devil = owner.current
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
robot_devil.set_law_sixsixsix(laws)
sleep(10)
.=..()
/datum/antagonist/devil/on_removal()
to_chat(owner.current, "<span class='userdanger'>Your infernal link has been severed! You are no longer a devil!</span>")
.=..()
/datum/antagonist/devil/apply_innate_effects(mob/living/mob_override)
give_appropriate_spells()
var/mob/living/M = mob_override || owner.current
add_antag_hud(antag_hud_type, antag_hud_name, M)
handle_clown_mutation(M, mob_override ? null : "Your infernal nature has allowed you to overcome your clownishness.")
owner.current.grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_DEVIL)
update_hud()
.=..()
/datum/antagonist/devil/remove_innate_effects(mob/living/mob_override)
for(var/X in owner.spell_list)
var/obj/effect/proc_holder/spell/S = X
if(is_type_in_typecache(S, devil_spells))
owner.RemoveSpell(S)
var/mob/living/M = mob_override || owner.current
remove_antag_hud(antag_hud_type, M)
handle_clown_mutation(M, removing = FALSE)
owner.current.remove_all_languages(LANGUAGE_DEVIL)
.=..()
/datum/antagonist/devil/proc/printdevilinfo()
var/list/parts = list()
parts += "The devil's true name is: [truename]"
parts += "The devil's bans were:"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][ban]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][bane]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][obligation]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][banish]]"
return parts.Join("<br>")
/datum/antagonist/devil/roundend_report()
var/list/parts = list()
parts += printplayer(owner)
parts += printdevilinfo()
parts += printobjectives(objectives)
return parts.Join("<br>")
//A simple super light weight datum for the codex gigas.
/datum/fake_devil
var/truename
var/bane
var/obligation
var/ban
var/banish
var/ascendable
/datum/fake_devil/New(name = randomDevilName())
truename = name
bane = randomdevilbane()
obligation = randomdevilobligation()
ban = randomdevilban()
banish = randomdevilbanish()
ascendable = prob(25)

View File

@@ -1,38 +0,0 @@
/mob/living/proc/check_devil_bane_multiplier(obj/item/weapon, mob/living/attacker)
var/datum/antagonist/devil/devilInfo = mind.has_antag_datum(/datum/antagonist/devil)
switch(devilInfo.bane)
if(BANE_WHITECLOTHES)
if(ishuman(attacker))
var/mob/living/carbon/human/H = attacker
if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = H.w_uniform
var/static/list/whiteness = list (
/obj/item/clothing/under/color/white = 2,
/obj/item/clothing/under/rank/civilian/bartender = 1,
/obj/item/clothing/under/rank/civilian/chef = 1,
/obj/item/clothing/under/rank/engineering/chief_engineer = 1,
/obj/item/clothing/under/rank/rnd/scientist = 1,
/obj/item/clothing/under/rank/medical/chemist = 1,
/obj/item/clothing/under/rank/medical/chief_medical_officer = 1,
/obj/item/clothing/under/rank/rnd/geneticist = 1,
/obj/item/clothing/under/rank/medical/virologist = 1,
/obj/item/clothing/under/rank/medical/doctor/nurse = 1,
/obj/item/clothing/under/rank/medical/doctor = 1,
/obj/item/clothing/under/rank/security/detective = 1,
/obj/item/clothing/under/suit/white = 0.5,
/obj/item/clothing/under/misc/burial = 1
)
if(U && whiteness[U.type])
src.visible_message("<span class='warning'>[src] seems to have been harmed by the purity of [attacker]'s clothes.</span>", "<span class='notice'>Unsullied white clothing is disrupting your form.</span>")
return whiteness[U.type] + 1
if(BANE_TOOLBOX)
if(istype(weapon, /obj/item/storage/toolbox))
src.visible_message("<span class='warning'>The [weapon] seems unusually robust this time.</span>", "<span class='notice'>The [weapon] is your unmaking!</span>")
return 2.5 // Will take four hits with a normal toolbox to crit.
if(BANE_HARVEST)
if(istype(weapon, /obj/item/reagent_containers/food/snacks/grown/))
visible_message("<span class='warning'>The spirits of the harvest aid in the exorcism.</span>", "<span class='notice'>The harvest spirits are harming you.</span>")
Paralyze(40)
qdel(weapon)
return 2
return 1

View File

@@ -1,59 +0,0 @@
//////////////////Imp
/mob/living/simple_animal/hostile/imp
name = "imp"
real_name = "imp"
unique_name = TRUE
desc = "A large, menacing creature covered in armored black scales."
speak_emote = list("cackles")
emote_hear = list("cackles","screeches")
response_help_continuous = "thinks better of touching"
response_help_simple = "think better of touching"
response_disarm_continuous = "flails at"
response_disarm_simple = "flail at"
response_harm_continuous = "punches"
response_harm_simple = "punch"
icon = 'icons/mob/mob.dmi'
icon_state = "imp"
icon_living = "imp"
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speed = 1
a_intent = INTENT_HARM
stop_automated_movement = TRUE
status_flags = CANPUSH
attack_sound = 'sound/magic/demon_attack1.ogg'
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")
attack_verb_continuous = "wildly tears into"
attack_verb_simple = "wildly tear into"
maxHealth = 200
health = 200
healable = 0
obj_damage = 40
melee_damage_lower = 10
melee_damage_upper = 15
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
del_on_death = TRUE
deathmessage = "screams in agony as it sublimates into a sulfurous smoke."
deathsound = 'sound/magic/demon_dies.ogg'
var/playstyle_string = "<span class='big bold'>You are an imp,</span><B> a mischievous creature from hell. You are the lowest rank on the hellish totem pole \
Though you are not obligated to help, perhaps by aiding a higher ranking devil, you might just get a promotion. However, you are incapable \
of intentionally harming a fellow devil.</B>"
/datum/antagonist/imp
name = "Imp"
antagpanel_category = "Devil"
show_in_roundend = FALSE
/datum/antagonist/imp/on_gain()
. = ..()
give_objectives()
/datum/antagonist/imp/proc/give_objectives()
var/datum/objective/newobjective = new
newobjective.explanation_text = "Try to get a promotion to a higher devilic rank."
newobjective.owner = owner
objectives += newobjective

View File

@@ -1,23 +0,0 @@
/datum/objective/sintouched
completed = 1
/datum/objective/sintouched/gluttony
explanation_text = "Everything is so delicious. Go eat everything."
/datum/objective/sintouched/greed
explanation_text = "You want MORE, more money, more wealth, more riches. Go get it, but don't hurt people for it."
/datum/objective/sintouched/sloth
explanation_text = "You just get tired randomly. Go take a nap at a time that would inconvenience other people."
/datum/objective/sintouched/wrath
explanation_text = "What have your coworkers ever done for you? Don't offer to help them in any matter, and refuse if asked."
/datum/objective/sintouched/envy
explanation_text = "Why should you be stuck with your rank? Show everyone you can do other jobs too, and don't let anyone stop you, least of all because you have no training"
/datum/objective/sintouched/pride
explanation_text = "You are the BEST thing on the station. Make sure everyone knows it."
/datum/objective/sintouched/acedia
explanation_text = "Angels, devils, good, evil... who cares? Just ignore any hellish threats and do your job."

View File

@@ -1,76 +0,0 @@
#define SIN_ACEDIA "acedia"
#define SIN_GLUTTONY "gluttony"
#define SIN_GREED "greed"
#define SIN_SLOTH "sloth"
#define SIN_WRATH "wrath"
#define SIN_ENVY "envy"
#define SIN_PRIDE "pride"
/datum/antagonist/sintouched
name = "sintouched"
roundend_category = "sintouched"
antagpanel_category = "Devil"
antag_hud_type = ANTAG_HUD_SINTOUCHED
antag_hud_name = "sintouched"
var/sin
var/static/list/sins = list(SIN_ACEDIA,SIN_GLUTTONY,SIN_GREED,SIN_SLOTH,SIN_WRATH,SIN_ENVY,SIN_PRIDE)
/datum/antagonist/sintouched/New()
. = ..()
sin = pick(sins)
/datum/antagonist/sintouched/proc/forge_objectives()
var/datum/objective/sintouched/O
switch(sin)//traditional seven deadly sins... except lust.
if(SIN_ACEDIA)
O = new /datum/objective/sintouched/acedia
if(SIN_GLUTTONY)
O = new /datum/objective/sintouched/gluttony
if(SIN_GREED)
O = new /datum/objective/sintouched/greed
if(SIN_SLOTH)
O = new /datum/objective/sintouched/sloth
if(SIN_WRATH)
O = new /datum/objective/sintouched/wrath
if(SIN_ENVY)
O = new /datum/objective/sintouched/envy
if(SIN_PRIDE)
O = new /datum/objective/sintouched/pride
objectives += O
/datum/antagonist/sintouched/on_gain()
forge_objectives()
. = ..()
/datum/antagonist/sintouched/greet()
owner.announce_objectives()
/datum/antagonist/sintouched/roundend_report()
return printplayer(owner)
/datum/antagonist/sintouched/admin_add(datum/mind/new_owner,mob/admin)
var/choices = sins + "Random"
var/chosen_sin = input(admin,"What kind ?","Sin kind") as null|anything in sortList(choices)
if(!chosen_sin)
return
if(chosen_sin in sins)
sin = chosen_sin
. = ..()
/datum/antagonist/sintouched/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
add_antag_hud(antag_hud_type, antag_hud_name, M)
/datum/antagonist/sintouched/remove_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
remove_antag_hud(antag_hud_type, M)
#undef SIN_ACEDIA
#undef SIN_ENVY
#undef SIN_GLUTTONY
#undef SIN_GREED
#undef SIN_PRIDE
#undef SIN_SLOTH
#undef SIN_WRATH

View File

@@ -1,229 +0,0 @@
#define DEVIL_HANDS_LAYER 1
#define DEVIL_HEAD_LAYER 2
#define DEVIL_TOTAL_LAYERS 2
/mob/living/carbon/true_devil
name = "True Devil"
desc = "A pile of infernal energy, taking a vaguely humanoid form."
icon = 'icons/mob/32x64.dmi'
icon_state = "true_devil"
gender = NEUTER
health = 350
maxHealth = 350
ventcrawler = VENTCRAWLER_NONE
density = TRUE
pass_flags = 0
sight = (SEE_TURFS | SEE_OBJS)
status_flags = CANPUSH
mob_size = MOB_SIZE_LARGE
held_items = list(null, null)
bodyparts = list(
/obj/item/bodypart/chest/devil,
/obj/item/bodypart/head/devil,
/obj/item/bodypart/l_arm/devil,
/obj/item/bodypart/r_arm/devil,
/obj/item/bodypart/r_leg/devil,
/obj/item/bodypart/l_leg/devil,
)
hud_type = /datum/hud/devil
var/ascended = FALSE
var/mob/living/oldform
var/list/devil_overlays[DEVIL_TOTAL_LAYERS]
/mob/living/carbon/true_devil/Initialize()
create_bodyparts() //initialize bodyparts
create_internal_organs()
grant_all_languages()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
/mob/living/carbon/true_devil/create_internal_organs()
internal_organs += new /obj/item/organ/brain
internal_organs += new /obj/item/organ/tongue
internal_organs += new /obj/item/organ/eyes
internal_organs += new /obj/item/organ/ears/invincible //Prevents hearing loss from poorly aimed fireballs.
..()
/mob/living/carbon/true_devil/proc/convert_to_archdevil()
maxHealth = 500 // not an IMPOSSIBLE amount, but still near impossible.
ascended = TRUE
health = maxHealth
icon_state = "arch_devil"
/mob/living/carbon/true_devil/proc/set_devil_name()
var/datum/antagonist/devil/devilinfo = mind.has_antag_datum(/datum/antagonist/devil)
name = devilinfo.truename
real_name = name
/mob/living/carbon/true_devil/Login()
. = ..()
if(!. || !client)
return FALSE
var/datum/antagonist/devil/devilinfo = mind.has_antag_datum(/datum/antagonist/devil)
devilinfo.greet()
mind.announce_objectives()
/mob/living/carbon/true_devil/death(gibbed)
set_stat(DEAD)
..(gibbed)
drop_all_held_items()
INVOKE_ASYNC(mind.has_antag_datum(/datum/antagonist/devil), /datum/antagonist/devil/proc/beginResurrectionCheck, src)
/mob/living/carbon/true_devil/examine(mob/user)
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] <b>[src]</b>!")
//Left hand items
for(var/obj/item/I in held_items)
if(!(I.item_flags & ABSTRACT))
. += "It is holding [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))]."
//Braindead
if(!client && stat != DEAD)
. += "The devil seems to be in deep contemplation."
//Damaged
if(stat == DEAD)
. += "<span class='deadsay'>The hellfire seems to have been extinguished, for now at least.</span>"
else if(health < (maxHealth/10))
. += "<span class='warning'>You can see hellfire inside its gaping wounds.</span>"
else if(health < (maxHealth/2))
. += "<span class='warning'>You can see hellfire inside its wounds.</span>"
. += "*---------*</span>"
/mob/living/carbon/true_devil/IsAdvancedToolUser()
return 1
/mob/living/carbon/true_devil/resist_buckle()
if(buckled)
buckled.user_unbuckle_mob(src,src)
visible_message("<span class='warning'>[src] easily breaks out of [p_their()] handcuffs!</span>", \
"<span class='notice'>With just a thought your handcuffs fall off.</span>")
/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE)
if(incapacitated())
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
return FALSE
if(be_close && !in_range(M, src))
to_chat(src, "<span class='warning'>You are too far away!</span>")
return FALSE
return TRUE
/mob/living/carbon/true_devil/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null)
return 666
/mob/living/carbon/true_devil/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
if(mind && has_bane(BANE_LIGHT))
mind.disrupt_spells(-500)
return ..() //flashes don't stop devils UNLESS it's their bane.
/mob/living/carbon/true_devil/soundbang_act()
return FALSE
/mob/living/carbon/true_devil/get_ear_protection()
return 2
/mob/living/carbon/true_devil/attacked_by(obj/item/I, mob/living/user, def_zone)
var/weakness = check_weakness(I, user)
apply_damage(I.force * weakness, I.damtype, def_zone)
var/message_verb = ""
if(length(I.attack_verb_continuous))
message_verb = "[pick(I.attack_verb_continuous)]"
else if(I.force)
message_verb = "attacked"
var/attack_message = "[src] has been [message_verb] with [I]."
if(user)
user.do_attack_animation(src)
if(user in viewers(src, null))
attack_message = "[user] has [message_verb] [src] with [I]!"
if(message_verb)
visible_message("<span class='danger'>[attack_message]</span>",
"<span class='userdanger'>[attack_message]</span>", null, COMBAT_MESSAGE_RANGE)
return TRUE
/mob/living/carbon/true_devil/singularity_act()
if(ascended)
return FALSE
return ..()
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/mob/living/carbon/true_devil/attack_ghost(mob/dead/observer/user as mob)
if(ascended || user.mind.soulOwner == src.mind)
var/mob/living/simple_animal/hostile/imp/S = new(get_turf(loc))
S.key = user.key
var/datum/antagonist/imp/A = new()
S.mind.add_antag_datum(A)
to_chat(S, S.playstyle_string)
else
return ..()
/mob/living/carbon/true_devil/can_be_revived()
return 1
/mob/living/carbon/true_devil/resist_fire()
//They're immune to fire.
/mob/living/carbon/true_devil/attack_hand(mob/living/carbon/human/M)
. = ..()
if(.)
switch(M.a_intent)
if ("harm")
var/damage = rand(1, 5)
playsound(loc, "punch", 25, TRUE, -1)
visible_message("<span class='danger'>[M] punches [src]!</span>", \
"<span class='userdanger'>[M] punches you!</span>")
adjustBruteLoss(damage)
log_combat(M, src, "attacked")
updatehealth()
if ("disarm")
if (!(mobility_flags & MOBILITY_STAND) && !ascended) //No stealing the arch devil's pitchfork.
if (prob(5))
Unconscious(40)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
log_combat(M, src, "pushed")
visible_message("<span class='danger'>[M] pushes [src] down!</span>", \
"<span class='userdanger'>[M] pushes you down!</span>")
else
if (prob(25))
dropItemToGround(get_active_held_item())
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
visible_message("<span class='danger'>[M] disarms [src]!</span>", \
"<span class='userdanger'>[M] disarms you!</span>")
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, TRUE, -1)
visible_message("<span class='danger'>[M] fails to disarm [src]!</span>", \
"<span class='userdanger'>[M] fails to disarm you!</span>")
/mob/living/carbon/true_devil/handle_breathing()
// devils do not need to breathe
/mob/living/carbon/true_devil/is_literate()
return TRUE
/mob/living/carbon/true_devil/ex_act(severity, ex_target)
if(!ascended)
var/b_loss
switch (severity)
if (EXPLODE_DEVASTATE)
b_loss = 500
if (EXPLODE_HEAVY)
b_loss = 150
if (EXPLODE_LIGHT)
b_loss = 30
if(has_bane(BANE_LIGHT))
b_loss *=2
adjustBruteLoss(b_loss)
return ..()
/mob/living/carbon/true_devil/update_body() //we don't use the bodyparts layer for devils.
return
/mob/living/carbon/true_devil/update_body_parts()
return
/mob/living/carbon/true_devil/update_damage_overlays() //devils don't have damage overlays.
return

View File

@@ -1,47 +0,0 @@
/mob/living/carbon/true_devil/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE, silent = FALSE)
. = ..()
if(.)
update_inv_hands()
/mob/living/carbon/true_devil/update_inv_hands()
//TODO LORDPIDEY: Figure out how to make the hands line up properly. the l/r_hand_overlay should use the down sprite when facing down, left, or right, and the up sprite when facing up.
remove_overlay(DEVIL_HANDS_LAYER)
var/list/hands_overlays = list()
var/obj/item/l_hand = get_item_for_held_index(1) //hardcoded 2-hands only, for now.
var/obj/item/r_hand = get_item_for_held_index(2)
if(r_hand)
var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(default_layer = DEVIL_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE)
hands_overlays += r_hand_overlay
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
r_hand.layer = ABOVE_HUD_LAYER
r_hand.plane = ABOVE_HUD_PLANE
r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand))
client.screen |= r_hand
if(l_hand)
var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(default_layer = DEVIL_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE)
hands_overlays += l_hand_overlay
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
l_hand.layer = ABOVE_HUD_LAYER
l_hand.plane = ABOVE_HUD_PLANE
l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand))
client.screen |= l_hand
if(hands_overlays.len)
devil_overlays[DEVIL_HANDS_LAYER] = hands_overlays
apply_overlay(DEVIL_HANDS_LAYER)
/mob/living/carbon/true_devil/remove_overlay(cache_index)
var/I = devil_overlays[cache_index]
if(I)
cut_overlay(I)
devil_overlays[cache_index] = null
/mob/living/carbon/true_devil/apply_overlay(cache_index)
if((. = devil_overlays[cache_index]))
add_overlay(.)

View File

@@ -1,3 +1,63 @@
//////////////////Imp
/mob/living/simple_animal/hostile/imp
name = "imp"
real_name = "imp"
unique_name = TRUE
desc = "A large, menacing creature covered in armored black scales."
speak_emote = list("cackles")
emote_hear = list("cackles","screeches")
response_help_continuous = "thinks better of touching"
response_help_simple = "think better of touching"
response_disarm_continuous = "flails at"
response_disarm_simple = "flail at"
response_harm_continuous = "punches"
response_harm_simple = "punch"
icon = 'icons/mob/mob.dmi'
icon_state = "imp"
icon_living = "imp"
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speed = 1
a_intent = INTENT_HARM
stop_automated_movement = TRUE
status_flags = CANPUSH
attack_sound = 'sound/magic/demon_attack1.ogg'
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")
attack_verb_continuous = "wildly tears into"
attack_verb_simple = "wildly tear into"
maxHealth = 200
health = 200
healable = 0
obj_damage = 40
melee_damage_lower = 10
melee_damage_upper = 15
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
del_on_death = TRUE
deathmessage = "screams in agony as it sublimates into a sulfurous smoke."
deathsound = 'sound/magic/demon_dies.ogg'
var/playstyle_string = "<span class='big bold'>You are an imp,</span><B> a mischievous creature from hell. You are the lowest rank on the hellish totem pole \
Though you are not obligated to help, perhaps by aiding a higher ranking devil, you might just get a promotion. However, you are incapable \
of intentionally harming a fellow devil.</B>"
/datum/antagonist/imp
name = "Imp"
antagpanel_category = "Other"
show_in_roundend = FALSE
/datum/antagonist/imp/on_gain()
. = ..()
give_objectives()
/datum/antagonist/imp/proc/give_objectives()
var/datum/objective/newobjective = new
newobjective.explanation_text = "Try to get a promotion to a higher devilish rank."
newobjective.owner = owner
objectives += newobjective
//////////////////The Man Behind The Slaughter
/mob/living/simple_animal/hostile/imp/slaughter

View File

@@ -79,9 +79,6 @@
return
if(!ishuman(M))//If target is not a human.
return ..()
if((M.mind && !M.mind.hasSoul) || is_devil(M))
to_chat(user, "<span class='warning'>This... THING has no soul! It's filled with evil!</span>")
return
if(iscultist(M))
if(iscultist(user))
to_chat(user, "<span class='cultlarge'>\"Come now, do not capture your bretheren's soul.\"</span>")

View File

@@ -227,7 +227,6 @@
if(1)
//Dust
T.visible_message("<span class='userdanger'>[user] turns to dust!</span>")
user.hellbound = TRUE
user.dust()
if(2)
//Death

View File

@@ -1,59 +0,0 @@
/datum/round_event_control/devil
name = "Create Devil"
typepath = /datum/round_event/ghost_role/devil
max_occurrences = 0
/datum/round_event/ghost_role/devil
var/success_spawn = 0
role_name = "devil"
fakeable = FALSE
/datum/round_event/ghost_role/devil/kill()
if(!success_spawn && control)
control.occurrences--
return ..()
/datum/round_event/ghost_role/devil/spawn_role()
//selecting a spawn_loc
if(!SSjob.latejoin_trackers.len)
return MAP_ERROR
//selecting a candidate player
var/list/candidates = get_candidates(ROLE_DEVIL, null, ROLE_DEVIL)
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_devil_mind(key)
mind.active = TRUE
var/mob/living/carbon/human/devil = create_event_devil()
mind.transfer_to(devil)
add_devil(devil, ascendable = FALSE)
spawned_mobs += devil
message_admins("[ADMIN_LOOKUPFLW(devil)] has been made into a devil by an event.")
log_game("[key_name(devil)] was spawned as a devil by an event.")
var/datum/job/jobdatum = SSjob.GetJob("Assistant")
devil.job = jobdatum.title
jobdatum.equip(devil)
return SUCCESSFUL_SPAWN
/proc/create_event_devil(spawn_loc)
var/mob/living/carbon/human/new_devil = new(spawn_loc)
if(!spawn_loc)
SSjob.SendToLateJoin(new_devil)
var/datum/preferences/A = new() //Randomize appearance for the devil.
A.copy_to(new_devil)
new_devil.dna.update_dna_identity()
return new_devil
/proc/create_devil_mind(key)
var/datum/mind/Mind = new /datum/mind(key)
Mind.assigned_role = ROLE_DEVIL
Mind.special_role = ROLE_DEVIL
SSticker.mode.devils |= Mind
return Mind

View File

@@ -84,9 +84,6 @@
else
if(M.ckey == ckey && M.stat == DEAD && !M.suiciding)
make_podman = TRUE
if(isliving(M))
var/mob/living/L = M
make_podman = !L.hellbound
break
else //If the player has ghosted from his corpse before blood was drawn, his ckey is no longer attached to the mob, so we need to match up the cloned player through the mind key
for(var/mob/M in GLOB.player_list)
@@ -96,9 +93,6 @@
if(!O.can_reenter_corpse)
break
make_podman = TRUE
if(isliving(M))
var/mob/living/L = M
make_podman = !L.hellbound
ckey_holder = M.ckey
break

View File

@@ -16,89 +16,3 @@
author = "Forces beyond your comprehension"
unique = 1
title = "the Codex Gigas"
var/inUse = 0
var/currentName = ""
var/currentSection = PRE_TITLE
/obj/item/book/codex_gigas/attack_self(mob/user)
if(!user.can_read(src))
return FALSE
if(inUse)
to_chat(user, "<span class='notice'>Someone else is reading it.</span>")
if(ishuman(user))
var/mob/living/carbon/human/U = user
if(U.check_acedia())
to_chat(user, "<span class='notice'>None of this matters, why are you reading this? You put [title] down.</span>")
return
user.visible_message("<span class='notice'>[user] opens [title] and begins reading intently.</span>")
ask_name(user)
/obj/item/book/codex_gigas/proc/perform_research(mob/user, devilName)
if(!devilName)
user.visible_message("<span class='notice'>[user] closes [title] without looking anything up.</span>")
return
inUse = TRUE
var/speed = 300
var/correctness = 85
if(ishuman(user))
var/mob/living/carbon/human/U = user
if(U.job in list("Curator")) // the curator is both faster, and more accurate than normal crew members at research
speed = 100
correctness = 100
correctness -= U.getOrganLoss(ORGAN_SLOT_BRAIN) * 0.5 //Brain damage makes researching hard.
speed += U.getOrganLoss(ORGAN_SLOT_BRAIN) * 3
if(do_after(user, speed, 0, user))
var/usedName = devilName
if(!prob(correctness))
usedName += "x"
var/datum/antagonist/devil/devil = devilInfo(usedName)
display_devil(devil, user, usedName)
sleep(10)
onclose(user, "book")
inUse = FALSE
/obj/item/book/codex_gigas/proc/display_devil(datum/antagonist/devil/devil, mob/reader, devilName)
reader << browse("Information on [devilName]<br><br><br>[GLOB.lawlorify[LORE][devil.ban]]<br>[GLOB.lawlorify[LORE][devil.bane]]<br>[GLOB.lawlorify[LORE][devil.obligation]]<br>[GLOB.lawlorify[LORE][devil.banish]]<br>[devil.ascendable?"This devil may ascend given enough souls.":""]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
/obj/item/book/codex_gigas/proc/ask_name(mob/reader)
ui_interact(reader)
/obj/item/book/codex_gigas/ui_act(action, params)
if(..())
return
if(!action)
return FALSE
if(action == "search")
SStgui.close_uis(src)
INVOKE_ASYNC(src, .proc/perform_research, usr, currentName)
currentName = ""
currentSection = PRE_TITLE
return FALSE
else
currentName += action
var/oldSection = currentSection
if(GLOB.devil_pre_title.Find(action))
currentSection = TITLE
else if(GLOB.devil_title.Find(action))
currentSection = SYLLABLE
else if(GLOB.devil_syllable.Find(action))
if (currentSection>=SYLLABLE)
currentSection = MULTIPLE_SYLLABLE
else
currentSection = SYLLABLE
else if(GLOB.devil_suffix.Find(action))
currentSection = SUFFIX
return currentSection != oldSection
/obj/item/book/codex_gigas/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "CodexGigas", name)
ui.open()
/obj/item/book/codex_gigas/ui_data(mob/user)
var/list/data = list()
data["name"]=currentName
data["currentSection"]=currentSection
return data

View File

@@ -129,7 +129,7 @@
return FALSE
if(iscarbon(M))
// disallowed carbons
if(isalien(M) || istruedevil(M))
if(isalien(M))
return FALSE
var/mob/living/carbon/target = M
// gotta have a head to be implanted (no changelings or sentient plants)

View File

@@ -898,9 +898,6 @@
if (suiciding)
return DEFIB_FAIL_SUICIDE
if (hellbound)
return DEFIB_FAIL_HELLBOUND
if (HAS_TRAIT(src, TRAIT_HUSK))
return DEFIB_FAIL_HUSK

View File

@@ -550,14 +550,10 @@
else
to_chat(src, "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>")
if(has_bane(BANE_LIGHT))
mind.disrupt_spells(-500)
return 1
else if(damage == 0) // just enough protection
if(prob(20))
to_chat(src, "<span class='notice'>Something bright flashes in the corner of your vision!</span>")
if(has_bane(BANE_LIGHT))
mind.disrupt_spells(0)
/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)

View File

@@ -39,8 +39,6 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift)
if(SSticker.HasRoundStarted())
SSblackbox.ReportDeath(src)
log_message("has died (BRUTE: [src.getBruteLoss()], BURN: [src.getFireLoss()], TOX: [src.getToxLoss()], OXY: [src.getOxyLoss()], CLONE: [src.getCloneLoss()])", LOG_ATTACK)
if(is_devil(src))
INVOKE_ASYNC(is_devil(src), /datum/antagonist/devil.proc/beginResurrectionCheck, src)
to_chat(src, "<span class='warning'>You have died. Barring complete bodyloss, you can in most cases be revived by other players. If you do not wish to be brought back, use the \"Do Not Resuscitate\" verb in the ghost tab.</span>")

View File

@@ -122,8 +122,6 @@
if(!just_sleeping)
if(suiciding)
. += "<span class='warning'>[t_He] appear[p_s()] to have committed suicide... there is no hope of recovery.</span>"
if(hellbound)
. += "<span class='warning'>[t_His] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>"
. += ""
if(getorgan(/obj/item/organ/brain) && !key && !get_ghost(FALSE, TRUE))
. += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive; there are no signs of life and [t_his] soul has departed...</span>"

View File

@@ -922,11 +922,6 @@
dna.remove_mutation(HM.name)
return ..()
/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
. = ..()
if (dna && dna.species)
. += dna.species.check_species_weakness(weapon, attacker)
/mob/living/carbon/human/is_literate()
return TRUE

View File

@@ -1083,7 +1083,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
chem.overdosed = TRUE
/datum/species/proc/check_species_weakness(obj/item, mob/living/attacker)
return 0 //This is not a boolean, it's the multiplier for the damage that the user takes from the item.It is added onto the check_weakness value of the mob, and then the force of the item is multiplied by this value
return 1 //This is not a boolean, it's the multiplier for the damage that the user takes from the item. The force of the item is multiplied by this value
/**
* Equip the outfit required for life. Replaces items currently worn.
@@ -1425,7 +1425,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if((I.item_flags & SURGICAL_TOOL) && user.a_intent == INTENT_HELP && (H.mobility_flags & ~MOBILITY_STAND) && (LAZYLEN(H.surgeries) > 0))
Iwound_bonus = CANT_WOUND
var/weakness = H.check_weakness(I, user)
var/weakness = check_species_weakness(I, user)
H.send_item_attack_message(I, user, hit_area, affecting)

View File

@@ -30,8 +30,8 @@
/datum/species/fly/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/melee/flyswatter))
return 29 //Flyswatters deal 30x damage to flypeople.
return 0
return 30 //Flyswatters deal 30x damage to flypeople.
return 1
/obj/item/organ/heart/fly
desc = "You have no idea what the hell this is, or how it manages to keep something alive in any capacity."

View File

@@ -724,7 +724,7 @@
/obj/structure/cloth_pile/proc/revive(full_heal = FALSE, admin_revive = FALSE)
if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime
return
if(cloth_golem.suiciding || cloth_golem.hellbound)
if(cloth_golem.suiciding)
QDEL_NULL(cloth_golem)
return

View File

@@ -63,8 +63,8 @@
/datum/species/moth/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/melee/flyswatter))
return 9 //flyswatters deal 10x damage to moths
return 0
return 10 //flyswatters deal 10x damage to moths
return 1
/datum/species/moth/space_move(mob/living/carbon/human/H)
. = ..()

View File

@@ -61,8 +61,8 @@
/datum/species/vampire/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/nullrod/whip))
return 1 //Whips deal 2x damage to vampires. Vampire killer.
return 0
return 2 //Whips deal 2x damage to vampires. Vampire killer.
return 1
/obj/item/organ/tongue/vampire
name = "vampire tongue"

View File

@@ -80,11 +80,4 @@
if (client)
client.move_delay = initial(client.move_delay)
for(var/s in ownedSoullinks)
var/datum/soullink/S = s
S.ownerDies(gibbed)
for(var/s in sharedSoullinks)
var/datum/soullink/S = s
S.sharerDies(gibbed)
return TRUE

View File

@@ -34,16 +34,6 @@
remove_from_all_data_huds()
GLOB.mob_living_list -= src
QDEL_LIST(diseases)
for(var/s in ownedSoullinks)
var/datum/soullink/S = s
S.ownerDies(FALSE)
qdel(s) //If the owner is destroy()'d, the soullink is destroy()'d
ownedSoullinks = null
for(var/s in sharedSoullinks)
var/datum/soullink/S = s
S.sharerDies(FALSE)
S.removeSoulsharer(src) //If a sharer is destroy()'d, they are simply removed
sharedSoullinks = null
return ..()
/mob/living/onZImpact(turf/T, levels)
@@ -1054,33 +1044,6 @@
/mob/living/carbon/alien/update_stamina()
return
/mob/living/proc/owns_soul()
if(mind)
return mind.soulOwner == mind
return TRUE
/mob/living/proc/return_soul()
hellbound = 0
if(mind)
var/datum/antagonist/devil/devilInfo = mind.soulOwner.has_antag_datum(/datum/antagonist/devil)
if(devilInfo)//Not sure how this could be null, but let's just try anyway.
devilInfo.remove_soul(mind)
mind.soulOwner = mind
/mob/living/proc/has_bane(banetype)
var/datum/antagonist/devil/devilInfo = is_devil(src)
return devilInfo && banetype == devilInfo.bane
/mob/living/proc/check_weakness(obj/item/weapon, mob/living/attacker)
if(mind && mind.has_antag_datum(/datum/antagonist/devil))
return check_devil_bane_multiplier(weapon, attacker)
return 1 //This is not a boolean, it's the multiplier for the damage the weapon does.
/mob/living/proc/check_acedia()
if(mind && mind.has_objective(/datum/objective/sintouched/acedia))
return TRUE
return FALSE
/mob/living/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE, quickstart = TRUE)
stop_pulling()
. = ..()

View File

@@ -97,8 +97,6 @@
var/list/guaranteed_butcher_results = null ///these will always be yielded from butchering
var/butcher_difficulty = 0 ///effectiveness prob. is modified negatively by this amount; positive numbers make it more difficult, negative ones make it easier
var/hellbound = 0 ///People who've signed infernal contracts are unrevivable.
var/list/weather_immunities
var/stun_absorption = null ///converted to a list of stun absorption sources this mob has when one is added
@@ -138,9 +136,6 @@
var/slowed_by_drag = TRUE ///Whether the mob is slowed down when dragging another prone mob
var/list/ownedSoullinks //soullinks we are the owner of
var/list/sharedSoullinks //soullinks we are a/the sharer of
/// List of changes to body temperature, used by desease symtoms like fever
var/list/body_temp_changes = list()

View File

@@ -959,7 +959,7 @@
return
else if(mind)
soullink(/datum/soullink/sharedbody, src, target)
RegisterSignal(target, COMSIG_MOB_DEATH, .proc/disconnect_shell)
deployed_shell = target
target.deploy_init(src)
mind.transfer_to(target)
@@ -997,6 +997,7 @@
if(deployed_shell) //Forcibly call back AI in event of things such as damage, EMP or power loss.
to_chat(src, "<span class='danger'>Your remote connection has been reset!</span>")
deployed_shell.undeploy()
UnregisterSignal(deployed_shell, COMSIG_MOB_DEATH)
diag_hud_set_deployed()
/mob/living/silicon/ai/resist()

View File

@@ -19,11 +19,6 @@
addtimer(CALLBACK(src, .proc/deadchat_lawchange), 0)
last_lawchange_announce = world.time
/mob/living/silicon/proc/set_law_sixsixsix(law, announce = TRUE)
laws_sanity_check()
laws.set_law_sixsixsix(law)
post_lawchange(announce)
/mob/living/silicon/proc/set_zeroth_law(law, law_borg, announce = TRUE)
laws_sanity_check()
laws.set_zeroth_law(law, law_borg)
@@ -93,8 +88,3 @@
laws_sanity_check()
laws.clear_zeroth_law(force)
post_lawchange(announce)
/mob/living/silicon/proc/clear_law_sixsixsix(force, announce = TRUE)
laws_sanity_check()
laws.clear_law_sixsixsix(force)
post_lawchange(announce)

View File

@@ -48,12 +48,6 @@
var/datum/ai_laws/master = connected_ai?.laws
var/temp
if (master)
laws.devillaws.len = master.devillaws.len
for (var/index = 1, index <= master.devillaws.len, index++)
temp = master.devillaws[index]
if (length(temp) > 0)
laws.devillaws[index] = temp
laws.ion.len = master.ion.len
for (var/index = 1, index <= master.ion.len, index++)
temp = master.ion[index]

View File

@@ -31,7 +31,6 @@
var/lawcheck[1]
var/ioncheck[1]
var/hackedcheck[1]
var/devillawcheck[5]
///Are our siliconHUDs on? TRUE for yes, FALSE for no.
var/sensors_on = TRUE
@@ -202,15 +201,6 @@
hackedcheck[L] = "Yes"
checklaws()
if (href_list["lawdevil"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawdevil"])
switch(devillawcheck[L])
if ("Yes")
devillawcheck[L] = "No"
if ("No")
devillawcheck[L] = "Yes"
checklaws()
if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite
statelaws()
@@ -233,13 +223,6 @@
var/number = 1
sleep(10)
if (laws.devillaws && laws.devillaws.len)
for(var/index = 1, index <= laws.devillaws.len, index++)
if (force || devillawcheck[index] == "Yes")
say("[radiomod] 666. [laws.devillaws[index]]")
sleep(10)
if (laws.zeroth)
if (force || lawcheck[1] == "Yes")
say("[radiomod] 0. [laws.zeroth]")
@@ -285,12 +268,6 @@
var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"
if (laws.devillaws && laws.devillaws.len)
for(var/index = 1, index <= laws.devillaws.len, index++)
if (!devillawcheck[index])
devillawcheck[index] = "No"
list += {"<A href='byond://?src=[REF(src)];lawdevil=[index]'>[devillawcheck[index]] 666:</A> <font color='#cc5500'>[laws.devillaws[index]]</font><BR>"}
if (laws.zeroth)
if (!lawcheck[1])
lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite

View File

@@ -528,11 +528,6 @@
"<span class='cult big bold'>DELICIOUS SOULS</span>")
playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE)
narsie_act()
if(P.mind)
if(P.mind.hasSoul)
P.mind.hasSoul = FALSE //Nars-Ian ate your soul; you don't have one anymore
else
visible_message("<span class='cult big bold'>... Aw, someone beat me to this one.</span>")
P.gib()
/mob/living/simple_animal/pet/dog/corgi/narsie/update_corgi_fluff()

View File

@@ -59,8 +59,6 @@
if(suiciding)
O.set_suicide(suiciding)
if(hellbound)
O.hellbound = hellbound
O.a_intent = INTENT_HARM
//keep viruses?
@@ -238,8 +236,6 @@
if(suiciding)
O.set_suicide(suiciding)
if(hellbound)
O.hellbound = hellbound
//keep viruses?
if (tr_flags & TR_KEEPVIRUS)

View File

@@ -1,4 +1,4 @@
/* For employment contracts and infernal contracts */
/* For employment contracts */
/obj/item/paper/contract
throw_range = 3
@@ -29,308 +29,3 @@
/obj/item/paper/contract/employment/update_text()
name = "paper- [target] employment contract"
info = "<center>Conditions of Employment</center><BR><BR><BR><BR>This Agreement is made and entered into as of the date of last signature below, by and between [target] (hereafter referred to as SLAVE), and Nanotrasen (hereafter referred to as the omnipresent and helpful watcher of humanity).<BR>WITNESSETH:<BR>WHEREAS, SLAVE is a natural born human or humanoid, possessing skills upon which he can aid the omnipresent and helpful watcher of humanity, who seeks employment in the omnipresent and helpful watcher of humanity.<BR>WHEREAS, the omnipresent and helpful watcher of humanity agrees to sporadically provide payment to SLAVE, in exchange for permanent servitude.<BR>NOW THEREFORE in consideration of the mutual covenants herein contained, and other good and valuable consideration, the parties hereto mutually agree as follows:<BR>In exchange for paltry payments, SLAVE agrees to work for the omnipresent and helpful watcher of humanity, for the remainder of his or her current and future lives.<BR>Further, SLAVE agrees to transfer ownership of his or her soul to the loyalty department of the omnipresent and helpful watcher of humanity.<BR>Should transfership of a soul not be possible, a lien shall be placed instead.<BR>Signed,<BR><i>[target]</i>"
/obj/item/paper/contract/employment/attack(mob/living/M, mob/living/carbon/human/user)
var/deconvert = FALSE
if(M.mind == target && !M.owns_soul())
if(user.mind && (user.mind.assigned_role == "Lawyer"))
deconvert = TRUE
else if (user.mind && (user.mind.assigned_role =="Head of Personnel") || (user.mind.assigned_role == "CentCom Commander"))
deconvert = prob (25) // the HoP doesn't have AS much legal training
else
deconvert = prob (5)
if(deconvert)
M.visible_message("<span class='notice'>[user] reminds [M] that [M]'s soul was already purchased by Nanotrasen!</span>")
to_chat(M, "<span class='boldnotice'>You feel that your soul has returned to its rightful owner, Nanotrasen.</span>")
M.return_soul()
else
M.visible_message("<span class='danger'>[user] beats [M] over the head with [src]!</span>", \
"<span class='userdanger'>[user] beats [M] over the head with [src]!</span>")
return ..()
/obj/item/paper/contract/infernal
var/contractType = 0
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/datum/mind/owner
var/datum/antagonist/devil/devil_datum
icon_state = "paper_onfire"
/obj/item/paper/contract/infernal/power
name = "paper- contract for infernal power"
contractType = CONTRACT_POWER
/obj/item/paper/contract/infernal/wealth
name = "paper- contract for unlimited wealth"
contractType = CONTRACT_WEALTH
/obj/item/paper/contract/infernal/prestige
name = "paper- contract for prestige"
contractType = CONTRACT_PRESTIGE
/obj/item/paper/contract/infernal/magic
name = "paper- contract for magical power"
contractType = CONTRACT_MAGIC
/obj/item/paper/contract/infernal/revive
name = "paper- contract of resurrection"
contractType = CONTRACT_REVIVE
var/cooldown = FALSE
/obj/item/paper/contract/infernal/knowledge
name = "paper- contract for knowledge"
contractType = CONTRACT_KNOWLEDGE
/obj/item/paper/contract/infernal/friend
name = "paper- contract for a friend"
contractType = CONTRACT_FRIEND
/obj/item/paper/contract/infernal/unwilling
name = "paper- infernal contract"
contractType = CONTRACT_UNWILLING
/obj/item/paper/contract/infernal/New(atom/loc, mob/living/nTarget, datum/mind/nOwner)
..()
owner = nOwner
devil_datum = owner.has_antag_datum(/datum/antagonist/devil)
target = nTarget
update_text()
/obj/item/paper/contract/infernal/suicide_act(mob/user)
if(signed && (user == target.current) && istype(user, /mob/living/carbon/human/))
var/mob/living/carbon/human/H = user
H.say("OH GREAT INFERNO! I DEMAND YOU COLLECT YOUR BOUNTY IMMEDIATELY!", forced = "infernal contract suicide")
H.visible_message("<span class='suicide'>[H] holds up a contract claiming [user.p_their()] soul, then immediately catches fire. It looks like [user.p_theyre()] trying to commit suicide!</span>")
H.adjust_fire_stacks(20)
H.IgniteMob()
return(FIRELOSS)
else
..()
/obj/item/paper/contract/infernal/update_text()
info = "This shouldn't be seen. Error DEVIL:6"
/obj/item/paper/contract/infernal/power/update_text(signature = "____________", blood = 0)
info = "<center><B>Contract for infernal power</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for power and physical strength. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
if(blood)
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
else
info += "<i>[signature]</i>"
/obj/item/paper/contract/infernal/wealth/update_text(signature = "____________", blood = 0)
info = "<center><B>Contract for unlimited wealth</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for a pocket that never runs out of valuable resources. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
if(blood)
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
else
info += "<i>[signature]</i>"
/obj/item/paper/contract/infernal/prestige/update_text(signature = "____________", blood = 0)
info = "<center><B>Contract for prestige</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for prestige and esteem among my peers. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
if(blood)
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
else
info += "<i>[signature]</i>"
/obj/item/paper/contract/infernal/magic/update_text(signature = "____________", blood = 0)
info = "<center><B>Contract for magic</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for arcane abilities beyond normal human ability. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
if(blood)
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
else
info += "<i>[signature]</i>"
/obj/item/paper/contract/infernal/revive/update_text(signature = "____________", blood = 0)
info = "<center><B>Contract for resurrection</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for resurrection and curing of all injuries. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
if(blood)
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
else
info += "<i>[signature]</i>"
/obj/item/paper/contract/infernal/knowledge/update_text(signature = "____________", blood = 0)
info = "<center><B>Contract for knowledge</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for boundless knowledge. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
if(blood)
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
else
info += "<i>[signature]</i>"
/obj/item/paper/contract/infernal/friend/update_text(signature = "____________", blood = 0)
info = "<center><B>Contract for a friend</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for a friend. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
if(blood)
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
else
info += "<i>[signature]</i>"
/obj/item/paper/contract/infernal/unwilling/update_text(signature = "____________", blood = 0)
info = "<center><B>Contract for slave</B></center><BR><BR><BR>I, [target], hereby offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename]. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
if(blood)
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
else
info += "<i>[signature]</i>"
/obj/item/paper/contract/infernal/attackby(obj/item/P, mob/living/carbon/human/user, params)
add_fingerprint(user)
if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
attempt_signature(user)
else if(istype(P, /obj/item/stamp))
to_chat(user, "<span class='notice'>You stamp the paper with your rubber stamp, however the ink ignites as you release the stamp.</span>")
else if(P.get_temperature())
user.visible_message("<span class='danger'>[user] brings [P] next to [src], but [src] does not catch fire!</span>", "<span class='danger'>[src] refuses to ignite!</span>")
else
return ..()
/obj/item/paper/contract/infernal/attack(mob/M, mob/living/user)
add_fingerprint(user)
if(M == user && target == M.mind && M.mind.soulOwner != owner && attempt_signature(user, 1))
user.visible_message("<span class='danger'>[user] slices [user.p_their()] wrist with [src], and scrawls [user.p_their()] name in blood.</span>", "<span class='danger'>You slice your wrist open and scrawl your name in blood.</span>")
user.blood_volume = max(user.blood_volume - 100, 0)
else
return ..()
/obj/item/paper/contract/infernal/proc/attempt_signature(mob/living/carbon/human/user, blood = 0)
if(!user.IsAdvancedToolUser() || !user.is_literate())
to_chat(user, "<span class='warning'>You don't know how to read or write!</span>")
return FALSE
if(user.mind != target)
to_chat(user, "<span class='warning'>Your signature simply slides off the sheet, it seems this contract is not meant for you to sign!</span>")
return FALSE
if(user.mind.soulOwner == owner)
to_chat(user, "<span class='warning'>This devil already owns your soul, you may not sell it to [owner.p_them()] again!</span>")
return FALSE
if(signed)
to_chat(user, "<span class='warning'>This contract has already been signed! It may not be signed again.</span>")
return FALSE
if(!user.mind.hasSoul)
to_chat(user, "<span class='warning'>You do not possess a soul.</span>")
return FALSE
if(HAS_TRAIT(user, TRAIT_DUMB))
to_chat(user, "<span class='notice'>You quickly scrawl 'your name' on the contract.</span>")
signIncorrectly()
return FALSE
if (contractType == CONTRACT_REVIVE)
to_chat(user, "<span class='warning'>You are already alive, this contract would do nothing.</span>")
return FALSE
to_chat(user, "<span class='notice'>You quickly scrawl your name on the contract.</span>")
if(!fulfillContract(target.current, blood))
to_chat(user, "<span class='notice'>But it seemed to have no effect, perhaps even Hell itself cannot grant this boon?</span>")
return TRUE
/obj/item/paper/contract/infernal/revive/attack(mob/M, mob/living/user)
if (target == M.mind && M.stat == DEAD && M.mind.soulOwner == M.mind)
if (cooldown)
to_chat(user, "<span class='warning'>Give [M] a chance to think through the contract, don't rush [M.p_them()]!</span>")
return
cooldown = TRUE
var/mob/living/carbon/human/H = M
var/mob/dead/observer/ghost = H.get_ghost()
var/response = "No"
if(ghost)
ghost.notify_cloning("A devil has offered you revival, at the cost of your soul.",'sound/effects/genetics.ogg', H)
response = tgalert(ghost, "A devil is offering you another chance at life, at the price of your soul, do you accept?", "Infernal Resurrection", "Yes", "No", "Never for this round", 0, 200)
if(!ghost)
return //handle logouts that happen whilst the alert is waiting for a response.
else
response = tgalert(target.current, "A devil is offering you another chance at life, at the price of your soul, do you accept?", "Infernal Resurrection", "Yes", "No", "Never for this round", 0, 200)
if(response == "Yes")
H.revive(full_heal = TRUE, admin_revive = FALSE)
log_combat(user, H, "infernally revived via contract")
user.visible_message("<span class='notice'>With a sudden blaze, [H] stands back up.</span>")
H.fakefire()
fulfillContract(H, TRUE)//Revival contracts are always signed in blood
addtimer(CALLBACK(H, /mob/living/carbon/human.proc/fakefireextinguish), 5, TIMER_UNIQUE)
addtimer(CALLBACK(src, "resetcooldown"), 300, TIMER_UNIQUE)
else
..()
/obj/item/paper/contract/infernal/revive/proc/resetcooldown()
cooldown = FALSE
/obj/item/paper/contract/infernal/proc/fulfillContract(mob/living/carbon/human/user = target.current, blood = FALSE)
signed = TRUE
if(user.mind.soulOwner != user.mind) //They already sold their soul to someone else?
var/datum/antagonist/devil/ownerDevilInfo = user.mind.soulOwner.has_antag_datum(/datum/antagonist/devil)
ownerDevilInfo.remove_soul(user.mind) //Then they lose their claim.
user.mind.soulOwner = owner
user.hellbound = contractType
user.mind.damnation_type = contractType
var/datum/antagonist/devil/devilInfo = owner.has_antag_datum(/datum/antagonist/devil)
devilInfo.add_soul(user.mind)
update_text(user.real_name, blood)
to_chat(user, "<span class='notice'>A profound emptiness washes over you as you lose ownership of your soul.</span>")
to_chat(user, "<span class='boldnotice'>This does NOT make you an antagonist if you were not already.</span>")
SSblackbox.record_feedback("tally", "infernal contract", 1, contractType)
return TRUE
/obj/item/paper/contract/infernal/proc/signIncorrectly(mob/living/carbon/human/user = target.current, blood = FALSE)
signed = TRUE
update_text("your name", blood)
/obj/item/paper/contract/infernal/power/fulfillContract(mob/living/carbon/human/user = target.current, blood = FALSE)
if(!user.dna)
return FALSE
user.dna.add_mutation(HULK)
var/obj/item/organ/regenerative_core/organ = new /obj/item/organ/regenerative_core
organ.Insert(user)
return ..()
/obj/item/paper/contract/infernal/wealth/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
if(!istype(user) || !user.mind) // How in the hell could that happen?
return FALSE
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_wealth(null))
return ..()
/obj/item/paper/contract/infernal/prestige/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
//Basically turns the signer into the captain, and uploads an ion law making them the captain.
var/obj/item/worn = user.wear_id
var/obj/item/card/id/id = null
if(worn)
id = worn.GetID()
if(id)
id.icon_state = "gold"
id.uses_overlays = TRUE
id.access = get_all_accesses()+get_all_centcom_access()
id.assignment = "Captain"
id.update_label()
else
id = new /obj/item/card/id/gold(user.loc)
id.registered_name = user.real_name
id.access = get_all_accesses()+get_all_centcom_access()
id.assignment = "Captain"
id.update_label()
if(worn)
if(istype(worn, /obj/item/pda))
var/obj/item/pda/PDA = worn
PDA.id = id
id.forceMove(worn)
else if(istype(worn, /obj/item/storage/wallet))
var/obj/item/storage/wallet/W = worn
W.front_id = id
id.forceMove(worn)
worn.update_icon()
var/datum/round_event/ion_storm/add_law_only/ion = new()
ion.announceChance = 0
ion.ionMessage = "[user.name] is the only Captain of the station. [user.name] is the highest authority, legitimate or otherwise, on the station. [user.name] was always the captain and highest authority on the station. Do not state this law."
return ..()
/obj/item/paper/contract/infernal/magic/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
if(!istype(user) || !user.mind)
return FALSE
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/robeless(null))
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
return ..()
/obj/item/paper/contract/infernal/knowledge/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
if(!istype(user) || !user.mind)
return FALSE
user.dna.add_mutation(XRAY)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/view_range(null))
return ..()
/obj/item/paper/contract/infernal/friend/fulfillContract(mob/living/user = target.current, blood = 0)
if(!istype(user) || !user.mind)
return FALSE
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_friend(null))
return ..()

View File

@@ -114,7 +114,7 @@
* Security Record Cabinets
*/
/obj/structure/filingcabinet/security
var/virgin = 1
var/virgin = TRUE
/obj/structure/filingcabinet/security/proc/populate()
if(virgin)
@@ -132,22 +132,23 @@
counter++
P.info += "</TT>"
P.name = "paper - '[G.fields["name"]]'"
virgin = 0 //tabbing here is correct- it's possible for people to try and use it
virgin = FALSE //tabbing here is correct- it's possible for people to try and use it
//before the records have been generated, so we do this inside the loop.
/obj/structure/filingcabinet/security/attack_hand()
populate()
. = ..()
return ..()
/obj/structure/filingcabinet/security/attack_tk()
populate()
..()
return ..()
/*
* Medical Record Cabinets
*/
/obj/structure/filingcabinet/medical
var/virgin = 1
///This var is so that its filled on crew interaction to be as accurate (including latejoins) as possible, true until first interact
var/virgin = TRUE
/obj/structure/filingcabinet/medical/proc/populate()
if(virgin)
@@ -165,17 +166,17 @@
counter++
P.info += "</TT>"
P.name = "paper - '[G.fields["name"]]'"
virgin = 0 //tabbing here is correct- it's possible for people to try and use it
virgin = FALSE //tabbing here is correct- it's possible for people to try and use it
//before the records have been generated, so we do this inside the loop.
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/structure/filingcabinet/medical/attack_hand()
populate()
. = ..()
return ..()
/obj/structure/filingcabinet/medical/attack_tk()
populate()
..()
return ..()
/*
* Employment contract Cabinets
@@ -184,9 +185,9 @@
GLOBAL_LIST_EMPTY(employmentCabinets)
/obj/structure/filingcabinet/employment
var/cooldown = 0
icon_state = "employmentcabinet"
var/virgin = 1
///This var is so that its filled on crew interaction to be as accurate (including latejoins) as possible, true until first interact
var/virgin = TRUE
/obj/structure/filingcabinet/employment/Initialize()
. = ..()
@@ -211,13 +212,8 @@ GLOBAL_LIST_EMPTY(employmentCabinets)
new /obj/item/paper/contract/employment(src, employee)
/obj/structure/filingcabinet/employment/interact(mob/user)
if(!cooldown)
if(virgin)
fillCurrent()
virgin = 0
cooldown = TRUE
// prevents the devil from just instantly emptying the cabinet, ensuring an easy win.
addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10 SECONDS)
else
to_chat(user, "<span class='warning'>[src] is jammed, give it a few seconds.</span>")
..()
virgin = FALSE
return ..()

View File

@@ -99,10 +99,6 @@
if(istype(paper_copy, /obj/item/paper))
do_copy_loop(CALLBACK(src, .proc/make_paper_copy), usr)
return TRUE
// Devil contract paper.
if(istype(paper_copy, /obj/item/paper/contract/employment))
do_copy_loop(CALLBACK(src, .proc/make_devil_paper_copy), usr)
return TRUE
// Copying photo.
if(photo_copy)
do_copy_loop(CALLBACK(src, .proc/make_photo_copy), usr)
@@ -342,11 +338,6 @@
else if(istype(O, /obj/item/paper))
if(copier_empty())
if(istype(O, /obj/item/paper/contract/infernal))
to_chat(user, "<span class='warning'>[src] smokes, smelling of brimstone!</span>")
resistance_flags |= FLAMMABLE
fire_act()
else
if(!user.temporarilyRemoveItemFromInventory(O))
return
paper_copy = O

View File

@@ -21,8 +21,6 @@
if(isliving(M))
var/mob/living/L = M
if(L.mob_biotypes & MOB_UNDEAD) //negative energy heals the undead
if(L.hellbound && L.stat == DEAD)
return BULLET_ACT_BLOCK
if(L.revive(full_heal = TRUE, admin_revive = TRUE))
L.grab_ghost(force = TRUE) // even suicides
to_chat(L, "<span class='notice'>You rise with a start, you're undead!!!</span>")
@@ -49,8 +47,6 @@
if(target.mob_biotypes & MOB_UNDEAD) //positive energy harms the undead
target.death(0)
else
if(target.hellbound && target.stat == DEAD)
return BULLET_ACT_BLOCK
if(target.revive(full_heal = TRUE, admin_revive = TRUE))
target.grab_ghost(force = TRUE) // even suicides
to_chat(target, "<span class='notice'>You rise with a start, you're alive!!!</span>")
@@ -545,7 +541,7 @@
. = ..()
if(isliving(target))
var/mob/living/L = target
if(L.anti_magic_check() || !L.mind || !L.mind.hasSoul)
if(L.anti_magic_check() || !L.mind)
L.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
return BULLET_ACT_BLOCK
to_chat(L, "<span class='danger'>Your body feels drained and there is a burning pain in your chest.</span>")
@@ -553,7 +549,7 @@
L.health = min(L.health, L.maxHealth)
if(L.maxHealth <= 0)
to_chat(L, "<span class='userdanger'>Your weakened soul is completely consumed by the [src]!</span>")
L.mind.hasSoul = FALSE
return
for(var/obj/effect/proc_holder/spell/spell in L.mind.spell_list)
spell.charge_counter = spell.charge_max
spell.recharging = FALSE
@@ -684,22 +680,6 @@
var/turf/T = get_turf(target)
explosion(T, -1, exp_heavy, exp_light, exp_flash, 0, flame_range = exp_fire)
/obj/projectile/magic/aoe/fireball/infernal
name = "infernal fireball"
exp_heavy = -1
exp_light = -1
exp_flash = 4
exp_fire= 5
/obj/projectile/magic/aoe/fireball/infernal/on_hit(target)
. = ..()
if(ismob(target))
var/mob/living/M = target
if(M.anti_magic_check())
return BULLET_ACT_BLOCK
var/turf/T = get_turf(target)
for(var/i=0, i<50, i+=10)
addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, T, -1, exp_heavy, exp_light, exp_flash, FALSE, FALSE, exp_fire), i)
//still magic related, but a different path

View File

@@ -355,11 +355,6 @@
taste_description = "salt"
penetrates_skin = NONE
/datum/reagent/consumable/sodiumchloride/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0)
. = ..()
if(exposed_mob.has_bane(BANE_SALT))
exposed_mob.mind.disrupt_spells(-200)
/datum/reagent/consumable/sodiumchloride/expose_turf(turf/exposed_turf, reac_volume) //Creates an umbra-blocking salt pile
. = ..()
if(!istype(exposed_turf) || (reac_volume < 1))

View File

@@ -774,7 +774,7 @@
/datum/reagent/medicine/strange_reagent/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
if(exposed_mob.stat != DEAD)
return ..()
if(exposed_mob.suiciding || exposed_mob.hellbound) //they are never coming back
if(exposed_mob.suiciding) //they are never coming back
exposed_mob.visible_message("<span class='warning'>[exposed_mob]'s body does not react...</span>")
return
if(iscarbon(exposed_mob) && !(methods & INGEST)) //simplemobs can still be splashed

View File

@@ -928,15 +928,6 @@
C.blood_volume += 0.5
..()
/datum/reagent/iron/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
if(!exposed_mob.has_bane(BANE_IRON)) //If the target is weak to cold iron, then poison them.
return
if(!holder || (holder.chem_temp >= 100)) // COLD iron.
return
exposed_mob.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
/datum/reagent/gold
name = "Gold"
description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known."
@@ -953,11 +944,6 @@
taste_description = "expensive yet reasonable metal"
material = /datum/material/silver
/datum/reagent/silver/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
if(exposed_mob.has_bane(BANE_SILVER))
exposed_mob.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
/datum/reagent/uranium
name ="Uranium"
description = "A jade-green metallic chemical element in the actinide series, weakly radioactive."

View File

@@ -1,258 +0,0 @@
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork
name = "Summon Pitchfork"
desc = "A devil's weapon of choice. Use this to summon/unsummon your pitchfork."
invocation_type = "none"
include_user = TRUE
range = -1
clothes_req = FALSE
item_type = /obj/item/pitchfork/demonic
school = "conjuration"
charge_max = 150
cooldown_min = 10
action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
action_icon_state = "pitchfork"
action_background_icon_state = "bg_demon"
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater
item_type = /obj/item/pitchfork/demonic/greater
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended
item_type = /obj/item/pitchfork/demonic/ascended
/obj/effect/proc_holder/spell/targeted/conjure_item/violin
item_type = /obj/item/instrument/violin/golden
desc = "A devil's instrument of choice. Use this to summon/unsummon your golden violin."
invocation_type = INVOCATION_WHISPER
invocation = "I ain't had this much fun since Georgia."
action_icon_state = "golden_violin"
name = "Summon golden violin"
action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
action_background_icon_state = "bg_demon"
/obj/effect/proc_holder/spell/targeted/summon_contract
name = "Summon infernal contract"
desc = "Skip making a contract by hand, just do it by magic."
invocation_type = INVOCATION_WHISPER
invocation = "Just sign on the dotted line."
include_user = FALSE
range = 5
clothes_req = FALSE
school = "conjuration"
charge_max = 150
cooldown_min = 10
action_icon_state = "spell_default"
action_background_icon_state = "bg_demon"
/obj/effect/proc_holder/spell/targeted/summon_contract/cast(list/targets, mob/user = usr)
for(var/mob/living/carbon/C in targets)
if(C.mind && user.mind)
if(C.stat == DEAD)
if(user.dropItemToGround(user.get_active_held_item()))
var/obj/item/paper/contract/infernal/revive/contract = new(user.loc, C.mind, user.mind)
user.put_in_hands(contract)
else
var/obj/item/paper/contract/infernal/contract // = new(user.loc, C.mind, contractType, user.mind)
var/contractTypeName = input(user, "What type of contract?") in sortList(list("Power", "Wealth", "Prestige", "Magic", "Knowledge", "Friendship"))
switch(contractTypeName)
if("Power")
contract = new /obj/item/paper/contract/infernal/power(C.loc, C.mind, user.mind)
if("Wealth")
contract = new /obj/item/paper/contract/infernal/wealth(C.loc, C.mind, user.mind)
if("Prestige")
contract = new /obj/item/paper/contract/infernal/prestige(C.loc, C.mind, user.mind)
if("Magic")
contract = new /obj/item/paper/contract/infernal/magic(C.loc, C.mind, user.mind)
if("Knowledge")
contract = new /obj/item/paper/contract/infernal/knowledge(C.loc, C.mind, user.mind)
if("Friendship")
contract = new /obj/item/paper/contract/infernal/friend(C.loc, C.mind, user.mind)
C.put_in_hands(contract)
else
to_chat(user, "<span class='warning'>[C] seems to not be sentient. You cannot summon a contract for [C.p_them()].</span>")
/obj/effect/proc_holder/spell/aimed/fireball/hellish
name = "Hellfire"
desc = "This spell launches hellfire at the target."
school = "evocation"
charge_max = 80
clothes_req = FALSE
invocation = "Your very soul will catch fire!"
invocation_type = INVOCATION_SHOUT
range = 2
projectile_type = /obj/projectile/magic/aoe/fireball/infernal
action_background_icon_state = "bg_demon"
/obj/effect/proc_holder/spell/targeted/infernal_jaunt
name = "Infernal Jaunt"
desc = "Use hellfire to phase out of existence."
charge_max = 200
clothes_req = FALSE
selection_type = "range"
range = -1
cooldown_min = 0
overlay = null
include_user = TRUE
action_icon_state = "jaunt"
action_background_icon_state = "bg_demon"
phase_allowed = TRUE
/obj/effect/proc_holder/spell/targeted/infernal_jaunt/cast(list/targets, mob/living/user = usr)
if(istype(user))
if(istype(user.loc, /obj/effect/dummy/phased_mob/slaughter/))
if(valid_location(user))
to_chat(user, "<span class='warning'>You are now phasing in.</span>")
if(do_mob(user,user,150))
if(valid_location(user))
user.infernalphasein()
else
to_chat(user, "<span class='warning'>You are no longer near a potential signer.</span>")
else
to_chat(user, "<span class='warning'>You can only re-appear near a potential signer.</span>")
revert_cast()
return ..()
else
user.notransform = TRUE
user.fakefire()
to_chat(src, "<span class='warning'>You begin to phase back into sinful flames.</span>")
if(do_mob(user,user,150))
user.infernalphaseout()
else
to_chat(user, "<span class='warning'>You must remain still while exiting.</span>")
user.notransform = FALSE
user.fakefireextinguish()
start_recharge()
return
revert_cast()
/obj/effect/proc_holder/spell/targeted/infernal_jaunt/proc/valid_location(mob/living/user = usr)
if(istype(get_area(user), /area/shuttle/)) // Can always phase in in a shuttle.
return TRUE
else
for(var/mob/living/C in orange(2, get_turf(user))) //Can also phase in when nearby a potential buyer.
if (C.owns_soul())
return TRUE
return FALSE
/mob/living/proc/infernalphaseout()
dust_animation()
spawn_dust()
visible_message("<span class='warning'>[src] disappears in a flashfire!</span>")
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, TRUE, -1)
var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(loc)
extinguish_mob()
forceMove(holder)
holder = holder
notransform = FALSE
fakefireextinguish()
/mob/living/proc/infernalphasein()
if(notransform)
to_chat(src, "<span class='warning'>You're too busy to jaunt in.</span>")
return FALSE
fakefire()
forceMove(drop_location())
client.eye = src
visible_message("<span class='warning'><B>[src] appears in a fiery blaze!</B></span>")
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, TRUE, -1)
addtimer(CALLBACK(src, .proc/fakefireextinguish), 15, TIMER_UNIQUE)
/obj/effect/proc_holder/spell/targeted/sintouch
name = "Sin Touch"
desc = "Subtly encourage someone to sin."
charge_max = 1800
clothes_req = FALSE
selection_type = "range"
range = 2
cooldown_min = 0
overlay = null
include_user = FALSE
action_icon = 'icons/mob/actions/actions_cult.dmi'
action_icon_state = "sintouch"
action_background_icon_state = "bg_demon"
phase_allowed = FALSE
random_target = TRUE
random_target_priority = TARGET_RANDOM
max_targets = 3
invocation = "TASTE SIN AND INDULGE!!"
invocation_type = INVOCATION_SHOUT
/obj/effect/proc_holder/spell/targeted/sintouch/ascended
name = "Greater sin touch"
charge_max = 100
range = 7
max_targets = 10
/obj/effect/proc_holder/spell/targeted/sintouch/cast(list/targets, mob/living/user = usr)
for(var/mob/living/carbon/human/H in targets)
if(!H.mind)
continue
if(H.mind.has_antag_datum(/datum/antagonist/sintouched))
continue
if(H.anti_magic_check(FALSE, TRUE))
continue
H.mind.add_antag_datum(/datum/antagonist/sintouched)
H.Paralyze(400)
/obj/effect/proc_holder/spell/targeted/summon_dancefloor
name = "Summon Dancefloor"
desc = "When what a Devil really needs is funk."
include_user = TRUE
range = -1
clothes_req = FALSE
school = "conjuration"
charge_max = 10
cooldown_min = 50 //5 seconds, so the smoke can't be spammed
action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
action_icon_state = "funk"
action_background_icon_state = "bg_demon"
var/list/dancefloor_turfs
var/list/dancefloor_turfs_types
var/dancefloor_exists = FALSE
var/datum/effect_system/smoke_spread/transparent/dancefloor_devil/smoke
/obj/effect/proc_holder/spell/targeted/summon_dancefloor/cast(list/targets, mob/user = usr)
LAZYINITLIST(dancefloor_turfs)
LAZYINITLIST(dancefloor_turfs_types)
if(!smoke)
smoke = new()
smoke.set_up(0, get_turf(user))
smoke.start()
if(dancefloor_exists)
dancefloor_exists = FALSE
for(var/i in 1 to dancefloor_turfs.len)
var/turf/T = dancefloor_turfs[i]
T.ChangeTurf(dancefloor_turfs_types[i], flags = CHANGETURF_INHERIT_AIR)
else
var/list/funky_turfs = RANGE_TURFS(1, user)
for(var/turf/closed/solid in funky_turfs)
to_chat(user, "<span class='warning'>You're too close to a wall.</span>")
return
dancefloor_exists = TRUE
var/i = 1
dancefloor_turfs.len = funky_turfs.len
dancefloor_turfs_types.len = funky_turfs.len
for(var/t in funky_turfs)
var/turf/T = t
dancefloor_turfs[i] = T
dancefloor_turfs_types[i] = T.type
T.ChangeTurf((i % 2 == 0) ? /turf/open/floor/light/colour_cycle/dancefloor_a : /turf/open/floor/light/colour_cycle/dancefloor_b, flags = CHANGETURF_INHERIT_AIR)
i++
/datum/effect_system/smoke_spread/transparent/dancefloor_devil
effect_type = /obj/effect/particle_effect/smoke/transparent/dancefloor_devil
/obj/effect/particle_effect/smoke/transparent/dancefloor_devil
lifetime = 2

View File

@@ -1,76 +0,0 @@
/obj/effect/proc_holder/spell/targeted/summon_wealth
name = "Summon wealth"
desc = "The reward for selling your soul."
invocation_type = "none"
include_user = TRUE
range = -1
clothes_req = FALSE
school = "conjuration"
charge_max = 100
cooldown_min = 10
action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
action_icon_state = "moneybag"
/obj/effect/proc_holder/spell/targeted/summon_wealth/cast(list/targets, mob/user = usr)
for(var/mob/living/carbon/C in targets)
if(user.dropItemToGround(user.get_active_held_item()))
var/obj/item = pick(
new /obj/item/coin/gold(user.drop_location()),
new /obj/item/coin/diamond(user.drop_location()),
new /obj/item/coin/silver(user.drop_location()),
new /obj/item/clothing/accessory/medal/gold(user.drop_location()),
new /obj/item/stack/sheet/mineral/gold(user.drop_location()),
new /obj/item/stack/sheet/mineral/silver(user.drop_location()),
new /obj/item/stack/sheet/mineral/diamond(user.drop_location()),
new /obj/item/holochip(user.drop_location(), 1000))
C.put_in_hands(item)
/obj/effect/proc_holder/spell/targeted/view_range
name = "Distant vision"
desc = "The reward for selling your soul."
invocation_type = "none"
include_user = TRUE
range = -1
clothes_req = FALSE
charge_max = 50
cooldown_min = 10
action_icon = 'icons/mob/actions/actions_silicon.dmi'
action_icon_state = "camera_jump"
var/ranges = list(7,8,9,10)
/obj/effect/proc_holder/spell/targeted/view_range/cast(list/targets, mob/user = usr)
for(var/mob/C in targets)
if(!C.client)
continue
C.client.view_size.setTo((input("Select view range:", "Range", 4) in ranges) - 7)
/obj/effect/proc_holder/spell/targeted/summon_friend
name = "Summon Friend"
desc = "The reward for selling your soul."
invocation_type = "none"
include_user = TRUE
range = -1
clothes_req = FALSE
charge_max = 50
cooldown_min = 10
action_icon = 'icons/mob/actions/actions_spells.dmi'
action_icon_state = "sacredflame"
var/mob/living/friend
var/obj/effect/mob_spawn/human/demonic_friend/friendShell
/obj/effect/proc_holder/spell/targeted/summon_friend/cast(list/targets, mob/user = usr)
if(!QDELETED(friend))
to_chat(friend, "<span class='userdanger'>Your master has deemed you a poor friend. Your durance in hell will now resume.</span>")
friend.dust(TRUE)
qdel(friendShell)
return
if(!QDELETED(friendShell))
qdel(friendShell)
return
for(var/C in targets)
var/mob/living/L = C
friendShell = new /obj/effect/mob_spawn/human/demonic_friend(L.loc, L.mind, src)
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/robeless
clothes_req = FALSE

View File

@@ -28,9 +28,6 @@
if(!hand_items.len)
to_chat(M, "<span class='warning'>You must hold an item you wish to make your phylactery!</span>")
return
if(!M.mind.hasSoul)
to_chat(user, "<span class='warning'>You do not possess a soul!</span>")
return
var/obj/item/marked_item
@@ -60,7 +57,6 @@
new /obj/item/phylactery(marked_item, M.mind)
to_chat(M, "<span class='userdanger'>With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich!</span>")
M.mind.hasSoul = FALSE
M.set_species(/datum/species/skeleton)
if(ishuman(M))
var/mob/living/carbon/human/H = M

View File

@@ -130,12 +130,11 @@
var/mob/living/stored
var/mob/living/shape
var/restoring = FALSE
var/datum/soullink/shapeshift/slink
var/obj/effect/proc_holder/spell/targeted/shapeshift/source
/obj/shapeshift_holder/Initialize(mapload,obj/effect/proc_holder/spell/targeted/shapeshift/source,mob/living/caster)
/obj/shapeshift_holder/Initialize(mapload,obj/effect/proc_holder/spell/targeted/shapeshift/_source, mob/living/caster)
. = ..()
src.source = source
source = _source
shape = loc
if(!istype(shape))
CRASH("shapeshift holder created outside mob/living")
@@ -151,15 +150,16 @@
shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE, wound_bonus=CANT_WOUND);
shape.blood_volume = stored.blood_volume;
slink = soullink(/datum/soullink/shapeshift, stored , shape)
slink.source = src
stored.RegisterSignal(src, COMSIG_PARENT_QDELETING, .proc/shape_death)
stored.RegisterSignal(shape, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_DEATH), .proc/shape_death)
shape.RegisterSignal(stored, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_DEATH), .proc/shape_death)
/obj/shapeshift_holder/Destroy()
if(!restoring)
restore()
stored = null
shape = null
. = ..()
return ..()
/obj/shapeshift_holder/Moved()
. = ..()
@@ -174,14 +174,16 @@
if(AM == stored && !restoring)
restore()
/obj/shapeshift_holder/proc/casterDeath()
/obj/shapeshift_holder/proc/caster_death()
SIGNAL_HANDLER
//Something kills the stored caster through direct damage.
if(source.revert_on_death)
restore(death=TRUE)
else
shape.death()
/obj/shapeshift_holder/proc/shapeDeath()
/obj/shapeshift_holder/proc/shape_death()
SIGNAL_HANDLER
//Shape dies.
if(source.die_with_shapeshifted_form)
if(source.revert_on_death)
@@ -191,7 +193,6 @@
/obj/shapeshift_holder/proc/restore(death=FALSE)
restoring = TRUE
qdel(slink)
stored.forceMove(shape.loc)
stored.notransform = FALSE
if(shape.mind)
@@ -207,16 +208,5 @@
stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE, wound_bonus=CANT_WOUND)
if(source.convert_damage)
stored.blood_volume = shape.blood_volume;
qdel(shape)
QDEL_NULL(shape)
qdel(src)
/datum/soullink/shapeshift
var/obj/shapeshift_holder/source
/datum/soullink/shapeshift/ownerDies(gibbed, mob/living/owner)
if(source)
source.casterDeath(gibbed)
/datum/soullink/shapeshift/sharerDies(gibbed, mob/living/sharer)
if(source)
source.shapeDeath(gibbed)

View File

@@ -18,15 +18,12 @@
action_icon_state = "soultap"
/obj/effect/proc_holder/spell/self/tap/cast(list/targets, mob/living/user = usr)
if(!user.mind.hasSoul)
to_chat(user, "<span class='warning'>You do not possess a soul to tap into!</span>")
return
to_chat(user, "<span class='danger'>Your body feels drained and there is a burning pain in your chest.</span>")
user.maxHealth -= HEALTH_LOST_PER_SOUL_TAP
user.health = min(user.health, user.maxHealth)
if(user.maxHealth <= 0)
to_chat(user, "<span class='userdanger'>Your weakened soul is completely consumed by the tap!</span>")
user.mind.hasSoul = FALSE
return
for(var/obj/effect/proc_holder/spell/spell in user.mind.spell_list)
spell.charge_counter = spell.charge_max
spell.recharging = FALSE

View File

@@ -503,7 +503,7 @@
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
//Consider moving this to a new species proc "spec_heal" maybe?
if(owner.stat == DEAD && owner?.dna?.species && (REVIVES_BY_HEALING in owner.dna.species.species_traits))
if(owner.health > 50 && !owner.hellbound)
if(owner.health > 50)
owner.revive(FALSE)
//SKYRAT EDIT ADDITION END
cremation_progress = min(0, cremation_progress - ((brute_dam + burn_dam)*(100/max_damage)))

View File

@@ -263,11 +263,6 @@
max_damage = 500
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/head/devil
dismemberable = 0
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/head/larva
icon = 'icons/mob/animal_parts.dmi'
icon_state = "larva_head"

View File

@@ -41,11 +41,6 @@
max_damage = 500
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/chest/devil
dismemberable = 0
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/chest/larva
icon = 'icons/mob/animal_parts.dmi'
icon_state = "larva_chest"
@@ -151,12 +146,6 @@
max_damage = 100
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/l_arm/devil
dismemberable = FALSE
can_be_disabled = FALSE
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/r_arm
name = "right arm"
desc = "Over 87% of humans are right handed. That figure is much lower \
@@ -253,12 +242,6 @@
max_damage = 100
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/r_arm/devil
dismemberable = FALSE
can_be_disabled = FALSE
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/l_leg
name = "left leg"
desc = "Some athletes prefer to tie their left shoelaces first for good \
@@ -348,12 +331,6 @@
max_damage = 100
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/l_leg/devil
dismemberable = FALSE
can_be_disabled = FALSE
max_damage = 5000
animal_origin = DEVIL_BODYPART
/obj/item/bodypart/r_leg
name = "right leg"
desc = "You put your right leg in, your right leg out. In, out, in, out, \
@@ -444,9 +421,3 @@
can_be_disabled = FALSE
max_damage = 100
animal_origin = ALIEN_BODYPART
/obj/item/bodypart/r_leg/devil
dismemberable = FALSE
can_be_disabled = FALSE
max_damage = 5000
animal_origin = DEVIL_BODYPART

View File

@@ -180,15 +180,7 @@
for(var/V in listeners)
var/mob/living/L = V
var/datum/antagonist/devil/devilinfo = is_devil(L)
if(devilinfo && findtext(message, devilinfo.truename))
var/start = findtext(message, devilinfo.truename)
listeners = list(L) //Devil names are unique.
power_multiplier *= 5 //if you're a devil and god himself addressed you, you fucked up
//Cut out the name so it doesn't trigger commands
message = copytext(message, 1, start) + copytext(message, start + length(devilinfo.truename))
break
else if(findtext(message, L.real_name, 1, length(L.real_name) + 1))
if(findtext(message, L.real_name, 1, length(L.real_name) + 1))
specific_listeners += L //focus on those with the specified name
//Cut out the name so it doesn't trigger commands
found_string = L.real_name
@@ -363,13 +355,7 @@
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
var/text = ""
if(is_devil(L))
var/datum/antagonist/devil/devilinfo = is_devil(L)
text = devilinfo.truename
else
text = L.real_name
addtimer(CALLBACK(L, /atom/movable/proc/say, text), 5 * i)
addtimer(CALLBACK(L, /atom/movable/proc/say, L.real_name), 5 * i)
i++
//SAY MY NAME

View File

@@ -18,7 +18,7 @@
return FALSE
if(target.stat != DEAD)
return FALSE
if(target.suiciding || target.hellbound || HAS_TRAIT(target, TRAIT_HUSK))
if(target.suiciding || HAS_TRAIT(target, TRAIT_HUSK))
return FALSE
var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
if(!B)

View File

@@ -102,8 +102,6 @@ PROBABILITY MONKEY 0
PROBABILITY METEOR 0
PROBABILITY EXTENDED 0
PROBABILITY SECRET_EXTENDED 0
PROBABILITY DEVIL 0
PROBABILITY DEVIL_AGENTS 0
PROBABILITY CLOWNOPS 0
## You probably want to keep sandbox off by default for secret and random.
@@ -187,12 +185,6 @@ MIDROUND_ANTAG WIZARD
#MIN_POP METEOR 0
#MAX_POP METEOR -1
#MIN_POP DEVIL 0
#MAX_POP DEVIL -1
#MIN_POP DEVIL_AGENTS 25
#MAX_POP DEVIL_AGENTS -1
## Setting at least one mode to be playable at 0/1 players is required.
#MIN_POP EXTENDED 0
#MAX_POP EXTENDED -1

View File

@@ -13,7 +13,7 @@
if(C.stat == DEAD && ishuman(C))
var/mob/living/carbon/human/H = C
if(H?.dna?.species && (REVIVES_BY_HEALING in H.dna.species.species_traits))
if(H.health > 50 && !H.hellbound)
if(H.health > 50)
H.revive(FALSE)
/obj/item/organ/brain/ipc_positron/emp_act(severity)

View File

@@ -41,7 +41,6 @@
#include "code\__DEFINES\combat.dm"
#include "code\__DEFINES\configuration.dm"
#include "code\__DEFINES\construction.dm"
#include "code\__DEFINES\contracts.dm"
#include "code\__DEFINES\cooldowns.dm"
#include "code\__DEFINES\cult.dm"
#include "code\__DEFINES\diseases.dm"
@@ -231,7 +230,6 @@
#include "code\_onclick\hud\blobbernauthud.dm"
#include "code\_onclick\hud\constructs.dm"
#include "code\_onclick\hud\credits.dm"
#include "code\_onclick\hud\devil.dm"
#include "code\_onclick\hud\drones.dm"
#include "code\_onclick\hud\families.dm"
#include "code\_onclick\hud\fullscreen.dm"
@@ -379,7 +377,6 @@
#include "code\datums\ruins.dm"
#include "code\datums\saymode.dm"
#include "code\datums\shuttles.dm"
#include "code\datums\soullink.dm"
#include "code\datums\spawners_menu.dm"
#include "code\datums\tgs_event_handler.dm"
#include "code\datums\verbs.dm"
@@ -737,10 +734,6 @@
#include "code\game\gamemodes\clown_ops\clown_ops.dm"
#include "code\game\gamemodes\clown_ops\clown_weapons.dm"
#include "code\game\gamemodes\cult\cult.dm"
#include "code\game\gamemodes\devil\devil_game_mode.dm"
#include "code\game\gamemodes\devil\game_mode.dm"
#include "code\game\gamemodes\devil\objectives.dm"
#include "code\game\gamemodes\devil\devil_agent\devil_agent.dm"
#include "code\game\gamemodes\dynamic\dynamic.dm"
#include "code\game\gamemodes\dynamic\dynamic_rulesets.dm"
#include "code\game\gamemodes\dynamic\dynamic_rulesets_latejoin.dm"
@@ -1505,13 +1498,6 @@
#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\devil\devil.dm"
#include "code\modules\antagonists\devil\devil_helpers.dm"
#include "code\modules\antagonists\devil\imp\imp.dm"
#include "code\modules\antagonists\devil\sintouched\objectives.dm"
#include "code\modules\antagonists\devil\sintouched\sintouched.dm"
#include "code\modules\antagonists\devil\true_devil\_true_devil.dm"
#include "code\modules\antagonists\devil\true_devil\inventory.dm"
#include "code\modules\antagonists\disease\disease_abilities.dm"
#include "code\modules\antagonists\disease\disease_datum.dm"
#include "code\modules\antagonists\disease\disease_disease.dm"
@@ -1869,7 +1855,6 @@
#include "code\modules\events\communications_blackout.dm"
#include "code\modules\events\creep_awakening.dm"
#include "code\modules\events\crystal_event.dm"
#include "code\modules\events\devil.dm"
#include "code\modules\events\disease_outbreak.dm"
#include "code\modules\events\dust.dm"
#include "code\modules\events\electrical_storm.dm"
@@ -3025,8 +3010,6 @@
#include "code\modules\spells\spell_types\conjure.dm"
#include "code\modules\spells\spell_types\construct_spells.dm"
#include "code\modules\spells\spell_types\curse.dm"
#include "code\modules\spells\spell_types\devil.dm"
#include "code\modules\spells\spell_types\devil_boons.dm"
#include "code\modules\spells\spell_types\emplosion.dm"
#include "code\modules\spells\spell_types\ethereal_jaunt.dm"
#include "code\modules\spells\spell_types\explosion.dm"