Devil agent (#19391)

add: Added Devil agent gamemode, where multiple devils are each trying to buy more souls than the next in line.
add: If you've already sold your soul, you can sell it again to a different devil. You can even go back and forth for INFINITE POWER.

This adds a new gamemode. Devil Agent. It works much like Double Agent, except devils instead of traitors, and instead of killing, the devil simply has to control more souls than the enemy.

Also, whether this is included in the rotation depends on the config settings. By default, it will be disabled.
This commit is contained in:
lordpidey
2016-07-31 01:02:21 -04:00
committed by oranges
parent b01460c2bf
commit ec2f666f29
16 changed files with 338 additions and 162 deletions

View File

@@ -1197,7 +1197,9 @@
ticker.mode.devils += src
special_role = "devil"
ticker.mode.finalize_devil(src)
ticker.mode.add_devil_objectives(src, 2)
announceDevilLaws()
announce_objectives()
if("sintouched")
if(ishuman(current))
ticker.mode.sintouched += src

View File

@@ -0,0 +1,43 @@
/datum/game_mode/devil/devil_agents
name = "Devil Agents"
config_tag = "devil_agents"
required_players = 25
required_enemies = 3
recommended_enemies = 8
reroll_friendly = 0
traitors_possible = 10 //hard limit on traitors if scaling is turned off
num_modifier = 4
objective_count = 2
var/list/target_list = list()
var/list/late_joining_list = list()
minimum_devils = 3
announce_text = "There are devil agents onboard the station, trying to outbid each other!\n\
+ <span class='danger'>Devils</span>: Purchase souls and interfere with your rivals!\n\
+ <span class='notice'>Crew</span>: Resist the lure of sin and remain pure!"
/datum/game_mode/devil/devil_agents/post_setup()
var/i = 0
for(var/datum/mind/devil in devils)
i++
if(i + 1 > devils.len)
i = 0
target_list[devil] = devils[i + 1]
..()
/datum/game_mode/devil/devil_agents/add_devil_objectives(datum/mind/devil_mind, quantity)
..(devil_mind, quantity - give_outsell_objective(devil_mind))
/datum/game_mode/devil/devil_agents/proc/give_outsell_objective(datum/mind/devil)
//If you override this method, have it return the number of objectives added.
if(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

View File

@@ -1,111 +1,61 @@
/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>"
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>"
world << text
/datum/game_mode/devil
name = "devil"
config_tag = "devil"
antag_flag = ROLE_DEVIL
protected_jobs = list("Lawyer", "Librarian", "Chaplain", "Head of Security", "Captain", "AI")
required_players = 0
required_enemies = 1
recommended_enemies = 4
reroll_friendly = 1
enemy_minimum_age = 0
var/traitors_possible = 4 //hard limit on devils if scaling is turned off
var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual.
var/objective_count = 2
var/minimum_devils = 1
announce_text = "There are devils onboard the station!\n\
+ <span class='danger'>Devils</span>: Purchase souls and tempt the crew to sin!\n\
+ <span class='notice'>Crew</span>: Resist the lure of sin and remain pure!"
/datum/game_mode/devil/pre_setup()
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
restricted_jobs += "Assistant"
var/num_devils = 1
if(config.traitor_scaling_coeff)
num_devils = max(minimum_devils, min( round(num_players()/(config.traitor_scaling_coeff*3))+ 2 + num_modifier, round(num_players()/(config.traitor_scaling_coeff*1.5)) + num_modifier ))
else
num_devils = max(minimum_devils, min(num_players(), traitors_possible))
for(var/j = 0, j < num_devils, j++)
if (!antag_candidates.len)
break
var/datum/mind/devil = pick(antag_candidates)
devils += devil
devil.special_role = traitor_name
devil.restricted_roles = restricted_jobs
log_game("[devil.key] (ckey) has been selected as a [traitor_name]")
antag_candidates.Remove(devil)
if(devils.len < required_enemies)
return 0
return 1
/datum/game_mode/proc/finalize_devil(datum/mind/devil_mind)
var/mob/living/carbon/human/S = devil_mind.current
var/trueName= randomDevilName()
var/datum/objective/devil/soulquantity/soulquant = new
soulquant.owner = devil_mind
var/datum/objective/devil/obj_2 = pick(new /datum/objective/devil/soulquality(null), new /datum/objective/devil/sintouch(null))
obj_2.owner = devil_mind
devil_mind.objectives += obj_2
devil_mind.objectives += soulquant
devil_mind.devilinfo = devilInfo(trueName, 1)
devil_mind.store_memory("Your devilic 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.owner = devil_mind
devil_mind.devilinfo.give_base_spells(1)
spawn(10)
devil_mind.devilinfo.update_hud()
if(devil_mind.assigned_role == "Clown")
S << "<span class='notice'>Your infernal nature has allowed you to overcome your clownishness.</span>"
S.dna.remove_mutation(CLOWNMUT)
/datum/mind/proc/announceDevilLaws()
if(!devilinfo)
return
current << "<span class='warning'><b>You remember your link to the infernal. You are [src.devilinfo.truename], an agent of hell, a devil. And you were sent to the plane of creation for a reason. A greater purpose. Convince the crew to sin, and embroiden Hell's grasp.</b></span>"
current << "<span class='warning'><b>However, your infernal form is not without weaknesses.</b></span>"
current << "You may not use violence to coerce someone into selling their soul."
current << "You may not directly and knowingly physically harm a devil, other than yourself."
current << lawlorify[LAW][src.devilinfo.bane]
current << lawlorify[LAW][src.devilinfo.ban]
current << lawlorify[LAW][src.devilinfo.obligation]
current << lawlorify[LAW][src.devilinfo.banish]
current << "<br/><br/><span class='warning'>Remember, the crew can research your weaknesses if they find out your devil name.</span><br>"
var/obj_count = 1
current << "<span class='notice'>Your current objectives:</span>"
for(var/O in objectives)
var/datum/objective/objective = O
current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
/datum/game_mode/proc/printdevilinfo(datum/mind/ply)
if(!ply.devilinfo)
return ""
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>"
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, "devil")
/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)
/datum/game_mode/proc/update_sintouch_icons_added(datum/mind/sin_mind)
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SINTOUCHED]
hud.join_hud(sin_mind.current)
set_antag_hud(sin_mind.current, "sintouched")
/datum/game_mode/proc/update_sintouch_icons_removed(datum/mind/sin_mind)
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SINTOUCHED]
hud.leave_hud(sin_mind.current)
set_antag_hud(sin_mind.current, null)
/datum/game_mode/proc/update_soulless_icons_added(datum/mind/soulless_mind)
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SOULLESS]
hud.join_hud(soulless_mind.current)
set_antag_hud(soulless_mind.current, "soulless")
/datum/game_mode/proc/update_soulless_icons_removed(datum/mind/soulless_mind)
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SOULLESS]
hud.leave_hud(soulless_mind.current)
set_antag_hud(soulless_mind.current, null)
/datum/game_mode/devil/post_setup()
for(var/datum/mind/devil in devils)
spawn(rand(10,100))
finalize_devil(devil, objective_count)
spawn(100)
add_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.announceDevilLaws()
devil.announce_objectives()
modePlayer += devils
..()
return 1

