mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 10:33:30 +01:00
I'm confused
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
#define CONTRACT_POWER "Power"
|
||||
#define CONTRACT_WEALTH "Wealth"
|
||||
#define CONTRACT_PRESTIGE "Prestige"
|
||||
#define CONTRACT_MAGIC "Magic"
|
||||
#define CONTRACT_REVIVE "Revive"
|
||||
#define CONTRACT_KNOWLEDGE "Knowledge"
|
||||
#define CONTRACT_UNWILLING "Unwilling"
|
||||
// FIXME: Implement these
|
||||
#define CONTRACT_ETALENT "Engineering Talent"
|
||||
#define CONTRACT_CTALENT "Chemistry Talent"
|
||||
#define CONTRACT_RETURNDEAD "Return Dead"
|
||||
#define CONTRACT_AUGMENT "Cybernetic Augmentations"
|
||||
#define CONTRACT_CANDY "Endless Candy"
|
||||
#define CONTRACT_ECHANCE "An Extra Chance"
|
||||
#define CONTRACT_ATECH "Advanced Technology"
|
||||
#define CONTRACT_DEVILSMACHINE "Devil's Machinery"
|
||||
#define CONTRACT_YOUTH "Eternal Youth"
|
||||
#define CONTRACT_FOOD "Food"
|
||||
#define CONTRACT_SPACE "Space Gear"
|
||||
#define CONTRACT_CALAMITY "Calamity"
|
||||
|
||||
#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_HURTMAN "hurtman"
|
||||
#define BAN_CHAPEL "chapel"
|
||||
#define BAN_HURTPRIEST "hurtpriest"
|
||||
#define BAN_AVOIDWATER "avoidwater"
|
||||
#define BAN_STRIKEUNCONCIOUS "strikeunconcious"
|
||||
#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
|
||||
@@ -56,8 +56,9 @@
|
||||
#define ANTAG_HUD_VAMPIRE 17
|
||||
#define ANTAG_HUD_ABDUCTOR 18
|
||||
#define DATA_HUD_ABDUCTOR 19
|
||||
#define ANTAG_HUD_DEVIL 20
|
||||
|
||||
// Notification action types
|
||||
#define NOTIFY_JUMP "jump"
|
||||
#define NOTIFY_ATTACK "attack"
|
||||
#define NOTIFY_FOLLOW "orbit"
|
||||
#define NOTIFY_FOLLOW "orbit"
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
|
||||
#define STATUS_UPDATE_NONE 0
|
||||
#define STATUS_UPDATE_ALL (~0)
|
||||
#define INVISIBILITY_ABSTRACT 101
|
||||
#define UNHEALING_EAR_DAMAGE 100
|
||||
|
||||
//Human sub-species
|
||||
|
||||
@@ -40,4 +40,13 @@
|
||||
#define EXP_TYPE_CREW "Crew"
|
||||
#define EXP_TYPE_SPECIAL "Special"
|
||||
#define EXP_TYPE_GHOST "Ghost"
|
||||
#define EXP_TYPE_EXEMPT "Exempt"
|
||||
#define EXP_TYPE_EXEMPT "Exempt"
|
||||
#define EXP_TYPE_COMMAND "Command"
|
||||
#define EXP_TYPE_ENGINEERING "Engineering"
|
||||
#define EXP_TYPE_MEDICAL "Medical"
|
||||
#define EXP_TYPE_SCIENCE "Science"
|
||||
#define EXP_TYPE_SUPPLY "Supply"
|
||||
#define EXP_TYPE_SECURITY "Security"
|
||||
#define EXP_TYPE_SILICON "Silicon"
|
||||
#define EXP_TYPE_SERVICE "Service"
|
||||
#define EXP_TYPE_WHITELIST "Whitelist"
|
||||
@@ -26,6 +26,7 @@
|
||||
#define ROLE_REVENANT "revenant"
|
||||
#define ROLE_HOG_GOD "hand of god: god" // We're prolly gonna port this one day or another
|
||||
#define ROLE_HOG_CULTIST "hand of god: cultist"
|
||||
#define ROLE_DEVIL "devil"
|
||||
#define ROLE_RAIDER "vox raider"
|
||||
#define ROLE_TRADER "trader"
|
||||
#define ROLE_VAMPIRE "vampire"
|
||||
@@ -73,4 +74,5 @@ var/global/list/special_roles = list(
|
||||
ROLE_MORPH,
|
||||
ROLE_TRADER,
|
||||
ROLE_GSPIDER,
|
||||
ROLE_DEVIL = /datum/game_mode/devil/devil_agents,
|
||||
)
|
||||
|
||||
@@ -791,4 +791,4 @@ proc/dd_sortedObjectList(list/incoming)
|
||||
while(start < end)
|
||||
L.Swap(start++, end--)
|
||||
|
||||
return L
|
||||
return L
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
//what could possibly go wrong
|
||||
var/list/devil_machines = typecacheof(/obj/item/circuitboard, TRUE) - list(
|
||||
/obj/item/circuitboard/shuttle,
|
||||
/obj/item/circuitboard/swfdoor,
|
||||
/obj/item/circuitboard/olddoor,
|
||||
/obj/item/circuitboard/computer,
|
||||
/obj/item/circuitboard/machine
|
||||
)
|
||||
@@ -22,6 +22,7 @@
|
||||
//Middle left indicators
|
||||
#define ui_lingchemdisplay "WEST:6,CENTER-1:15"
|
||||
#define ui_lingstingdisplay "WEST:6,CENTER-3:11"
|
||||
#define ui_devilsouldisplay "WEST:6,CENTER-1:15"
|
||||
|
||||
//Lower center, persistant menu
|
||||
#define ui_sstore1 "CENTER-5:10,SOUTH:5"
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
inv_slots[inv.slot_id] = inv
|
||||
inv.update_icon()
|
||||
|
||||
/datum/hud/alien/persistant_inventory_update()
|
||||
/datum/hud/alien/persistent_inventory_update()
|
||||
if(!mymob)
|
||||
return
|
||||
var/mob/living/carbon/alien/humanoid/H = mymob
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
//Soul counter is stored with the humans, it does weird when you place it here apparently...
|
||||
|
||||
|
||||
/datum/hud/devil/New(mob/owner, ui_style = 'icons/mob/screen_midnight.dmi')
|
||||
..()
|
||||
|
||||
var/obj/screen/using
|
||||
var/obj/screen/inventory/inv_box
|
||||
|
||||
using = new /obj/screen/drop()
|
||||
using.icon = ui_style
|
||||
using.screen_loc = ui_drop_throw
|
||||
static_inventory += using
|
||||
|
||||
mymob.pullin = new /obj/screen/pull()
|
||||
mymob.pullin.icon = ui_style
|
||||
mymob.pullin.update_icon(mymob)
|
||||
mymob.pullin.screen_loc = ui_pull_resist
|
||||
static_inventory += mymob.pullin
|
||||
|
||||
inv_box = new /obj/screen/inventory/hand()
|
||||
inv_box.name = "right hand"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "hand_r"
|
||||
inv_box.screen_loc = ui_rhand
|
||||
inv_box.slot_id = slot_r_hand
|
||||
static_inventory += inv_box
|
||||
|
||||
inv_box = new /obj/screen/inventory/hand()
|
||||
inv_box.name = "left hand"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "hand_l"
|
||||
inv_box.screen_loc = ui_lhand
|
||||
inv_box.slot_id = slot_l_hand
|
||||
static_inventory += inv_box
|
||||
|
||||
using = new /obj/screen/swap_hand()
|
||||
using.name = "hand"
|
||||
using.icon = ui_style
|
||||
using.icon_state = "swap_1"
|
||||
using.screen_loc = ui_swaphand1
|
||||
using.layer = 19
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/swap_hand()
|
||||
using.name = "hand"
|
||||
using.icon = ui_style
|
||||
using.icon_state = "swap_2"
|
||||
using.screen_loc = ui_swaphand2
|
||||
using.layer = 19
|
||||
static_inventory += using
|
||||
|
||||
mymob.zone_sel = new /obj/screen/zone_sel()
|
||||
mymob.zone_sel.icon = ui_style
|
||||
mymob.zone_sel.update_icon(mymob)
|
||||
|
||||
lingchemdisplay = new /obj/screen/ling/chems()
|
||||
devilsouldisplay = new /obj/screen/devil/soul_counter
|
||||
infodisplay += devilsouldisplay
|
||||
|
||||
for(var/obj/screen/inventory/inv in static_inventory)
|
||||
if(inv.slot_id)
|
||||
inv.hud = src
|
||||
inv_slots[inv.slot_id] = inv
|
||||
inv.update_icon()
|
||||
|
||||
|
||||
/datum/hud/devil/persistent_inventory_update()
|
||||
if(!mymob)
|
||||
return
|
||||
var/mob/living/carbon/true_devil/D = mymob
|
||||
|
||||
if(hud_version != HUD_STYLE_NOHUD)
|
||||
if(D.r_hand)
|
||||
D.r_hand.screen_loc = ui_rhand
|
||||
D.client.screen += D.r_hand
|
||||
if(D.l_hand)
|
||||
D.l_hand.screen_loc = ui_lhand
|
||||
D.client.screen += D.l_hand
|
||||
else
|
||||
if(D.r_hand)
|
||||
D.r_hand.screen_loc = null
|
||||
if(D.l_hand)
|
||||
D.l_hand.screen_loc = null
|
||||
|
||||
/mob/living/carbon/true_devil/create_mob_hud()
|
||||
if(client && !hud_used)
|
||||
hud_used = new /datum/hud/devil(src, ui_style2icon(client.prefs.UI_style))
|
||||
@@ -27,6 +27,8 @@
|
||||
var/obj/screen/move_intent
|
||||
var/obj/screen/module_store_icon
|
||||
|
||||
var/obj/screen/devil/soul_counter/devilsouldisplay
|
||||
|
||||
var/list/static_inventory = list() //the screen objects which are static
|
||||
var/list/toggleable_inventory = list() //the screen objects which can be hidden
|
||||
var/list/hotkeybuttons = list() //the buttons that can be used via hotkeys
|
||||
@@ -79,6 +81,7 @@
|
||||
alien_plasma_display = null
|
||||
vampire_blood_display = null
|
||||
nightvisionicon = null
|
||||
devilsouldisplay = null
|
||||
|
||||
mymob = null
|
||||
return ..()
|
||||
@@ -155,7 +158,7 @@
|
||||
mymob.client.screen -= infodisplay
|
||||
|
||||
hud_version = display_hud_version
|
||||
persistant_inventory_update()
|
||||
persistent_inventory_update()
|
||||
mymob.update_action_buttons(1)
|
||||
reorganize_alerts()
|
||||
reload_fullscreen()
|
||||
@@ -171,7 +174,7 @@
|
||||
/datum/hud/proc/hidden_inventory_update()
|
||||
return
|
||||
|
||||
/datum/hud/proc/persistant_inventory_update()
|
||||
/datum/hud/proc/persistent_inventory_update()
|
||||
return
|
||||
|
||||
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
|
||||
|
||||
@@ -36,6 +36,35 @@
|
||||
var/mob/living/carbon/U = usr
|
||||
U.unset_sting()
|
||||
|
||||
/obj/screen/devil
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/obj/screen/devil/soul_counter
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
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/chems
|
||||
name = "chemical storage"
|
||||
icon_state = "power_display"
|
||||
@@ -337,6 +366,9 @@
|
||||
lingstingdisplay = new /obj/screen/ling/sting()
|
||||
infodisplay += lingstingdisplay
|
||||
|
||||
devilsouldisplay = new /obj/screen/devil/soul_counter
|
||||
infodisplay += devilsouldisplay
|
||||
|
||||
mymob.zone_sel = new /obj/screen/zone_sel()
|
||||
mymob.zone_sel.icon = ui_style
|
||||
mymob.zone_sel.update_icon(mymob)
|
||||
@@ -393,7 +425,7 @@
|
||||
if(H.wear_mask) H.wear_mask.screen_loc = null
|
||||
if(H.head) H.head.screen_loc = null
|
||||
|
||||
/datum/hud/human/persistant_inventory_update()
|
||||
/datum/hud/human/persistent_inventory_update()
|
||||
if(!mymob)
|
||||
return
|
||||
var/mob/living/carbon/human/H = mymob
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
M.lastattacker = user
|
||||
|
||||
user.do_attack_animation(M)
|
||||
M.attacked_by(src, user, def_zone)
|
||||
. = M.attacked_by(src, user, def_zone)
|
||||
|
||||
add_attack_logs(user, M, "Attacked with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])", (M.ckey && force > 0 && damtype != STAMINA) ? null : ATKLOG_ALMOSTALL)
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
|
||||
/datum/ai_law/zero/get_index()
|
||||
return 0
|
||||
|
||||
/datum/ai_law/sixsixsix/get_index()
|
||||
return 666
|
||||
|
||||
|
||||
/datum/ai_laws
|
||||
var/name = "Unknown Laws"
|
||||
var/law_header = "Prime Directives"
|
||||
@@ -27,9 +31,11 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
|
||||
var/list/datum/ai_law/inherent_laws = list()
|
||||
var/list/datum/ai_law/supplied_laws = list()
|
||||
var/list/datum/ai_law/ion/ion_laws = list()
|
||||
var/list/datum/ai_law/sixsixsix/devil_laws = list()
|
||||
var/list/datum/ai_law/sorted_laws = list()
|
||||
|
||||
var/state_zeroth = 0
|
||||
var/list/state_devil = list()
|
||||
var/list/state_ion = list()
|
||||
var/list/state_inherent = list()
|
||||
var/list/state_supplied = list()
|
||||
@@ -58,6 +64,9 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
|
||||
|
||||
for(var/ion_law in ion_laws)
|
||||
sorted_laws += ion_law
|
||||
|
||||
for(var/evil_law in devil_laws)
|
||||
sorted_laws += evil_law
|
||||
|
||||
if(zeroth_law)
|
||||
sorted_laws += zeroth_law
|
||||
@@ -117,6 +126,21 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
|
||||
zeroth_law_borg = null
|
||||
sorted_laws.Cut()
|
||||
|
||||
/datum/ai_laws/proc/set_sixsixsix_law(var/law)
|
||||
if(!law)
|
||||
return
|
||||
|
||||
for(var/datum/ai_law/AL in devil_laws)
|
||||
if(AL.law == law)
|
||||
return
|
||||
|
||||
var/new_law = new/datum/ai_law/sixsixsix(law)
|
||||
devil_laws += new_law
|
||||
if(state_devil.len < devil_laws.len)
|
||||
state_devil += 1
|
||||
|
||||
sorted_laws.Cut()
|
||||
|
||||
/datum/ai_laws/proc/add_ion_law(var/law)
|
||||
if(!law)
|
||||
return
|
||||
@@ -185,6 +209,9 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
|
||||
|
||||
/datum/ai_law/ion/delete_law(var/datum/ai_laws/laws)
|
||||
laws.internal_delete_law(laws.ion_laws, laws.state_ion, src)
|
||||
|
||||
/datum/ai_law/sixsixsix/delete_law(var/datum/ai_laws/laws)
|
||||
laws.internal_delete_law(laws.devil_laws, laws.state_devil, src)
|
||||
|
||||
/datum/ai_law/inherent/delete_law(var/datum/ai_laws/laws)
|
||||
laws.internal_delete_law(laws.inherent_laws, laws.state_inherent, src)
|
||||
@@ -210,6 +237,10 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
|
||||
zeroth_law = null
|
||||
zeroth_law_borg = null
|
||||
|
||||
/datum/ai_laws/proc/clear_sixsixsix_laws()
|
||||
devil_laws.Cut()
|
||||
sorted_laws.Cut()
|
||||
|
||||
/datum/ai_laws/proc/clear_ion_laws()
|
||||
ion_laws.Cut()
|
||||
sorted_laws.Cut()
|
||||
|
||||
@@ -339,6 +339,7 @@ var/record_id_num = 1001
|
||||
L.fields["enzymes"] = H.dna.SE // Used in respawning
|
||||
L.fields["identity"] = H.dna.UI // "
|
||||
L.fields["image"] = getFlatIcon(H) //This is god-awful
|
||||
L.fields["reference"] = H
|
||||
locked += L
|
||||
return
|
||||
|
||||
|
||||
+2
-1
@@ -21,7 +21,8 @@ var/datum/atom_hud/huds = list( \
|
||||
ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_VAMPIRE = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),\
|
||||
DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor()\
|
||||
DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(),\
|
||||
ANTAG_HUD_DEVIL = new/datum/atom_hud/antag/hidden()\
|
||||
)
|
||||
|
||||
/datum/atom_hud
|
||||
|
||||
@@ -51,10 +51,16 @@
|
||||
var/linglink
|
||||
var/datum/vampire/vampire //vampire holder
|
||||
var/datum/nations/nation //nation holder
|
||||
var/datum/abductor/abductor //abductor holder
|
||||
var/datum/devilinfo/devilinfo //devil holder
|
||||
|
||||
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/datum/mindslaves/som //stands for slave or master...hush..
|
||||
var/datum/devilinfo/devilinfo //Information about the devil, if any.
|
||||
var/damnation_type = 0
|
||||
var/datum/mind/soulOwner //who owns the soul. Under normal circumstances, this will point to src
|
||||
var/hasSoul = TRUE
|
||||
|
||||
var/rev_cooldown = 0
|
||||
|
||||
@@ -74,6 +80,7 @@
|
||||
|
||||
/datum/mind/New(new_key)
|
||||
key = new_key
|
||||
soulOwner = src
|
||||
|
||||
/datum/mind/Destroy()
|
||||
ticker.minds -= src
|
||||
@@ -291,6 +298,22 @@
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_ABDUCTOR)
|
||||
|
||||
/datum/mind/proc/memory_edit_devil(mob/living/H)
|
||||
. = _memory_edit_header("devil", list("devilagents"))
|
||||
if(src in ticker.mode.devils)
|
||||
if(!devilinfo)
|
||||
. += "<b>No devilinfo found! Yell at a coder!</b>"
|
||||
else if(!devilinfo.ascendable)
|
||||
. += "<b>DEVIL</b>|<a href='?src=[UID()];devil=ascendable_devil'>Ascendable Devil</a>|sintouched|<a href='?src=[UID()];devil=clear'>no</a>"
|
||||
else
|
||||
. += "<a href='?src=[UID()];devil=devil'>DEVIL</a>|<b>ASCENDABLE DEVIL</b>|sintouched|<a href='?src=[UID()];devil=clear'>no</a>"
|
||||
else if(src in ticker.mode.sintouched)
|
||||
. += "devil|Ascendable Devil|<b>SINTOUCHED</b>|<a href='?src=[UID()];devil=clear'>no</a>"
|
||||
else
|
||||
. += "<a href='?src=[UID()];devil=devil'>devil</a>|<a href='?src=[UID()];devil=ascendable_devil'>Ascendable Devil</a>|<a href='?src=[UID()];devil=sintouched'>sintouched</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_DEVIL)
|
||||
|
||||
/datum/mind/proc/memory_edit_traitor()
|
||||
. = _memory_edit_header("traitor", list("traitorchan", "traitorvamp"))
|
||||
if(src in ticker.mode.traitors)
|
||||
@@ -374,6 +397,10 @@
|
||||
sections["shadowling"] = memory_edit_shadowling(H)
|
||||
/** Abductors **/
|
||||
sections["abductor"] = memory_edit_abductor(H)
|
||||
/** DEVIL ***/
|
||||
var/static/list/devils_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/carbon/true_devil, /mob/living/silicon/robot))
|
||||
if(is_type_in_typecache(current, devils_typecache))
|
||||
sections["devil"] = memory_edit_devil(H)
|
||||
/** TRAITOR ***/
|
||||
sections["traitor"] = memory_edit_traitor()
|
||||
/** SILICON ***/
|
||||
@@ -1003,6 +1030,77 @@
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>No valid nuke found!</span>")
|
||||
|
||||
else if(href_list["devil"])
|
||||
switch(href_list["devil"])
|
||||
if("clear")
|
||||
if(src in ticker.mode.devils)
|
||||
if(istype(current,/mob/living/carbon/true_devil/))
|
||||
to_chat(usr,"<span class='warning'>This cannot be used on true or arch-devils.</span>")
|
||||
else
|
||||
ticker.mode.devils -= src
|
||||
ticker.mode.update_devil_icons_removed(src)
|
||||
special_role = null
|
||||
to_chat(current,"<span class='userdanger'>Your infernal link has been severed! You are no longer a devil!</span>")
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/infernal_jaunt)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/fireball/hellish)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_contract)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/greater)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/ascended)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/violin)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_dancefloor)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/sintouch)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/sintouch/ascended)
|
||||
message_admins("[key_name_admin(usr)] has de-devil'ed [current].")
|
||||
if(issilicon(current))
|
||||
var/mob/living/silicon/S = current
|
||||
S.laws.clear_sixsixsix_laws()
|
||||
devilinfo = null
|
||||
log_admin("[key_name(usr)] has de-devil'ed [current].")
|
||||
else if(src in ticker.mode.sintouched)
|
||||
ticker.mode.sintouched -= src
|
||||
message_admins("[key_name_admin(usr)] has de-sintouch'ed [current].")
|
||||
log_admin("[key_name(usr)] has de-sintouch'ed [current].")
|
||||
if("devil")
|
||||
if(devilinfo)
|
||||
devilinfo.ascendable = FALSE
|
||||
message_admins("[key_name_admin(usr)] has made [current] unable to ascend as a devil.")
|
||||
log_admin("[key_name_admin(usr)] has made [current] unable to ascend as a devil.")
|
||||
return
|
||||
if(!ishuman(current) && !isrobot(current))
|
||||
to_chat(usr, "<span class='warning'>This only works on humans and cyborgs!</span>")
|
||||
return
|
||||
ticker.mode.devils += src
|
||||
special_role = "devil"
|
||||
ticker.mode.update_devil_icons_added(src)
|
||||
ticker.mode.finalize_devil(src, FALSE)
|
||||
ticker.mode.forge_devil_objectives(src, 2)
|
||||
ticker.mode.greet_devil(src)
|
||||
message_admins("[key_name_admin(usr)] has devil'ed [current].")
|
||||
log_admin("[key_name(usr)] has devil'ed [current].")
|
||||
if("ascendable_devil")
|
||||
if(devilinfo)
|
||||
devilinfo.ascendable = TRUE
|
||||
message_admins("[key_name_admin(usr)] has made [current] able to ascend as a devil.")
|
||||
log_admin("[key_name_admin(usr)] has made [current] able to ascend as a devil.")
|
||||
return
|
||||
if(!ishuman(current) && !isrobot(current))
|
||||
to_chat(usr, "<span class='warning'>This only works on humans and cyborgs!</span>")
|
||||
return
|
||||
ticker.mode.devils += src
|
||||
special_role = "devil"
|
||||
ticker.mode.update_devil_icons_added(src)
|
||||
ticker.mode.finalize_devil(src, TRUE)
|
||||
ticker.mode.forge_devil_objectives(src, 2)
|
||||
ticker.mode.greet_devil(src)
|
||||
message_admins("[key_name_admin(usr)] has devil'ed [current]. The devil has been marked as ascendable.")
|
||||
log_admin("[key_name(usr)] has devil'ed [current]. The devil has been marked as ascendable.")
|
||||
if("sintouched")
|
||||
var/mob/living/carbon/human/H = current
|
||||
H.influenceSin()
|
||||
message_admins("[key_name_admin(usr)] has sintouch'ed [current].")
|
||||
log_admin("[key_name(usr)] has sintouch'ed [current].")
|
||||
|
||||
else if(href_list["traitor"])
|
||||
switch(href_list["traitor"])
|
||||
if("clear")
|
||||
@@ -1455,6 +1553,17 @@
|
||||
var/obj/effect/proc_holder/spell/S = X
|
||||
S.action.Grant(new_character)
|
||||
|
||||
/datum/mind/proc/disrupt_spells(delay, list/exceptions = New())
|
||||
for(var/X in spell_list)
|
||||
var/obj/effect/proc_holder/spell/S = X
|
||||
for(var/type in exceptions)
|
||||
if(istype(S, type))
|
||||
continue
|
||||
S.charge_counter = delay
|
||||
spawn(0)
|
||||
S.start_recharge()
|
||||
S.updateButtonIcon()
|
||||
|
||||
/datum/mind/proc/get_ghost(even_if_they_cant_reenter)
|
||||
for(var/mob/dead/observer/G in GLOB.dead_mob_list)
|
||||
if(G.mind == src)
|
||||
@@ -1533,6 +1642,18 @@
|
||||
to_chat(current, "<span class='warning'>You seem to have forgotten the events of the past 10 minutes or so, and your head aches a bit as if someone beat it savagely with a stick.</span>")
|
||||
to_chat(current, "<span class='warning'>This means you don't remember who you were working for or what you were doing.</span>")
|
||||
|
||||
/datum/mind/proc/is_revivable() //Note, this ONLY checks the mind.
|
||||
if(damnation_type)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// returns a mob to message to produce something visible for the target mind
|
||||
/datum/mind/proc/messageable_mob()
|
||||
if(!QDELETED(current) && current.client)
|
||||
return current
|
||||
else
|
||||
return get_ghost(even_if_they_cant_reenter = TRUE)
|
||||
|
||||
//Initialisation procs
|
||||
/mob/proc/mind_initialize()
|
||||
if(mind)
|
||||
|
||||
@@ -708,7 +708,8 @@
|
||||
id = /obj/item/card/id/supply
|
||||
pda = /obj/item/pda
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/survival = 1
|
||||
/obj/item/storage/box/survival = 1,
|
||||
/obj/item/hand_labeler = 1
|
||||
)
|
||||
|
||||
/datum/outfit/admin/sol_trader/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
if(soulsharer)
|
||||
soulsharer.dust(FALSE)
|
||||
|
||||
/datum/soullink/oneway/devilfriend
|
||||
|
||||
/////////////////
|
||||
// SHARED BODY //
|
||||
|
||||
@@ -294,6 +294,10 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/updateButtonIcon()
|
||||
if(action)
|
||||
action.UpdateButtonIcon()
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/adjust_var(mob/living/target = usr, type, amount) //handles the adjustment of the var when the spell is used. has some hardcoded types
|
||||
switch(type)
|
||||
if("bruteloss")
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item
|
||||
name = "Summon weapon"
|
||||
desc = "A generic spell that should not exist. This summons an instance of a specific type of item, or if one already exists, un-summons it."
|
||||
invocation_type = "none"
|
||||
include_user = 1
|
||||
range = -1
|
||||
clothes_req = FALSE
|
||||
var/obj/item/item
|
||||
var/item_type = /obj/item/banhammer
|
||||
school = "conjuration"
|
||||
charge_max = 150
|
||||
cooldown_min = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/cast(list/targets, mob/user = usr)
|
||||
if(item)
|
||||
QDEL_NULL(item)
|
||||
else
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
if(C.drop_item())
|
||||
item = new item_type
|
||||
C.put_in_hands(item)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/Destroy()
|
||||
QDEL_NULL(item)
|
||||
return ..()
|
||||
@@ -0,0 +1,249 @@
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork
|
||||
name = "Summon Pitchfork"
|
||||
desc = "A devil's weapon of choice. Use this to summon/unsummon your pitchfork."
|
||||
item_type = /obj/item/twohanded/pitchfork/demonic
|
||||
action_icon_state = "pitchfork"
|
||||
action_background_icon_state = "bg_demon"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/greater
|
||||
item_type = /obj/item/twohanded/pitchfork/demonic/greater
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/ascended
|
||||
item_type = /obj/item/twohanded/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 = "whisper"
|
||||
invocation = "I ain't have this much fun since Georgia."
|
||||
action_icon_state = "golden_violin"
|
||||
name = "Summon golden violin"
|
||||
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 = "whisper"
|
||||
invocation = "Just sign on the dotted line."
|
||||
include_user = 0
|
||||
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.drop_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
|
||||
var/contractTypeName = input(user, "What type of contract?") in list (CONTRACT_POWER, CONTRACT_WEALTH, CONTRACT_PRESTIGE, CONTRACT_MAGIC, CONTRACT_KNOWLEDGE)
|
||||
switch(contractTypeName)
|
||||
if(CONTRACT_POWER)
|
||||
contract = new /obj/item/paper/contract/infernal/power(C.loc, C.mind, user.mind)
|
||||
if(CONTRACT_WEALTH)
|
||||
contract = new /obj/item/paper/contract/infernal/wealth(C.loc, C.mind, user.mind)
|
||||
if(CONTRACT_PRESTIGE)
|
||||
contract = new /obj/item/paper/contract/infernal/prestige(C.loc, C.mind, user.mind)
|
||||
if(CONTRACT_MAGIC)
|
||||
contract = new /obj/item/paper/contract/infernal/magic(C.loc, C.mind, user.mind)
|
||||
if(CONTRACT_KNOWLEDGE)
|
||||
contract = new /obj/item/paper/contract/infernal/knowledge(C.loc, C.mind, user.mind)
|
||||
C.put_in_hands(contract)
|
||||
else
|
||||
to_chat(user,"<span class='notice'>[C] seems to not be sentient. You are unable to summon a contract for them.</span>")
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/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 = "shout"
|
||||
fireball_type = /obj/item/projectile/magic/fireball/infernal
|
||||
action_background_icon_state = "bg_demon"
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/hellish/cast(list/targets, mob/living/user = usr)
|
||||
msg_admin_attack("[key_name_admin(usr)] has fired a fireball.", ATKLOG_FEW)
|
||||
.=..()
|
||||
|
||||
|
||||
/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"
|
||||
|
||||
/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/slaughter))
|
||||
var/continuing = 0
|
||||
if(istype(get_area(user), /area/shuttle)) // Can always phase in in a shuttle.
|
||||
continuing = TRUE
|
||||
else
|
||||
for(var/mob/living/C in orange(2, get_turf(user.loc))) //Can also phase in when nearby a potential buyer.
|
||||
if (C.mind && C.mind.soulOwner == C.mind)
|
||||
continuing = TRUE
|
||||
break
|
||||
if(continuing)
|
||||
to_chat(user,"<span class='warning'>You are now phasing in.</span>")
|
||||
if(do_mob(user,user,150))
|
||||
user.infernalphasein()
|
||||
else
|
||||
to_chat(user,"<span class='warning'>You can only re-appear near a potential signer or on a shuttle.</span>")
|
||||
revert_cast()
|
||||
return ..()
|
||||
else
|
||||
user.notransform = TRUE
|
||||
user.fakefire()
|
||||
to_chat(user,"<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.ExtinguishMob()
|
||||
start_recharge()
|
||||
return
|
||||
revert_cast()
|
||||
|
||||
|
||||
/mob/living/proc/infernalphaseout()
|
||||
dust_animation()
|
||||
visible_message("<span class='warning'>[src] disappears in a flashfire!</span>")
|
||||
playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, 1, -1)
|
||||
var/obj/effect/dummy/slaughter/s_holder = new(loc)
|
||||
ExtinguishMob()
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob(src,force=1)
|
||||
if(has_buckled_mobs())
|
||||
unbuckle_mob()
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
if(pulling)
|
||||
stop_pulling()
|
||||
forceMove(s_holder)
|
||||
holder = s_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 0
|
||||
fakefire()
|
||||
forceMove(get_turf(src))
|
||||
reset_perspective()
|
||||
visible_message("<span class='warning'><B>[src] appears in a firey blaze!</B></span>")
|
||||
playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1)
|
||||
spawn(15)
|
||||
fakefireextinguish(TRUE)
|
||||
|
||||
/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_state = "sintouch"
|
||||
action_background_icon_state = "bg_demon"
|
||||
random_target = TRUE
|
||||
random_target_priority = TARGET_RANDOM
|
||||
max_targets = 3
|
||||
invocation = "TASTE SIN AND INDULGE!!"
|
||||
invocation_type = "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
|
||||
for(var/datum/objective/sintouched/A in H.mind.objectives)
|
||||
continue
|
||||
H.influenceSin()
|
||||
H.Weaken(2)
|
||||
H.Stun(2)
|
||||
|
||||
/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_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])
|
||||
else
|
||||
var/list/funky_turfs = RANGE_TURFS(1, user)
|
||||
for(var/turf/T in funky_turfs)
|
||||
if(T.density)
|
||||
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/simulated/floor/light/colour_cycle/dancefloor_a : /turf/simulated/floor/light/colour_cycle/dancefloor_b)
|
||||
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
|
||||
*/
|
||||
@@ -0,0 +1,73 @@
|
||||
/obj/effect/proc_holder/spell/targeted/summon_wealth
|
||||
name = "Summon wealth"
|
||||
desc = "The reward for selling your soul."
|
||||
invocation_type = "none"
|
||||
include_user = 1
|
||||
range = -1
|
||||
clothes_req = 0
|
||||
school = "conjuration"
|
||||
charge_max = 100
|
||||
cooldown_min = 10
|
||||
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.drop_item())
|
||||
var/obj/item = pick(
|
||||
new /obj/item/coin/gold(user.loc),
|
||||
new /obj/item/coin/diamond(user.loc),
|
||||
new /obj/item/coin/silver(user.loc),
|
||||
new /obj/item/stack/sheet/mineral/gold(user.loc),
|
||||
new /obj/item/stack/sheet/mineral/silver(user.loc),
|
||||
new /obj/item/stack/sheet/mineral/diamond(user.loc),
|
||||
new /obj/item/stack/spacecash/c1000(user.loc))
|
||||
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 = 1
|
||||
range = -1
|
||||
clothes_req = 0
|
||||
charge_max = 50
|
||||
cooldown_min = 10
|
||||
action_icon_state = "camera_jump"
|
||||
var/ranges = list(7,8,9,10/*,11,12*/)
|
||||
|
||||
/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 = input("Select view range:", "Range", 4) in ranges
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/summon_friend
|
||||
name = "Summon Friend"
|
||||
desc = "The reward for selling your soul."
|
||||
invocation_type = "none"
|
||||
include_user = 1
|
||||
range = -1
|
||||
clothes_req = 0
|
||||
charge_max = 50
|
||||
cooldown_min = 10
|
||||
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>")
|
||||
to_chat(user, "<span class='notice'>You banish your friend back to whence [friend.p_they()] came.</span>")
|
||||
friend.dust()
|
||||
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
|
||||
@@ -12,7 +12,7 @@
|
||||
var/proj_trail_icon = 'icons/obj/wizard.dmi'
|
||||
var/proj_trail_icon_state = "trail"
|
||||
|
||||
var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this
|
||||
var/proj_type = /obj/effect/proc_holder/spell //IMPORTANT use only subtypes of this
|
||||
|
||||
var/proj_insubstantial = 0 //if it can pass through dense objects or not
|
||||
var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target)
|
||||
@@ -35,12 +35,7 @@
|
||||
for(var/turf/target in targets)
|
||||
spawn(0)
|
||||
var/obj/effect/proc_holder/spell/targeted/projectile
|
||||
if(istext(proj_type))
|
||||
var/projectile_type = text2path(proj_type)
|
||||
projectile = new projectile_type(user)
|
||||
if(istype(proj_type,/obj/effect/proc_holder/spell))
|
||||
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
|
||||
projectile:linked_spells += proj_type
|
||||
projectile = new proj_type(user)
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.dir = get_dir(projectile, target)
|
||||
|
||||
@@ -443,4 +443,4 @@
|
||||
L.adjust_fire_stacks(20)
|
||||
if(isliving(user))
|
||||
var/mob/living/U = user
|
||||
U.IgniteMob()
|
||||
U.IgniteMob()
|
||||
|
||||
@@ -1314,7 +1314,9 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
|
||||
/obj/item/storage/bible/booze,
|
||||
/obj/item/storage/bible/booze,
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie,
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie)
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie,
|
||||
/obj/item/clothing/under/burial,
|
||||
/obj/item/clothing/under/burial)
|
||||
cost = 40
|
||||
containername = "religious supplies crate"
|
||||
|
||||
@@ -1341,6 +1343,19 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
|
||||
cost = 15
|
||||
containername = "bureaucracy crate"
|
||||
|
||||
/datum/supply_packs/misc/book_crate
|
||||
name = "Research Crate"
|
||||
contains = list(/obj/item/book/codex_gigas)
|
||||
cost = 15
|
||||
containername = "book crate"
|
||||
|
||||
/datum/supply_packs/misc/book_crate/New()
|
||||
contains += pick(subtypesof(/obj/item/book/manual))
|
||||
contains += pick(subtypesof(/obj/item/book/manual))
|
||||
contains += pick(subtypesof(/obj/item/book/manual))
|
||||
contains += pick(subtypesof(/obj/item/book/manual))
|
||||
..()
|
||||
|
||||
/datum/supply_packs/misc/tape
|
||||
name = "Sticky Tape Crate"
|
||||
contains = list(/obj/item/stack/tape_roll,
|
||||
|
||||
@@ -202,7 +202,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
//Chef
|
||||
/datum/uplink_item/jobspecific/specialsauce
|
||||
name = "Chef Excellence's Special Sauce"
|
||||
desc = "A custom made sauce made from the toxin glands of 1000 space carp, if somebody ingests enough they'll be dead in 3 minutes or less guaranteed."
|
||||
desc = "A custom sauce made from the highly poisonous fly amanita mushrooms. Anyone who ingests it will take variable toxin damage depending on how long it has been in their system, with a higher dosage taking longer to metabolize."
|
||||
reference = "CESS"
|
||||
item = /obj/item/reagent_containers/food/condiment/syndisauce
|
||||
cost = 2
|
||||
@@ -552,7 +552,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/dangerous/syndieborg
|
||||
name = "Syndicate Cyborg"
|
||||
desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel."
|
||||
desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. Comes in Assault, Medical, or Saboteur variants."
|
||||
reference = "SC"
|
||||
item = /obj/item/antag_spawner/borg_tele
|
||||
refund_path = /obj/item/antag_spawner/borg_tele
|
||||
|
||||
@@ -33,15 +33,13 @@
|
||||
. = ..()
|
||||
areaMaster = get_area(src)
|
||||
|
||||
/atom/movable/attempt_init()
|
||||
/atom/movable/attempt_init(loc, ...)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && SSatoms.initialized != INITIALIZATION_INSSATOMS && space_manager.is_zlevel_dirty(T.z))
|
||||
space_manager.postpone_init(T.z, src)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
|
||||
|
||||
/atom/movable/Destroy()
|
||||
if(loc)
|
||||
loc.handle_atom_del(src)
|
||||
|
||||
@@ -979,7 +979,7 @@ var/list/teleport_runes = list()
|
||||
..()
|
||||
cultist_desc = "manifests a spirit as a servant of [ticker.cultdat.entity_title3]. The invoker must not move from atop the rune, and will take damage for each summoned spirit."
|
||||
|
||||
notify_ghosts("Manifest rune created in [get_area(src)].", 'sound/effects/ghost2.ogg', source = src)
|
||||
notify_ghosts("Manifest rune created in [get_area(src)].", ghost_sound='sound/effects/ghost2.ogg', source = src)
|
||||
|
||||
/obj/effect/rune/manifest/can_invoke(mob/living/user)
|
||||
if(ghosts >= ghost_limit)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/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 = "<span class='big bold'>You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil.</span><b> Be aware that if you do not live up to [owner.name]'s expectations, [owner.p_they()] can send you back to hell with a single thought. [owner.name]'s death will also return you to hell.</b>"
|
||||
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.real_name = "[owner.name]'s best friend"
|
||||
L.name = L.real_name
|
||||
soullink(/datum/soullink/oneway/devilfriend, 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()
|
||||
to_chat(owner.current, "<span class='notice'>Your friend has arrived!</span>")
|
||||
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/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
|
||||
@@ -0,0 +1,38 @@
|
||||
/datum/game_mode/devil/devil_agents
|
||||
name = "Devil Agents"
|
||||
config_tag = "devilagents"
|
||||
required_players = 25
|
||||
required_enemies = 3
|
||||
recommended_enemies = 8
|
||||
|
||||
traitors_possible = 10 //hard limit on traitors if scaling is turned off
|
||||
num_modifier = 4
|
||||
objective_count = 2
|
||||
|
||||
var/list/target_list = list()
|
||||
var/list/late_joining_list = list()
|
||||
minimum_devils = 3
|
||||
|
||||
/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
|
||||
target_list[devil] = devils[i + 1]
|
||||
..()
|
||||
|
||||
/datum/game_mode/devil/devil_agents/forge_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(target_list.len && target_list[devil]) // Is a double agent
|
||||
var/datum/mind/target_mind = target_list[devil]
|
||||
var/datum/objective/devil/outsell/outsellobjective = new
|
||||
outsellobjective.owner = devil
|
||||
outsellobjective.target = target_mind
|
||||
outsellobjective.update_explanation_text()
|
||||
devil.objectives += outsellobjective
|
||||
return 1
|
||||
return 0
|
||||
@@ -0,0 +1,48 @@
|
||||
var/global/list/whiteness = list (
|
||||
/obj/item/clothing/under/color/white = 2,
|
||||
/obj/item/clothing/under/rank/bartender = 1,
|
||||
/obj/item/clothing/under/rank/chef = 1,
|
||||
/obj/item/clothing/under/rank/chief_engineer = 1,
|
||||
/obj/item/clothing/under/rank/scientist = 1,
|
||||
/obj/item/clothing/under/rank/chemist = 1,
|
||||
/obj/item/clothing/under/rank/chief_medical_officer = 1,
|
||||
/obj/item/clothing/under/rank/geneticist = 1,
|
||||
/obj/item/clothing/under/rank/virologist = 1,
|
||||
/obj/item/clothing/under/rank/nursesuit = 1,
|
||||
/obj/item/clothing/under/rank/medical = 1,
|
||||
/obj/item/clothing/under/rank/psych = 1,
|
||||
/obj/item/clothing/under/rank/orderly = 1,
|
||||
/obj/item/clothing/under/rank/security/brigphys = 1,
|
||||
/obj/item/clothing/under/rank/internalaffairs = 1,
|
||||
/obj/item/clothing/under/rank/ntrep = 1,
|
||||
/obj/item/clothing/under/det = 1,
|
||||
/obj/item/clothing/under/wedding/bride_white = 1,
|
||||
/obj/item/clothing/under/mafia/white = 1,
|
||||
/obj/item/clothing/under/noble_clothes = 1,
|
||||
/obj/item/clothing/under/sl_suit = 1,
|
||||
/obj/item/clothing/under/burial = 1
|
||||
)
|
||||
|
||||
|
||||
|
||||
/mob/living/proc/check_devil_bane_multiplier(obj/item/weapon, mob/living/attacker)
|
||||
switch(mind.devilinfo.bane)
|
||||
if(BANE_WHITECLOTHES)
|
||||
if(istype(attacker, /mob/living/carbon/human))
|
||||
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
|
||||
if(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.
|
||||
if(BANE_HARVEST)
|
||||
if(istype(weapon,/obj/item/reagent_containers/food/snacks/grown/) || istype(weapon,/obj/item/grown))
|
||||
src.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>")
|
||||
src.Weaken(2)
|
||||
qdel(weapon)
|
||||
return 2
|
||||
return 1
|
||||
@@ -0,0 +1,67 @@
|
||||
/datum/game_mode/devil
|
||||
name = "devil"
|
||||
config_tag = "devil"
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate",
|
||||
"Internal Affairs Agent", "Librarian", "Chaplain", "Head of Security", "Captain", "Brig Physician",
|
||||
"Nanotrasen Navy Officer", "Special Operations Officer", "AI", "Cyborg")
|
||||
required_players = 2
|
||||
required_enemies = 1
|
||||
recommended_enemies = 4
|
||||
|
||||
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
|
||||
var/devil_scale_coefficient = 10
|
||||
|
||||
/datum/game_mode/devil/announce()
|
||||
to_chat(world, {"<B>The current game mode is - Devil!</B><br>)
|
||||
<span class='danger'>Devils</span>: Purchase souls and tempt the crew to sin!<br>
|
||||
<span class='notice'>Crew</span>: Resist the lure of sin and remain pure!"})
|
||||
|
||||
/datum/game_mode/devil/pre_setup()
|
||||
|
||||
if(config.protect_roles_from_antagonist)
|
||||
restricted_jobs += protected_jobs
|
||||
|
||||
var/list/possible_devils = get_players_for_role(ROLE_DEVIL)
|
||||
var/num_devils = 0
|
||||
if(!possible_devils.len)
|
||||
return 0
|
||||
if(config.traitor_scaling)
|
||||
num_devils = max(1, round((num_players())/(devil_scale_coefficient))+1)
|
||||
else
|
||||
num_devils = max(1, min(num_players(), traitors_possible))
|
||||
|
||||
|
||||
for(var/j = 0, j < num_devils, j++)
|
||||
if (!possible_devils.len)
|
||||
break
|
||||
var/datum/mind/devil = pick(possible_devils)
|
||||
devils += devil
|
||||
devil.special_role = ROLE_DEVIL
|
||||
devil.restricted_roles = restricted_jobs
|
||||
|
||||
log_game("[devil.key] (ckey) has been selected as a [config_tag]")
|
||||
possible_devils.Remove(devil)
|
||||
|
||||
if(devils.len < required_enemies)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/devil/post_setup()
|
||||
for(var/datum/mind/devil in devils)
|
||||
spawn(rand(10, 100))
|
||||
finalize_devil(devil, TRUE)
|
||||
spawn(100)
|
||||
forge_devil_objectives(devil, objective_count) //This has to be in a separate loop, as we need devil names to be generated before we give objectives in devil agent.
|
||||
devil.devilinfo.announce_laws(devil.current)
|
||||
var/obj_count = 1
|
||||
to_chat(devil.current, "<span class='notice'> Your current objectives:</span>")
|
||||
for(var/datum/objective/objective in devil.objectives)
|
||||
to_chat(devil.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
|
||||
obj_count++
|
||||
modePlayer += devils
|
||||
..()
|
||||
return 1
|
||||
@@ -0,0 +1,559 @@
|
||||
#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
|
||||
|
||||
var/global/list/allDevils = list()
|
||||
var/global/list/lawlorify = list (
|
||||
LORE = list(
|
||||
OBLIGATION_FOOD = "This devil seems to always offer it's 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 anointed 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_STRIKEUNCONCIOUS = "This devil only shows interest in those who are awake.",
|
||||
BAN_HURTLIZARD = "This devil will not strike an Unathi first.",
|
||||
BAN_HURTANIMAL = "This devil avoids hurting animals.",
|
||||
BANISH_WATER = "To banish the devil, you must infuse it's body with holy water.",
|
||||
BANISH_COFFIN = "This devil will return to life if it's remains are not placed within a coffin.",
|
||||
BANISH_FORMALDYHIDE = "To banish the devil, you must inject it's lifeless body with embalming fluid.",
|
||||
BANISH_RUNES = "This devil will resurrect after death, unless it's remains are within a rune.",
|
||||
BANISH_CANDLES = "A large number of nearby lit candles will prevent it from resurrecting.",
|
||||
BANISH_DESTRUCTION = "It's 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_STRIKEUNCONCIOUS = "You must never strike an unconscious person.",
|
||||
BAN_HURTLIZARD = "You must never harm an Unathi 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 it's 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."
|
||||
)
|
||||
)
|
||||
|
||||
/datum/devilinfo
|
||||
var/datum/mind/owner = null
|
||||
var/obligation
|
||||
var/ban
|
||||
var/bane
|
||||
var/banish
|
||||
var/truename
|
||||
var/list/datum/mind/soulsOwned = new
|
||||
var/datum/dna/humanform = null
|
||||
var/reviveNumber = 0
|
||||
var/form = BASIC_DEVIL
|
||||
var/exists = 0
|
||||
var/static/list/dont_remove_spells = list(
|
||||
/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/devilinfo/New()
|
||||
..()
|
||||
dont_remove_spells = typecacheof(dont_remove_spells)
|
||||
|
||||
/proc/randomDevilInfo(name = randomDevilName())
|
||||
var/datum/devilinfo/devil = new
|
||||
devil.truename = name
|
||||
devil.bane = randomdevilbane()
|
||||
devil.obligation = randomdevilobligation()
|
||||
devil.ban = randomdevilban()
|
||||
devil.banish = randomdevilbanish()
|
||||
return devil
|
||||
|
||||
/proc/devilInfo(name, saveDetails = 0)
|
||||
if(allDevils[lowertext(name)])
|
||||
return allDevils[lowertext(name)]
|
||||
else
|
||||
var/datum/devilinfo/devil = randomDevilInfo(name)
|
||||
allDevils[lowertext(name)] = devil
|
||||
devil.exists = saveDetails
|
||||
return devil
|
||||
|
||||
|
||||
|
||||
/proc/randomDevilName()
|
||||
var/preTitle = ""
|
||||
var/title = ""
|
||||
var/mainName = ""
|
||||
var/suffix = ""
|
||||
if(prob(65))
|
||||
if(prob(35))
|
||||
preTitle = pick("Dark ", "Hellish ", "Fiery ", "Sinful ", "Blood ")
|
||||
title = pick("Lord ", "Fallen Prelate ", "Count ", "Viscount ", "Vizier ", "Elder ", "Adept ")
|
||||
var/probability = 100
|
||||
mainName = pick("Hal", "Ve", "Odr", "Neit", "Ci", "Quon", "Mya", "Folth", "Wren", "Gyer", "Geyr", "Hil", "Niet", "Twou", "Hu", "Don")
|
||||
while(prob(probability))
|
||||
mainName += pick("hal", "ve", "odr", "neit", "ca", "quon", "mya", "folth", "wren", "gyer", "geyr", "hil", "niet", "twoe", "phi", "coa")
|
||||
probability -= 20
|
||||
if(prob(40))
|
||||
suffix = pick(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr.")
|
||||
return preTitle + title + mainName + suffix
|
||||
|
||||
/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_STRIKEUNCONCIOUS, 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/devilinfo/proc/link_with_mob(mob/living/L)
|
||||
if(istype(L, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = L
|
||||
humanform = H.dna.Clone()
|
||||
owner = L.mind
|
||||
give_base_spells(1)
|
||||
|
||||
/datum/devilinfo/proc/add_soul(datum/mind/soul)
|
||||
if(soulsOwned.Find(soul))
|
||||
return
|
||||
soulsOwned += soul
|
||||
owner.current.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_base_spells()
|
||||
if(BLOOD_THRESHOLD)
|
||||
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)
|
||||
increase_blood_lizard()
|
||||
if(TRUE_THRESHOLD)
|
||||
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)
|
||||
increase_true_devil()
|
||||
if(ARCH_THRESHOLD)
|
||||
arch_devil_prelude()
|
||||
increase_arch_devil()
|
||||
|
||||
/datum/devilinfo/proc/remove_soul(datum/mind/soul)
|
||||
if(soulsOwned.Remove(soul))
|
||||
to_chat(owner.current, "<span class='warning'>You feel as though a soul has slipped from your grasp.</span>")
|
||||
check_regression()
|
||||
update_hud()
|
||||
|
||||
/datum/devilinfo/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)
|
||||
remove_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/devilinfo/proc/regress_humanoid()
|
||||
to_chat(owner.current, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.</span>")
|
||||
if(istype(owner.current, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(humanform)
|
||||
H.set_species(humanform.species)
|
||||
H.dna = humanform.Clone()
|
||||
H.sync_organ_dna(assimilate = 0)
|
||||
else
|
||||
H.set_species(/datum/species/human)
|
||||
// TODO: Add some appearance randomization here or something
|
||||
humanform = H.dna.Clone()
|
||||
H.regenerate_icons()
|
||||
else
|
||||
owner.current.color = ""
|
||||
give_base_spells()
|
||||
if(istype(owner.current.loc, /obj/effect/dummy/slaughter))
|
||||
owner.current.forceMove(get_turf(owner.current))//Fixes dying while jaunted leaving you permajaunted.
|
||||
form = BASIC_DEVIL
|
||||
|
||||
/datum/devilinfo/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.loc = D.loc
|
||||
owner.transfer_to(D.oldform)
|
||||
D.oldform.status_flags &= ~GODMODE
|
||||
give_lizard_spells()
|
||||
qdel(D)
|
||||
form = BLOOD_LIZARD
|
||||
update_hud()
|
||||
|
||||
|
||||
/datum/devilinfo/proc/increase_blood_lizard()
|
||||
if(ishuman(owner.current))
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
var/list/language_temp = H.languages.Copy()
|
||||
H.set_species(/datum/species/unathi)
|
||||
H.languages = language_temp
|
||||
H.underwear = "Nude"
|
||||
H.undershirt = "Nude"
|
||||
H.socks = "Nude"
|
||||
H.change_skin_color(80, 16, 16) //A deep red
|
||||
H.regenerate_icons()
|
||||
else //Did the devil get hit by a staff of transmutation?
|
||||
owner.current.color = "#501010"
|
||||
give_lizard_spells()
|
||||
form = BLOOD_LIZARD
|
||||
|
||||
|
||||
|
||||
/datum/devilinfo/proc/increase_true_devil()
|
||||
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc, owner.current)
|
||||
A.faction |= "hell"
|
||||
// Put the old body in stasis
|
||||
owner.current.status_flags |= GODMODE
|
||||
owner.current.loc = A
|
||||
A.oldform = owner.current
|
||||
owner.transfer_to(A)
|
||||
A.set_name()
|
||||
give_true_spells()
|
||||
form = TRUE_DEVIL
|
||||
update_hud()
|
||||
|
||||
/datum/devilinfo/proc/arch_devil_prelude()
|
||||
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, "<span class='sinister'>Yes!</span>")
|
||||
sleep(10)
|
||||
if(!D)
|
||||
return
|
||||
to_chat(D, "<span class='big sinister'>YES!!</span>")
|
||||
sleep(10)
|
||||
if(!D)
|
||||
return
|
||||
to_chat(D, "<span class='reallybig sinister'>YE--</span>")
|
||||
sleep(1)
|
||||
if(!D)
|
||||
return
|
||||
to_chat(world, "<font size=5><span class='danger'>SLOTH, WRATH, GLUTTONY, ACEDIA, ENVY, GREED, PRIDE! FIRES OF HELL AWAKEN!!</span></font>")
|
||||
world << 'sound/hallucinations/veryfar_noise.ogg'
|
||||
sleep(50)
|
||||
if(!ticker.mode.devil_ascended)
|
||||
SSshuttle.emergency.request(null, 0.3)
|
||||
ticker.mode.devil_ascended++
|
||||
|
||||
/datum/devilinfo/proc/increase_arch_devil()
|
||||
if(!ascendable)
|
||||
return
|
||||
var/mob/living/carbon/true_devil/D = owner.current
|
||||
if(!istype(D))
|
||||
return
|
||||
give_arch_spells()
|
||||
D.convert_to_archdevil()
|
||||
if(istype(D.loc, /obj/effect/dummy/slaughter))
|
||||
D.forceMove(get_turf(D))
|
||||
var/area/A = get_area(owner.current)
|
||||
if(A)
|
||||
notify_ghosts("An arch devil has ascended in [A.name]. Reach out to the devil to start climbing the infernal corporate ladder.", title = "Arch Devil Ascended", source = owner.current, action = NOTIFY_ATTACK)
|
||||
form = ARCH_DEVIL
|
||||
|
||||
/datum/devilinfo/proc/remove_spells()
|
||||
for(var/X in owner.spell_list)
|
||||
var/obj/effect/proc_holder/spell/S = X
|
||||
if(!is_type_in_typecache(S, dont_remove_spells))
|
||||
owner.RemoveSpell(S)
|
||||
|
||||
/datum/devilinfo/proc/give_summon_contract()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_contract(null))
|
||||
|
||||
|
||||
/datum/devilinfo/proc/give_base_spells(give_summon_contract = 0)
|
||||
remove_spells()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork(null))
|
||||
if(give_summon_contract)
|
||||
give_summon_contract()
|
||||
if(obligation == OBLIGATION_FIDDLE)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/violin(null))
|
||||
if(obligation == OBLIGATION_DANCEOFF)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_dancefloor(null))
|
||||
|
||||
/datum/devilinfo/proc/give_lizard_spells()
|
||||
remove_spells()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
|
||||
|
||||
/datum/devilinfo/proc/give_true_spells()
|
||||
remove_spells()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/greater(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/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/devilinfo/proc/give_arch_spells()
|
||||
remove_spells()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/ascended(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch/ascended(null))
|
||||
|
||||
/datum/devilinfo/proc/beginResurrectionCheck(mob/living/body)
|
||||
if(owner.current != body)
|
||||
body = owner.current
|
||||
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.</span>")
|
||||
addtimer(CALLBACK(src, "activateResurrection", body), DEVILRESURRECTTIME)
|
||||
else
|
||||
to_chat(owner.messageable_mob(), "<span class='userdanger'>Your hellish powers are too weak to resurrect yourself.</span>")
|
||||
|
||||
/datum/devilinfo/proc/activateResurrection(mob/living/body)
|
||||
if(QDELETED(body) || body.stat == DEAD)
|
||||
if(SOULVALUE > 0)
|
||||
if(check_banishment(body))
|
||||
to_chat(owner.messageable_mob(), "<span class='userdanger'>Unfortunately, the mortals have finished a ritual that prevents your resurrection.</span>")
|
||||
return -1
|
||||
else
|
||||
to_chat(owner.messageable_mob(), "<span class='userdanger'>WE LIVE AGAIN!</span>")
|
||||
return hellish_resurrection(body)
|
||||
else
|
||||
to_chat(owner.messageable_mob(), "<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>")
|
||||
|
||||
/datum/devilinfo/proc/check_banishment(mob/living/body)
|
||||
switch(banish)
|
||||
if(BANISH_WATER)
|
||||
if(!QDELETED(body) && iscarbon(body))
|
||||
var/mob/living/carbon/H = body
|
||||
return H.reagents.has_reagent("holy water")
|
||||
return 0
|
||||
if(BANISH_COFFIN)
|
||||
return (!QDELETED(body) && istype(body.loc, /obj/structure/closet/coffin))
|
||||
if(BANISH_FORMALDYHIDE)
|
||||
if(!QDELETED(body) && iscarbon(body))
|
||||
var/mob/living/carbon/H = body
|
||||
return H.reagents.has_reagent("formaldehyde")
|
||||
return 0
|
||||
if(BANISH_RUNES)
|
||||
if(!QDELETED(body))
|
||||
for(var/obj/effect/decal/cleanable/crayon/R in range(0,body))
|
||||
if (R.name == "rune")
|
||||
return 1
|
||||
return 0
|
||||
if(BANISH_CANDLES)
|
||||
if(!QDELETED(body))
|
||||
var/count = 0
|
||||
for(var/obj/item/candle/C in range(1,body))
|
||||
count += C.lit
|
||||
if(count>=4)
|
||||
return 1
|
||||
return 0
|
||||
if(BANISH_DESTRUCTION)
|
||||
if(!QDELETED(body))
|
||||
return 0
|
||||
return 1
|
||||
if(BANISH_FUNERAL_GARB)
|
||||
if(!QDELETED(body) && iscarbon(body))
|
||||
var/mob/living/carbon/human/H = body
|
||||
if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under/burial))
|
||||
return 1
|
||||
return 0
|
||||
else
|
||||
for(var/obj/item/clothing/under/burial/B in range(0,body))
|
||||
if(B.loc == get_turf(B)) //Make sure it's not in someone's inventory or something.
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/devilinfo/proc/hellish_resurrection(mob/living/body)
|
||||
message_admins("[owner.name] (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(!QDELETED(body))
|
||||
body.revive()
|
||||
if(!body.client)
|
||||
var/mob/dead/observer/O = owner.get_ghost()
|
||||
O.reenter_corpse()
|
||||
if(istype(body.loc, /obj/effect/dummy/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() // Heal the old body too, so the devil doesn't resurrect, then immediately regress into a dead body.
|
||||
if(body.stat == DEAD) // Not sure why this would happen
|
||||
create_new_body()
|
||||
else if(blobstart.len > 0)
|
||||
// teleport the body so repeated beatdowns aren't an option)
|
||||
body.forceMove(get_turf(pick(blobstart)))
|
||||
// give them the devil lawyer outfit in case they got stripped
|
||||
if(ishuman(body))
|
||||
var/mob/living/carbon/human/H = body
|
||||
H.equipOutfit(/datum/outfit/devil_lawyer)
|
||||
else
|
||||
create_new_body()
|
||||
check_regression()
|
||||
|
||||
/datum/devilinfo/proc/create_new_body()
|
||||
if(blobstart.len > 0)
|
||||
var/turf/targetturf = get_turf(pick(blobstart))
|
||||
var/mob/currentMob = owner.current
|
||||
if(QDELETED(currentMob))
|
||||
currentMob = owner.get_ghost()
|
||||
if(!currentMob)
|
||||
message_admins("[owner.name]'s devil resurrection failed due to client logoff. Aborting.")
|
||||
return -1
|
||||
if(currentMob.mind != owner)
|
||||
message_admins("[owner.name]'s devil resurrection failed due to becoming a new mob. Aborting.")
|
||||
return -1
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(targetturf)
|
||||
owner.transfer_to(H)
|
||||
if(isobserver(currentMob))
|
||||
var/mob/dead/observer/O = currentMob
|
||||
O.reenter_corpse()
|
||||
if(humanform)
|
||||
H.set_species(humanform.species)
|
||||
H.dna = humanform.Clone()
|
||||
|
||||
H.dna.UpdateSE()
|
||||
H.dna.UpdateUI()
|
||||
|
||||
H.sync_organ_dna(1) // It's literally a fresh body as you can get, so all organs properly belong to it
|
||||
H.UpdateAppearance()
|
||||
else
|
||||
// gibbed cyborg or similar - create a randomized "humanform" appearance
|
||||
H.scramble_appearance()
|
||||
humanform = H.dna.Clone()
|
||||
|
||||
|
||||
H.equipOutfit(/datum/outfit/devil_lawyer)
|
||||
give_base_spells(TRUE)
|
||||
if(SOULVALUE >= BLOOD_THRESHOLD)
|
||||
increase_blood_lizard()
|
||||
if(SOULVALUE >= TRUE_THRESHOLD) //Yes, BOTH this and the above if statement are to run if soulpower is high enough.
|
||||
increase_true_devil()
|
||||
if(SOULVALUE >= ARCH_THRESHOLD && ascendable)
|
||||
increase_arch_devil()
|
||||
else
|
||||
throw EXCEPTION("Unable to find a blobstart landmark for hellish resurrection")
|
||||
|
||||
/datum/devilinfo/proc/update_hud()
|
||||
if(istype(owner.current, /mob/living/carbon))
|
||||
var/mob/living/C = owner.current
|
||||
if(C.hud_used && C.hud_used.devilsouldisplay)
|
||||
C.hud_used.devilsouldisplay.update_counter(SOULVALUE)
|
||||
|
||||
// SECTION: Messages and explanations
|
||||
|
||||
/datum/devilinfo/proc/announce_laws(mob/living/owner)
|
||||
to_chat(owner, "<span class='boldwarning'>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.</span>")
|
||||
to_chat(owner, "<span class='boldwarning'>However, your infernal form is not without weaknesses.</span>")
|
||||
to_chat(owner, "You may not use violence to coerce someone into selling their soul.")
|
||||
to_chat(owner, "You may not directly and knowingly physically harm a devil, other than yourself.")
|
||||
to_chat(owner,lawlorify[LAW][bane])
|
||||
to_chat(owner,lawlorify[LAW][ban])
|
||||
to_chat(owner,lawlorify[LAW][obligation])
|
||||
to_chat(owner,lawlorify[LAW][banish])
|
||||
to_chat(owner, "<br/><br/><span class='warning'>Remember, the crew can research your weaknesses if they find out your devil name.</span><br>")
|
||||
|
||||
|
||||
#undef BLOOD_THRESHOLD
|
||||
#undef TRUE_THRESHOLD
|
||||
#undef ARCH_THRESHOLD
|
||||
#undef BASIC_DEVIL
|
||||
#undef BLOOD_LIZARD
|
||||
#undef TRUE_DEVIL
|
||||
#undef ARCH_DEVIL
|
||||
#undef LOSS_PER_DEATH
|
||||
#undef SOULVALUE
|
||||
#undef DEVILRESURRECTTIME
|
||||
|
||||
/datum/outfit/devil_lawyer
|
||||
name = "Devil Lawyer"
|
||||
uniform = /obj/item/clothing/under/lawyer/black
|
||||
shoes = /obj/item/clothing/shoes/laceup
|
||||
back = /obj/item/storage/backpack
|
||||
l_hand = /obj/item/storage/briefcase
|
||||
l_pocket = /obj/item/pen
|
||||
l_ear = /obj/item/radio/headset
|
||||
|
||||
id = /obj/item/card/id
|
||||
|
||||
/datum/outfit/devil_lawyer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
if(!istype(W) || W.assignment) // either doesn't have a card, or the card is already written to
|
||||
return
|
||||
var/name_to_use = H.real_name
|
||||
if(H.mind && H.mind.devilinfo)
|
||||
// Having hell create an ID for you causes its risks
|
||||
name_to_use = H.mind.devilinfo.truename
|
||||
|
||||
W.name = "[name_to_use]'s ID Card (Lawyer)"
|
||||
W.registered_name = name_to_use
|
||||
W.assignment = "Lawyer"
|
||||
W.rank = W.assignment
|
||||
W.age = H.age
|
||||
W.sex = capitalize(H.gender)
|
||||
W.access = list(access_maint_tunnels, access_syndicate, access_external_airlocks)
|
||||
W.photo = get_id_photo(H)
|
||||
@@ -0,0 +1,91 @@
|
||||
/datum/game_mode
|
||||
var/list/datum/mind/sintouched = list()
|
||||
var/list/datum/mind/devils = list()
|
||||
var/devil_ascended = 0 // Number of arch devils on station
|
||||
|
||||
/datum/game_mode/proc/auto_declare_completion_sintouched()
|
||||
var/text = ""
|
||||
if(sintouched.len)
|
||||
text += "<br><span class='big'><b>The sintouched were:</b></span>"
|
||||
var/list/sintouchedUnique = uniqueList(sintouched)
|
||||
for(var/S in sintouchedUnique)
|
||||
var/datum/mind/sintouched_mind = S
|
||||
text += printplayer(sintouched_mind)
|
||||
text += printobjectives(sintouched_mind)
|
||||
text += "<br>"
|
||||
text += "<br>"
|
||||
to_chat(world,text)
|
||||
|
||||
/datum/game_mode/proc/auto_declare_completion_devils()
|
||||
/var/text = ""
|
||||
if(devils.len)
|
||||
text += "<br><span class='big'><b>The devils were:</b></span>"
|
||||
for(var/D in devils)
|
||||
var/datum/mind/devil = D
|
||||
text += printplayer(devil)
|
||||
text += printdevilinfo(devil)
|
||||
text += printobjectives(devil)
|
||||
text += "<br>"
|
||||
text += "<br>"
|
||||
to_chat(world,text)
|
||||
|
||||
|
||||
/datum/game_mode/proc/finalize_devil(datum/mind/devil_mind, ascendable = FALSE)
|
||||
var/trueName= randomDevilName()
|
||||
devil_mind.devilinfo = devilInfo(trueName, 1)
|
||||
devil_mind.devilinfo.ascendable = ascendable
|
||||
devil_mind.store_memory("Your diabolical true name is [devil_mind.devilinfo.truename]<br>[lawlorify[LAW][devil_mind.devilinfo.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>[lawlorify[LAW][devil_mind.devilinfo.bane]]<br>[lawlorify[LAW][devil_mind.devilinfo.obligation]]<br>[lawlorify[LAW][devil_mind.devilinfo.banish]]<br>")
|
||||
devil_mind.devilinfo.link_with_mob(devil_mind.current)
|
||||
if(devil_mind.assigned_role == "Clown")
|
||||
to_chat(devil_mind.current, "Your infernal nature allows you to wield weapons without harming yourself.")
|
||||
devil_mind.current.mutations.Remove(CLUMSY)
|
||||
spawn(10)
|
||||
devil_mind.devilinfo.update_hud()
|
||||
if(issilicon(devil_mind.current))
|
||||
var/mob/living/silicon/S = devil_mind.current
|
||||
S.laws.set_sixsixsix_law("You may not use violence to coerce someone into selling their soul.")
|
||||
S.laws.set_sixsixsix_law("You may not directly and knowingly physically harm a devil, other than yourself.")
|
||||
S.laws.set_sixsixsix_law("[lawlorify[LAW][devil_mind.devilinfo.ban]]")
|
||||
S.laws.set_sixsixsix_law("[lawlorify[LAW][devil_mind.devilinfo.obligation]]")
|
||||
S.laws.set_sixsixsix_law("Accomplish your objectives at all costs.")
|
||||
|
||||
// unsure about the second "quantity" arg and how it fits with the antag refactor
|
||||
/datum/game_mode/proc/forge_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)
|
||||
for(var/i = 1 to quantity)
|
||||
var/type = pick(validtypes)
|
||||
var/datum/objective/devil/objective = new type(null)
|
||||
objective.owner = devil_mind
|
||||
devil_mind.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/greet_devil(datum/mind/devil_mind)
|
||||
if(!devil_mind.devilinfo)
|
||||
return
|
||||
devil_mind.devilinfo.announce_laws(devil_mind.current)
|
||||
devil_mind.announce_objectives()
|
||||
|
||||
|
||||
/datum/game_mode/proc/printdevilinfo(datum/mind/ply)
|
||||
if(!ply.devilinfo)
|
||||
return "Target is not a devil."
|
||||
var/text = "</br>The devil's true name is: [ply.devilinfo.truename]</br>"
|
||||
text += "The devil's bans were:</br>"
|
||||
text += " [lawlorify[LORE][ply.devilinfo.ban]]</br>"
|
||||
text += " [lawlorify[LORE][ply.devilinfo.bane]]</br>"
|
||||
text += " [lawlorify[LORE][ply.devilinfo.obligation]]</br>"
|
||||
text += " [lawlorify[LORE][ply.devilinfo.banish]]</br></br>"
|
||||
return text
|
||||
|
||||
/datum/game_mode/proc/update_devil_icons_added(datum/mind/devil_mind)
|
||||
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_DEVIL]
|
||||
hud.join_hud(devil_mind.current)
|
||||
set_antag_hud(devil_mind.current, "huddevil")
|
||||
|
||||
/datum/game_mode/proc/update_devil_icons_removed(datum/mind/devil_mind)
|
||||
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_DEVIL]
|
||||
hud.leave_hud(devil_mind.current)
|
||||
set_antag_hud(devil_mind.current, null)
|
||||
@@ -0,0 +1,54 @@
|
||||
//////////////////The Monster
|
||||
|
||||
/mob/living/simple_animal/imp
|
||||
name = "imp"
|
||||
real_name = "imp"
|
||||
desc = "A large, menacing creature covered in armored black scales."
|
||||
speak_emote = list("cackles")
|
||||
emote_hear = list("cackles","screeches")
|
||||
response_help = "thinks better of touching"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "imp"
|
||||
icon_living = "imp"
|
||||
speed = 1
|
||||
a_intent = INTENT_HARM
|
||||
stop_automated_movement = 1
|
||||
status_flags = CANPUSH
|
||||
attack_sound = 'sound/misc/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")
|
||||
attacktext = "wildly tears into"
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
healable = 0
|
||||
environment_smash = 1
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 15
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
var/boost
|
||||
var/playstyle_string = "<B><font size=3 color='red'>You are an imp,</font> a mischevious 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>"
|
||||
|
||||
/mob/living/simple_animal/imp/New()
|
||||
..()
|
||||
boost = world.time + 60
|
||||
|
||||
/mob/living/simple_animal/imp/Life()
|
||||
..()
|
||||
if(boost<world.time)
|
||||
speed = 1
|
||||
else
|
||||
speed = 0
|
||||
|
||||
/mob/living/simple_animal/imp/death()
|
||||
..(1)
|
||||
playsound(get_turf(src),'sound/misc/demon_dies.ogg', 200, 1)
|
||||
visible_message("<span class='danger'>[src] screams in agony as it sublimates into a sulfurous smoke.</span>")
|
||||
ghostize()
|
||||
qdel(src)
|
||||
@@ -0,0 +1,109 @@
|
||||
/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/proc/update_explanation_text()
|
||||
//Intentionally empty
|
||||
|
||||
/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
|
||||
for(var/S in owner.devilinfo.soulsOwned)
|
||||
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)
|
||||
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
|
||||
for(var/S in owner.devilinfo.soulsOwned)
|
||||
var/datum/mind/L = S
|
||||
if(L.soulOwner != L && 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()
|
||||
return target_amount <= ticker.mode.sintouched.len
|
||||
|
||||
|
||||
|
||||
/datum/objective/devil/buy_target
|
||||
explanation_text = "You shouldn't see this text. Error:DEVIL4"
|
||||
|
||||
/datum/objective/devil/buy_target/New()
|
||||
find_target()
|
||||
update_explanation_text()
|
||||
|
||||
/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/update_explanation_text()
|
||||
explanation_text = "Purchase and retain control over more souls than [target.devilinfo.truename], known to mortals as [target.name], the [target.assigned_role]."
|
||||
|
||||
/datum/objective/devil/outsell/check_completion()
|
||||
var/selfcount = 0
|
||||
for(var/S in owner.devilinfo.soulsOwned)
|
||||
var/datum/mind/L = S
|
||||
if(L.soulOwner == owner)
|
||||
selfcount++
|
||||
var/targetcount = 0
|
||||
for(var/S in target.devilinfo.soulsOwned)
|
||||
var/datum/mind/L = S
|
||||
if(L.soulOwner == target)
|
||||
targetcount++
|
||||
return selfcount > targetcount
|
||||
@@ -0,0 +1,234 @@
|
||||
#define DEVIL_R_HAND_LAYER 1
|
||||
#define DEVIL_L_HAND_LAYER 2
|
||||
#define DEVIL_TOTAL_LAYERS 2
|
||||
|
||||
// This is used primarily for having hands.
|
||||
/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 = FALSE
|
||||
density = TRUE
|
||||
pass_flags = 0
|
||||
var/ascended = FALSE
|
||||
sight = (SEE_TURFS | SEE_OBJS)
|
||||
status_flags = CANPUSH
|
||||
universal_understand = TRUE
|
||||
universal_speak = TRUE //The devil speaks all languages meme
|
||||
var/mob/living/oldform
|
||||
var/list/devil_overlays[DEVIL_TOTAL_LAYERS]
|
||||
|
||||
/mob/living/carbon/true_devil/New(loc, mob/living/carbon/dna_source)
|
||||
dna = dna_source.dna.Clone()
|
||||
var/obj/item/organ/internal/brain/B = new(src)
|
||||
var/obj/item/organ/internal/ears/E = new(src)
|
||||
B.insert()
|
||||
E.insert()
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/update_sight()
|
||||
if(stat == DEAD)
|
||||
sight |= SEE_TURFS
|
||||
sight |= SEE_MOBS
|
||||
sight |= SEE_OBJS
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
else
|
||||
sight = (SEE_TURFS | SEE_OBJS)
|
||||
see_in_dark = 2
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if(see_override)
|
||||
see_invisible = see_override
|
||||
|
||||
// inventory system could use some love
|
||||
/mob/living/carbon/true_devil/put_in_hands(obj/item/W)
|
||||
if(!W)
|
||||
return 0
|
||||
if(put_in_active_hand(W))
|
||||
return TRUE
|
||||
else if(put_in_inactive_hand(W))
|
||||
return TRUE
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/true_devil/proc/convert_to_archdevil()
|
||||
maxHealth = 5000 // not an IMPOSSIBLE amount, but still near impossible.
|
||||
ascended = TRUE
|
||||
health = maxHealth
|
||||
icon_state = "arch_devil"
|
||||
|
||||
/mob/living/carbon/true_devil/proc/set_name()
|
||||
name = mind.devilinfo.truename
|
||||
real_name = name
|
||||
|
||||
/mob/living/carbon/true_devil/Login()
|
||||
..()
|
||||
if(mind.devilinfo)
|
||||
mind.devilinfo.announce_laws(src)
|
||||
mind.announce_objectives()
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/death(gibbed)
|
||||
. = ..(gibbed)
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/examine(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\nThis is [bicon(src)] <b>[src]</b>!\n"
|
||||
|
||||
//Left hand items
|
||||
if(l_hand && !(l_hand.flags & ABSTRACT))
|
||||
if(l_hand.blood_DNA)
|
||||
msg += "<span class='warning'>It is holding [bicon(l_hand)] [l_hand.gender == PLURAL? "some" : "a"] blood-stained [l_hand.name] in its left hand!</span>\n"
|
||||
else
|
||||
msg += "It is holding [bicon(l_hand)] \a [l_hand] in its left hand.\n"
|
||||
|
||||
//Right hand items
|
||||
if(r_hand && !(r_hand.flags & ABSTRACT))
|
||||
if(r_hand.blood_DNA)
|
||||
msg += "<span class='warning'>It is holding [bicon(r_hand)] [r_hand.gender == PLURAL? "some" : "a"] blood-stained [r_hand.name] in its right hand!</span>\n"
|
||||
else
|
||||
msg += "It is holding [bicon(r_hand)] \a [r_hand] in its right hand.\n"
|
||||
|
||||
//Braindead
|
||||
if(!client && stat != DEAD)
|
||||
msg += "The devil seems to be in deep contemplation.\n"
|
||||
|
||||
//Damaged
|
||||
if(stat == DEAD)
|
||||
msg += "<span class='deadsay'>The hellfire seems to have been extinguished, for now at least.</span>\n"
|
||||
else if(health < (maxHealth/10))
|
||||
msg += "<span class='warning'>You can see hellfire inside of it's gaping wounds.</span>\n"
|
||||
else if(health < (maxHealth/2))
|
||||
msg += "<span class='warning'>You can see hellfire inside of it's wounds.</span>\n"
|
||||
msg += "*---------*</span>"
|
||||
to_chat(user, msg)
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/IsAdvancedToolUser()
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/true_devil/assess_threat()
|
||||
return 666
|
||||
|
||||
/mob/living/carbon/true_devil/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 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/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(I.attack_verb && I.attack_verb.len)
|
||||
message_verb = "[pick(I.attack_verb)]"
|
||||
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>")
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity)
|
||||
if(!ishuman(A))
|
||||
// `attack_hand` on mobs assumes the attacker is a human
|
||||
// I am the worst
|
||||
A.attack_hand(src)
|
||||
// If the devil wants to actually attack, they have the pitchfork.
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/Process_Spacemove(movement_dir = 0)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/true_devil/singularity_act()
|
||||
if(ascended)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/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/imp/S = new(get_turf(loc))
|
||||
S.key = user.key
|
||||
S.mind.assigned_role = "MODE"
|
||||
S.mind.special_role = "Imp"
|
||||
var/datum/objective/newobjective = new
|
||||
newobjective.explanation_text = "Try to get a promotion to a higher infernal rank."
|
||||
S.mind.objectives += newobjective
|
||||
to_chat(S,S.playstyle_string)
|
||||
to_chat(S,"<B>Objective #1</B>: [newobjective.explanation_text]")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/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(INTENT_HARM)
|
||||
var/damage = rand(1, 5)
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [src]!</span>")
|
||||
adjustBruteLoss(damage)
|
||||
add_attack_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
if(INTENT_DISARM)
|
||||
if(!lying && !ascended) //No stealing the arch devil's pitchfork.
|
||||
if(prob(5))
|
||||
// Weaken knocks people over
|
||||
// Paralyse knocks people out
|
||||
// It's Paralyse for parity though
|
||||
// Weaken(2)
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_attack_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
if(prob(25))
|
||||
drop_item()
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to disarm [src]!</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 (1)
|
||||
b_loss = 500
|
||||
if (2)
|
||||
b_loss = 150
|
||||
if(3)
|
||||
b_loss = 30
|
||||
if(has_bane(BANE_LIGHT))
|
||||
b_loss *=2
|
||||
adjustBruteLoss(b_loss)
|
||||
return ..()
|
||||
|
||||
#undef DEVIL_TOTAL_LAYERS
|
||||
@@ -0,0 +1,52 @@
|
||||
/mob/living/carbon/true_devil/unEquip(obj/item/I, force)
|
||||
if(..(I,force))
|
||||
update_inv_r_hand()
|
||||
update_inv_l_hand()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/true_devil/update_inv_r_hand(var/update_icons=1)
|
||||
..()
|
||||
if(r_hand)
|
||||
var/t_state = r_hand.item_state
|
||||
if(!t_state)
|
||||
t_state = r_hand.icon_state
|
||||
|
||||
var/image/I = image("icon" = r_hand.righthand_file, "icon_state" = "[t_state]")
|
||||
I = center_image(I, r_hand.inhand_x_dimension, r_hand.inhand_y_dimension)
|
||||
devil_overlays[DEVIL_R_HAND_LAYER] = I
|
||||
else
|
||||
devil_overlays[DEVIL_R_HAND_LAYER] = null
|
||||
if(update_icons)
|
||||
update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/update_inv_l_hand(var/update_icons=1)
|
||||
..()
|
||||
if(l_hand)
|
||||
var/t_state = l_hand.item_state
|
||||
if(!t_state)
|
||||
t_state = l_hand.icon_state
|
||||
|
||||
var/image/I = image("icon" = l_hand.lefthand_file, "icon_state" = "[t_state]")
|
||||
I = center_image(I, l_hand.inhand_x_dimension, l_hand.inhand_y_dimension)
|
||||
devil_overlays[DEVIL_L_HAND_LAYER] = I
|
||||
else
|
||||
devil_overlays[DEVIL_L_HAND_LAYER] = null
|
||||
if(update_icons)
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/true_devil/proc/remove_overlay(cache_index)
|
||||
if(devil_overlays[cache_index])
|
||||
overlays -= devil_overlays[cache_index]
|
||||
devil_overlays[cache_index] = null
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/proc/apply_overlay(cache_index)
|
||||
var/image/I = devil_overlays[cache_index]
|
||||
if(I)
|
||||
if(I in overlays)
|
||||
return
|
||||
var/list/new_overlays = overlays.Copy()
|
||||
new_overlays += I
|
||||
overlays = new_overlays
|
||||
@@ -476,3 +476,6 @@ var/round_start_time = 0
|
||||
event_manager.RoundEnd()
|
||||
|
||||
return 1
|
||||
|
||||
/datum/controller/gameticker/proc/HasRoundStarted()
|
||||
return current_state >= GAME_STATE_PLAYING
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
S = H.dna.species
|
||||
S.team = team_number
|
||||
H.real_name = team_name + " Agent"
|
||||
H.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ayys.
|
||||
H.cleanSE() //No fat/blind/colourblind/epileptic/whatever ayys.
|
||||
H.overeatduration = 0
|
||||
H.equipOutfit(/datum/outfit/abductor/agent)
|
||||
greet_agent(agent,team_number)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/datum/objective/sintouched
|
||||
completed = 1
|
||||
|
||||
/* NO ERP OBJECTIVE FOR YOU.
|
||||
/datum/objective/sintouched/lust
|
||||
dangerrating = 3 // it's not AS dangerous.
|
||||
|
||||
/datum/objective/sintouched/lust/New()
|
||||
var/mob/dead/D = pick(dead_mob_list)
|
||||
if(prob(50) && D)
|
||||
explanation_text = "You know that [D] has perished.... and you think [D] is kinda cute. Make sure everyone knows how HOT [D]'s lifeless body is."
|
||||
else
|
||||
explanation_text = "Go get married, then immediately cheat on your new spouse." */
|
||||
|
||||
/datum/objective/sintouched/gluttony
|
||||
explanation_text = "Food is delicious, so delicious you can't let it be wasted on other people."
|
||||
|
||||
/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."
|
||||
@@ -169,7 +169,7 @@ proc/issyndicate(mob/living/M as mob)
|
||||
M.set_species(/datum/species/human, TRUE)
|
||||
M.dna.ready_dna(M) // Quadriplegic Nuke Ops won't be participating in the paralympics
|
||||
M.dna.species.create_organs(M)
|
||||
M.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ops.
|
||||
M.cleanSE() //No fat/blind/colourblind/epileptic/whatever ops.
|
||||
M.overeatduration = 0
|
||||
|
||||
var/obj/item/organ/external/head/head_organ = M.get_organ("head")
|
||||
@@ -266,7 +266,7 @@ proc/issyndicate(mob/living/M as mob)
|
||||
synd_mob.equip_to_slot_or_del(new /obj/item/storage/backpack(synd_mob), slot_back)
|
||||
synd_mob.equip_to_slot_or_del(new /obj/item/gun/projectile/automatic/pistol(synd_mob), slot_belt)
|
||||
synd_mob.equip_to_slot_or_del(new /obj/item/storage/box/survival_syndi(synd_mob.back), slot_in_backpack)
|
||||
|
||||
synd_mob.equip_to_slot_or_del(new /obj/item/pinpointer/nukeop(synd_mob), slot_wear_pda)
|
||||
var/obj/item/radio/uplink/nuclear/U = new /obj/item/radio/uplink/nuclear(synd_mob)
|
||||
U.hidden_uplink.uplink_owner="[synd_mob.key]"
|
||||
U.hidden_uplink.uses = 20
|
||||
|
||||
@@ -724,51 +724,18 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
|
||||
if(vox_total_kills > vox_allowed_kills) return 0
|
||||
return 1
|
||||
|
||||
// Traders
|
||||
|
||||
/datum/objective/trade // Yes, I know there's no check_completion. The objectives exist only to tell the traders what to get.
|
||||
/datum/objective/trade/proc/choose_target(var/station)
|
||||
// Traders
|
||||
// These objectives have no check_completion, they exist only to tell Sol Traders what to aim for.
|
||||
|
||||
/datum/objective/trade/proc/choose_target()
|
||||
return
|
||||
|
||||
/datum/objective/trade/stock // Stock or spare parts.
|
||||
var/target_rating = 1
|
||||
/datum/objective/trade/stock/choose_target(var/station)
|
||||
var/itemname
|
||||
switch(rand(1,8))
|
||||
if(1)
|
||||
target = /obj/item/stock_parts/cell
|
||||
target_amount = 10
|
||||
target_rating = 3
|
||||
itemname = "ten high-capacity power cells"
|
||||
if(2)
|
||||
target = /obj/item/stock_parts/manipulator
|
||||
target_amount = 20
|
||||
itemname = "twenty micro manipulators"
|
||||
if(3)
|
||||
target = /obj/item/stock_parts/matter_bin
|
||||
target_amount = 20
|
||||
itemname = "twenty matter bins"
|
||||
if(4)
|
||||
target = /obj/item/stock_parts/micro_laser
|
||||
target_amount = 15
|
||||
itemname = "fifteen micro-lasers"
|
||||
if(5)
|
||||
target = /obj/item/stock_parts/capacitor
|
||||
target_amount = 15
|
||||
itemname = "fifteen capacitors"
|
||||
if(6)
|
||||
target = /obj/item/stock_parts/subspace/filter
|
||||
target_amount = 4
|
||||
itemname = "four hyperwave filters"
|
||||
if(7)
|
||||
target = /obj/item/solar_assembly
|
||||
target_amount = 10
|
||||
itemname = "ten solar panel assemblies"
|
||||
if(8)
|
||||
target = /obj/item/flash
|
||||
target_amount = 6
|
||||
itemname = "six flashes"
|
||||
explanation_text = "We are running low on spare parts. Trade for [itemname]."
|
||||
/datum/objective/trade/plasma/choose_target()
|
||||
explanation_text = "Acquire at least 15 sheets of plasma through trade."
|
||||
|
||||
/datum/objective/trade/credits/choose_target()
|
||||
explanation_text = "Acquire at least 10,000 credits through trade."
|
||||
|
||||
//wizard
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
access_heads, access_construction, access_sec_doors,
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_minisat, access_mechanic, access_mineral_storeroom)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 600
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_CREW
|
||||
outfit = /datum/outfit/job/chief_engineer
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
|
||||
access_keycard_auth, access_sec_doors, access_psychiatrist, access_maint_tunnels, access_paramedic, access_mineral_storeroom)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 600
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_CREW
|
||||
outfit = /datum/outfit/job/cmo
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
access_research, access_robotics, access_xenobiology, access_ai_upload,
|
||||
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_minisat, access_maint_tunnels, access_mineral_storeroom, access_network)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 600
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_CREW
|
||||
// All science-y guys get bonuses for maxing out their tech.
|
||||
required_objectives = list(
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
|
||||
access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_pilot, access_weapons)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 600
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_CREW
|
||||
disabilities_allowed = 0
|
||||
outfit = /datum/outfit/job/hos
|
||||
@@ -63,7 +63,7 @@
|
||||
access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_morgue, access_weapons)
|
||||
minimal_access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_weapons)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 300
|
||||
exp_requirements = 600
|
||||
exp_type = EXP_TYPE_CREW
|
||||
outfit = /datum/outfit/job/warden
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
minimal_access = list(access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court, access_weapons)
|
||||
alt_titles = list("Forensic Technician")
|
||||
minimal_player_age = 14
|
||||
exp_requirements = 300
|
||||
exp_requirements = 600
|
||||
exp_type = EXP_TYPE_CREW
|
||||
outfit = /datum/outfit/job/detective
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_morgue, access_weapons)
|
||||
minimal_access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_weapons)
|
||||
minimal_player_age = 14
|
||||
exp_requirements = 300
|
||||
exp_requirements = 600
|
||||
exp_type = EXP_TYPE_CREW
|
||||
outfit = /datum/outfit/job/officer
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
|
||||
access = list() //See get_access()
|
||||
minimal_access = list() //See get_access()
|
||||
minimal_player_age = 30
|
||||
exp_requirements = 1200
|
||||
exp_requirements = 2400
|
||||
exp_type = EXP_TYPE_CREW
|
||||
disabilities_allowed = 0
|
||||
outfit = /datum/outfit/job/captain
|
||||
@@ -68,7 +68,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
|
||||
req_admin_notify = 1
|
||||
is_command = 1
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 600
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_CREW
|
||||
access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers,
|
||||
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
|
||||
|
||||
@@ -176,10 +176,7 @@ var/global/list/role_playtime_requirements = list(
|
||||
if(dep == EXP_TYPE_EXEMPT)
|
||||
return_text += "<LI>Exempt (all jobs auto-unlocked)</LI>"
|
||||
else if(exp_data[EXP_TYPE_LIVING] > 0)
|
||||
var/my_pc = num2text(round(exp_data[dep]/exp_data[EXP_TYPE_LIVING]*100))
|
||||
return_text += "<LI>[dep]: [get_exp_format(exp_data[dep])] ([my_pc]%)</LI>"
|
||||
else
|
||||
return_text += "<LI>[dep]: [get_exp_format(exp_data[dep])] </LI>"
|
||||
return_text += "<LI>[dep]: [get_exp_format(exp_data[dep])]</LI>"
|
||||
if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, mob))
|
||||
return_text += "<LI>Admin</LI>"
|
||||
return_text += "</UL>"
|
||||
|
||||
+10
-1
@@ -193,5 +193,14 @@ var/global/list/exp_jobsmap = list(
|
||||
EXP_TYPE_CREW = list(titles = command_positions | engineering_positions | medical_positions | science_positions | support_positions | supply_positions | security_positions | civilian_positions | list("AI","Cyborg") | whitelisted_positions), // crew positions
|
||||
EXP_TYPE_SPECIAL = list(), // antags, ERT, etc
|
||||
EXP_TYPE_GHOST = list(), // dead people, observers
|
||||
EXP_TYPE_EXEMPT = list() // special grandfather setting
|
||||
EXP_TYPE_EXEMPT = list(), // special grandfather setting
|
||||
EXP_TYPE_COMMAND = list(titles = command_positions),
|
||||
EXP_TYPE_ENGINEERING = list(titles = engineering_positions),
|
||||
EXP_TYPE_MEDICAL = list(titles = medical_positions),
|
||||
EXP_TYPE_SCIENCE = list(titles = science_positions),
|
||||
EXP_TYPE_SUPPLY = list(titles = supply_positions),
|
||||
EXP_TYPE_SECURITY = list(titles = security_positions),
|
||||
EXP_TYPE_SILICON = list(titles = list("AI","Cyborg")),
|
||||
EXP_TYPE_SERVICE = list(titles = service_positions),
|
||||
EXP_TYPE_WHITELIST = list(titles = whitelisted_positions) // karma-locked jobs
|
||||
)
|
||||
|
||||
@@ -190,6 +190,11 @@
|
||||
if(radio_announce)
|
||||
Radio.autosay(message, name, "Medical", list(z))
|
||||
|
||||
/obj/machinery/clonepod/proc/spooky_devil_flavor()
|
||||
playsound(loc, pick('sound/goonstation/voice/male_scream.ogg', 'sound/goonstation/voice/female_scream.ogg'), 100, 1)
|
||||
mess = 1
|
||||
update_icon()
|
||||
connected_message("<font face=\"REBUFFED\" color=#600A0A>If you keep trying to steal from me, you'll end up with me.</font>")
|
||||
|
||||
//Start growing a human clone in the pod!
|
||||
/obj/machinery/clonepod/proc/growclone(datum/dna2/record/R)
|
||||
@@ -200,8 +205,13 @@
|
||||
return 0
|
||||
if(clonemind.current && clonemind.current.stat != DEAD) //mind is associated with a non-dead body
|
||||
return 0
|
||||
if(clonemind.damnation_type)
|
||||
spooky_devil_flavor()
|
||||
return 0
|
||||
if(!clonemind.is_revivable()) //Other reasons for being unrevivable
|
||||
return 0
|
||||
if(clonemind.active) //somebody is using that mind
|
||||
if(ckey(clonemind.key) != R.ckey)
|
||||
if(ckey(clonemind.key) != R.ckey )
|
||||
return 0
|
||||
if(clonemind.suicided) // and stay out!
|
||||
malfunction(go_easy = 0)
|
||||
@@ -300,7 +310,7 @@
|
||||
connected_message("Clone Ejected: Loss of power.")
|
||||
|
||||
else if((occupant) && (occupant.loc == src))
|
||||
if((occupant.stat == DEAD) || (occupant.suiciding)) //Autoeject corpses and suiciding dudes.
|
||||
if((occupant.stat == DEAD) || (occupant.suiciding) || (occupant.mind && !occupant.mind.is_revivable())) //Autoeject corpses and suiciding dudes.
|
||||
announce_radio_message("The cloning of <b>[occupant]</b> has been aborted due to unrecoverable tissue failure.")
|
||||
go_out()
|
||||
connected_message("Clone Rejected: Deceased.")
|
||||
|
||||
@@ -167,7 +167,6 @@
|
||||
|
||||
active = 0
|
||||
update_icon()
|
||||
anchored = 0
|
||||
|
||||
for(var/obj/machinery/shield/shield_tile in deployed_shields)
|
||||
qdel(shield_tile)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -290,3 +290,7 @@
|
||||
..()
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
T.burn_tile()
|
||||
|
||||
|
||||
/obj/effect/landmark/battle_mob_point
|
||||
name = "Nanomob Battle Avatar Spawn Point"
|
||||
@@ -189,26 +189,25 @@
|
||||
/obj/item/soap/syndie = 50,
|
||||
/obj/item/lighter/zippo/gonzofist = 50,
|
||||
/obj/item/stack/nanopaste = 50,
|
||||
/obj/item/clothing/under/psyjump = 50
|
||||
/obj/item/clothing/under/psyjump = 50,
|
||||
/obj/item/immortality_talisman = 50,
|
||||
/obj/item/grenade/clusterbuster/smoke = 50
|
||||
)
|
||||
|
||||
|
||||
/obj/effect/spawner/lootdrop/trade_sol/minerals
|
||||
name = "2. minerals"
|
||||
lootdoubles = 1
|
||||
loot = list(
|
||||
// Common stuff you get from mining which isn't already present on the station
|
||||
// Note that plasma and derived hybrid materials are NOT included in this list because plasma is the trader's objective!
|
||||
/obj/item/stack/sheet/mineral/silver = 50,
|
||||
/obj/item/stack/sheet/mineral/gold = 50,
|
||||
/obj/item/stack/sheet/mineral/plasma = 50,
|
||||
/obj/item/stack/sheet/mineral/uranium = 50,
|
||||
/obj/item/stack/sheet/mineral/diamond = 50,
|
||||
/obj/item/stack/sheet/mineral/titanium = 50,
|
||||
/obj/item/stack/sheet/plasteel = 50,
|
||||
|
||||
// Hybrid stuff you could in theory get from mining
|
||||
/obj/item/stack/sheet/plasmaglass = 50,
|
||||
/obj/item/stack/sheet/plasmarglass = 50,
|
||||
/obj/item/stack/sheet/titaniumglass = 50,
|
||||
|
||||
// Rare stuff you can't get from mining
|
||||
@@ -216,8 +215,7 @@
|
||||
/obj/item/stack/sheet/mineral/bananium = 50,
|
||||
/obj/item/stack/sheet/wood = 50,
|
||||
/obj/item/stack/sheet/plastic = 50,
|
||||
/obj/item/stack/sheet/mineral/sandstone = 50,
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone = 50
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/trade_sol/minerals/New()
|
||||
@@ -244,7 +242,7 @@
|
||||
/obj/item/gun/projectile/automatic/toy/pistol/enforcer = 50,
|
||||
/obj/item/gun/projectile/shotgun/toy = 50,
|
||||
/obj/item/gun/projectile/shotgun/toy/crossbow = 50,
|
||||
/obj/item/gun/projectile/shotgun/toy/tommygun = 50,
|
||||
/obj/item/gun/projectile/shotgun/toy/tommygun = 50
|
||||
)
|
||||
|
||||
|
||||
@@ -259,13 +257,11 @@
|
||||
/obj/item/autoimplanter = 50,
|
||||
|
||||
// Research / Experimentor
|
||||
/obj/item/relic = 150, // strange object
|
||||
/obj/item/paper/researchnotes = 150, // papers that give random R&D levels
|
||||
|
||||
// Xenobio
|
||||
/obj/item/slimepotion/sentience = 50, // Low-value, but we want to encourage getting more players back in the round.
|
||||
/obj/item/slimepotion/transference = 50,
|
||||
/obj/item/slimepotion/speed = 50,
|
||||
/obj/item/slimepotion/transference = 50
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/trade_sol/med
|
||||
@@ -279,16 +275,16 @@
|
||||
// Surgery
|
||||
/obj/item/scalpel/laser/manager = 100,
|
||||
/obj/item/organ/internal/heart/gland/ventcrawling = 50,
|
||||
/obj/item/organ/internal/heart/gland/heals = 50,
|
||||
|
||||
// Genetics Research (should really be under science, but I was stuck for items to put in medical)
|
||||
/obj/item/dnainjector/regenerate = 50, // regeneration
|
||||
/obj/item/dnainjector/nobreath = 50,
|
||||
/obj/item/dnainjector/midgit = 50,
|
||||
/obj/item/dnainjector/telemut = 50,
|
||||
|
||||
// Virology
|
||||
/obj/item/reagent_containers/glass/bottle/regeneration = 50,
|
||||
/obj/item/reagent_containers/glass/bottle/sensory_restoration = 50,
|
||||
/obj/item/reagent_containers/glass/bottle/sensory_restoration = 50
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/trade_sol/sec
|
||||
@@ -301,17 +297,31 @@
|
||||
// Utility
|
||||
/obj/item/storage/belt/military/assault = 50,
|
||||
/obj/item/clothing/mask/gas/sechailer/swat = 50,
|
||||
/obj/item/clothing/glasses/thermal = 50, // see heat-source mobs through walls. Less powerful than already-available xray.
|
||||
|
||||
// Ranged weapons
|
||||
/obj/item/storage/box/enforcer_rubber = 50,
|
||||
/obj/item/storage/box/enforcer_lethal = 50,
|
||||
/obj/item/gun/projectile/shotgun/automatic/combat = 50, // combat shotgun, between riot and bulldog in robustness. Not illegal, can be obtained from cargo.
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube = 50, // cycler shotgun, not normally available to crew
|
||||
|
||||
// Cluster grenades
|
||||
/obj/item/grenade/clusterbuster = 50, // cluster flashbang
|
||||
/obj/item/grenade/clusterbuster/teargas = 50
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/trade_sol/eng
|
||||
name = "7. eng gear"
|
||||
lootcount = 3
|
||||
loot = list(
|
||||
/obj/item/storage/belt/utility/chief/full = 25,
|
||||
/obj/item/rcd/combat = 25,
|
||||
/obj/item/rpd/bluespace = 25,
|
||||
/obj/item/tank/emergency_oxygen/double/full = 25,
|
||||
/obj/item/slimepotion/speed = 25,
|
||||
/obj/item/storage/backpack/holding = 25,
|
||||
/obj/item/clothing/glasses/meson/night = 25, // NV mesons
|
||||
/obj/item/clothing/glasses/material = 25, // shows objects, but not mobs, through walls
|
||||
/obj/item/grenade/clusterbuster/metalfoam = 25 // cluster metal foam grenade
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/trade_sol/largeitem
|
||||
@@ -319,7 +329,7 @@
|
||||
lootcount = 1
|
||||
loot = list(
|
||||
/obj/machinery/disco = 20,
|
||||
/obj/mecha/combat/durand/old = 20,
|
||||
/obj/mecha/combat/durand/old = 20
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/trade_sol/vehicle
|
||||
@@ -348,18 +358,22 @@
|
||||
// Mining
|
||||
/obj/item/mining_voucher = 100,
|
||||
/obj/item/pickaxe/drill/jackhammer = 100,
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide = 100,
|
||||
/obj/item/gun/energy/kinetic_accelerator/experimental = 100,
|
||||
/obj/item/borg/upgrade/modkit/aoe/turfs/andmobs = 100,
|
||||
|
||||
// Botanist
|
||||
/obj/item/seeds/random/labelled = 100,
|
||||
|
||||
// Clown
|
||||
/obj/item/grenade/bananade = 100,
|
||||
/obj/item/grenade/clusterbuster/honk = 100,
|
||||
/obj/item/bikehorn/golden = 100,
|
||||
|
||||
// Bartender
|
||||
/obj/item/storage/box/bartender_rare_ingredients_kit = 100,
|
||||
|
||||
// It would be nice to also have items for other service jobs: Bartender, Mime, Chef, Librarian, Chaplain, etc
|
||||
// Chef
|
||||
/obj/item/storage/box/chef_rare_ingredients_kit = 100
|
||||
// It would be nice to also have items for other service jobs: Mime, Librarian, Chaplain, etc
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
eject_all()
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
QDEL_NULL(active_dummy)
|
||||
to_chat(usr, "<span class='notice'>You deactivate \the [src].</span>")
|
||||
to_chat(usr, "<span class='notice'>You deactivate [src].</span>")
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
@@ -58,7 +58,7 @@
|
||||
var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(usr.loc)
|
||||
C.activate(O, usr, saved_icon, saved_icon_state, saved_overlays, saved_underlays, src)
|
||||
qdel(O)
|
||||
to_chat(usr, "<span class='notice'>You activate \the [src].</span>")
|
||||
to_chat(usr, "<span class='notice'>You activate [src].</span>")
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
@@ -148,3 +148,102 @@
|
||||
/obj/effect/dummy/chameleon/Destroy()
|
||||
master.disrupt(0)
|
||||
return ..()
|
||||
|
||||
/obj/item/borg_chameleon
|
||||
name = "cyborg chameleon projector"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "shield0"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/active = FALSE
|
||||
var/activationCost = 300
|
||||
var/activationUpkeep = 50
|
||||
var/disguise = "landmate"
|
||||
var/mob/living/silicon/robot/syndicate/saboteur/S
|
||||
|
||||
/obj/item/borg_chameleon/Destroy()
|
||||
if(S)
|
||||
S.cham_proj = null
|
||||
return ..()
|
||||
|
||||
/obj/item/borg_chameleon/dropped(mob/user)
|
||||
. = ..()
|
||||
disrupt(user)
|
||||
|
||||
/obj/item/borg_chameleon/equipped(mob/user)
|
||||
. = ..()
|
||||
disrupt(user)
|
||||
|
||||
/obj/item/borg_chameleon/attack_self(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(user && user.cell && user.cell.charge > activationCost)
|
||||
if(isturf(user.loc))
|
||||
toggle(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't use [src] while inside something!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need at least [activationCost] charge in your cell to use [src]!</span>")
|
||||
|
||||
/obj/item/borg_chameleon/proc/toggle(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(active)
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
to_chat(user, "<span class='notice'>You deactivate [src].</span>")
|
||||
deactivate(user)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You activate [src].</span>")
|
||||
var/start = user.filters.len
|
||||
var/X
|
||||
var/Y
|
||||
var/rsq
|
||||
var/i
|
||||
var/f
|
||||
for(i in 1 to 7)
|
||||
do
|
||||
X = 60 * rand() - 30
|
||||
Y = 60 * rand() - 30
|
||||
rsq = X * X + Y * Y
|
||||
while(rsq < 100 || rsq > 900)
|
||||
user.filters += filter(type = "wave", x = X, y = Y, size = rand() * 2.5 + 0.5, offset = rand())
|
||||
for(i in 1 to 7)
|
||||
f = user.filters[start+i]
|
||||
animate(f, offset = f:offset, time = 0, loop = 3, flags = ANIMATION_PARALLEL)
|
||||
animate(offset = f:offset - 1, time = rand() * 20 + 10)
|
||||
if(do_after(user, 50, target = user) && user.cell.use(activationCost))
|
||||
playsound(src, 'sound/effects/bamf.ogg', 100, 1, -6)
|
||||
to_chat(user, "<span class='notice'>You are now disguised as a Nanotrasen engineering cyborg.</span>")
|
||||
activate(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The chameleon field fizzles.</span>")
|
||||
do_sparks(3, FALSE, user)
|
||||
for(i in 1 to min(7, user.filters.len)) // removing filters that are animating does nothing, we gotta stop the animations first
|
||||
f = user.filters[start + i]
|
||||
animate(f)
|
||||
user.filters = null
|
||||
|
||||
/obj/item/borg_chameleon/process()
|
||||
if(S)
|
||||
if(!S.cell || !S.cell.use(activationUpkeep))
|
||||
disrupt(S)
|
||||
else
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/item/borg_chameleon/proc/activate(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
processing_objects.Add(src)
|
||||
S = user
|
||||
user.base_icon = disguise
|
||||
user.icon_state = disguise
|
||||
user.cham_proj = src
|
||||
active = TRUE
|
||||
user.update_icons()
|
||||
|
||||
/obj/item/borg_chameleon/proc/deactivate(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
processing_objects.Remove(src)
|
||||
S = user
|
||||
user.base_icon = initial(user.base_icon)
|
||||
user.icon_state = initial(user.icon_state)
|
||||
active = FALSE
|
||||
user.update_icons()
|
||||
|
||||
/obj/item/borg_chameleon/proc/disrupt(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(active)
|
||||
to_chat(user, "<span class='danger'>Your chameleon field deactivates.</span>")
|
||||
deactivate(user)
|
||||
|
||||
@@ -1143,6 +1143,37 @@ obj/item/toy/cards/deck/syndicate/black
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/toy/codex_gigas
|
||||
name = "Toy Codex Gigas"
|
||||
desc = "A tool to help you write fictional devils!"
|
||||
icon = 'icons/obj/library.dmi'
|
||||
icon_state = "demonomicon"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/cooldown = FALSE
|
||||
|
||||
/obj/item/toy/codex_gigas/attack_self(mob/user)
|
||||
if(!cooldown)
|
||||
user.visible_message(
|
||||
"<span class='notice'>[user] presses the button on \the [src].</span>",
|
||||
"<span class='notice'>You press the button on \the [src].</span>",
|
||||
"<span class='notice'>You hear a soft click.</span>")
|
||||
var/list/messages = list()
|
||||
var/datum/devilinfo/devil = randomDevilInfo()
|
||||
messages += "Some fun facts about: [devil.truename]"
|
||||
messages += "[lawlorify[LORE][devil.bane]]"
|
||||
messages += "[lawlorify[LORE][devil.obligation]]"
|
||||
messages += "[lawlorify[LORE][devil.ban]]"
|
||||
messages += "[lawlorify[LORE][devil.banish]]"
|
||||
playsound(loc, 'sound/machines/click.ogg', 20, 1)
|
||||
cooldown = TRUE
|
||||
for(var/message in messages)
|
||||
user.loc.visible_message("<span class='danger'>[bicon(src)] [message]</span>")
|
||||
sleep(10)
|
||||
spawn(20)
|
||||
cooldown = FALSE
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/toy/owl
|
||||
name = "owl action figure"
|
||||
desc = "An action figure modeled after 'The Owl', defender of justice."
|
||||
|
||||
@@ -456,20 +456,24 @@ GLOBAL_LIST_INIT(rcd_door_types, list(
|
||||
/obj/item/rcd/proc/checkResource(amount, mob/user)
|
||||
return matter >= amount
|
||||
|
||||
/obj/item/rcd/borg
|
||||
canRwall = 1
|
||||
var/use_multiplier = 160
|
||||
|
||||
/obj/item/rcd/borg/syndicate
|
||||
use_multiplier = 80
|
||||
|
||||
/obj/item/rcd/borg/useResource(amount, mob/user)
|
||||
if(!isrobot(user))
|
||||
return 0
|
||||
var/mob/living/silicon/robot/R = user
|
||||
return R.cell.use(amount * 160)
|
||||
return R.cell.use(amount * use_multiplier)
|
||||
|
||||
/obj/item/rcd/borg/checkResource(amount, mob/user)
|
||||
if(!isrobot(user))
|
||||
return 0
|
||||
var/mob/living/silicon/robot/R = user
|
||||
return R.cell.charge >= (amount * 160)
|
||||
|
||||
/obj/item/rcd/borg
|
||||
canRwall = 1
|
||||
return R.cell.charge >= (amount * use_multiplier)
|
||||
|
||||
/obj/item/rcd/proc/detonate_pulse()
|
||||
audible_message("<span class='danger'><b>[src] begins to vibrate and \
|
||||
|
||||
@@ -405,7 +405,7 @@
|
||||
for(var/obj/item/organ/external/O in H.bodyparts)
|
||||
total_brute += O.brute_dam
|
||||
total_burn += O.burn_dam
|
||||
if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.get_int_organ(/obj/item/organ/internal/heart) || H.get_int_organ(/obj/item/organ/internal/brain/slime)))
|
||||
if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.mind && H.mind.is_revivable()) && (H.get_int_organ(/obj/item/organ/internal/heart) || H.get_int_organ(/obj/item/organ/internal/brain/slime)))
|
||||
tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you
|
||||
tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived
|
||||
H.adjustOxyLoss(tobehealed)
|
||||
@@ -512,7 +512,7 @@
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
if(do_after(user, 20 * toolspeed, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
|
||||
if(H.stat == 2)
|
||||
if(H.stat == DEAD)
|
||||
var/health = H.health
|
||||
M.visible_message("<span class='warning'>[M]'s body convulses a bit.")
|
||||
playsound(get_turf(src), "bodyfall", 50, 1)
|
||||
@@ -520,7 +520,7 @@
|
||||
for(var/obj/item/organ/external/O in H.bodyparts)
|
||||
total_brute += O.brute_dam
|
||||
total_burn += O.burn_dam
|
||||
if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations))
|
||||
if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.mind && H.mind.is_revivable()))
|
||||
tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you
|
||||
tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived
|
||||
H.adjustOxyLoss(tobehealed)
|
||||
|
||||
@@ -109,6 +109,8 @@
|
||||
message_say = "FOR THE REVOLOUTION!"
|
||||
else if(role == "death commando" || role == ROLE_ERT)
|
||||
message_say = "FOR NANOTRASEN!"
|
||||
else if(role == ROLE_DEVIL)
|
||||
message_say = "FOR INFERNO!"
|
||||
user.say(message_say)
|
||||
target = user
|
||||
sleep(10)
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
payload = /obj/item/grenade/chem_grenade/cleaner
|
||||
|
||||
/obj/item/grenade/clusterbuster/teargas
|
||||
name = "Oignon Grenade"
|
||||
name = "Oignon Teargas Grenade"
|
||||
payload = /obj/item/grenade/chem_grenade/teargas
|
||||
|
||||
/obj/item/grenade/clusterbuster/facid
|
||||
|
||||
@@ -680,6 +680,56 @@
|
||||
new /obj/item/clothing/head/syndicatefake(src)
|
||||
new /obj/item/clothing/suit/syndicatefake(src)
|
||||
|
||||
/obj/item/storage/box/enforcer_rubber
|
||||
name = "enforcer pistol kit (rubber)"
|
||||
desc = "A box marked with pictures of an enforcer pistol, two ammo clips, and the word 'NON-LETHAL'."
|
||||
icon_state = "box_ert"
|
||||
|
||||
/obj/item/storage/box/enforcer_rubber/New()
|
||||
..()
|
||||
new /obj/item/gun/projectile/automatic/pistol/enforcer(src) // loaded with rubber by default
|
||||
new /obj/item/ammo_box/magazine/enforcer(src)
|
||||
new /obj/item/ammo_box/magazine/enforcer(src)
|
||||
|
||||
/obj/item/storage/box/enforcer_lethal
|
||||
name = "enforcer pistol kit (lethal)"
|
||||
desc = "A box marked with pictures of an enforcer pistol, two ammo clips, and the word 'LETHAL'."
|
||||
icon_state = "box_ert"
|
||||
|
||||
/obj/item/storage/box/enforcer_lethal/New()
|
||||
..()
|
||||
new /obj/item/gun/projectile/automatic/pistol/enforcer/lethal(src)
|
||||
new /obj/item/ammo_box/magazine/enforcer/lethal(src)
|
||||
new /obj/item/ammo_box/magazine/enforcer/lethal(src)
|
||||
|
||||
/obj/item/storage/box/bartender_rare_ingredients_kit
|
||||
name = "bartender rare reagents kit"
|
||||
desc = "A box intended for experienced bartenders."
|
||||
|
||||
/obj/item/storage/box/bartender_rare_ingredients_kit/New()
|
||||
..()
|
||||
var/list/reagent_list = list("sacid", "radium", "ether", "methamphetamine", "plasma", "gold", "silver", "capsaicin", "psilocybin")
|
||||
for(var/reag in reagent_list)
|
||||
var/obj/item/reagent_containers/glass/bottle/B = new(src)
|
||||
B.reagents.add_reagent(reag, 30)
|
||||
B.name = "[reag] bottle"
|
||||
|
||||
/obj/item/storage/box/chef_rare_ingredients_kit
|
||||
name = "chef rare reagents kit"
|
||||
desc = "A box intended for experienced chefs."
|
||||
|
||||
/obj/item/storage/box/chef_rare_ingredients_kit/New()
|
||||
..()
|
||||
new /obj/item/reagent_containers/food/condiment/soysauce(src)
|
||||
new /obj/item/reagent_containers/food/condiment/enzyme(src)
|
||||
new /obj/item/reagent_containers/food/condiment/pack/hotsauce(src)
|
||||
new /obj/item/kitchen/knife/butcher(src)
|
||||
var/list/reagent_list = list("msg", "triple_citrus", "salglu_solution", "nutriment", "gravy", "honey", "vitfro")
|
||||
for(var/reag in reagent_list)
|
||||
var/obj/item/reagent_containers/glass/bottle/B = new(src)
|
||||
B.reagents.add_reagent(reag, 30)
|
||||
B.name = "[reag] bottle"
|
||||
|
||||
/obj/item/storage/box/mousetraps
|
||||
name = "box of Pest-B-Gon mousetraps"
|
||||
desc = "<B><FONT color='red'>WARNING:</FONT></B> <I>Keep out of reach of children</I>."
|
||||
|
||||
@@ -758,4 +758,73 @@
|
||||
qdel(A)
|
||||
if(prob(4))
|
||||
charged++
|
||||
user.visible_message("<span class='notice'>The axe starts to emit an electric buzz!</span>")
|
||||
user.visible_message("<span class='notice'>The axe starts to emit an electric buzz!</span>")
|
||||
|
||||
/obj/item/twohanded/pitchfork
|
||||
icon_state = "pitchfork0"
|
||||
name = "pitchfork"
|
||||
desc = "A simple tool used for moving hay."
|
||||
force = 7
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force_unwielded = 7
|
||||
force_wielded = 15
|
||||
attack_verb = list("attacked", "impaled", "pierced")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
/obj/item/twohanded/pitchfork/demonic
|
||||
name = "demonic pitchfork"
|
||||
desc = "A red pitchfork, it looks like the work of the devil."
|
||||
force = 19
|
||||
throwforce = 24
|
||||
force_unwielded = 19
|
||||
force_wielded = 25
|
||||
|
||||
/obj/item/twohanded/pitchfork/demonic/greater
|
||||
force = 24
|
||||
throwforce = 50
|
||||
force_unwielded = 24
|
||||
force_wielded = 34
|
||||
|
||||
/obj/item/twohanded/pitchfork/demonic/ascended
|
||||
force = 100
|
||||
throwforce = 100
|
||||
force_unwielded = 100
|
||||
force_wielded = 500000 // Kills you DEAD.
|
||||
|
||||
/obj/item/twohanded/pitchfork/update_icon()
|
||||
icon_state = "pitchfork[wielded]"
|
||||
|
||||
/obj/item/twohanded/pitchfork/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] impales \himself in \his abdomen with [src]! It looks like \he's trying to commit suicide...</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/twohanded/pitchfork/demonic/pickup(mob/user)
|
||||
if(istype(user, /mob/living))
|
||||
var/mob/living/U = user
|
||||
if(U.mind && !U.mind.devilinfo && (U.mind.soulOwner == U.mind)) //Burn hands unless they are a devil or have sold their soul
|
||||
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 the [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("l_arm", "r_arm"))
|
||||
else
|
||||
U.adjustFireLoss(rand(force/2,force))
|
||||
|
||||
/obj/item/twohanded/pitchfork/demonic/attack(mob/target, mob/living/carbon/human/user)
|
||||
if(user.mind && !user.mind.devilinfo && (user.mind.soulOwner != user.mind))
|
||||
to_chat(user, "<span class ='warning'>The [src] burns in your hands.</span>")
|
||||
user.apply_damage(rand(force/2, force), BURN, pick("l_arm", "r_arm"))
|
||||
..()
|
||||
|
||||
// It's no fun being the lord of all hell if you can't get out of a simple room
|
||||
/obj/item/twohanded/pitchfork/demonic/ascended/afterattack(atom/target, mob/user, proximity)
|
||||
if(!proximity || !wielded)
|
||||
return
|
||||
if(istype(target, /turf/simulated/wall))
|
||||
var/turf/simulated/wall/W = target
|
||||
user.visible_message("<span class='danger'>[user] blasts \the [target] with \the [src]!</span>")
|
||||
playsound(target, 'sound/magic/Disintegrate.ogg', 100, 1)
|
||||
W.devastate_wall(TRUE)
|
||||
return 1
|
||||
..()
|
||||
|
||||
@@ -281,6 +281,7 @@
|
||||
new /obj/item/clothing/under/lawyer/oldman(src)
|
||||
new /obj/item/clothing/under/lawyer/black(src)
|
||||
new /obj/item/clothing/under/lawyer/female(src)
|
||||
new /obj/item/clothing/under/rank/centcom/representative(src)
|
||||
new /obj/item/clothing/head/ntrep(src)
|
||||
new /obj/item/clothing/shoes/sandal/fancy(src)
|
||||
new /obj/item/storage/box/tapes(src)
|
||||
@@ -434,3 +435,29 @@
|
||||
icon_state = icon_closed
|
||||
else
|
||||
icon_state = icon_opened
|
||||
|
||||
/obj/structure/closet/secure_closet/magistrate
|
||||
name = "\improper Magistrate's locker"
|
||||
req_access = list(access_magistrate)
|
||||
icon_state = "magistratesecure1"
|
||||
icon_closed = "magistratesecure"
|
||||
icon_locked = "magistratesecure1"
|
||||
icon_opened = "magistratesecureopen"
|
||||
icon_broken = "magistratesecurebroken"
|
||||
icon_off = "magistratesecureoff"
|
||||
|
||||
/obj/structure/closet/secure_closet/magistrate/New()
|
||||
..()
|
||||
new /obj/item/book/manual/faxes(src)
|
||||
new /obj/item/storage/secure/briefcase(src)
|
||||
new /obj/item/flash(src)
|
||||
new /obj/item/clothing/glasses/sunglasses(src)
|
||||
new /obj/item/clothing/gloves/color/white(src)
|
||||
new /obj/item/clothing/shoes/centcom(src)
|
||||
new /obj/item/clothing/under/suit_jacket/really_black(src)
|
||||
new /obj/item/clothing/under/rank/centcom/magistrate(src)
|
||||
new /obj/item/clothing/suit/judgerobe(src)
|
||||
new /obj/item/clothing/head/powdered_wig(src)
|
||||
new /obj/item/gavelblock(src)
|
||||
new /obj/item/gavelhammer(src)
|
||||
new /obj/item/clothing/head/justice_wig(src)
|
||||
@@ -47,11 +47,6 @@
|
||||
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
|
||||
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
|
||||
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
|
||||
new /obj/item/pinpointer/nukeop(src)
|
||||
new /obj/item/pinpointer/nukeop(src)
|
||||
new /obj/item/pinpointer/nukeop(src)
|
||||
new /obj/item/pinpointer/nukeop(src)
|
||||
new /obj/item/pinpointer/nukeop(src)
|
||||
new /obj/item/pda/syndicate(src)
|
||||
|
||||
/obj/structure/closet/syndicate/resources/
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#define LIGHTFLOOR_BLUE 6
|
||||
#define LIGHTFLOOR_PURPLE 7
|
||||
|
||||
#define LIGHTFLOOR_GENERICCYCLE 8
|
||||
#define LIGHTFLOOR_CYCLEA 9
|
||||
#define LIGHTFLOOR_CYCLEB 10
|
||||
|
||||
/turf/simulated/floor/light
|
||||
name = "Light floor"
|
||||
light_range = 5
|
||||
@@ -14,6 +18,7 @@
|
||||
broken_states = list("light_broken")
|
||||
var/on = 1
|
||||
var/state = LIGHTFLOOR_ON
|
||||
var/can_modify_colour = TRUE
|
||||
|
||||
/turf/simulated/floor/light/New()
|
||||
..()
|
||||
@@ -44,6 +49,15 @@
|
||||
if(LIGHTFLOOR_PURPLE)
|
||||
icon_state = "light_on-p"
|
||||
set_light(5,null,LIGHT_COLOR_PURPLE)
|
||||
if(LIGHTFLOOR_GENERICCYCLE)
|
||||
icon_state = "light_on-cycle_all"
|
||||
set_light(5,null,LIGHT_COLOR_WHITE)
|
||||
if(LIGHTFLOOR_CYCLEA)
|
||||
icon_state = "light_on-dancefloor_A"
|
||||
set_light(5,null,LIGHT_COLOR_RED)
|
||||
if(LIGHTFLOOR_CYCLEB)
|
||||
icon_state = "light_on-dancefloor_B"
|
||||
set_light(5,null,LIGHT_COLOR_DARKBLUE)
|
||||
else
|
||||
icon_state = "light_off"
|
||||
set_light(0)
|
||||
@@ -56,6 +70,8 @@
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/light/attack_hand(mob/user)
|
||||
if(!can_modify_colour)
|
||||
return
|
||||
on = !on
|
||||
update_icon()
|
||||
|
||||
@@ -71,7 +87,9 @@
|
||||
to_chat(user, "<span class='notice'>You replace the light bulb.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The light bulb seems fine, no need to replace it.</span>")
|
||||
if(istype(C,/obj/item/multitool))
|
||||
if(ismultitool(C))
|
||||
if(!can_modify_colour)
|
||||
return
|
||||
if(state != 0)
|
||||
if(state < LIGHTFLOOR_PURPLE)
|
||||
state++
|
||||
@@ -81,3 +99,21 @@
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src]'s light bulb appears to have burned out.</span>")
|
||||
|
||||
|
||||
//Cycles through all of the colours
|
||||
/turf/simulated/floor/light/colour_cycle
|
||||
state = LIGHTFLOOR_GENERICCYCLE
|
||||
can_modify_colour = FALSE
|
||||
|
||||
//Two different "dancefloor" types so that you can have a checkered pattern
|
||||
// (also has a longer delay than colour_cycle between cycling colours)
|
||||
/turf/simulated/floor/light/colour_cycle/dancefloor_a
|
||||
name = "dancefloor"
|
||||
desc = "Funky floor."
|
||||
state = LIGHTFLOOR_CYCLEA
|
||||
|
||||
/turf/simulated/floor/light/colour_cycle/dancefloor_b
|
||||
name = "dancefloor"
|
||||
desc = "Funky floor."
|
||||
state = LIGHTFLOOR_CYCLEB
|
||||
|
||||
@@ -518,6 +518,9 @@
|
||||
|
||||
if(ticker.mode.vampire_enthralled.len)
|
||||
dat += check_role_table("Vampire Thralls", ticker.mode.vampire_enthralled)
|
||||
|
||||
if(ticker.mode.devils.len)
|
||||
dat += check_role_table("Devils", ticker.mode.devils)
|
||||
|
||||
if(ticker.mode.xenos.len)
|
||||
dat += check_role_table("Xenos", ticker.mode.xenos)
|
||||
|
||||
@@ -115,14 +115,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
return
|
||||
|
||||
if(!A || !IsValidSrc(A))
|
||||
to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
|
||||
to_chat(src, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
|
||||
return
|
||||
message_admins("[key_name_admin(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]")
|
||||
log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]")
|
||||
|
||||
spawn()
|
||||
var/returnval = call(A,procname)(arglist(lst)) // Pass the lst as an argument list to the proc
|
||||
to_chat(usr, "<span class='notice'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</span>")
|
||||
to_chat(src, "<span class='notice'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</span>")
|
||||
|
||||
feedback_add_details("admin_verb","DPC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
var/checking = FALSE
|
||||
var/TC_cost = 0
|
||||
var/borg_to_spawn
|
||||
var/list/possible_types = list("Assault", "Medical")
|
||||
var/list/possible_types = list("Assault", "Medical", "Saboteur")
|
||||
|
||||
/obj/item/antag_spawner/borg_tele/attack_self(mob/user)
|
||||
if(used)
|
||||
@@ -43,6 +43,7 @@
|
||||
var/mob/M = pick(borg_candidates)
|
||||
var/client/C = M.client
|
||||
spawn_antag(C, get_turf(src.loc), "syndieborg")
|
||||
qdel(src)
|
||||
else
|
||||
checking = FALSE
|
||||
to_chat(user, "<span class='notice'>Unable to connect to Syndicate command. Please wait and try again later or refund your teleporter through your uplink.</span>")
|
||||
@@ -57,6 +58,8 @@
|
||||
switch(borg_to_spawn)
|
||||
if("Medical")
|
||||
R = new /mob/living/silicon/robot/syndicate/medical(T)
|
||||
else if("Saboteur")
|
||||
R = new /mob/living/silicon/robot/syndicate/saboteur(T)
|
||||
else
|
||||
R = new /mob/living/silicon/robot/syndicate(T) //Assault borg by default
|
||||
R.key = C.key
|
||||
|
||||
@@ -9,23 +9,20 @@
|
||||
anchored = 1
|
||||
var/obj/item/nanomob_card/card
|
||||
var/datum/mob_hunt/mob_info
|
||||
var/obj/effect/landmark/battle_mob_point/avatar_point
|
||||
var/obj/effect/nanomob/battle/avatar
|
||||
var/ready = 0
|
||||
var/team = "Grey"
|
||||
var/avatar_x_offset = 4
|
||||
var/avatar_y_offset = 0
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/red
|
||||
pixel_y = 24
|
||||
dir = SOUTH
|
||||
team = "Red"
|
||||
avatar_y_offset = -1
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/blue
|
||||
pixel_y = -24
|
||||
dir = NORTH
|
||||
team = "Blue"
|
||||
avatar_y_offset = 1
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/red/Initialize()
|
||||
..()
|
||||
@@ -94,7 +91,11 @@
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/update_avatar()
|
||||
//if we don't have avatars yet, spawn them
|
||||
if(!avatar)
|
||||
avatar = new(locate((x + avatar_x_offset), (y + avatar_y_offset), z))
|
||||
if(!avatar_point)
|
||||
log_debug("[src] attempted to spawn a battle mob avatar without a spawn point!")
|
||||
return
|
||||
else
|
||||
avatar = new(get_turf(avatar_point))
|
||||
//update avatar info from card
|
||||
if(mob_info)
|
||||
avatar.mob_info = mob_info
|
||||
@@ -211,6 +212,29 @@
|
||||
if(SSmob_hunt && !SSmob_hunt.blue_terminal)
|
||||
SSmob_hunt.blue_terminal = src
|
||||
|
||||
find_avatar_spawn_point()
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/find_avatar_spawn_point()
|
||||
if(avatar_point)
|
||||
return
|
||||
var/obj/effect/landmark/battle_mob_point/closest
|
||||
for(var/obj/effect/landmark/battle_mob_point/bmp in GLOB.landmarks_list)
|
||||
if(!istype(bmp, /obj/effect/landmark/battle_mob_point))
|
||||
continue
|
||||
if(bmp.z != z) //only match with points on the same z-level)
|
||||
continue
|
||||
if(!closest || isnull(closest))
|
||||
closest = bmp
|
||||
continue
|
||||
if(closest == bmp)
|
||||
continue
|
||||
if((abs(x-bmp.x)+abs(y-bmp.y)) < (abs(x-closest.x)+abs(y-closest.y))) //get_dist would be preferable if it didn't count diagonals as 1 distance, so we have to rely on actual x/y distances in this janky way.
|
||||
closest = bmp
|
||||
if(closest)
|
||||
avatar_point = closest
|
||||
else
|
||||
log_debug("[src] was unable to locate a nearby mob battle landmark! Unable to spawn battle avatars!")
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/do_attack()
|
||||
if(!ready) //no attacking if you arent ready to fight (duh)
|
||||
return
|
||||
|
||||
@@ -276,6 +276,12 @@ var/global/datum/prizes/global_prizes = new
|
||||
typepath = /obj/item/toy/griffin
|
||||
cost = 125
|
||||
|
||||
/datum/prize_item/codex_gigas
|
||||
name = "Toy Codex Gigas"
|
||||
desc = "For helping you come up with writing ideas for your diabolical adventures."
|
||||
typepath = /obj/item/toy/codex_gigas/
|
||||
cost = 75
|
||||
|
||||
/datum/prize_item/esword
|
||||
name = "Toy Energy Sword"
|
||||
desc = "A plastic replica of an energy blade."
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
|
||||
/obj/effect/mob_spawn/human/clown/Initialize()
|
||||
mob_name = pick(GLOB.clown_names)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/clownmili
|
||||
name = "Clown Soldier"
|
||||
@@ -359,7 +359,7 @@
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/clownmili/Initialize()
|
||||
mob_name = "Officer [pick(GLOB.clown_names)]"
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/clownoff
|
||||
name = "Clown Officer"
|
||||
@@ -367,7 +367,7 @@
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/clownoff/Initialize()
|
||||
mob_name = "Honk Specialist [pick(GLOB.clown_names)]"
|
||||
..()
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/outfit/clownsoldier
|
||||
@@ -398,7 +398,7 @@
|
||||
|
||||
/obj/effect/mob_spawn/human/mime/Initialize()
|
||||
mob_name = pick(GLOB.mime_names)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/scientist
|
||||
name = "Scientist"
|
||||
|
||||
@@ -17,8 +17,8 @@ You can set verify to TRUE if you want send() to sleep until the client has the
|
||||
//When sending mutiple assets, how many before we give the client a quaint little sending resources message
|
||||
#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
|
||||
|
||||
//When passively preloading assets, how many to send at once? Too high creates noticable lag where as too low can flood the client's cache with "verify" files
|
||||
#define ASSET_CACHE_PRELOAD_CONCURRENT 3
|
||||
//When passively preloading assets, how many to send at once? Too high creates noticable lag where as too low can flood the client's cache with "verify" files
|
||||
#define ASSET_CACHE_PRELOAD_CONCURRENT 3
|
||||
|
||||
/client
|
||||
var/list/cache = list() // List of all assets sent to this client by the asset cache.
|
||||
@@ -191,6 +191,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the
|
||||
"large_stamp-cent.png" = 'icons/paper_icons/large_stamp-cent.png',
|
||||
"large_stamp-syndicate.png" = 'icons/paper_icons/large_stamp-syndicate.png',
|
||||
"large_stamp-rep.png" = 'icons/paper_icons/large_stamp-rep.png',
|
||||
"large_stamp-magistrate.png"= 'icons/paper_icons/large_stamp-magistrate.png',
|
||||
"talisman.png" = 'icons/paper_icons/talisman.png',
|
||||
"ntlogo.png" = 'icons/paper_icons/ntlogo.png'
|
||||
)
|
||||
|
||||
@@ -23,6 +23,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
ROLE_NINJA = 21,
|
||||
ROLE_GSPIDER = 21,
|
||||
ROLE_ABDUCTOR = 30,
|
||||
ROLE_DEVIL = 14
|
||||
)
|
||||
|
||||
/proc/player_old_enough_antag(client/C, role)
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
icon_state = "pwig"
|
||||
item_state = "pwig"
|
||||
|
||||
/obj/item/clothing/head/justice_wig
|
||||
name = "Justice wig"
|
||||
desc = "A fancy powdered wig given to arbitrators of the law. It looks itchy."
|
||||
icon_state = "jwig"
|
||||
item_state = "jwig"
|
||||
|
||||
/obj/item/clothing/head/beret/blue
|
||||
icon_state = "beret_blue"
|
||||
|
||||
|
||||
@@ -145,6 +145,19 @@
|
||||
..()
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Ensign\" and bears [station_name()] on the left shoulder."
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/magistrate
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Magistrate\" and bears \"N.S.S. Cyberiad\" on the left shoulder."
|
||||
name = "\improper Nanotrasen Navy Uniform"
|
||||
icon_state = "officer"
|
||||
item_state = "g_suit"
|
||||
item_color = "officer"
|
||||
displays_id = 0
|
||||
flags_size = ONESIZEFITSALL
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/magistrate/New()
|
||||
..()
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Magistrate\" and bears [station_name()] on the left shoulder."
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/diplomatic
|
||||
desc = "A very gaudy and official looking uniform of the Nanotrasen Diplomatic Corps."
|
||||
name = "\improper Nanotrasen Diplomatic Uniform"
|
||||
@@ -798,7 +811,6 @@
|
||||
flags = NODROP
|
||||
has_sensor = 0 // HUNKE
|
||||
|
||||
|
||||
/obj/item/clothing/under/victdress
|
||||
name = "black victorian dress"
|
||||
desc = "A victorian style dress, fancy!"
|
||||
@@ -840,3 +852,10 @@
|
||||
item_state = "medicalgown"
|
||||
item_color = "medicalgown"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO
|
||||
|
||||
/obj/item/clothing/under/burial
|
||||
name = "burial garments"
|
||||
desc = "Traditional burial garments from the early 22nd century."
|
||||
icon_state = "burial"
|
||||
item_state = "burial"
|
||||
item_color = "burial"
|
||||
|
||||
@@ -1597,3 +1597,10 @@
|
||||
item_color = "Xann_necklace"
|
||||
slot_flags = SLOT_TIE
|
||||
|
||||
/obj/item/instrument/accordion/fluff/asmer_accordion //Asmerath: Coloratura
|
||||
name = "Rara's Somber Accordion"
|
||||
desc = "A blue colored accordion with claw indentations on the keys made special for vulpkanins."
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "asmer_accordion"
|
||||
item_state = "asmer_accordion"
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ var/list/event_last_fired = list()
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 5), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1),
|
||||
new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 0, is_one_shot = 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 180, is_one_shot = 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 0, list(ASSIGNMENT_SECURITY = 15), is_one_shot = 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Floor Cluwne", /datum/event/spawn_floor_cluwne, 15, is_one_shot = 1)
|
||||
|
||||
@@ -6,7 +6,7 @@ var/global/list/unused_trade_stations = list("sol")
|
||||
/datum/event/traders
|
||||
var/success_spawn = 0
|
||||
var/station = null
|
||||
var/spawn_count = 3
|
||||
var/spawn_count = 2
|
||||
var/list/trader_objectives = list()
|
||||
|
||||
/datum/event/traders/setup()
|
||||
@@ -16,6 +16,10 @@ var/global/list/unused_trade_stations = list("sol")
|
||||
/datum/event/traders/start()
|
||||
if(!station) // If there are no unused stations, just no.
|
||||
return
|
||||
if(seclevel2num(get_security_level()) >= SEC_LEVEL_RED)
|
||||
event_announcement.Announce("A trading shuttle from Jupiter Station has been denied docking permission due to the heightened security alert aboard [station_name()].", "Trader Shuttle Docking Request Refused")
|
||||
return
|
||||
|
||||
var/list/spawnlocs = list()
|
||||
for(var/obj/effect/landmark/landmark in GLOB.landmarks_list)
|
||||
if(landmark.name == "traderstart_[station]")
|
||||
@@ -35,6 +39,7 @@ var/global/list/unused_trade_stations = list("sol")
|
||||
var/turf/picked_loc = spawnlocs[index]
|
||||
index++
|
||||
var/mob/C = pick_n_take(candidates)
|
||||
spawn_count--
|
||||
if(C)
|
||||
GLOB.respawnable_list -= C.client
|
||||
var/mob/living/carbon/human/M = new /mob/living/carbon/human(picked_loc)
|
||||
@@ -44,7 +49,9 @@ var/global/list/unused_trade_stations = list("sol")
|
||||
M.mind.objectives += trader_objectives
|
||||
greet_trader(M)
|
||||
success_spawn = 1
|
||||
if(!success_spawn)
|
||||
if(success_spawn)
|
||||
event_announcement.Announce("A trading shuttle from Jupiter Station has been granted docking permission at [station_name()] arrivals port 4.", "Trader Shuttle Docking Request Accepted")
|
||||
else
|
||||
unused_trade_stations += station // Return the station to the list of usable stations.
|
||||
|
||||
/datum/event/traders/proc/greet_trader(var/mob/living/carbon/human/M)
|
||||
@@ -55,17 +62,14 @@ var/global/list/unused_trade_stations = list("sol")
|
||||
show_objectives(M.mind)
|
||||
|
||||
/datum/event/traders/proc/forge_trader_objectives()
|
||||
var/i = 1
|
||||
var/max_objectives = pick(2, 2, 2, 2, 3, 3, 3, 4)
|
||||
var/list/objs = list()
|
||||
var/list/goals = list("stockparts")
|
||||
while(i<= max_objectives)
|
||||
var/goal = pick(goals)
|
||||
var/datum/objective/trade/O
|
||||
if(goal == "stockparts")
|
||||
O = new /datum/objective/trade/stock(station)
|
||||
O.choose_target()
|
||||
objs += O
|
||||
|
||||
i++
|
||||
var/datum/objective/trade/plasma/P = new /datum/objective/trade/plasma
|
||||
P.choose_target()
|
||||
objs += P
|
||||
|
||||
var/datum/objective/trade/credits/C = new /datum/objective/trade/credits
|
||||
C.choose_target()
|
||||
objs += C
|
||||
|
||||
return objs
|
||||
|
||||
@@ -30,15 +30,19 @@
|
||||
if(!contains_sample)
|
||||
for(var/datum/reagent/blood/bloodSample in W.reagents.reagent_list)
|
||||
if(bloodSample.data["mind"] && bloodSample.data["cloneable"] == 1)
|
||||
mind = bloodSample.data["mind"]
|
||||
ckey = bloodSample.data["ckey"]
|
||||
realName = bloodSample.data["real_name"]
|
||||
blood_gender = bloodSample.data["gender"]
|
||||
blood_type = bloodSample.data["blood_type"]
|
||||
factions = bloodSample.data["factions"]
|
||||
W.reagents.clear_reagents()
|
||||
to_chat(user, "<span class='notice'>You inject the contents of the syringe into the seeds.</span>")
|
||||
contains_sample = 1
|
||||
var/datum/mind/tempmind = bloodSample.data["mind"]
|
||||
if(tempmind.is_revivable())
|
||||
mind = bloodSample.data["mind"]
|
||||
ckey = bloodSample.data["ckey"]
|
||||
realName = bloodSample.data["real_name"]
|
||||
blood_gender = bloodSample.data["gender"]
|
||||
blood_type = bloodSample.data["blood_type"]
|
||||
factions = bloodSample.data["factions"]
|
||||
W.reagents.clear_reagents()
|
||||
to_chat(user, "<span class='notice'>You inject the contents of the syringe into the seeds.</span>")
|
||||
contains_sample = 1
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The seeds reject the sample!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The seeds reject the sample!</span>")
|
||||
else
|
||||
@@ -80,6 +84,9 @@
|
||||
ckey_holder = M.ckey
|
||||
break
|
||||
|
||||
if(mind && !mind.is_revivable())
|
||||
make_podman = 0
|
||||
|
||||
if(make_podman) //all conditions met!
|
||||
var/mob/living/carbon/human/diona/podman = new /mob/living/carbon/human/diona(parent.loc)
|
||||
if(realName)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/obj/item/book/codex_gigas
|
||||
name = "Codex Gigas"
|
||||
icon_state ="demonomicon"
|
||||
throw_speed = 1
|
||||
throw_range = 10
|
||||
burn_state = LAVA_PROOF
|
||||
author = "Forces beyond your comprehension"
|
||||
unique = TRUE
|
||||
title = "The codex gigas"
|
||||
var/inUse = 0
|
||||
|
||||
|
||||
/obj/item/book/codex_gigas/attack_self(mob/user)
|
||||
if(!user.has_vision())
|
||||
return
|
||||
if(inUse)
|
||||
to_chat(user,"<span class='notice'>Someone else is reading it.</span>")
|
||||
return
|
||||
if(!user.is_literate())
|
||||
to_chat(user,"<span class='notice'>You don't know how to read.</span>")
|
||||
return
|
||||
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 the [title] down.</span>")
|
||||
return
|
||||
inUse = 1
|
||||
var/devilName = copytext(sanitize(input(user, "What infernal being do you wish to research?", "Codex Gigas", null) as text),1,MAX_MESSAGE_LEN)
|
||||
var/speed = 300
|
||||
var/correctness = 85
|
||||
var/willpower = 95
|
||||
if(U.job in list("Librarian")) // the librarian is both faster, and more accurate than normal crew members at research
|
||||
speed = 45
|
||||
correctness = 100
|
||||
willpower = 100
|
||||
if(U.job in list("Captain", "Security Officer", "Head of Security", "Detective", "Warden"))
|
||||
willpower = 99
|
||||
if(U.job in list("Clown")) // WHO GAVE THE CLOWN A DEMONOMICON? BAD THINGS WILL HAPPEN!
|
||||
willpower = 25
|
||||
correctness -= U.getBrainLoss() *0.5 //Brain damage makes researching hard.
|
||||
speed += U.getBrainLoss() * 3
|
||||
user.visible_message("[user] opens [title] and begins reading intently.")
|
||||
if(do_after(U, speed, 0, U))
|
||||
var/usedName = devilName
|
||||
if(!prob(correctness))
|
||||
usedName += "x"
|
||||
var/datum/devilinfo/devil = devilInfo(usedName, 0)
|
||||
user << browse("Information on [devilName]<br><br><br>[lawlorify[LORE][devil.ban]]<br>[lawlorify[LORE][devil.bane]]<br>[lawlorify[LORE][devil.obligation]]<br>[lawlorify[LORE][devil.banish]]", "window=book")
|
||||
inUse = 0
|
||||
sleep(10)
|
||||
if(!prob(willpower))
|
||||
U.influenceSin()
|
||||
onclose(user, "book")
|
||||
@@ -715,6 +715,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
else
|
||||
new_char.key = key
|
||||
|
||||
/mob/dead/observer/is_literate()
|
||||
return TRUE
|
||||
/mob/dead/observer/proc/open_spawners_menu()
|
||||
set name = "Mob spawners menu"
|
||||
set desc = "See all currently available ghost spawners"
|
||||
|
||||
@@ -10,3 +10,14 @@
|
||||
|
||||
/mob/proc/death(gibbed)
|
||||
return FALSE
|
||||
|
||||
/mob/proc/dust_animation()
|
||||
var/atom/movable/overlay/animation = null
|
||||
animation = new(loc)
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
|
||||
// flick("dust-m", animation)
|
||||
new /obj/effect/decal/cleanable/ash(loc)
|
||||
QDEL_IN(animation, 15)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/mob/living/carbon/alien/gib()
|
||||
if(!death(TRUE) && stat != DEAD)
|
||||
return FALSE
|
||||
death(1)
|
||||
var/atom/movable/overlay/animation = null
|
||||
notransform = 1
|
||||
@@ -17,30 +19,33 @@
|
||||
xgibs(loc)
|
||||
GLOB.dead_mob_list -= src
|
||||
|
||||
spawn(15)
|
||||
if(animation) qdel(animation)
|
||||
if(src) qdel(src)
|
||||
QDEL_IN(animation, 15)
|
||||
QDEL_IN(src, 15)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/alien/dust()
|
||||
death(1)
|
||||
var/atom/movable/overlay/animation = null
|
||||
if(!death(TRUE) && stat != DEAD)
|
||||
return FALSE
|
||||
notransform = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
dust_animation()
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
GLOB.dead_mob_list -= src
|
||||
QDEL_IN(src, 15)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/alien/dust_animation()
|
||||
var/atom/movable/overlay/animation = null
|
||||
animation = new(loc)
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
|
||||
flick("dust-a", animation)
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
GLOB.dead_mob_list -= src
|
||||
|
||||
spawn(15)
|
||||
if(animation) qdel(animation)
|
||||
if(src) qdel(src)
|
||||
QDEL_IN(animation, 15)
|
||||
|
||||
/mob/living/carbon/alien/death(gibbed)
|
||||
// Only execute the below if we successfully died
|
||||
|
||||
@@ -119,6 +119,9 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/gib()
|
||||
. = death(1)
|
||||
if(!.)
|
||||
return
|
||||
for(var/obj/item/organ/internal/I in internal_organs)
|
||||
if(isturf(loc))
|
||||
I.remove(src)
|
||||
@@ -130,7 +133,6 @@
|
||||
src.stomach_contents.Remove(M)
|
||||
M.forceMove(get_turf(src))
|
||||
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, override = 0, tesla_shock = 0)
|
||||
if(status_flags & GODMODE) //godmode
|
||||
@@ -356,11 +358,15 @@
|
||||
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>")
|
||||
if(mind && 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(mind && has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(0)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/tintcheck()
|
||||
|
||||
@@ -464,3 +464,12 @@
|
||||
valid_alt_heads += alternate_head
|
||||
|
||||
return valid_alt_heads
|
||||
|
||||
/mob/living/carbon/human/proc/scramble_appearance()
|
||||
scramble(1, src, 100)
|
||||
real_name = random_name(gender, dna.species.name) //Give them a name that makes sense for their species.
|
||||
sync_organ_dna(assimilate = 1)
|
||||
update_body(0)
|
||||
reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover.
|
||||
reset_markings() //...Or markings.
|
||||
dna.ResetUIFrom(src)
|
||||
|
||||
@@ -50,11 +50,16 @@
|
||||
/mob/living/carbon/human/dust()
|
||||
if(!death(TRUE) && stat != DEAD)
|
||||
return FALSE
|
||||
var/atom/movable/overlay/animation = null
|
||||
notransform = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
dust_animation()
|
||||
QDEL_IN(src, 15)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/dust_animation()
|
||||
var/atom/movable/overlay/animation = null
|
||||
|
||||
animation = new(loc)
|
||||
animation.icon_state = "blank"
|
||||
@@ -63,7 +68,6 @@
|
||||
|
||||
flick("dust-h", animation)
|
||||
new dna.species.remains_type(get_turf(src))
|
||||
QDEL_IN(src, 0)
|
||||
QDEL_IN(animation, 15)
|
||||
return TRUE
|
||||
|
||||
@@ -88,9 +92,6 @@
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/death(gibbed)
|
||||
if(can_die() && !gibbed)
|
||||
emote("deathgasp") //let the world KNOW WE ARE DEAD
|
||||
|
||||
// Only execute the below if we successfully died
|
||||
. = ..(gibbed)
|
||||
if(!.)
|
||||
@@ -176,3 +177,12 @@
|
||||
ChangeToHusk()
|
||||
mutations |= NOCLONE
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/cure_husk()
|
||||
mutations.Remove(HUSK)
|
||||
var/obj/item/organ/external/head/H = bodyparts_by_name["head"]
|
||||
if(istype(H))
|
||||
H.disfigured = FALSE
|
||||
update_body(0)
|
||||
update_mutantrace(0)
|
||||
UpdateAppearance() // reset hair from DNA
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
voice_name = "unknown"
|
||||
icon = 'icons/mob/human.dmi'
|
||||
icon_state = "body_m_s"
|
||||
deathgasp_on_death = TRUE
|
||||
var/obj/item/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
|
||||
|
||||
/mob/living/carbon/human/New(loc)
|
||||
@@ -733,7 +734,7 @@
|
||||
found_record = 1
|
||||
if(R.fields["criminal"] == "*Execute*")
|
||||
to_chat(usr, "<span class='warning'>Unable to modify the sec status of a person with an active Execution order. Use a security computer instead.</span>")
|
||||
else
|
||||
else
|
||||
var/rank
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/U = usr
|
||||
@@ -1179,7 +1180,6 @@
|
||||
restore_all_organs() //Rejuvenate and reset all existing organs.
|
||||
check_and_regenerate_organs(src) //Regenerate limbs and organs only if they're really missing.
|
||||
surgeries.Cut() //End all surgeries.
|
||||
update_revive()
|
||||
|
||||
if(!isskeleton(src) && (SKELETON in mutations))
|
||||
mutations.Remove(SKELETON)
|
||||
@@ -1942,3 +1942,53 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
/mob/living/carbon/human/proc/special_post_clone_handling()
|
||||
if(mind && mind.assigned_role == "Cluwne") //HUNKE your suffering never stops
|
||||
makeCluwne()
|
||||
|
||||
/mob/living/carbon/human/proc/influenceSin()
|
||||
var/datum/objective/sintouched/O
|
||||
switch(rand(1,7))//traditional seven deadly sins... except lust.
|
||||
if(1) // acedia
|
||||
log_game("[src] was influenced by the sin of Acedia.")
|
||||
O = new /datum/objective/sintouched/acedia
|
||||
if(2) // Gluttony
|
||||
log_game("[src] was influenced by the sin of gluttony.")
|
||||
O = new /datum/objective/sintouched/gluttony
|
||||
if(3) // Greed
|
||||
log_game("[src] was influenced by the sin of greed.")
|
||||
O = new /datum/objective/sintouched/greed
|
||||
if(4) // sloth
|
||||
log_game("[src] was influenced by the sin of sloth.")
|
||||
O = new /datum/objective/sintouched/sloth
|
||||
if(5) // Wrath
|
||||
log_game("[src] was influenced by the sin of wrath.")
|
||||
O = new /datum/objective/sintouched/wrath
|
||||
if(6) // Envy
|
||||
log_game("[src] was influenced by the sin of envy.")
|
||||
O = new /datum/objective/sintouched/envy
|
||||
if(7) // Pride
|
||||
log_game("[src] was influenced by the sin of pride.")
|
||||
O = new /datum/objective/sintouched/pride
|
||||
ticker.mode.sintouched += src.mind
|
||||
src.mind.objectives += O
|
||||
var/obj_count = 1
|
||||
to_chat(src, "<span class='notice> Your current objectives:")
|
||||
for(var/datum/objective/objective in src.mind.objectives)
|
||||
to_chat(src, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
|
||||
obj_count++
|
||||
|
||||
/mob/living/carbon/human/is_literate()
|
||||
return getBrainLoss() < 100
|
||||
|
||||
|
||||
/mob/living/carbon/human/fakefire(var/fire_icon = "Generic_mob_burning")
|
||||
if(!overlays_standing[FIRE_LAYER])
|
||||
overlays_standing[FIRE_LAYER] = image("icon"=fire_dmi, "icon_state"=fire_icon)
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/human/fakefireextinguish()
|
||||
overlays_standing[FIRE_LAYER] = null
|
||||
update_icons()
|
||||
/mob/living/carbon/human/proc/cleanSE() //remove all disabilities/powers
|
||||
for(var/block = 1; block <= DNA_SE_LENGTH; block++)
|
||||
dna.SetSEState(block, FALSE, TRUE)
|
||||
genemutcheck(src, block, null, MUTCHK_FORCED)
|
||||
dna.UpdateSE()
|
||||
|
||||
@@ -224,6 +224,8 @@ emp_act
|
||||
|
||||
send_item_attack_message(I, user, hit_area)
|
||||
|
||||
var/weakness = check_weakness(I,user)
|
||||
|
||||
if(!I.force)
|
||||
return 0 //item force is zero
|
||||
|
||||
@@ -231,12 +233,11 @@ emp_act
|
||||
var/weapon_sharp = is_sharp(I)
|
||||
if(weapon_sharp && prob(getarmor(user.zone_sel.selecting, "melee")))
|
||||
weapon_sharp = 0
|
||||
|
||||
if(armor >= 100)
|
||||
return 0
|
||||
var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
|
||||
apply_damage(I.force, I.damtype, affecting, armor, sharp = weapon_sharp, used_weapon = I)
|
||||
apply_damage(I.force * weakness, I.damtype, affecting, armor, sharp = weapon_sharp, used_weapon = I)
|
||||
|
||||
var/bloody = 0
|
||||
if(I.damtype == BRUTE && I.force && prob(25 + I.force * 2))
|
||||
|
||||
@@ -321,7 +321,7 @@
|
||||
if(put_in_active_hand(W)) return 1
|
||||
else if(put_in_inactive_hand(W)) return 1
|
||||
else
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
// Return the item currently in the slot ID
|
||||
/mob/living/carbon/human/get_item_by_slot(slot_id)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN)
|
||||
clothing_flags = HAS_SOCKS
|
||||
default_hair_colour = "#000000"
|
||||
has_gender = FALSE
|
||||
dietflags = 0 //Diona regenerate nutrition in light and water, no diet necessary
|
||||
taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE
|
||||
skinned_type = /obj/item/stack/sheet/wood
|
||||
@@ -110,4 +111,4 @@
|
||||
H.adjustFireLoss(-(light_amount/4))
|
||||
if(H.nutrition < NUTRITION_LEVEL_STARVING+50)
|
||||
H.take_overall_damage(10,0)
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
species_traits = list(LIPS, IS_WHITELISTED)
|
||||
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT
|
||||
bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS
|
||||
has_gender = FALSE
|
||||
dietflags = DIET_OMNI
|
||||
|
||||
cold_level_1 = -1 //Default 260 - Lower is better
|
||||
@@ -59,4 +60,4 @@
|
||||
"metabolic strainer" = /obj/item/organ/internal/liver/drask,
|
||||
"eyes" = /obj/item/organ/internal/eyes/drask, //5 darksight.
|
||||
"brain" = /obj/item/organ/internal/brain/drask
|
||||
)
|
||||
)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
|
||||
bodyflags = HAS_BODY_MARKINGS
|
||||
dietflags = DIET_HERB
|
||||
has_gender = FALSE
|
||||
reagent_tag = PROCESS_ORG
|
||||
blood_color = "#A200FF"
|
||||
|
||||
@@ -57,4 +58,4 @@
|
||||
if(R.id == "sacid")
|
||||
H.reagents.del_reagent(R.id)
|
||||
return 0
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
flesh_color = "#808D11"
|
||||
//Default styles for created mobs.
|
||||
default_hair = "Short Vox Quills"
|
||||
has_gender = FALSE
|
||||
default_hair_colour = "#614f19" //R: 97, G: 79, B: 25
|
||||
butt_sprite = "vox"
|
||||
|
||||
@@ -201,4 +202,4 @@
|
||||
"is huffing oxygen!")
|
||||
|
||||
/datum/species/vox/armalis/handle_reagents() //Skip the Vox oxygen reagent toxicity. Armalis are above such things.
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
SetJitter(0)
|
||||
SetLoseBreath(0)
|
||||
|
||||
if(!gibbed && deathgasp_on_death)
|
||||
emote("deathgasp")
|
||||
|
||||
if(suiciding)
|
||||
mind.suicided = TRUE
|
||||
clear_fullscreens()
|
||||
@@ -86,6 +89,8 @@
|
||||
|
||||
if(ticker && ticker.mode)
|
||||
ticker.mode.check_win()
|
||||
if(mind && mind.devilinfo) // Expand this into a general-purpose death-response system when appropriate
|
||||
mind.devilinfo.beginResurrectionCheck(src)
|
||||
|
||||
// u no we dead
|
||||
return TRUE
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if(notransform)
|
||||
return
|
||||
return 0
|
||||
if(!loc)
|
||||
return
|
||||
return 0
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
if(stat != DEAD)
|
||||
|
||||
@@ -940,3 +940,38 @@
|
||||
return
|
||||
|
||||
to_chat(src, "<span class='notice'>You can taste [english_list(final_taste_list)].</span>")
|
||||
|
||||
/mob/living/proc/owns_soul()
|
||||
if(mind)
|
||||
return mind.soulOwner == mind
|
||||
return 1
|
||||
|
||||
/mob/living/proc/return_soul()
|
||||
if(mind)
|
||||
if(mind.soulOwner.devilinfo)//Not sure how this could happen, but whatever.
|
||||
mind.soulOwner.devilinfo.remove_soul(mind)
|
||||
mind.soulOwner = mind
|
||||
mind.damnation_type = 0
|
||||
|
||||
/mob/living/proc/has_bane(banetype)
|
||||
if(mind)
|
||||
if(mind.devilinfo)
|
||||
return mind.devilinfo.bane == banetype
|
||||
return 0
|
||||
|
||||
/mob/living/proc/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
if(mind && mind.devilinfo)
|
||||
return check_devil_bane_multiplier(weapon, attacker)
|
||||
return 1
|
||||
|
||||
/mob/living/proc/check_acedia()
|
||||
if(src.mind && src.mind.objectives)
|
||||
for(var/datum/objective/sintouched/acedia/A in src.mind.objectives)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/proc/fakefireextinguish()
|
||||
return
|
||||
|
||||
/mob/living/proc/fakefire()
|
||||
return
|
||||
|
||||
@@ -66,3 +66,5 @@
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,SPECIALROLE_HUD)
|
||||
|
||||
var/list/status_effects //a list of all status effects the mob has
|
||||
|
||||
var/deathgasp_on_death = FALSE
|
||||
|
||||
@@ -22,22 +22,23 @@
|
||||
if(src) qdel(src)
|
||||
|
||||
/mob/living/silicon/dust()
|
||||
death(1)
|
||||
var/atom/movable/overlay/animation = null
|
||||
if(!death(TRUE) && stat != DEAD)
|
||||
return FALSE
|
||||
notransform = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
dust_animation()
|
||||
GLOB.dead_mob_list -= src
|
||||
QDEL_IN(src, 15)
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/dust_animation()
|
||||
//hmmm
|
||||
var/atom/movable/overlay/animation = null
|
||||
|
||||
animation = new(loc)
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
|
||||
// flick("dust-r", animation)
|
||||
new /obj/effect/decal/remains/robot(loc)
|
||||
|
||||
GLOB.dead_mob_list -= src
|
||||
spawn(15)
|
||||
if(animation) qdel(animation)
|
||||
if(src) qdel(src)
|
||||
QDEL_IN(animation, 15)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user