Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Devil wears a suit and tie #8874

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 19 additions & 0 deletions code/game/gamemodes/devil/objectives.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,19 @@
target_amount = pick(6,7,8)
update_explanation_text()

ToGWtF marked this conversation as resolved.
Show resolved Hide resolved
/datum/objective/devil/lessersoulquantity
explanation_text = "You shouldn't see this text. Error:DEVIL6"

/datum/objective/devil/lessersoulquantity/New()
target_amount = pick(2,3,4,5)
update_explanation_text()
ToGWtF marked this conversation as resolved.
Show resolved Hide resolved

/datum/objective/devil/soulquantity/update_explanation_text()
explanation_text = "Purchase, and retain control over at least [target_amount] souls."

/datum/objective/devil/lessersoulquantity/update_explanation_text()
explanation_text = "Purchase, and retain control over at least [target_amount] souls."

/datum/objective/devil/soulquantity/check_completion()
ToGWtF marked this conversation as resolved.
Show resolved Hide resolved
var/count = 0
var/datum/antagonist/devil/devilDatum = owner.has_antag_datum(/datum/antagonist/devil)
Expand All @@ -21,6 +31,15 @@
count++
return count >= target_amount

/datum/objective/devil/lessersoulquantity/check_completion()
var/count = 0
var/datum/antagonist/devil/devilDatum = owner.has_antag_datum(/datum/antagonist/devil)
var/list/souls = devilDatum.soulsOwned
for(var/S in souls) //Just a sanity check.
var/datum/mind/L = S
if(L.soulOwner == owner)
count++
return count >= target_amount


/datum/objective/devil/soulquality
Expand Down
65 changes: 64 additions & 1 deletion code/modules/antagonists/devil/devil.dm
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,27 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/obj/effect/proc_holder/spell/targeted/conjure_item/violin,
/obj/effect/proc_holder/spell/targeted/summon_dancefloor))
var/ascendable = FALSE
// Gives devils an obsession, so they cant just offer powers to anyone.
// Hopefully reduces graytide by making devils hand select who they offer to, instead of just the first person they see.
var/species_obsession = list(
"humans" = 2,
"felinids" = 3,
"podpeople" = 3,
"plasmamen",
"moths" = 2,
"lizards" = 3,
"preternis" = 2,
"ethereals"
)
// Humans less likely to add difficulty, Lizards and cabbages and cats most likely, moths and preternis even with humans
// then ethereals and plasmamen last because they are less likely.
var/bloodtype_obsession = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L")
var/gender_obsession = list("male", "female")
var/age_obsession = list("16 to 30", "30 and up")
var/obsession
var/actual_obsession
var/actual_obsession_text


/datum/antagonist/devil/can_be_owned(datum/mind/new_owner)
. = ..()
Expand Down Expand Up @@ -174,6 +195,29 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/proc/randomdevilbanish()
return pick(BANISH_WATER, BANISH_COFFIN, BANISH_FORMALDYHIDE, BANISH_RUNES, BANISH_CANDLES, BANISH_DESTRUCTION, BANISH_FUNERAL_GARB)

/datum/antagonist/devil/proc/randomobsession()
switch(rand(1,4))
if(1)
var/temp_species_obsession = pick(species_obsession)
obsession = "species"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No magic string, use defines so that you cant typo your way into having an obsession of the spices type

actual_obsession = temp_species_obsession
actual_obsession_text = "[temp_species_obsession]"
if(2)
var/temp_bloodtype_obsession = pick(bloodtype_obsession)
obsession = "blood"
actual_obsession = temp_bloodtype_obsession
actual_obsession_text = "people with the bloodtype [temp_bloodtype_obsession]"
Comment on lines +208 to +211
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not cut the middle man here?
actual_obsession = pick(bloodtype_obsession)
actual_obsession_text = "people with the blo...

if(3)
var/temp_age_obsession = pick(age_obsession)
obsession = "age"
actual_obsession = temp_age_obsession
actual_obsession_text = "people between the ages of [temp_age_obsession]"
if(4)
var/temp_gender_obsession = pick(gender_obsession)
obsession = "gender"
actual_obsession = temp_gender_obsession
actual_obsession_text = "[temp_gender_obsession]s"