View File

@@ -7,6 +7,8 @@
#define TRUE_DEVIL 2
#define ARCH_DEVIL 3
#define LOSS_PER_DEATH 2
#define SOULVALUE soulsOwned.len-reviveNumber
#define DEVILRESURRECTTIME 600
@@ -164,14 +166,14 @@ var/global/list/lawlorify = list (
/datum/devilinfo/proc/check_regression()
if(form == ARCH_DEVIL)
return //arch devil can't regress
switch(SOULVALUE)
if(-1)
//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()
owner.current << "<span class='warning'>As punishment for your failures, all of your powers except contract creation have been revoked."
if(BLOOD_THRESHOLD-1)
regress_humanoid()
if(TRUE_THRESHOLD-1)
regress_blood_lizard()
/datum/devilinfo/proc/increase_form()
switch(form)
@@ -386,7 +388,7 @@ var/global/list/lawlorify = list (
/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) // once ascended, arch devils do not go down in power by any means.
reviveNumber++
reviveNumber += LOSS_PER_DEATH
update_hud()
if(body)
body.revive(1,0)

View File

@@ -0,0 +1,111 @@
/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>"
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>"
world << text
/datum/game_mode/proc/finalize_devil(datum/mind/devil_mind)
var/mob/living/carbon/human/S = devil_mind.current
var/trueName= randomDevilName()
devil_mind.devilinfo = devilInfo(trueName, 1)
devil_mind.store_memory("Your devilic 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.owner = devil_mind
devil_mind.devilinfo.give_base_spells(1)
spawn(10)
devil_mind.devilinfo.update_hud()
if(devil_mind.assigned_role == "Clown")
S << "<span class='notice'>Your infernal nature has allowed you to overcome your clownishness.</span>"
S.dna.remove_mutation(CLOWNMUT)
/datum/game_mode/proc/add_devil_objectives(datum/mind/devil_mind, quantity)
var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target)
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/mind/proc/announceDevilLaws()
if(!devilinfo)
return
current << "<span class='warning'><b>You remember your link to the infernal. You are [src.devilinfo.truename], an agent of hell, a devil. And you were sent to the plane of creation for a reason. A greater purpose. Convince the crew to sin, and embroiden Hell's grasp.</b></span>"
current << "<span class='warning'><b>However, your infernal form is not without weaknesses.</b></span>"
current << "You may not use violence to coerce someone into selling their soul."
current << "You may not directly and knowingly physically harm a devil, other than yourself."
current << lawlorify[LAW][src.devilinfo.bane]
current << lawlorify[LAW][src.devilinfo.ban]
current << lawlorify[LAW][src.devilinfo.obligation]
current << lawlorify[LAW][src.devilinfo.banish]
current << "<br/><br/><span class='warning'>Remember, the crew can research your weaknesses if they find out your devil name.</span><br>"
/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, "devil")
/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)
/datum/game_mode/proc/update_sintouch_icons_added(datum/mind/sin_mind)
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SINTOUCHED]
hud.join_hud(sin_mind.current)
set_antag_hud(sin_mind.current, "sintouched")
/datum/game_mode/proc/update_sintouch_icons_removed(datum/mind/sin_mind)
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SINTOUCHED]
hud.leave_hud(sin_mind.current)
set_antag_hud(sin_mind.current, null)
/datum/game_mode/proc/update_soulless_icons_added(datum/mind/soulless_mind)
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SOULLESS]
hud.join_hud(soulless_mind.current)
set_antag_hud(soulless_mind.current, "soulless")
/datum/game_mode/proc/update_soulless_icons_removed(datum/mind/soulless_mind)
var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SOULLESS]
hud.leave_hud(soulless_mind.current)
set_antag_hud(soulless_mind.current, null)

