mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
[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:
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -204,13 +204,6 @@
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
True Devil
|
||||
*/
|
||||
|
||||
/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity)
|
||||
A.attack_hand(src)
|
||||
|
||||
/*
|
||||
Brain
|
||||
*/
|
||||
|
||||
@@ -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]"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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++
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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."
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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(.)
|
||||
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user