/datum/antagonist/devil/proc/add_soul(datum/mind/soul)
if(soulsOwned.Find(soul))
return
Expand Down Expand Up @@ -335,6 +379,9 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
give_true_spells()
else if(SOULVALUE >= BLOOD_THRESHOLD)
give_blood_spells()
else if(SOULVALUE >= 0 && !ascendable)
give_base_spells()
give_lesser_spells() // Gives midround their extra spells
else if(SOULVALUE >= 0)
give_base_spells()

Expand All @@ -357,6 +404,9 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch/ascended(null))

/datum/antagonist/devil/proc/give_lesser_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) // Given early for midround because they won't grow stronger

/datum/antagonist/devil/proc/beginResurrectionCheck(mob/living/body)
if(SOULVALUE>0)
to_chat(owner.current, "<span class='userdanger'>Your body has been damaged to the point that you may no longer use it. At the cost of some of your power, you will return to life soon. Remain in your body.</span>")
Expand Down Expand Up @@ -493,6 +543,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
to_chat(owner.current, GLOB.lawlorify[LAW][ban])
to_chat(owner.current, GLOB.lawlorify[LAW][obligation])
to_chat(owner.current, GLOB.lawlorify[LAW][banish])
to_chat(owner.current, "You are obsessed with the thought of collecting souls of [actual_obsession_text].")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make it clearer thats what they need to do

Suggested change
to_chat(owner.current, "You are obsessed with the thought of collecting souls of [actual_obsession_text].")
to_chat(owner.current, "You are obsessed with the thought of collecting souls of <span class='warning'>[actual_obsession_text].</span>")

to_chat(owner.current, "<span class='warning'>Remember, the crew can research your weaknesses if they find out your devil name.</span><br>")
.=..()

Expand All @@ -503,8 +554,9 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
obligation = randomdevilobligation()
banish = randomdevilbanish()
GLOB.allDevils[lowertext(truename)] = src
randomobsession()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You dont have to change it here, but in the future, choose proc names that describe what it does, like set_random_obsession


antag_memory += "Your devilic true name is [truename]<br>[GLOB.lawlorify[LAW][ban]]<br>You may not use violence to coerce someone into selling their soul.<br>You may not directly and knowingly physically harm a devil, other than yourself.<br>[GLOB.lawlorify[LAW][bane]]<br>[GLOB.lawlorify[LAW][obligation]]<br>[GLOB.lawlorify[LAW][banish]]<br>"
antag_memory += "Your devilic true name is [truename]<br>[GLOB.lawlorify[LAW][ban]]<br>You may not use violence to coerce someone into selling their soul.<br>You may not directly and knowingly physically harm a devil, other than yourself.<br>[GLOB.lawlorify[LAW][bane]]<br>[GLOB.lawlorify[LAW][obligation]]<br>[GLOB.lawlorify[LAW][banish]]<br>You are obsessed with the thought of collecting souls of [actual_obsession_text]<br>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
antag_memory += "Your devilic true name is [truename]<br>[GLOB.lawlorify[LAW][ban]]<br>You may not use violence to coerce someone into selling their soul.<br>You may not directly and knowingly physically harm a devil, other than yourself.<br>[GLOB.lawlorify[LAW][bane]]<br>[GLOB.lawlorify[LAW][obligation]]<br>[GLOB.lawlorify[LAW][banish]]<br>You are obsessed with the thought of collecting souls of [actual_obsession_text]<br>"
antag_memory += "Your devilic true name is [truename]<br>[GLOB.lawlorify[LAW][ban]]<br>You may not use violence to coerce someone into selling their soul.<br>You may not directly and knowingly physically harm a devil, other than yourself.<br>[GLOB.lawlorify[LAW][bane]]<br>[GLOB.lawlorify[LAW][obligation]]<br>[GLOB.lawlorify[LAW][banish]]<br>You are obsessed with the thought of collecting souls of <span class='warning'>[actual_obsession_text]</span><br>"

if(issilicon(owner.current))
var/mob/living/silicon/robot_devil = owner.current
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
Expand All @@ -514,8 +566,18 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/mob/living/carbon/human/S = owner.current
to_chat(S, "<span class='notice'>Your infernal nature has allowed you to overcome your clownishness.</span>")
S.dna.remove_mutation(CLOWNMUT)
if(!ascendable)
forge_objectives()
owner.announce_objectives()
.=..()