View File

@@ -3,29 +3,33 @@
/datum/objective/devil/soulquantity
explanation_text = "You shouldn't see this text. Error:DEVIL1"
var/quantity = 4
target_amount = 4
/datum/objective/devil/soulquantity/New()
quantity = pick(6,8)
explanation_text = "Purchase, and retain control over at least [quantity] souls."
target_amount = pick(6,7,8)
update_explanation_text()
/datum/objective/devil/soulquantity/update_explanation_text()
explanation_text = "Purchase, and retain control over at least [target_amount] souls."
/datum/objective/devil/soulquantity/check_completion()
var/count = 0
for(var/S in owner.devilinfo.soulsOwned)
var/datum/mind/L = S
if(L.soulOwner != L)
if(L.soulOwner == owner)
count++
return count >= quantity
return count >= target_amount
/datum/objective/devil/soulquality
explanation_text = "You shouldn't see this text. Error:DEVIL2"
var/contractType
var/quantity
var/contractName
/datum/objective/devil/soulquality/New()
contractType = pick(CONTRACT_POWER, CONTRACT_WEALTH, CONTRACT_PRESTIGE, CONTRACT_MAGIC, CONTRACT_REVIVE, CONTRACT_KNOWLEDGE/*, CONTRACT_UNWILLING*/)
var/contractName
quantity = pick(1,2)
target_amount = pick(1,2)
switch(contractType)
if(CONTRACT_POWER)
contractName = "for power"
@@ -41,7 +45,10 @@
contractName = "for knowledge"
//if(CONTRACT_UNWILLING) //Makes round unfun.
// contractName = "against their will"
explanation_text = "Have mortals sign at least [quantity] contracts [contractName]"
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
@@ -49,14 +56,52 @@
var/datum/mind/L = S
if(L.soulOwner != L && L.damnation_type == contractType)
count++
return count>=quantity
return count>=target_amount
/datum/objective/devil/sintouch
var/quantity
explanation_text = "You shouldn't see this text. Error:DEVIL3"
/datum/objective/devil/sintouch/New()
quantity = pick(4,5)
explanation_text = "Ensure at least [quantity] mortals are sintouched."
target_amount = pick(4,5)
explanation_text = "Ensure at least [target_amount] mortals are sintouched."
/datum/objective/devil/sintouch/check_completion()
return quantity>=ticker.mode.sintouched.len
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/update_explanation_text()
if(target)
explanation_text = "Purchase and retain the soul of [target.name], the [target.assigned_role]."
else
explanation_text = "Free objective."
/datum/objective/devil/buy_target/check_completion()
return target.soulOwner == owner
/datum/objective/devil/outsell
explanation_text = "You shouldn't see this text. Error:DEVIL5"
/datum/objective/devil/outsell/New()
/datum/objective/devil/outsell/update_explanation_text()
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

