mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-27 06:54:18 +01:00
Cultist Memory (#10622)
This commit is contained in:
@@ -469,6 +469,7 @@
|
||||
#include "code\game\gamemodes\changeling\implements\powers\stings.dm"
|
||||
#include "code\game\gamemodes\changeling\implements\powers\suck.dm"
|
||||
#include "code\game\gamemodes\cult\cult.dm"
|
||||
#include "code\game\gamemodes\cult\cultist_datum.dm"
|
||||
#include "code\game\gamemodes\cult\hell_universe.dm"
|
||||
#include "code\game\gamemodes\cult\narsie.dm"
|
||||
#include "code\game\gamemodes\cult\cultify\mob.dm"
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
/obj/screen/vampire/blood/Click(var/location, var/control, var/params)
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
to_chat(H, SPAN_NOTICE("You have [H.mind.vampire.blood_usable]u of blood to use for vampiric powers."))
|
||||
to_chat(H, SPAN_WARNING("If it drops too low, you will go into a blood frenzy. You can only store a maximum of [VAMPIRE_MAX_USABLE_BLOOD]u."))
|
||||
var/datum/vampire/vampire = usr.mind.antag_datums[MODE_VAMPIRE]
|
||||
to_chat(usr, SPAN_NOTICE("You have [vampire.blood_usable]u of blood to use for vampiric powers."))
|
||||
to_chat(usr, SPAN_WARNING("If it drops too low, you will go into a blood frenzy. You can only store a maximum of [VAMPIRE_MAX_USABLE_BLOOD]u."))
|
||||
|
||||
/obj/screen/vampire/frenzy
|
||||
name = "frenzy count"
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
/obj/screen/vampire/frenzy/Click(var/location, var/control, var/params)
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
to_chat(H, SPAN_WARNING("Your frenzy counter is at [H.mind.vampire.frenzy]."))
|
||||
to_chat(H, SPAN_WARNING("If it raises too high, you will gain incredible power, but they will be very unsubtle. You can lower your frenzy counter by getting out of holy areas and by obtaining usable blood."))
|
||||
var/datum/vampire/vampire = usr.mind.antag_datums[MODE_VAMPIRE]
|
||||
to_chat(usr, SPAN_WARNING("Your frenzy counter is at [vampire.frenzy]."))
|
||||
to_chat(usr, SPAN_WARNING("If it raises too high, you will gain incredible power, but they will be very unsubtle. You can lower your frenzy counter by getting out of holy areas and by obtaining usable blood."))
|
||||
|
||||
/obj/screen/vampire/suck
|
||||
name = "blood_suck"
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
runes_by_name[R.name] = rune
|
||||
tome_data += "<div class='rune-block'>"
|
||||
tome_data += "<b>[capitalize_first_letters(R.name)]</b>: <i>[R.desc]</i><br>"
|
||||
tome_data += "This rune <b><i>[R.can_be_talisman() ? "can" : "cannot"]</i></b> be turned into a talisman.<br><hr>"
|
||||
tome_data += "This rune <b><i>[R.can_be_talisman() ? "can" : "cannot"]</i></b> be turned into a talisman.<br>"
|
||||
tome_data += "This rune <b><i>[R.can_memorize() ? "can" : "cannot"]</i></b> be memorized to be scribed without a tome.<br><hr>"
|
||||
tome_data += "</div>"
|
||||
|
||||
/datum/controller/subsystem/cult/proc/add_rune(var/datum/rune/R)
|
||||
|
||||
+5
-5
@@ -54,9 +54,7 @@
|
||||
var/has_been_rev = 0//Tracks if this mind has been a rev or not
|
||||
|
||||
var/datum/faction/faction //associated faction
|
||||
var/datum/changeling/changeling //changeling holder
|
||||
|
||||
var/datum/vampire/vampire //vampire holder
|
||||
var/list/antag_datums = list()
|
||||
|
||||
var/rev_cooldown = 0
|
||||
|
||||
@@ -88,6 +86,8 @@
|
||||
/datum/mind/proc/transfer_to(mob/living/new_character)
|
||||
if(!istype(new_character))
|
||||
world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to( a non mob/living mob. Please inform Carn"
|
||||
var/datum/changeling/changeling = antag_datums[MODE_CHANGELING]
|
||||
var/datum/vampire/vampire = antag_datums[MODE_VAMPIRE]
|
||||
if(current) //remove ourself from our old body's mind variable
|
||||
if(changeling)
|
||||
current.remove_changeling_powers()
|
||||
@@ -485,8 +485,8 @@
|
||||
role_alt_title = null
|
||||
assigned_job = null
|
||||
//faction = null //Uncommenting this causes a compile error due to 'undefined type', fucked if I know.
|
||||
changeling = null
|
||||
vampire = null
|
||||
for(var/thing in antag_datums)
|
||||
QDEL_NULL(thing)
|
||||
initial_account = null
|
||||
objectives = list()
|
||||
special_verbs = list()
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
faction = "Changeling"
|
||||
|
||||
/datum/antagonist/changeling/get_special_objective_text(var/datum/mind/player)
|
||||
return "<br><b>Changeling ID:</b> [player.changeling.changelingID].<br><b>Genomes Absorbed:</b> [player.changeling.absorbedcount]"
|
||||
var/datum/changeling/changeling = player.antag_datums[MODE_CHANGELING]
|
||||
return "<br><b>Changeling ID:</b> [changeling.changelingID].<br><b>Genomes Absorbed:</b> [changeling.absorbedcount]"
|
||||
|
||||
/datum/antagonist/changeling/update_antag_mob(var/datum/mind/player)
|
||||
..()
|
||||
|
||||
@@ -87,11 +87,19 @@ var/datum/antagonist/cultist/cult
|
||||
if(player.current && !istype(player.current, /mob/living/simple_animal/construct))
|
||||
player.current.add_language(LANGUAGE_CULT)
|
||||
player.current.verbs |= /datum/antagonist/cultist/proc/appraise_offering
|
||||
player.current.verbs |= /datum/cultist/proc/memorize_rune
|
||||
player.current.verbs |= /datum/cultist/proc/forget_rune
|
||||
player.current.verbs |= /datum/cultist/proc/scribe_rune
|
||||
player.antag_datums[MODE_CULTIST] = new /datum/cultist()
|
||||
|
||||
|
||||
/datum/antagonist/cultist/remove_antagonist(var/datum/mind/player)
|
||||
. = ..()
|
||||
|
||||
player.current.verbs -= /datum/antagonist/cultist/proc/appraise_offering
|
||||
player.current.verbs -= /datum/cultist/proc/memorize_rune
|
||||
player.current.verbs -= /datum/cultist/proc/forget_rune
|
||||
player.current.verbs -= /datum/cultist/proc/scribe_rune
|
||||
|
||||
/datum/antagonist/cultist/can_become_antag(var/datum/mind/player, ignore_role = 1)
|
||||
if(!..())
|
||||
@@ -104,7 +112,7 @@ var/datum/antagonist/cultist/cult
|
||||
/datum/antagonist/cultist/proc/appraise_offering()
|
||||
set name = "Appraise Offering"
|
||||
set desc = "Find out if someone close-by can be converted to join the cult, or not."
|
||||
set category = "IC"
|
||||
set category = "Cultist"
|
||||
|
||||
var/list/targets = list()
|
||||
for(var/mob/living/carbon/target in view(5, usr))
|
||||
|
||||
@@ -29,13 +29,15 @@ var/datum/antagonist/thrall/thralls = null
|
||||
var/datum/mind/M = user.mind
|
||||
if(!M)
|
||||
return
|
||||
if(M.vampire.master_image)
|
||||
user.client.images += M.vampire.master_image
|
||||
var/datum/vampire/vampire = M.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire.master_image)
|
||||
user.client.images += vampire.master_image
|
||||
|
||||
/datum/antagonist/thrall/update_antag_mob(var/datum/mind/player)
|
||||
..()
|
||||
player.current.vampire_make_thrall()
|
||||
|
||||
/datum/antagonist/thrall/remove_antagonist(datum/mind/player, show_message, implanted)
|
||||
player.vampire.lose_master(player.current)
|
||||
var/datum/vampire/vampire = player.antag_datums[MODE_VAMPIRE]
|
||||
vampire.lose_master(player.current)
|
||||
return ..()
|
||||
@@ -67,33 +67,36 @@ var/datum/antagonist/vampire/vamp = null
|
||||
/datum/antagonist/vampire/remove_antagonist(var/datum/mind/player, var/show_message = TRUE, var/implanted)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/datum/vampire/vampire = player.antag_datums[MODE_VAMPIRE]
|
||||
if(player.current.client)
|
||||
player.current.client.screen -= player.vampire.blood_hud
|
||||
player.current.client.screen -= player.vampire.frenzy_hud
|
||||
player.current.client.screen -= vampire.blood_hud
|
||||
player.current.client.screen -= vampire.frenzy_hud
|
||||
player.current.verbs -= /datum/antagonist/vampire/proc/vampire_help
|
||||
for(var/datum/power/vampire/P in vampirepowers)
|
||||
player.current.verbs -= P.verbpath
|
||||
QDEL_NULL(player.vampire)
|
||||
QDEL_NULL(vampire)
|
||||
|
||||
/datum/antagonist/vampire/handle_latelogin(var/mob/user)
|
||||
var/datum/mind/M = user.mind
|
||||
if(!M)
|
||||
return
|
||||
if(M.vampire.master_image)
|
||||
user.client.images += M.vampire.master_image
|
||||
if(M.vampire.status & VAMP_ISTHRALL)
|
||||
var/datum/vampire/vampire = M.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire.master_image)
|
||||
user.client.images += vampire.master_image
|
||||
if(vampire.status & VAMP_ISTHRALL)
|
||||
return
|
||||
M.vampire.blood_hud = new /obj/screen/vampire/blood()
|
||||
M.vampire.frenzy_hud = new /obj/screen/vampire/frenzy()
|
||||
M.vampire.blood_suck_hud = new /obj/screen/vampire/suck()
|
||||
user.client.screen += M.vampire.blood_hud
|
||||
user.client.screen += M.vampire.frenzy_hud
|
||||
user.client.screen += M.vampire.blood_suck_hud
|
||||
vampire.blood_hud = new /obj/screen/vampire/blood()
|
||||
vampire.frenzy_hud = new /obj/screen/vampire/frenzy()
|
||||
vampire.blood_suck_hud = new /obj/screen/vampire/suck()
|
||||
user.client.screen += vampire.blood_hud
|
||||
user.client.screen += vampire.frenzy_hud
|
||||
user.client.screen += vampire.blood_suck_hud
|
||||
|
||||
for(var/thrall in M.vampire.thralls)
|
||||
for(var/thrall in vampire.thralls)
|
||||
var/mob/T = thrall
|
||||
if(T?.mind?.vampire.thrall_image)
|
||||
user.client.images += T.mind.vampire.thrall_image
|
||||
var/datum/vampire/T_vampire = T.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(T_vampire.thrall_image)
|
||||
user.client.images += T_vampire.thrall_image
|
||||
|
||||
/datum/antagonist/vampire/proc/vampire_help()
|
||||
set category = "Vampire"
|
||||
|
||||
@@ -40,8 +40,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
|
||||
/mob/proc/absorbDNA(var/datum/absorbed_dna/newDNA)
|
||||
var/datum/changeling/changeling = null
|
||||
if(src.mind && src.mind.changeling)
|
||||
changeling = src.mind.changeling
|
||||
if(mind)
|
||||
changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
@@ -58,8 +58,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
|
||||
if(!mind)
|
||||
return
|
||||
if(!mind.changeling)
|
||||
mind.changeling = new /datum/changeling(gender)
|
||||
if(!mind.antag_datums[MODE_CHANGELING])
|
||||
mind.antag_datums[MODE_CHANGELING] = new /datum/changeling(gender)
|
||||
|
||||
verbs += /datum/changeling/proc/EvolutionMenu
|
||||
add_language("Changeling")
|
||||
@@ -70,34 +70,39 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
for(var/P in powers)
|
||||
powerinstances += new P()
|
||||
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
|
||||
// Code to auto-purchase free powers.
|
||||
for(var/datum/power/changeling/P in powerinstances)
|
||||
if(!P.genomecost) // Is it free?
|
||||
if(!(P in mind.changeling.purchasedpowers)) // Do we not have it already?
|
||||
mind.changeling.purchasePower(mind, P.name, 0) // Purchase it. Don't remake our verbs, we're doing it after this.
|
||||
if(!(P in changeling.purchasedpowers)) // Do we not have it already?
|
||||
changeling.purchasePower(mind, P.name, 0) // Purchase it. Don't remake our verbs, we're doing it after this.
|
||||
|
||||
for(var/datum/power/changeling/P in mind.changeling.purchasedpowers)
|
||||
for(var/datum/power/changeling/P in changeling.purchasedpowers)
|
||||
if(P.isVerb)
|
||||
if(lesser_form && !P.allowduringlesserform) continue
|
||||
if(!(P in src.verbs))
|
||||
src.verbs += P.verbpath
|
||||
|
||||
for(var/language in languages)
|
||||
mind.changeling.absorbed_languages |= language
|
||||
changeling.absorbed_languages |= language
|
||||
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(istype(H))
|
||||
var/datum/absorbed_dna/newDNA = new(H.real_name, H.dna, H.species.get_cloning_variant(), H.languages)
|
||||
absorbDNA(newDNA)
|
||||
mind.changeling.mimiced_accent = H.accent
|
||||
changeling.mimiced_accent = H.accent
|
||||
|
||||
return TRUE
|
||||
|
||||
//removes our changeling verbs
|
||||
/mob/proc/remove_changeling_powers()
|
||||
if(!mind || !mind.changeling)
|
||||
var/datum/changeling/changeling
|
||||
if(mind)
|
||||
changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(!changeling)
|
||||
return
|
||||
for(var/datum/power/changeling/P in mind.changeling.purchasedpowers)
|
||||
for(var/datum/power/changeling/P in changeling.purchasedpowers)
|
||||
if(P.isVerb)
|
||||
verbs -= P.verbpath
|
||||
|
||||
@@ -110,7 +115,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
if(!iscarbon(src))
|
||||
return
|
||||
|
||||
var/datum/changeling/changeling = src.mind.changeling
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(!changeling)
|
||||
log_and_message_admins("has the changeling_transform() verb but is not a changeling.", src, get_turf(src))
|
||||
return
|
||||
|
||||
@@ -220,9 +220,10 @@ var/list/datum/power/changeling/powerinstances = list()
|
||||
set category = "Changeling"
|
||||
set desc = "Buy new abilities with the genomes we obtained."
|
||||
|
||||
if(!usr || !usr.mind || !usr.mind.changeling)
|
||||
var/datum/changeling/changeling = usr.mind.antag_datums[MODE_CHANGELING]
|
||||
if(!usr || !usr.mind || !changeling)
|
||||
return
|
||||
src = usr.mind.changeling
|
||||
src = changeling
|
||||
|
||||
if(!powerinstances.len)
|
||||
for(var/P in powers)
|
||||
@@ -480,7 +481,8 @@ var/list/datum/power/changeling/powerinstances = list()
|
||||
|
||||
|
||||
/datum/changeling/proc/purchasePower(var/datum/mind/M, var/power_name, var/remake_verbs = 1)
|
||||
if(!M || !M.changeling)
|
||||
var/datum/changeling/changeling = M.antag_datums[MODE_CHANGELING]
|
||||
if(!M || !changeling)
|
||||
return
|
||||
|
||||
var/datum/power/changeling/power = power_name
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#define CHECK_STING(holder, target) \
|
||||
if(isliving(target) && holder.a_intent == I_HURT && holder.mind && holder.mind.changeling && holder.mind.changeling.prepared_sting) { \
|
||||
if(holder.mind.changeling.prepared_sting.can_sting(A)) { \
|
||||
holder.mind.changeling.prepared_sting.do_sting(A); \
|
||||
QDEL_NULL(holder.mind.changeling.prepared_sting); \
|
||||
return; \
|
||||
if(isliving(target) && holder.a_intent == I_HURT && holder.mind) { \
|
||||
var/datum/changeling/changeling = holder.mind.antag_datums[MODE_CHANGELING]; \
|
||||
if(changeling && changeling.prepared_sting) { \
|
||||
if(changeling.prepared_sting.can_sting(A)) { \
|
||||
changeling.prepared_sting.do_sting(A); \
|
||||
QDEL_NULL(changeling.prepared_sting); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
set desc = "Relinquish your life and enter the land of the dead."
|
||||
|
||||
announce_ghost_joinleave(ghostize(1, 0))
|
||||
changeling_mob.mind.changeling.hivemind_members -= src
|
||||
var/datum/changeling/changeling = changeling_mob.mind.antag_datums[MODE_CHANGELING]
|
||||
changeling.hivemind_members -= src
|
||||
relay_hivemind(SPAN_NOTICE("[src] has left our hivemind to join the living dead."), changeling_mob)
|
||||
|
||||
/mob/abstract/hivemind/proc/add_to_hivemind(var/mob/original_body, var/mob/living/carbon/human/ling)
|
||||
@@ -28,7 +29,8 @@
|
||||
ckey = original_body.ckey
|
||||
changeling_mob = ling
|
||||
if(changeling_mob)
|
||||
changeling_mob.mind.changeling.hivemind_members[name] = src
|
||||
var/datum/changeling/changeling = changeling_mob.mind.antag_datums[MODE_CHANGELING]
|
||||
changeling.hivemind_members[name] = src
|
||||
introduction(changeling_mob)
|
||||
|
||||
/mob/abstract/hivemind/proc/introduction(var/mob/living/carbon/human/ling)
|
||||
@@ -62,7 +64,8 @@
|
||||
var/mob/living/simple_animal/hostile/morph/M = new /mob/living/simple_animal/hostile/morph(get_turf(changeling_mob))
|
||||
M.stop_thinking = TRUE // prevent the AI from taking over when the player ghosts
|
||||
M.ckey = ckey
|
||||
changeling_mob.mind.changeling.hivemind_members -= src
|
||||
var/datum/changeling/changeling = changeling_mob.mind.antag_datums[MODE_CHANGELING]
|
||||
changeling.hivemind_members -= src
|
||||
|
||||
to_chat(M, SPAN_DANGER(FONT_LARGE("You are a morph, released by [changeling_mob]!")))
|
||||
to_chat(M, SPAN_DANGER("As a morph, you can disguise as objects by alt-clicking on them."))
|
||||
|
||||
@@ -287,8 +287,8 @@
|
||||
C.digitalcamo = !C.digitalcamo
|
||||
|
||||
spawn(0)
|
||||
while(C && C.digitalcamo && C.mind && C.mind.changeling)
|
||||
C.mind.changeling.chem_charges = max(C.mind.changeling.chem_charges - 1, 0)
|
||||
while(C && C.digitalcamo && C.mind && changeling)
|
||||
changeling.chem_charges = max(changeling.chem_charges - 1, 0)
|
||||
sleep(40)
|
||||
|
||||
src.verbs -= /mob/proc/changeling_digitalcamo
|
||||
@@ -305,7 +305,7 @@
|
||||
var/datum/changeling/changeling = changeling_power(30, 0, 100, UNCONSCIOUS)
|
||||
if(!changeling)
|
||||
return FALSE
|
||||
src.mind.changeling.chem_charges -= 30
|
||||
changeling.chem_charges -= 30
|
||||
|
||||
var/mob/living/carbon/human/C = src
|
||||
spawn(0)
|
||||
@@ -366,11 +366,11 @@
|
||||
feedback_add_details("changeling_powers","MV")
|
||||
|
||||
spawn(0)
|
||||
while(src && src.mind && src.mind.changeling && src.mind.changeling.mimicing)
|
||||
src.mind.changeling.chem_charges = max(src.mind.changeling.chem_charges - 1, 0)
|
||||
while(src?.mind && changeling?.mimicing)
|
||||
changeling.chem_charges = max(changeling.chem_charges - 1, 0)
|
||||
sleep(40)
|
||||
if(src && src.mind && src.mind.changeling)
|
||||
src.mind.changeling.mimicing = ""
|
||||
if(changeling)
|
||||
changeling.mimicing = ""
|
||||
|
||||
/mob/proc/armblades()
|
||||
set category = "Changeling"
|
||||
@@ -380,7 +380,7 @@
|
||||
var/datum/changeling/changeling = changeling_power(20, 0, 0)
|
||||
if(!changeling)
|
||||
return FALSE
|
||||
src.mind.changeling.chem_charges -= 20
|
||||
changeling.chem_charges -= 20
|
||||
|
||||
var/mob/living/carbon/M = src
|
||||
|
||||
@@ -418,7 +418,7 @@
|
||||
var/datum/changeling/changeling = changeling_power(20,0,0)
|
||||
if(!changeling)
|
||||
return FALSE
|
||||
src.mind.changeling.chem_charges -= 20
|
||||
changeling.chem_charges -= 20
|
||||
|
||||
var/mob/living/carbon/M = src
|
||||
|
||||
@@ -465,7 +465,7 @@
|
||||
if(alert("Are we sure we wish to reveal ourselves? This will only revert after ten minutes.", , "Yes", "No") == "No") //Changelings have to confirm whether they want to go full horrorform
|
||||
return
|
||||
|
||||
src.mind.changeling.chem_charges -= 40
|
||||
changeling.chem_charges -= 40
|
||||
|
||||
M.visible_message("<span class='danger'>[M] writhes and contorts, their body expanding to inhuman proportions!</span>", \
|
||||
"<span class='danger'>We begin our transformation to our true form!</span>")
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
set name = "Hivemind Eject"
|
||||
set desc = "Ejects a member of our internal hivemind."
|
||||
|
||||
if(!(mind?.changeling))
|
||||
var/datum/changeling/changeling = changeling_power()
|
||||
if(!changeling)
|
||||
return
|
||||
if(!mind.changeling.hivemind_members.len)
|
||||
return
|
||||
var/chosen_player = input("Choose a hivemind member to eject.", "Eject") as null|anything in mind.changeling.hivemind_members
|
||||
var/chosen_player = input("Choose a hivemind member to eject.", "Eject") as null|anything in changeling.hivemind_members
|
||||
if(!chosen_player)
|
||||
return
|
||||
var/mob/abstract/hivemind/M = mind.changeling.hivemind_members[chosen_player]
|
||||
var/mob/abstract/hivemind/M = changeling.hivemind_members[chosen_player]
|
||||
M.ghost() //Deuces
|
||||
return TRUE
|
||||
|
||||
@@ -27,9 +26,10 @@
|
||||
return TRUE
|
||||
|
||||
/mob/proc/relay_hivemind(var/message, var/mob/ling)
|
||||
if(ling.mind?.changeling)
|
||||
for(var/H in ling.mind.changeling.hivemind_members) // tell the others in the hivemind
|
||||
var/mob/M = ling.mind.changeling.hivemind_members[H]
|
||||
var/datum/changeling/changeling = ling.mind.antag_datums[MODE_CHANGELING]
|
||||
if(changeling)
|
||||
for(var/H in changeling.hivemind_members) // tell the others in the hivemind
|
||||
var/mob/M = changeling.hivemind_members[H]
|
||||
to_chat(M, message)
|
||||
to_chat(ling, message)
|
||||
|
||||
@@ -41,17 +41,18 @@
|
||||
set name = "Hivemind Release Morph"
|
||||
set desc = "Releases a member of our internal hivemind as a morph, at the cost of one of our limbs."
|
||||
|
||||
if(!mind?.changeling)
|
||||
var/datum/changeling/changeling = changeling_power()
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
if(!length(mind.changeling.hivemind_members))
|
||||
if(!length(changeling.hivemind_members))
|
||||
to_chat(src, SPAN_WARNING("We have no internal hivemind members to release!"))
|
||||
return
|
||||
|
||||
var/chosen_player = input("Choose a hivemind member to release as a morph.", "Hivemind Morph") as null|anything in mind.changeling.hivemind_members
|
||||
var/chosen_player = input("Choose a hivemind member to release as a morph.", "Hivemind Morph") as null|anything in changeling.hivemind_members
|
||||
if(!chosen_player)
|
||||
return
|
||||
|
||||
var/mob/abstract/hivemind/M = mind.changeling.hivemind_members[chosen_player]
|
||||
var/mob/abstract/hivemind/M = changeling.hivemind_members[chosen_player]
|
||||
M.release_as_morph()
|
||||
return TRUE
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
//Speeds up chemical regeneration
|
||||
/mob/proc/changeling_fastchemical()
|
||||
src.mind.changeling.chem_recharge_rate *= 2.5
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
changeling.chem_recharge_rate *= 2.5
|
||||
return TRUE
|
||||
|
||||
//Increases maximum chemical storage
|
||||
/mob/proc/changeling_engorgedglands()
|
||||
src.mind.changeling.chem_storage += 50
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
changeling.chem_storage += 50
|
||||
return TRUE
|
||||
|
||||
// HIVE MIND UPLOAD/DOWNLOAD DNA
|
||||
|
||||
@@ -14,11 +14,14 @@
|
||||
stealthy = set_stealthy
|
||||
|
||||
/datum/changeling_sting/proc/can_sting(var/mob/living/target)
|
||||
if(!target)
|
||||
if(!target || !owner.mind)
|
||||
return FALSE
|
||||
if(!(target in view(owner.mind.changeling.sting_range)))
|
||||
var/datum/changeling/changeling = owner.mind.antag_datums[MODE_CHANGELING]
|
||||
if(!changeling)
|
||||
return FALSE
|
||||
if(!owner.sting_can_reach(target, owner.mind.changeling.sting_range))
|
||||
if(!(target in view(changeling.sting_range)))
|
||||
return FALSE
|
||||
if(!owner.sting_can_reach(target, changeling.sting_range))
|
||||
to_chat(owner, SPAN_WARNING("Our sting can't reach here!"))
|
||||
return FALSE
|
||||
if(!owner.changeling_power(required_chems))
|
||||
@@ -30,8 +33,9 @@
|
||||
return TRUE
|
||||
|
||||
/datum/changeling_sting/proc/do_sting(var/mob/living/target)
|
||||
owner.mind.changeling.chem_charges -= required_chems
|
||||
owner.mind.changeling.sting_range = 1
|
||||
var/datum/changeling/changeling = owner.mind.antag_datums[MODE_CHANGELING]
|
||||
changeling.chem_charges -= required_chems
|
||||
changeling.sting_range = 1
|
||||
owner.verbs -= verb_path
|
||||
ADD_VERB_IN(owner, 10, verb_path)
|
||||
|
||||
@@ -53,17 +57,18 @@
|
||||
feedback_add_details("changeling_powers", feedback_tag)
|
||||
|
||||
/mob/proc/changeling_sting(var/required_chems = 0, var/verb_path, var/datum_path, var/stealthy = FALSE)
|
||||
if(istype(mind.changeling.prepared_sting, datum_path))
|
||||
to_chat(src, SPAN_NOTICE("You unprepare the <b>[mind.changeling.prepared_sting.name]</b>."))
|
||||
QDEL_NULL(mind.changeling.prepared_sting)
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(istype(changeling.prepared_sting, datum_path))
|
||||
to_chat(src, SPAN_NOTICE("You unprepare the <b>[changeling.prepared_sting.name]</b>."))
|
||||
QDEL_NULL(changeling.prepared_sting)
|
||||
return
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(required_chems)
|
||||
changeling = changeling_power(required_chems)
|
||||
if(!changeling)
|
||||
return FALSE
|
||||
|
||||
changeling.prepared_sting = new datum_path(src, verb_path, required_chems, stealthy)
|
||||
to_chat(src, SPAN_NOTICE("You prepare to fire the <b>[mind.changeling.prepared_sting.name]</b>."))
|
||||
to_chat(src, SPAN_NOTICE("You prepare to fire the <b>[changeling.prepared_sting.name]</b>."))
|
||||
return TRUE
|
||||
|
||||
/mob/proc/changeling_hallucinate_sting()
|
||||
@@ -153,8 +158,8 @@
|
||||
set name = "Transformation Sting (40)"
|
||||
set desc = "Causes the target to permanently transform into a collected DNA subject."
|
||||
|
||||
|
||||
if(!length(mind.changeling.absorbed_dna))
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(!length(changeling.absorbed_dna))
|
||||
to_chat(src, SPAN_WARNING("You have no DNA to load this sting with!"))
|
||||
return
|
||||
|
||||
@@ -163,23 +168,23 @@
|
||||
return
|
||||
|
||||
var/list/names = list()
|
||||
for(var/thing in mind.changeling.absorbed_dna)
|
||||
for(var/thing in changeling.absorbed_dna)
|
||||
var/datum/absorbed_dna/DNA = thing
|
||||
names += "[DNA.name]"
|
||||
|
||||
var/S = input(src, "Select the target DNA:", "Target DNA") as null|anything in names
|
||||
if(!S)
|
||||
QDEL_NULL(mind.changeling.prepared_sting)
|
||||
QDEL_NULL(changeling.prepared_sting)
|
||||
to_chat(src, SPAN_NOTICE("With no DNA chosen, you unprepare the sting."))
|
||||
return
|
||||
|
||||
var/datum/absorbed_dna/chosen_dna = mind.changeling.GetDNA(S)
|
||||
var/datum/absorbed_dna/chosen_dna = changeling.GetDNA(S)
|
||||
if(!chosen_dna)
|
||||
QDEL_NULL(mind.changeling.prepared_sting)
|
||||
QDEL_NULL(changeling.prepared_sting)
|
||||
to_chat(src, SPAN_WARNING("Something went wrong, you do not possess the DNA of this person."))
|
||||
return
|
||||
|
||||
var/datum/changeling_sting/transformation/T = mind.changeling.prepared_sting
|
||||
var/datum/changeling_sting/transformation/T = changeling.prepared_sting
|
||||
T.dna_payload = chosen_dna
|
||||
|
||||
/datum/changeling_sting/transformation
|
||||
@@ -253,11 +258,12 @@
|
||||
set name = "Ranged Sting (10)"
|
||||
set desc = "Your next sting ability can be used against targets 2 squares away."
|
||||
|
||||
if(mind.changeling.sting_range > 1)
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(changeling.sting_range > 1)
|
||||
to_chat(src, SPAN_WARNING("The range of your sting has already been boosted!"))
|
||||
return
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(10, 0, 100)
|
||||
changeling = changeling_power(10, 0, 100)
|
||||
if(!changeling)
|
||||
return FALSE
|
||||
changeling.chem_charges -= 10
|
||||
@@ -266,4 +272,4 @@
|
||||
src.verbs -= /mob/proc/changeling_boost_range
|
||||
ADD_VERB_IN(src, 5, /mob/proc/changeling_boost_range)
|
||||
feedback_add_details("changeling_powers", "RS")
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -80,17 +80,18 @@
|
||||
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.get_cloning_variant(), T.languages)
|
||||
absorbDNA(newDNA)
|
||||
|
||||
if(T.mind && T.mind.changeling)
|
||||
if(T.mind.changeling.absorbed_dna)
|
||||
for(var/datum/absorbed_dna/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot
|
||||
var/datum/changeling/changeling_check = T.mind.antag_datums[MODE_CHANGELING]
|
||||
if(changeling_check)
|
||||
if(changeling_check.absorbed_dna)
|
||||
for(var/datum/absorbed_dna/dna_data in changeling_check.absorbed_dna) //steal all their loot
|
||||
if(changeling.GetDNA(dna_data.name))
|
||||
continue
|
||||
absorbDNA(dna_data)
|
||||
changeling.absorbedcount++
|
||||
T.mind.changeling.absorbed_dna.len = TRUE
|
||||
changeling_check.absorbed_dna.len = TRUE
|
||||
|
||||
if(T.mind.changeling.purchasedpowers)
|
||||
for(var/datum/power/changeling/Tp in T.mind.changeling.purchasedpowers) //who the fuck named these variables?
|
||||
if(changeling_check.purchasedpowers)
|
||||
for(var/datum/power/changeling/Tp in changeling_check.purchasedpowers) //who the fuck named these variables?
|
||||
if(Tp in changeling.purchasedpowers)
|
||||
continue
|
||||
else
|
||||
@@ -100,11 +101,11 @@
|
||||
else
|
||||
src.make_changeling()
|
||||
|
||||
changeling.chem_charges += T.mind.changeling.chem_charges
|
||||
changeling.geneticpoints += T.mind.changeling.geneticpoints
|
||||
T.mind.changeling.chem_charges = 0
|
||||
T.mind.changeling.geneticpoints = 0
|
||||
T.mind.changeling.absorbedcount = 0
|
||||
changeling.chem_charges += changeling_check.chem_charges
|
||||
changeling.geneticpoints += changeling_check.geneticpoints
|
||||
changeling_check.chem_charges = 0
|
||||
changeling_check.geneticpoints = 0
|
||||
changeling_check.absorbedcount = 0
|
||||
|
||||
changeling.absorbedcount++
|
||||
changeling.isabsorbing = FALSE
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/datum/cultist
|
||||
var/list/memorized_runes
|
||||
|
||||
/datum/cultist/proc/memorize_rune()
|
||||
set name = "Memorize Rune"
|
||||
set desc = "Stand atop a rune and memorize it, allowing you to draw it without your tome."
|
||||
set category = "Cultist"
|
||||
|
||||
if(!ishuman(usr))
|
||||
to_chat(usr, SPAN_WARNING("Your form is too simple to memorize runes!"))
|
||||
return
|
||||
|
||||
if(usr.stat || usr.incapacitated())
|
||||
to_chat(usr, SPAN_WARNING("You are in no shape to do this."))
|
||||
return
|
||||
|
||||
var/datum/cultist/C = usr.mind.antag_datums[MODE_CULTIST]
|
||||
|
||||
if(LAZYLEN(C.memorized_runes) >= 3)
|
||||
to_chat(usr, SPAN_WARNING("You can only memorize up to three runes!"))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = usr
|
||||
var/obj/effect/rune/R = locate() in get_turf(H)
|
||||
if(R)
|
||||
if(!R.rune.can_memorize())
|
||||
to_chat(H, SPAN_WARNING("This rune is too complex to be memorized!"))
|
||||
return
|
||||
if(LAZYISIN(C.memorized_runes, R.rune.name))
|
||||
to_chat(H, SPAN_WARNING("This rune is already memorized!"))
|
||||
return
|
||||
H.visible_message("<b>[H]</b> bends over and runs their hands across \the [src].", SPAN_NOTICE("You bend over and run your hands across the patterns of the rune, slowly memorizing it."))
|
||||
if(!do_after(H, 10 SECONDS, TRUE))
|
||||
return
|
||||
LAZYSET(C.memorized_runes, R.rune.name, R.rune.type)
|
||||
to_chat(H, SPAN_NOTICE("You memorize the [R.rune.name]! You will now be able to scribe it at will."))
|
||||
else
|
||||
to_chat(H, SPAN_WARNING("There was no rune beneath you to memorize."))
|
||||
|
||||
/datum/cultist/proc/forget_rune()
|
||||
set name = "Forget Rune"
|
||||
set desc = "Cleanse the knowledge of a rune from your memory, freeing up space for another."
|
||||
set category = "Cultist"
|
||||
|
||||
if(!ishuman(usr))
|
||||
to_chat(usr, SPAN_WARNING("Your form is too simple to memorize runes!"))
|
||||
return
|
||||
|
||||
if(usr.stat || usr.incapacitated())
|
||||
to_chat(usr, SPAN_WARNING("You are in no shape to do this."))
|
||||
return
|
||||
|
||||
var/datum/cultist/C = usr.mind.antag_datums[MODE_CULTIST]
|
||||
|
||||
if(!LAZYLEN(C.memorized_runes))
|
||||
to_chat(usr, SPAN_WARNING("You have no runes memorized!"))
|
||||
return
|
||||
|
||||
var/chosen_rune = input("Choose a rune to forget.") as null|anything in C.memorized_runes
|
||||
if(!chosen_rune)
|
||||
return
|
||||
LAZYREMOVE(C.memorized_runes, chosen_rune)
|
||||
|
||||
/datum/cultist/proc/scribe_rune()
|
||||
set name = "Scribe Rune"
|
||||
set desc = "Scribe a rune that you have memorized."
|
||||
set category = "Cultist"
|
||||
|
||||
if(!ishuman(usr))
|
||||
to_chat(usr, SPAN_WARNING("Your form is too simple to memorize runes!"))
|
||||
return
|
||||
|
||||
var/datum/cultist/C = usr.mind.antag_datums[MODE_CULTIST]
|
||||
|
||||
if(!LAZYLEN(C.memorized_runes))
|
||||
to_chat(usr, SPAN_WARNING("You have no runes memorized!"))
|
||||
return
|
||||
|
||||
if(usr.stat || usr.incapacitated())
|
||||
to_chat(usr, SPAN_WARNING("You are in no shape to do this."))
|
||||
return
|
||||
|
||||
var/chosen_rune = input("Choose a rune to scribe.") as null|anything in C.memorized_runes
|
||||
if(!chosen_rune)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.visible_message(SPAN_CULT("Blood flows out from \the [H]'s hands, taking shape beneath them..."))
|
||||
H.drip(4)
|
||||
|
||||
if(do_after(H, 15 SECONDS))
|
||||
create_rune(H, chosen_rune)
|
||||
|
||||
/proc/create_rune(var/mob/living/carbon/human/scribe, var/chosen_rune)
|
||||
if(scribe.stat || scribe.incapacitated())
|
||||
to_chat(scribe, SPAN_WARNING("You are in no shape to do this."))
|
||||
return
|
||||
|
||||
var/area/A = get_area(scribe)
|
||||
//prevents using multiple dialogs to layer runes.
|
||||
if(locate(/obj/effect/rune) in get_turf(scribe)) //This is check is done twice. once when choosing to scribe a rune, once here
|
||||
to_chat(scribe, SPAN_WARNING("There is already a rune in this location."))
|
||||
return
|
||||
|
||||
log_and_message_admins("created \an [chosen_rune] at \the [A.name] - [scribe.loc.x]-[scribe.loc.y]-[scribe.loc.z].") //only message if it's actually made
|
||||
|
||||
var/obj/effect/rune/R = new(get_turf(scribe), SScult.runes_by_name[chosen_rune])
|
||||
to_chat(scribe, SPAN_CULT("You finish drawing the Geometer's markings."))
|
||||
R.blood_DNA = list()
|
||||
R.blood_DNA[scribe.dna.unique_enzymes] = scribe.dna.b_type
|
||||
R.color = scribe.species.blood_color
|
||||
R.filters = filter(type="drop_shadow", x = 1, y = 1, size = 4, color = scribe.species.blood_color)
|
||||
@@ -95,23 +95,7 @@
|
||||
scribe.drip(4)
|
||||
|
||||
if(do_after(scribe, 50))
|
||||
var/area/A = get_area(scribe)
|
||||
if(use_check_and_message(scribe))
|
||||
return
|
||||
|
||||
//prevents using multiple dialogs to layer runes.
|
||||
if(locate(/obj/effect/rune) in get_turf(scribe)) //This is check is done twice. once when choosing to scribe a rune, once here
|
||||
to_chat(scribe, SPAN_WARNING("There is already a rune in this location."))
|
||||
return
|
||||
|
||||
log_and_message_admins("created \an [chosen_rune] at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].") //only message if it's actually made
|
||||
|
||||
var/obj/effect/rune/R = new(get_turf(scribe), SScult.runes_by_name[chosen_rune])
|
||||
to_chat(scribe, SPAN_CULT("You finish drawing the Geometer's markings."))
|
||||
R.blood_DNA = list()
|
||||
R.blood_DNA[scribe.dna.unique_enzymes] = scribe.dna.b_type
|
||||
R.color = scribe.species.blood_color
|
||||
R.filters = filter(type="drop_shadow", x = 1, y = 1, size = 4, color = scribe.species.blood_color)
|
||||
create_rune(scribe, chosen_rune)
|
||||
else
|
||||
to_chat(user, SPAN_CULT("The book seems full of illegible scribbles."))
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define NO_TALISMAN 1
|
||||
#define HAS_SPECIAL_TALISMAN_ACTION 2
|
||||
#define CAN_MEMORIZE 2
|
||||
#define HAS_SPECIAL_TALISMAN_ACTION 4
|
||||
|
||||
/datum/rune
|
||||
var/name // The rune's name.
|
||||
@@ -42,3 +43,6 @@
|
||||
|
||||
/datum/rune/proc/can_be_talisman()
|
||||
return !(rune_flags & NO_TALISMAN)
|
||||
|
||||
/datum/rune/proc/can_memorize()
|
||||
return rune_flags & CAN_MEMORIZE
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/rune/communicate
|
||||
name = "communication rune"
|
||||
desc = "This rune is used to send a message to all acolytes."
|
||||
rune_flags = CAN_MEMORIZE
|
||||
|
||||
/datum/rune/communicate/do_rune_action(mob/living/user, atom/movable/A)
|
||||
var/input = input(user, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")//sanitize() below, say() and whisper() have their own
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/rune/convert
|
||||
name = "conversion rune"
|
||||
desc = "A rune used to convert the Unenlightened."
|
||||
rune_flags = NO_TALISMAN
|
||||
rune_flags = NO_TALISMAN | CAN_MEMORIZE
|
||||
|
||||
var/list/converting
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/rune/talisman
|
||||
name = "talisman creation rune"
|
||||
desc = "This rune creates a talisman out of a rune around it."
|
||||
rune_flags = NO_TALISMAN
|
||||
rune_flags = NO_TALISMAN | CAN_MEMORIZE
|
||||
|
||||
/datum/rune/talisman/do_rune_action(mob/living/user, atom/movable/A)
|
||||
var/obj/item/paper/new_talisman
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/rune/deafen
|
||||
name = "deafening rune"
|
||||
desc = "This rune is used to deafen all unbelievers in a wide range around us."
|
||||
rune_flags = HAS_SPECIAL_TALISMAN_ACTION
|
||||
rune_flags = HAS_SPECIAL_TALISMAN_ACTION | CAN_MEMORIZE
|
||||
|
||||
/datum/rune/deafen/do_rune_action(mob/living/user, atom/movable/A)
|
||||
do_deafen(user, A, 1, TRUE)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/rune/ethereal
|
||||
name = "ethereal rune"
|
||||
desc = "This rune is used to temporarily send an acolyte into the afterlife."
|
||||
rune_flags = NO_TALISMAN
|
||||
rune_flags = NO_TALISMAN | CAN_MEMORIZE
|
||||
|
||||
/datum/rune/ethereal/do_rune_action(mob/living/user, atom/movable/A) //some bits copypastaed from admin tools - Urist
|
||||
if(get_turf(user) == get_turf(A) && ishuman(user))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/rune/hide_runes
|
||||
name = "concealment rune"
|
||||
desc = "This rune is used to conceal other runes in an area around us."
|
||||
rune_flags = CAN_MEMORIZE
|
||||
|
||||
/datum/rune/hide_runes/do_rune_action(mob/living/user, atom/movable/A)
|
||||
var/rune_found
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/rune/raise_dead
|
||||
name = "revival rune"
|
||||
desc = "This rune is used to revive a body in exchange for a dead sacrifice."
|
||||
rune_flags = NO_TALISMAN
|
||||
rune_flags = NO_TALISMAN | CAN_MEMORIZE
|
||||
|
||||
/datum/rune/raise_dead/do_rune_action(mob/living/user, atom/movable/A)
|
||||
var/mob/living/carbon/human/corpse_to_raise
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/rune/reveal_runes
|
||||
name = "revealing rune"
|
||||
desc = "This rune is used to reveal hidden runes in a radius around us."
|
||||
rune_flags = HAS_SPECIAL_TALISMAN_ACTION
|
||||
rune_flags = HAS_SPECIAL_TALISMAN_ACTION | CAN_MEMORIZE
|
||||
|
||||
/datum/rune/reveal_runes/do_rune_action(mob/living/user, atom/movable/A)
|
||||
reveal(user, A, 6, SPAN_WARNING("\The [A] turns into red dust, reveaing the surrounding runes."))
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
if(iscultist(user) || isobserver(user))
|
||||
to_chat(user, rune.get_cultist_fluff_text())
|
||||
to_chat(user, "This rune [rune.can_be_talisman() ? "<span class='cult'><b><i>can</i></b></span>" : "<span class='warning'><b><i>cannot</i></b></span>"] be turned into a talisman.")
|
||||
to_chat(user, "This rune [rune.can_memorize() ? "<span class='cult'><b><i>can</i></b></span>" : "<span class='warning'><b><i>cannot</i></b></span>"] be memorized to be scribed without a tome.")
|
||||
else
|
||||
to_chat(user, rune.get_normal_fluff_text())
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/rune/sacrifice
|
||||
name = "sacrificial rune"
|
||||
desc = "This rune is used to sacrifice an unbeliever."
|
||||
rune_flags = NO_TALISMAN
|
||||
rune_flags = NO_TALISMAN | CAN_MEMORIZE
|
||||
|
||||
/datum/rune/sacrifice/do_rune_action(mob/living/user, atom/movable/A)
|
||||
var/list/mob/living/carbon/human/cultists_in_range = list()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/rune/see_invisible
|
||||
name = "visibility rune"
|
||||
desc = "This rune is used to see the invisible."
|
||||
rune_flags = NO_TALISMAN
|
||||
rune_flags = NO_TALISMAN | CAN_MEMORIZE
|
||||
|
||||
/datum/rune/see_invisible/do_rune_action(mob/living/user, atom/movable/A)
|
||||
if(user.seer == TRUE)
|
||||
|
||||
@@ -600,7 +600,8 @@ datum/objective/capture
|
||||
n_p ++
|
||||
else if (SSticker.current_state == GAME_STATE_PLAYING)
|
||||
for(var/mob/living/carbon/human/P in player_list)
|
||||
if(P.client && !(P.mind.changeling) && P.mind!=owner)
|
||||
var/datum/changeling/changeling = P.mind.antag_datums[MODE_CHANGELING]
|
||||
if(P.client && !changeling && P.mind != owner)
|
||||
n_p ++
|
||||
target_amount = min(target_amount, n_p)
|
||||
|
||||
@@ -608,7 +609,8 @@ datum/objective/capture
|
||||
return target_amount
|
||||
|
||||
check_completion()
|
||||
if(owner && owner.changeling && owner.changeling.absorbed_dna && (owner.changeling.absorbedcount >= target_amount))
|
||||
var/datum/changeling/changeling = owner.antag_datums[MODE_CHANGELING]
|
||||
if(owner && changeling?.absorbed_dna && (changeling.absorbedcount >= target_amount))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
/datum/vampire/proc/lose_master(var/mob/M)
|
||||
QDEL_NULL(thrall_image)
|
||||
QDEL_NULL(master_image)
|
||||
if(master?.mind?.vampire)
|
||||
master.mind.vampire.thralls -= M
|
||||
if(master)
|
||||
var/datum/vampire/master_vampire = master.mind.antag_datums[MODE_VAMPIRE]
|
||||
master_vampire.thralls -= M
|
||||
master = null
|
||||
@@ -2,26 +2,28 @@
|
||||
/mob/proc/make_vampire()
|
||||
if (!mind)
|
||||
return
|
||||
if (!mind.vampire)
|
||||
mind.vampire = new /datum/vampire()
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(!vampire)
|
||||
mind.antag_datums[MODE_VAMPIRE] = new /datum/vampire()
|
||||
vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
// No powers to thralls. Ew.
|
||||
if (mind.vampire.status & VAMP_ISTHRALL)
|
||||
if(vampire.status & VAMP_ISTHRALL)
|
||||
return
|
||||
|
||||
mind.vampire.blood_usable += 30
|
||||
vampire.blood_usable += 30
|
||||
|
||||
if(client)
|
||||
mind.vampire.blood_hud = new /obj/screen/vampire/blood()
|
||||
mind.vampire.frenzy_hud = new /obj/screen/vampire/frenzy()
|
||||
client.screen += mind.vampire.blood_hud
|
||||
client.screen += mind.vampire.frenzy_hud
|
||||
vampire.blood_hud = new /obj/screen/vampire/blood()
|
||||
vampire.frenzy_hud = new /obj/screen/vampire/frenzy()
|
||||
client.screen += vampire.blood_hud
|
||||
client.screen += vampire.frenzy_hud
|
||||
|
||||
verbs += new /datum/antagonist/vampire/proc/vampire_help
|
||||
|
||||
for(var/datum/power/vampire/P in vampirepowers)
|
||||
if(!(P in mind.vampire.purchased_powers))
|
||||
if(!(P in vampire.purchased_powers))
|
||||
if(!P.blood_cost)
|
||||
mind.vampire.add_power(mind, P, 0)
|
||||
vampire.add_power(mind, P, 0)
|
||||
else if(P.isVerb && P.verbpath)
|
||||
verbs += P.verbpath
|
||||
|
||||
@@ -29,11 +31,10 @@
|
||||
|
||||
// Checks the vampire's bloodlevel and unlocks new powers based on that.
|
||||
/mob/proc/check_vampire_upgrade()
|
||||
if (!mind.vampire)
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(!vampire)
|
||||
return
|
||||
|
||||
var/datum/vampire/vampire = mind.vampire
|
||||
|
||||
for (var/datum/power/vampire/P in vampirepowers)
|
||||
if (P.blood_cost <= vampire.blood_total)
|
||||
if (!(P in vampire.purchased_powers))
|
||||
@@ -50,7 +51,7 @@
|
||||
if (!ishuman(src))
|
||||
return
|
||||
|
||||
var/datum/vampire/vampire = mind.vampire
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if (!vampire)
|
||||
log_debug("[src] has a vampire power but is not a vampire.")
|
||||
return
|
||||
@@ -73,26 +74,30 @@
|
||||
/mob/proc/vampire_can_affect_target(var/mob/living/carbon/human/T, var/notify = 1, var/account_loyalty_implant = 0, var/ignore_thrall = FALSE, var/affect_ipc = TRUE)
|
||||
if (!T || !istype(T))
|
||||
return FALSE
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
// How did you even get here?
|
||||
if (!mind.vampire)
|
||||
if (!vampire)
|
||||
return FALSE
|
||||
if ((mind.vampire.status & VAMP_FULLPOWER) && !(T.mind && T.mind.vampire && (T.mind.vampire.status & VAMP_FULLPOWER)))
|
||||
return TRUE
|
||||
if (T.mind)
|
||||
if (T.mind.assigned_role == "Chaplain")
|
||||
if (notify)
|
||||
var/datum/vampire/vampire_check
|
||||
if(T.mind)
|
||||
if(T.mind.assigned_role == "Chaplain")
|
||||
if(notify)
|
||||
to_chat(src, "<span class='warning'>Your connection with the Veil is not strong enough to affect a man as devout as them.</span>")
|
||||
return FALSE
|
||||
else if (T.mind.vampire && (!(T.mind.vampire.status & VAMP_ISTHRALL) || ((T.mind.vampire.status & VAMP_ISTHRALL) && !ignore_thrall)))
|
||||
if (notify)
|
||||
to_chat(src, "<span class='warning'>You lack the power required to affect another creature of the Veil.</span>")
|
||||
return FALSE
|
||||
|
||||
vampire_check = T.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire_check)
|
||||
if(!(vampire_check.status & VAMP_ISTHRALL && ignore_thrall))
|
||||
if(notify)
|
||||
to_chat(src, "<span class='warning'>You lack the power required to affect another creature of the Veil.</span>")
|
||||
return FALSE
|
||||
if(vampire_check)
|
||||
if((vampire.status & VAMP_FULLPOWER) && !(vampire_check.status & VAMP_FULLPOWER))
|
||||
return TRUE
|
||||
if(!affect_ipc && isipc(T))
|
||||
if (notify)
|
||||
to_chat(src, SPAN_WARNING("You lack the power to interact with mechanical constructs."))
|
||||
return FALSE
|
||||
if(is_special_character(T) && (!(T.mind.vampire.status & VAMP_ISTHRALL)))
|
||||
if(is_special_character(T) && (!(vampire_check.status & VAMP_ISTHRALL)))
|
||||
if (notify)
|
||||
to_chat(src, "<span class='warning'>\The [T]'s mind is too strong to be affected by our powers!</span>")
|
||||
return FALSE
|
||||
@@ -123,13 +128,14 @@
|
||||
return
|
||||
|
||||
var/datum/vampire/thrall/thrall = new()
|
||||
mind.vampire = thrall
|
||||
mind.antag_datums[MODE_VAMPIRE] = thrall
|
||||
|
||||
/mob/proc/vampire_check_frenzy(var/force_frenzy = 0)
|
||||
if (!mind || !mind.vampire)
|
||||
if(!mind)
|
||||
return
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(!vampire)
|
||||
return
|
||||
|
||||
var/datum/vampire/vampire = mind.vampire
|
||||
// Thralls don't frenzy.
|
||||
if (vampire.status & VAMP_ISTHRALL)
|
||||
return
|
||||
@@ -176,8 +182,7 @@
|
||||
vampire.last_frenzy_message = world.time
|
||||
|
||||
/mob/proc/vampire_start_frenzy(var/force_frenzy = 0)
|
||||
var/datum/vampire/vampire = mind.vampire
|
||||
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if (vampire.status & VAMP_FRENZIED)
|
||||
return
|
||||
|
||||
@@ -196,7 +201,7 @@
|
||||
verbs += /mob/living/carbon/human/proc/grapple
|
||||
|
||||
/mob/proc/vampire_stop_frenzy(var/force_stop = 0)
|
||||
var/datum/vampire/vampire = mind.vampire
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
|
||||
if (!(vampire.status & VAMP_FRENZIED))
|
||||
return
|
||||
@@ -217,57 +222,63 @@
|
||||
|
||||
// Removes all vampire powers.
|
||||
/mob/proc/remove_vampire_powers()
|
||||
if (!mind || !mind.vampire)
|
||||
if(!mind)
|
||||
return
|
||||
|
||||
for (var/datum/power/vampire/P in mind.vampire.purchased_powers)
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(!vampire)
|
||||
return
|
||||
for (var/datum/power/vampire/P in vampire.purchased_powers)
|
||||
if (P.isVerb)
|
||||
verbs -= P.verbpath
|
||||
|
||||
if (mind.vampire.status & VAMP_FRENZIED)
|
||||
if (vampire.status & VAMP_FRENZIED)
|
||||
vampire_stop_frenzy(1)
|
||||
|
||||
/mob/proc/handle_vampire()
|
||||
if(mind.vampire.status & VAMP_ISTHRALL)
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire.status & VAMP_ISTHRALL)
|
||||
return
|
||||
|
||||
// Apply frenzy while in the chapel.
|
||||
if (istype(get_area(loc), /area/chapel))
|
||||
mind.vampire.frenzy += 3
|
||||
vampire.frenzy += 3
|
||||
|
||||
if (mind.vampire.blood_usable < 10)
|
||||
mind.vampire.frenzy += 2
|
||||
else if (mind.vampire.frenzy > 0)
|
||||
mind.vampire.frenzy = max(0, mind.vampire.frenzy -= Clamp(mind.vampire.blood_usable * 0.1, 1, 10))
|
||||
if (vampire.blood_usable < 10)
|
||||
vampire.frenzy += 2
|
||||
else if (vampire.frenzy > 0)
|
||||
vampire.frenzy = max(0, vampire.frenzy -= Clamp(vampire.blood_usable * 0.1, 1, 10))
|
||||
|
||||
mind.vampire.frenzy = round(min(mind.vampire.frenzy, 450))
|
||||
vampire.frenzy = round(min(vampire.frenzy, 450))
|
||||
|
||||
vampire_check_frenzy()
|
||||
|
||||
if(client)
|
||||
if(!mind.vampire.blood_hud)
|
||||
mind.vampire.blood_hud = new /obj/screen/vampire/blood()
|
||||
client.screen += mind.vampire.blood_hud
|
||||
if(!mind.vampire.frenzy_hud)
|
||||
mind.vampire.frenzy_hud = new /obj/screen/vampire/frenzy()
|
||||
client.screen += mind.vampire.frenzy_hud
|
||||
if(!mind.vampire.blood_suck_hud)
|
||||
mind.vampire.blood_suck_hud = new /obj/screen/vampire/suck()
|
||||
client.screen += mind.vampire.blood_suck_hud
|
||||
if(!vampire.blood_hud)
|
||||
vampire.blood_hud = new /obj/screen/vampire/blood()
|
||||
client.screen += vampire.blood_hud
|
||||
if(!vampire.frenzy_hud)
|
||||
vampire.frenzy_hud = new /obj/screen/vampire/frenzy()
|
||||
client.screen += vampire.frenzy_hud
|
||||
if(!vampire.blood_suck_hud)
|
||||
vampire.blood_suck_hud = new /obj/screen/vampire/suck()
|
||||
client.screen += vampire.blood_suck_hud
|
||||
|
||||
mind.vampire.blood_hud.maptext = SMALL_FONTS(7, mind.vampire.blood_usable)
|
||||
if(mind.vampire.frenzy)
|
||||
if(!mind.vampire.frenzy_hud.alpha)
|
||||
animate(mind.vampire.frenzy_hud, 1 SECOND, alpha = 255, LINEAR_EASING)
|
||||
mind.vampire.frenzy_hud.maptext = SMALL_FONTS(7, mind.vampire.frenzy)
|
||||
vampire.blood_hud.maptext = SMALL_FONTS(7, vampire.blood_usable)
|
||||
if(vampire.frenzy)
|
||||
if(!vampire.frenzy_hud.alpha)
|
||||
animate(vampire.frenzy_hud, 1 SECOND, alpha = 255, LINEAR_EASING)
|
||||
vampire.frenzy_hud.maptext = SMALL_FONTS(7, vampire.frenzy)
|
||||
else
|
||||
if(mind.vampire.frenzy_hud.alpha)
|
||||
animate(mind.vampire.frenzy_hud, 1 SECOND, alpha = 0, LINEAR_EASING)
|
||||
mind.vampire.frenzy_hud.maptext = null
|
||||
if(vampire.frenzy_hud.alpha)
|
||||
animate(vampire.frenzy_hud, 1 SECOND, alpha = 0, LINEAR_EASING)
|
||||
vampire.frenzy_hud.maptext = null
|
||||
|
||||
/mob/living/carbon/human/proc/finish_vamp_timeout(vamp_flags = 0)
|
||||
if (!mind || !mind.vampire)
|
||||
if(!mind)
|
||||
return FALSE
|
||||
if (vamp_flags && !(mind.vampire.status & vamp_flags))
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(!vampire)
|
||||
return FALSE
|
||||
if (vamp_flags && !(vampire.status & vamp_flags))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
return
|
||||
|
||||
var/datum/vampire/draining_vamp = null
|
||||
if(T.mind?.vampire)
|
||||
draining_vamp = T.mind.vampire
|
||||
if(T.mind)
|
||||
draining_vamp = T.mind.antag_datums[MODE_VAMPIRE]
|
||||
|
||||
var/target_aware = !!T.client
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
playsound(src.loc, 'sound/effects/drain_blood_new.ogg', 50, 1)
|
||||
|
||||
while(do_mob(src, T, 50) && vampire.status & VAMP_DRAINING && vampire.blood_usable < VAMPIRE_MAX_USABLE_BLOOD)
|
||||
if(!mind.vampire)
|
||||
if(!vampire)
|
||||
to_chat(src, SPAN_DANGER("Your fangs have disappeared!"))
|
||||
return
|
||||
|
||||
@@ -498,7 +498,8 @@
|
||||
last_valid_turf = get_turf(owner.loc)
|
||||
owner.forceMove(src)
|
||||
|
||||
if(owner.mind.vampire.status & VAMP_FULLPOWER)
|
||||
var/datum/vampire/vampire = owner_mob.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire.status & VAMP_FULLPOWER)
|
||||
for(var/obj/item/grab/G in list(owner.l_hand, owner.r_hand))
|
||||
G.affecting.vampire_phase_out(get_turf(G))
|
||||
G.affecting.forceMove(src)
|
||||
@@ -748,8 +749,9 @@
|
||||
to_chat(T, SPAN_DANGER("Your mind blanks as you finish feeding from [src]'s wrist."))
|
||||
thralls.add_antagonist(T.mind, 1, 1, 0, 1, 1)
|
||||
|
||||
T.mind.vampire.assign_master(T, src, vampire)
|
||||
to_chat(T, SPAN_NOTICE("You have been forced into a blood bond by [T.mind.vampire.master], and are thus their thrall. While a thrall may feel a myriad of emotions towards their master, ranging from fear, to hate, to love; the supernatural bond between them still forces the thrall to obey their master, and to listen to the master's commands.<br><br>You must obey your master's orders, you must protect them, you cannot harm them."))
|
||||
var/datum/vampire/T_vampire = T.mind.antag_datums[MODE_VAMPIRE]
|
||||
T_vampire.assign_master(T, src, vampire)
|
||||
to_chat(T, SPAN_NOTICE("You have been forced into a blood bond by [T_vampire.master], and are thus their thrall. While a thrall may feel a myriad of emotions towards their master, ranging from fear, to hate, to love; the supernatural bond between them still forces the thrall to obey their master, and to listen to the master's commands.<br><br>You must obey your master's orders, you must protect them, you cannot harm them."))
|
||||
to_chat(src, SPAN_NOTICE("You have completed the thralling process. They are now your slave and will obey your commands."))
|
||||
admin_attack_log(src, T, "enthralled [key_name(T)]", "was enthralled by [key_name(src)]", "successfully enthralled")
|
||||
|
||||
@@ -882,30 +884,30 @@
|
||||
to_chat(src, SPAN_WARNING("Your fangs are already sunk into a victim's neck!"))
|
||||
return
|
||||
|
||||
if(T.mind.vampire)
|
||||
var/datum/vampire/draining_vamp = T.mind.vampire
|
||||
if(T.mind)
|
||||
var/datum/vampire/draining_vamp = T.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(draining_vamp)
|
||||
if(draining_vamp.status & VAMP_ISTHRALL)
|
||||
var/choice_text = ""
|
||||
var/denial_response = ""
|
||||
if(draining_vamp.master == src)
|
||||
choice_text = "[T] is your thrall. Do you wish to release them from the blood bond and give them the chance to become your equal?"
|
||||
denial_response = "You opt against giving [T] a chance to ascend, and choose to keep them as a servant."
|
||||
else
|
||||
choice_text = "You can feel the taint of another master running in the veins of [T]. Do you wish to release them of their blood bond, and convert them into a vampire, in spite of their master?"
|
||||
denial_response = "You choose not to continue with the Embrace, and permit [T] to keep serving their master."
|
||||
|
||||
if(draining_vamp.status & VAMP_ISTHRALL)
|
||||
var/choice_text = ""
|
||||
var/denial_response = ""
|
||||
if(draining_vamp.master == src)
|
||||
choice_text = "[T] is your thrall. Do you wish to release them from the blood bond and give them the chance to become your equal?"
|
||||
denial_response = "You opt against giving [T] a chance to ascend, and choose to keep them as a servant."
|
||||
if(alert(src, choice_text, "Choices", "Yes", "No") == "No")
|
||||
to_chat(src, SPAN_NOTICE("[denial_response]"))
|
||||
return
|
||||
|
||||
thralls.remove_antagonist(T.mind, 0, 0)
|
||||
qdel(draining_vamp)
|
||||
draining_vamp = null
|
||||
else
|
||||
choice_text = "You can feel the taint of another master running in the veins of [T]. Do you wish to release them of their blood bond, and convert them into a vampire, in spite of their master?"
|
||||
denial_response = "You choose not to continue with the Embrace, and permit [T] to keep serving their master."
|
||||
|
||||
if(alert(src, choice_text, "Choices", "Yes", "No") == "No")
|
||||
to_chat(src, SPAN_NOTICE("[denial_response]"))
|
||||
to_chat(src, SPAN_WARNING("You feel corruption running in [T]'s blood. Much like yourself, [T.get_pronoun("he")] is already a spawn of the Veil, and cannot be Embraced."))
|
||||
return
|
||||
|
||||
thralls.remove_antagonist(T.mind, 0, 0)
|
||||
qdel(draining_vamp)
|
||||
draining_vamp = null
|
||||
else
|
||||
to_chat(src, SPAN_WARNING("You feel corruption running in [T]'s blood. Much like yourself, [T.get_pronoun("he")] is already a spawn of the Veil, and cannot be Embraced."))
|
||||
return
|
||||
|
||||
vampire.status |= VAMP_DRAINING
|
||||
|
||||
visible_message(SPAN_DANGER("[src] bites [T]'s neck!"), SPAN_DANGER("You bite [T]'s neck and begin to drain their blood, as the first step of introducing the corruption of the Veil to them."), SPAN_NOTICE("You hear a soft puncture and a wet sucking noise."))
|
||||
@@ -914,7 +916,7 @@
|
||||
|
||||
var/drained_all_blood = FALSE
|
||||
while(do_mob(src, T, 50))
|
||||
if(!mind.vampire)
|
||||
if(!vampire)
|
||||
to_chat(src, SPAN_WARNING("Your fangs have disappeared!"))
|
||||
return
|
||||
if(!T.vessel.get_reagent_amount(/datum/reagent/blood))
|
||||
@@ -947,8 +949,9 @@
|
||||
to_chat(T, SPAN_DANGER("You awaken. Moments ago, you were dead, your conciousness still forced stuck inside your body. Now you live. You feel different, a strange, dark force now present within you. You have an insatiable desire to drain the blood of mortals, and to grow in power."))
|
||||
to_chat(src, SPAN_WARNING("You have corrupted another mortal with the taint of the Veil. Beware: they will awaken hungry and maddened; not bound to any master."))
|
||||
|
||||
T.mind.vampire.blood_usable = 0
|
||||
T.mind.vampire.frenzy = 250
|
||||
var/datum/vampire/T_vampire = T.mind.antag_datums[MODE_VAMPIRE]
|
||||
T_vampire.blood_usable = 0
|
||||
T_vampire.frenzy = 250
|
||||
T.vampire_check_frenzy()
|
||||
|
||||
vampire.status &= ~VAMP_DRAINING
|
||||
@@ -1015,4 +1018,4 @@
|
||||
G.synch()
|
||||
|
||||
verbs -= /mob/living/carbon/human/proc/grapple
|
||||
ADD_VERB_IN_IF(src, 800, /mob/living/carbon/human/proc/grapple, CALLBACK(src, .proc/finish_vamp_timeout, VAMP_FRENZIED))
|
||||
ADD_VERB_IN_IF(src, 800, /mob/living/carbon/human/proc/grapple, CALLBACK(src, .proc/finish_vamp_timeout, VAMP_FRENZIED))
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
return TRUE
|
||||
if(ishuman(mover))
|
||||
var/mob/living/carbon/human/H = mover
|
||||
if(H.mind.changeling)
|
||||
if(H.mind.antag_datums[MODE_CHANGELING])
|
||||
return TRUE
|
||||
|
||||
/obj/structure/gore/tendrils/Destroy()
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
var/list/ui_users = list()
|
||||
|
||||
/obj/structure/mirror/attack_hand(mob/user as mob)
|
||||
if(shattered)
|
||||
return
|
||||
|
||||
if(shattered) return
|
||||
|
||||
if(user.mind && user.mind.vampire && (!(user.mind.vampire.status & VAMP_ISTHRALL)))
|
||||
to_chat(user, "<span class='notice'>Your reflection appears distorted on the surface of \the [src].</span>")
|
||||
if(user.mind)
|
||||
var/datum/vampire/vampire = user.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire && !(vampire.status & VAMP_ISTHRALL))
|
||||
to_chat(user, "<span class='notice'>Your reflection appears distorted on the surface of \the [src].</span>")
|
||||
|
||||
if(ishuman(user))
|
||||
var/datum/nano_module/appearance_changer/AC = ui_users[user]
|
||||
@@ -82,9 +84,10 @@
|
||||
var/list/ui_users = list()
|
||||
|
||||
/obj/item/mirror/attack_self(mob/user as mob)
|
||||
|
||||
if(user.mind && user.mind.vampire && (!(user.mind.vampire.status & VAMP_ISTHRALL)))
|
||||
to_chat(user, "<span class='notice'>Your reflection appears distorted on the surface of \the [src].</span>")
|
||||
if(user.mind)
|
||||
var/datum/vampire/vampire = user.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire && !(vampire.status & VAMP_ISTHRALL))
|
||||
to_chat(user, "<span class='notice'>Your reflection appears distorted on the surface of \the [src].</span>")
|
||||
|
||||
if(ishuman(user))
|
||||
var/datum/nano_module/appearance_changer/AC = ui_users[user]
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
|
||||
/datum/language/ling/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
|
||||
|
||||
if(speaker.mind && speaker.mind.changeling)
|
||||
..(speaker,message,speaker.mind.changeling.changelingID)
|
||||
else
|
||||
..(speaker,message)
|
||||
if(speaker.mind)
|
||||
var/datum/changeling/changeling = speaker.mind.antag_datums[MODE_CHANGELING]
|
||||
if(changeling)
|
||||
..(speaker,message, changeling.changelingID)
|
||||
return
|
||||
..(speaker,message)
|
||||
|
||||
/datum/language/corticalborer
|
||||
name = LANGUAGE_BORER
|
||||
|
||||
@@ -210,12 +210,14 @@
|
||||
stat(null, "Suit charge: [cell_status]")
|
||||
|
||||
if(mind)
|
||||
if(mind.vampire)
|
||||
stat("Usable Blood", mind.vampire.blood_usable)
|
||||
stat("Total Blood", mind.vampire.blood_total)
|
||||
if(mind.changeling)
|
||||
stat("Chemical Storage", mind.changeling.chem_charges)
|
||||
stat("Genetic Damage Time", mind.changeling.geneticdamage)
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire)
|
||||
stat("Usable Blood", vampire.blood_usable)
|
||||
stat("Total Blood", vampire.blood_total)
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(changeling)
|
||||
stat("Chemical Storage", changeling.chem_charges)
|
||||
stat("Genetic Damage Time", changeling.geneticdamage)
|
||||
|
||||
/mob/living/carbon/human/ex_act(severity)
|
||||
if(!blinded)
|
||||
@@ -2016,8 +2018,10 @@
|
||||
/mob/living/carbon/human/get_accent_icon(var/datum/language/speaking, var/mob/hearer, var/force_accent)
|
||||
var/used_accent = accent //starts with the mob's default accent
|
||||
|
||||
if(mind?.changeling)
|
||||
used_accent = mind.changeling.mimiced_accent
|
||||
if(mind)
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(changeling?.mimiced_accent)
|
||||
used_accent = changeling.mimiced_accent
|
||||
|
||||
if(istype(back,/obj/item/rig)) //checks for the rig voice changer module
|
||||
var/obj/item/rig/rig = back
|
||||
|
||||
@@ -87,8 +87,12 @@
|
||||
tally = max(0, tally-3)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && !mind.changeling) // changelings don't get movement costs
|
||||
tally += T.movement_cost
|
||||
if(T) // changelings don't get movement costs
|
||||
var/datum/changeling/changeling
|
||||
if(mind)
|
||||
changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(!changeling)
|
||||
tally += T.movement_cost
|
||||
|
||||
tally += config.human_delay
|
||||
|
||||
|
||||
@@ -84,8 +84,10 @@
|
||||
//Update our name based on whether our face is obscured/disfigured
|
||||
name = get_visible_name()
|
||||
|
||||
if(mind?.vampire)
|
||||
handle_vampire()
|
||||
if(mind)
|
||||
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire)
|
||||
handle_vampire()
|
||||
|
||||
/mob/living/carbon/human/think()
|
||||
..()
|
||||
@@ -1041,8 +1043,10 @@
|
||||
playsound_simple(null, pick(scarySounds), 50, TRUE)
|
||||
|
||||
/mob/living/carbon/human/proc/handle_changeling()
|
||||
if(mind && mind.changeling)
|
||||
mind.changeling.regenerate()
|
||||
if(mind)
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(changeling)
|
||||
changeling.regenerate()
|
||||
|
||||
/mob/living/carbon/human/proc/handle_shock()
|
||||
if(status_flags & GODMODE)
|
||||
|
||||
@@ -79,8 +79,10 @@
|
||||
var/obj/item/organ/external/head/face = organs_by_name[BP_HEAD]
|
||||
if(face?.disfigured) // if your face is ruined, your ability to vocalize is also ruined
|
||||
return "Unknown" // above ling voice mimicing so they don't get caught out immediately
|
||||
if(mind?.changeling?.mimicing)
|
||||
return mind.changeling.mimicing
|
||||
if(mind)
|
||||
var/datum/changeling/changeling = mind.antag_datums[MODE_CHANGELING]
|
||||
if(changeling?.mimicing)
|
||||
return changeling.mimicing
|
||||
if(GetSpecialVoice())
|
||||
return GetSpecialVoice()
|
||||
return real_name
|
||||
|
||||
@@ -213,7 +213,10 @@
|
||||
|
||||
if (!injected || !our)
|
||||
return
|
||||
if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"],injected.data["species"],our.data["species"]) && !(mind && mind.vampire))
|
||||
var/datum/vampire/vampire
|
||||
if(mind)
|
||||
vampire = mind.antag_datums[MODE_VAMPIRE]
|
||||
if(!vampire && blood_incompatible(injected.data["blood_type"],our.data["blood_type"],injected.data["species"],our.data["species"]))
|
||||
reagents.add_reagent(/datum/reagent/toxin,amount * 0.5)
|
||||
reagents.update_total()
|
||||
else
|
||||
|
||||
@@ -48,11 +48,12 @@
|
||||
|
||||
/datum/reagent/blood/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
if(ishuman(M))
|
||||
if (M.mind && M.mind.vampire)
|
||||
if(M.mind)
|
||||
var/datum/vampire/vampire = M.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(M.dna.unique_enzymes == data["blood_DNA"]) //so vampires can't drink their own blood
|
||||
return
|
||||
M.mind.vampire.blood_usable += removed
|
||||
to_chat(M, "<span class='notice'>You have accumulated [M.mind.vampire.blood_usable] [M.mind.vampire.blood_usable > 1 ? "units" : "unit"] of usable blood. It tastes quite stale.</span>")
|
||||
vampire.blood_usable += removed
|
||||
to_chat(M, "<span class='notice'>You have accumulated [vampire.blood_usable] [vampire.blood_usable > 1 ? "units" : "unit"] of usable blood. It tastes quite stale.</span>")
|
||||
return
|
||||
if(dose > 5)
|
||||
M.adjustToxLoss(removed)
|
||||
|
||||
@@ -218,11 +218,12 @@
|
||||
/datum/reagent/water/holywater/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
..()
|
||||
if(ishuman(M))
|
||||
if (M.mind && M.mind.vampire)
|
||||
var/datum/vampire/vampire = M.mind.vampire
|
||||
vampire.frenzy += removed * 5
|
||||
else if(M.mind && cult.is_antagonist(M.mind) && prob(10))
|
||||
cult.remove_antagonist(M.mind)
|
||||
if(M.mind)
|
||||
var/datum/vampire/vampire = M.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire)
|
||||
vampire.frenzy += removed * 5
|
||||
if(cult.is_antagonist(M.mind) && prob(10))
|
||||
cult.remove_antagonist(M.mind)
|
||||
if(alien && alien == IS_UNDEAD)
|
||||
M.adjust_fire_stacks(10)
|
||||
M.IgniteMob()
|
||||
|
||||
@@ -44,32 +44,34 @@
|
||||
if(51 to INFINITY) icon_state = "full"
|
||||
|
||||
/obj/item/reagent_containers/blood/attack(mob/living/carbon/human/M as mob, mob/living/carbon/human/user as mob, var/target_zone)
|
||||
if (user == M && (user.mind.vampire))
|
||||
if (being_feed)
|
||||
to_chat(user, "<span class='notice'>You are already feeding on \the [src].</span>")
|
||||
return
|
||||
if (reagents.get_reagent_amount(/datum/reagent/blood))
|
||||
user.visible_message("<span class='warning'>[user] raises \the [src] up to their mouth and bites into it.</span>", "<span class='notice'>You raise \the [src] up to your mouth and bite into it, starting to drain its contents.<br>You need to stand still.</span>")
|
||||
being_feed = TRUE
|
||||
vampire_marks = TRUE
|
||||
if (!LAZYLEN(src.other_DNA))
|
||||
LAZYADD(src.other_DNA, M.dna.unique_enzymes)
|
||||
src.other_DNA_type = "saliva"
|
||||
if(user == M && user.mind)
|
||||
var/datum/vampire/vampire = user.mind.antag_datums[MODE_VAMPIRE]
|
||||
if(vampire)
|
||||
if (being_feed)
|
||||
to_chat(user, "<span class='notice'>You are already feeding on \the [src].</span>")
|
||||
return
|
||||
if (reagents.get_reagent_amount(/datum/reagent/blood))
|
||||
user.visible_message("<span class='warning'>[user] raises \the [src] up to their mouth and bites into it.</span>", "<span class='notice'>You raise \the [src] up to your mouth and bite into it, starting to drain its contents.<br>You need to stand still.</span>")
|
||||
being_feed = TRUE
|
||||
vampire_marks = TRUE
|
||||
if (!LAZYLEN(src.other_DNA))
|
||||
LAZYADD(src.other_DNA, M.dna.unique_enzymes)
|
||||
src.other_DNA_type = "saliva"
|
||||
|
||||
while (do_after(user, 25, 5, 1))
|
||||
var/blood_taken = 0
|
||||
blood_taken = min(5, reagents.get_reagent_amount(/datum/reagent/blood)/4)
|
||||
while (do_after(user, 25, 5, 1))
|
||||
var/blood_taken = 0
|
||||
blood_taken = min(5, reagents.get_reagent_amount(/datum/reagent/blood)/4)
|
||||
|
||||
reagents.remove_reagent(/datum/reagent/blood, blood_taken*4)
|
||||
user.mind.vampire.blood_usable += blood_taken
|
||||
reagents.remove_reagent(/datum/reagent/blood, blood_taken*4)
|
||||
vampire.blood_usable += blood_taken
|
||||
|
||||
if (blood_taken)
|
||||
to_chat(user, "<span class='notice'>You have accumulated [user.mind.vampire.blood_usable] [user.mind.vampire.blood_usable > 1 ? "units" : "unit"] of usable blood. It tastes quite stale.</span>")
|
||||
if (blood_taken)
|
||||
to_chat(user, "<span class='notice'>You have accumulated [vampire.blood_usable] [vampire.blood_usable > 1 ? "units" : "unit"] of usable blood. It tastes quite stale.</span>")
|
||||
|
||||
if (reagents.get_reagent_amount(/datum/reagent/blood) < 1)
|
||||
break
|
||||
user.visible_message("<span class='warning'>[user] licks [user.get_pronoun("his")] fangs dry, lowering \the [src].</span>", "<span class='notice'>You lick your fangs clean of the tasteless blood.</span>")
|
||||
being_feed = FALSE
|
||||
if (reagents.get_reagent_amount(/datum/reagent/blood) < 1)
|
||||
break
|
||||
user.visible_message("<span class='warning'>[user] licks [user.get_pronoun("his")] fangs dry, lowering \the [src].</span>", "<span class='notice'>You lick your fangs clean of the tasteless blood.</span>")
|
||||
being_feed = FALSE
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
author: Geeves
|
||||
|
||||
delete-after: True
|
||||
|
||||
changes:
|
||||
- backend: "Converted how Vampire and Changeling variables are handled on the backend, let me know if there's something funky."
|
||||
- rscadd: "Cultists can now memorize up to three runes, and can scribe them at will without a tome, at the cost of taking three times longer to do so. Check the Cultists tab in the top right. Only specific runes can be memorized."
|
||||
Reference in New Issue
Block a user