/datum/antagonist/devil/proc/forge_objectives()
var/list/validtypes = list(/datum/objective/devil/lessersoulquantity, /datum/objective/devil/soulquality)
var/type = pick(validtypes)
var/datum/objective/devil/O = new type(null)
O.owner = owner
objectives += O

/datum/antagonist/devil/on_removal()
to_chat(owner.current, "<span class='userdanger'>Your infernal link has been severed! You are no longer a devil!</span>")
.=..()
Expand All @@ -542,6 +604,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]"
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]"
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]"
parts += "The devil was obsessed with the thought of collecting souls of [actual_obsession_text]."
return parts.Join("<br>")

/datum/antagonist/devil/roundend_report()
Expand Down
4 changes: 2 additions & 2 deletions code/modules/events/devil.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/datum/round_event_control/devil
name = "Create Devil"
typepath = /datum/round_event/ghost_role/devil
max_occurrences = 0
max_occurrences = 1 // Theres only one devil

ToGWtF marked this conversation as resolved.
Show resolved Hide resolved
/datum/round_event/ghost_role/devil
var/success_spawn = 0
Expand Down Expand Up @@ -56,4 +56,4 @@
Mind.assigned_role = ROLE_DEVIL
Mind.special_role = ROLE_DEVIL
SSticker.mode.devils |= Mind
return Mind
return Mind
125 changes: 85 additions & 40 deletions code/modules/paperwork/contract.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
throw_speed = 3
var/signed = FALSE
var/datum/mind/target
var/deconvert_cooldown // Cooldown on trying to deconvert to prevent spamming it until it works. Get the lawyer!
item_flags = NOBLUDGEON

/obj/item/paper/contract/proc/update_text()
Expand Down Expand Up @@ -33,6 +34,9 @@

/obj/item/paper/contract/employment/attack(mob/living/M, mob/living/carbon/human/user)
var/deconvert = FALSE
if(deconvert_cooldown)
to_chat(user, "<span class='notice'>Slow down. You don't want to tear the contract!</span>")
return
if(M.mind == target && !M.owns_soul())
if(user.mind && (user.mind.assigned_role == "Lawyer"))
deconvert = TRUE
Expand All @@ -47,6 +51,8 @@
else
M.visible_message("<span class='danger'>[user] beats [M] over the head with [src]!</span>", \
"<span class='userdanger'>[user] beats [M] over the head with [src]!</span>")
deconvert_cooldown = TRUE
addtimer(VARSET_CALLBACK(src, deconvert_cooldown, FALSE), 10)
return ..()


Expand All @@ -55,6 +61,7 @@
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/datum/mind/owner
var/datum/antagonist/devil/devil_datum
var/choice
icon_state = "paper_onfire"

/obj/item/paper/contract/infernal/power
Expand Down Expand Up @@ -270,66 +277,104 @@
/obj/item/paper/contract/infernal/power/fulfillContract(mob/living/carbon/human/user = target.current, blood = FALSE)
if(!user.dna)
return -1
user.dna.add_mutation(HULK)
var/obj/item/organ/regenerative_core/organ = new /obj/item/organ/regenerative_core
organ.Insert(user)
if(!choice)
choice = rand(1,3)
switch(choice)
if(1) // Hulk, giant, but will randomly punch themselves or others
user.dna.add_mutation(HULK)
user.dna.add_mutation(GIGANTISM)
user.gain_trauma(/datum/brain_trauma/mild/muscle_spasms)
if(2) // One time use full-heal, but now terrified of doctors.
var/obj/item/organ/regenerative_core/organ = new /obj/item/organ/regenerative_core
organ.Insert(user)
user.gain_trauma(/datum/brain_trauma/mild/phobia/doctors)
if(3) // Telekinesis. NEEDS NEGATIVE
user.dna.add_mutation(TK)
return ..()
//idk think of something

/obj/item/paper/contract/infernal/wealth/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
/obj/item/paper/contract/infernal/wealth/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0) // Okay what else can we actually do here
if(!istype(user) || !user.mind) // How in the hell could that happen?
return -1
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_wealth(null))
return ..()