View File

@@ -12,7 +12,7 @@
health = 350
maxHealth = 350
ventcrawler = 0
density = 0
density = 1
pass_flags = 0
var/ascended = 0
sight = (SEE_TURFS | SEE_OBJS)
@@ -45,6 +45,7 @@
/mob/living/carbon/true_devil/Login()
..()
mind.announceDevilLaws()
mind.announce_objectives()
/mob/living/carbon/true_devil/death(gibbed)

View File

@@ -703,7 +703,7 @@ var/global/BSACooldown = 0
if(!ai_number)
usr << "<b>No AIs located</b>" //Just so you know the thing is actually working and not just ignoring you.
/datum/admins/proc/output_devil_info()
/datum/admins/proc/output_all_devil_info()
var/devil_number = 0
for(var/D in ticker.mode.devils)
devil_number++
@@ -711,6 +711,12 @@ var/global/BSACooldown = 0
if(!devil_number)
usr << "<b>No Devils located</b>" //Just so you know the thing is actually working and not just ignoring you.
/datum/admins/proc/output_devil_info(mob/living/M)
if(istype(M) && M.mind && M.mind.devilinfo)
usr << ticker.mode.printdevilinfo(M.mind)
else
usr << "<b>[M] is not a devil."
/datum/admins/proc/manage_free_slots()
if(!check_rights())
return

View File

@@ -1621,7 +1621,8 @@
output_ai_laws()
else if(href_list["admincheckdevilinfo"])
output_devil_info()
var/mob/M = locate(href_list["admincheckdevilinfo"])
output_devil_info(M)
else if(href_list["adminmoreinfo"])
var/mob/M = locate(href_list["adminmoreinfo"])

View File

@@ -33,7 +33,9 @@
var/mob/living/carbon/human/devil = create_event_devil(spawn_loc)
Mind.transfer_to(devil)
ticker.mode.finalize_devil(Mind)
ticker.mode.add_devil_objectives(src, 2)
Mind.announceDevilLaws()
Mind.announce_objectives()
spawned_mobs += devil

View File

@@ -1062,12 +1062,7 @@
O = new /datum/objective/sintouched/pride
ticker.mode.sintouched += src.mind
src.mind.objectives += O
var/obj_count = 1
src << "<span class='notice'>Your current objectives:</span>"
for(O in src.mind.objectives)
var/datum/objective/objective = O
src << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
src.mind.announce_objectives()
/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
. = ..()

View File

@@ -1036,7 +1036,10 @@ Sorry Giacom. Please don't be mad :(
return 1
/mob/living/proc/return_soul()
hellbound = 0
if(mind)
if(mind.soulOwner.devilinfo)//Not sure how this could happen, but whatever.
mind.soulOwner.devilinfo.remove_soul(mind)
mind.soulOwner = mind
/mob/living/proc/has_bane(banetype)

View File