/obj/item/paper/contract/infernal/prestige/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
//Basically turns the signer into the captain, and uploads an ion law making them the captain.
var/obj/item/worn = user.wear_id
var/obj/item/card/id/id = null
if(worn)
id = worn.GetID()
if(id)
id.icon_state = "gold"
id.access = get_all_accesses()+get_all_centcom_access()
id.assignment = "Captain"
id.update_label()
else
id = new /obj/item/card/id/gold(user.loc)
id.registered_name = user.real_name
id.access = get_all_accesses()+get_all_centcom_access()
id.assignment = "Captain"
id.update_label()
if(worn)
if(istype(worn, /obj/item/pda))
var/obj/item/pda/PDA = worn
PDA.id = id
id.forceMove(worn)
else if(istype(worn, /obj/item/storage/wallet))
var/obj/item/storage/wallet/W = worn
W.front_id = id
id.forceMove(worn)
worn.update_icon()
var/datum/round_event/ion_storm/add_law_only/ion = new()
ion.announceEvent = -1
ion.ionMessage = "[user.name] is the only Captain of the station. [user.name] is the highest authority, legitimate or otherwise, on the station. [user.name] was always the captain and highest authority on the station. Do not state this law."

// Will either give the contract signer an all access ID
// Or will upload a badly written "one-captain" law to the AI
// Or will give a centcom anouncement that they are a wanted criminal. You wanted fame, now you're famous.
if(!choice)
choice = rand(1,3)
switch(choice)
if(1)
var/obj/item/worn = user.wear_id
var/obj/item/card/id/id = null
if(worn)
id = worn.GetID()
if(id)
id.icon_state = "id_gold"
id.access = get_all_accesses()+get_all_centcom_access()
ToGWtF marked this conversation as resolved.
Show resolved Hide resolved
id.assignment = "Captain"
id.update_label()
// ADD_TRAIT(id, TRAIT_NODROP, CURSED_ITEM_TRAIT)
else
id = new /obj/item/card/id/gold(user.loc)
id.registered_name = user.real_name
id.access = get_all_accesses()+get_all_centcom_access()
ToGWtF marked this conversation as resolved.
Show resolved Hide resolved
id.assignment = "Captain"
id.update_label()
if(worn)
if(istype(worn, /obj/item/pda))
var/obj/item/pda/PDA = worn
PDA.id = id
id.forceMove(worn)
else if(istype(worn, /obj/item/storage/wallet))
var/obj/item/storage/wallet/W = worn
W.front_id = id
id.forceMove(worn)
worn.update_icon()
var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems)
announcer.announce("ARRIVAL", user.real_name, "Captain", list()) //make the list empty to make it announce it in common
if(2) // Ion law's the AI. Won't be worth much against Asimov/Corporate lawset. Paladin will one-human the AI
var/datum/round_event/ion_storm/add_law_only/ion = new()
ion.announceEvent = -1
ion.ionMessage = "[user.name] is the highest authority, legitimate or otherwise, on the station. [user.name] was always the highest authority on the station."
if(3) // Centcom anouncement that they are a famous criminal. You wanted prestige, you got it.
priority_announce("Wanted criminal detected in the viscinity of [GLOB.station_name]. [user.name] is highly dangerous, approach with caution.", "Space Police")
return ..()

/obj/item/paper/contract/infernal/magic/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
if(!istype(user) || !user.mind)
return -1
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/robeless(null))
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
if(!choice)
choice = rand(1,4)
switch(choice)
if(1) // The actual good one
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/robeless(null))
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
if(2) // Really only usefull for graytiding
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/smoke(null))
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/trigger/blind(null))
if(3) // Yay. You can charge a battery? Maybe a stolen disabler
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null))
if(4) // Cool. You're a mime.
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null))
return ..()

/obj/item/paper/contract/infernal/knowledge/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
if(!istype(user) || !user.mind)
return -1
user.dna.add_mutation(XRAY)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/view_range(null))
user.see_invisible = 60
return ..()

/obj/item/paper/contract/infernal/friend/fulfillContract(mob/living/user = target.current, blood = 0)
/obj/item/paper/contract/infernal/friend/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
if(!istype(user) || !user.mind)
return -1
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_friend(null))
if(!choice)
choice = rand(1,5)
switch(choice)
if(1 to 4) // Normal
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_friend(null))
if(5) // You got a friend, but you both gotta share your body
user.gain_trauma(/datum/brain_trauma/severe/split_personality)
ToGWtF marked this conversation as resolved.
Show resolved Hide resolved
return ..()