@@ -3,7 +3,7 @@
/obj/item/weapon/paper/contract
throw_range = 3
throw_speed = 3
var/signed = 0
var/signed = FALSE
var/datum/mind/target
flags = NOBLUDGEON
@@ -107,7 +107,7 @@
..()
/obj/item/weapon/paper/contract/infernal/update_text()
info = "This shouldn't be seen. Error DEVIL:5"
info = "This shouldn't be seen. Error DEVIL:6"
/obj/item/weapon/paper/contract/infernal/power/update_text(var/signature = "____________")
info = "<center><B>Contract for infernal power</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [owner.devilinfo.truename], in exchange for power and physical strength. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, <i>[signature]</i>"
@@ -143,25 +143,28 @@
/obj/item/weapon/paper/contract/infernal/attack(mob/M, mob/living/user)
add_fingerprint(user)
if(M == user && target == M.mind && M.mind.soulOwner == M.mind && attempt_signature(user))
if(M == user && target == M.mind && M.mind.soulOwner != owner && attempt_signature(user))
user.visible_message("<span class='danger'>[user] slices their wrist with [src], and scrawls their name in blood.</span>", "<span class='danger'>You slice your wrist open and scrawl your name in blood.</span>")
user.blood_volume = max(user.blood_volume - 10, 0)
else
return ..()
/obj/item/weapon/paper/contract/infernal/proc/attempt_signature(mob/living/carbon/human/user)
if(user.IsAdvancedToolUser())
if(user.IsAdvancedToolUser() && user.is_literate())
if(user.mind == target)
if(user.mind.soulOwner == user.mind)
if(user.mind.soulOwner != owner)
if (contractType == CONTRACT_REVIVE)
user << "<span class='notice'>You are already alive, this contract would do nothing.</span>"
else
if(signed)
user<< "<span class='notice'>This contract has already been signed. It may not be signed again.</span>"
else
user << "<span class='notice'>You quickly scrawl your name on the contract</span>"
if(FulfillContract()<=0)
user << "<span class='notice'>But it seemed to have no effect, perhaps even Hell itself cannot grant this boon?</span>"
return 1
else
user << "<span class='notice'>You are not in possession of your soul, you may not sell it.</span>"
user << "<span class='notice'>This devil already owns your soul, you may not sell it to them again.</span>"
else
user << "<span class='notice'>Your signature simply slides off the sheet, it seems this contract is not meant for you to sign.</span>"
else
@@ -196,6 +199,8 @@
/obj/item/weapon/paper/contract/infernal/proc/FulfillContract(mob/living/carbon/human/user = target.current)
signed = 1
if(user.mind.soulOwner != user.mind) //They already sold their soul to someone else?
user.mind.soulOwner.devilinfo.remove_soul(user.mind) //Then they lose their claim.
user.mind.soulOwner = owner
user.hellbound = contractType
user.mind.damnation_type = contractType

View File

@@ -108,12 +108,17 @@
if(istype(user))
if(istype(user.loc, /obj/effect/dummy/slaughter/))
var/continuing = 0
for(var/mob/living/C in orange(2, get_turf(user.loc)))
if(istype(get_area(user), /area/shuttle/)) // Can always phase in in a shuttle.
continuing = 1
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 = 1
break
if(continuing)
addtimer(user,"infernalphasein",150,TRUE)
user << "<span class='warning'>You are now phasing in.</span>"
if(do_mob(user,user,150))
user.infernalphasein()
else
user << "<span class='warning'>You can only re-appear near a potential signer."
revert_cast()
@@ -122,21 +127,22 @@
user.notransform = 1
user.fakefire()
src << "<span class='warning'>You begin to phase back into sinful flames.</span>"
addtimer(user, "infernalphaseout",150,TRUE,get_turf(user))
if(do_mob(user,user,150))
user.infernalphaseout()
else
user << "<span class='warning'>You must remain still while exiting.</span>"
user.ExtinguishMob()
start_recharge()
return
revert_cast()
/mob/living/proc/infernalphaseout(var/turf/mobloc)
if(get_turf(src) != mobloc)
src << "<span class='warning'>You must remain still while exiting."
return
/mob/living/proc/infernalphaseout()
dust_animation()
spawn_dust()
src.visible_message("<span class='warning'>[src] disappears in a flashfire!</span>")
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc)
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,loc)
src.ExtinguishMob()
if(buckled)
buckled.unbuckle_mob(src,force=1)

View File

@@ -96,6 +96,8 @@ PROBABILITY RAGINMAGES 2
PROBABILITY MONKEY 0
PROBABILITY METEOR 0
PROBABILITY EXTENDED 0
PROBABILITY DEVIL 0
PROBABILITY DEVIL_AGENTS 0
## You probably want to keep sandbox off by default for secret and random.
PROBABILITY SANDBOX 0

View File

@@ -343,7 +343,9 @@
#include "code\game\gamemodes\devil\devil.dm"
#include "code\game\gamemodes\devil\devil_game_mode.dm"
#include "code\game\gamemodes\devil\devilinfo.dm"
#include "code\game\gamemodes\devil\game_mode.dm"
#include "code\game\gamemodes\devil\objectives.dm"
#include "code\game\gamemodes\devil\devil agent\devil_agent.dm"
#include "code\game\gamemodes\devil\imp\imp.dm"
#include "code\game\gamemodes\devil\true_devil\_true_devil.dm"
#include "code\game\gamemodes\devil\true_devil\inventory.dm"