diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 1464d037a32..e1f66449fd7 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -291,9 +291,16 @@
/datum/mind/proc/memory_edit_vampire(mob/living/carbon/human/H)
. = _memory_edit_header("vampire", list("traitorvamp"))
- if(has_antag_datum(/datum/antagonist/vampire))
+ var/datum/antagonist/vampire/vamp = has_antag_datum(/datum/antagonist/vampire)
+ if(vamp)
. += "VAMPIRE|no"
- if(objectives.len==0)
+ . += "
Usable blood: [vamp.bloodusable]"
+ . += " | Total blood: [vamp.bloodtotal]"
+ var/has_subclass = !QDELETED(vamp.subclass)
+ . += "
Subclass: [has_subclass ? capitalize(vamp.subclass.name) : "None"]"
+ if(has_subclass)
+ . += " | Force full power: [vamp.subclass.full_power_override ? "Yes" : "No"]"
+ if(!length(vamp.objectives))
. += "
Objectives are empty! Randomize!"
else
. += "vampire|NO"
@@ -1001,6 +1008,71 @@
log_admin("[key_name(usr)] has vampired [key_name(current)]")
message_admins("[key_name_admin(usr)] has vampired [key_name_admin(current)]")
+ if("edit_usable_blood")
+ var/new_usable = input(usr, "Select a new value:", "Modify usable blood") as null|num
+ if(isnull(new_usable) || new_usable < 0)
+ return
+ var/datum/antagonist/vampire/vamp = has_antag_datum(/datum/antagonist/vampire)
+ vamp.bloodusable = new_usable
+ current.update_action_buttons_icon()
+ log_admin("[key_name(usr)] has set [key_name(current)]'s usable blood to [new_usable].")
+ message_admins("[key_name_admin(usr)] has set [key_name_admin(current)]'s usable blood to [new_usable].")
+
+ if("edit_total_blood")
+ var/new_total = input(usr, "Select a new value:", "Modify total blood") as null|num
+ if(isnull(new_total) || new_total < 0)
+ return
+
+ var/datum/antagonist/vampire/vamp = has_antag_datum(/datum/antagonist/vampire)
+ if(new_total < vamp.bloodtotal)
+ if(alert(usr, "Note that reducing the vampire's total blood may remove some active powers. Continue?", "Confirm New Total", "Yes", "No") == "No")
+ return
+ vamp.remove_all_powers()
+
+ vamp.bloodtotal = new_total
+ vamp.check_vampire_upgrade()
+ log_admin("[key_name(usr)] has set [key_name(current)]'s total blood to [new_total].")
+ message_admins("[key_name_admin(usr)] has set [key_name_admin(current)]'s total blood to [new_total].")
+
+ if("change_subclass")
+ var/list/subclass_selection = list()
+ for(var/subtype in subtypesof(/datum/vampire_subclass))
+ var/datum/vampire_subclass/subclass = subtype
+ subclass_selection[capitalize(initial(subclass.name))] = subtype
+ subclass_selection["Let them choose (remove current subclass)"] = NONE
+
+ var/new_subclass_name = input(usr, "Choose a new subclass:", "Change Vampire Subclass") as null|anything in subclass_selection
+ if(!new_subclass_name)
+ return
+
+ var/datum/antagonist/vampire/vamp = has_antag_datum(/datum/antagonist/vampire)
+ var/subclass_type = subclass_selection[new_subclass_name]
+
+ if(subclass_type == NONE)
+ vamp.clear_subclass()
+ log_admin("[key_name(usr)] has removed [key_name(current)]'s vampire subclass.")
+ message_admins("[key_name_admin(usr)] has removed [key_name_admin(current)]'s vampire subclass.")
+ else
+ vamp.upgrade_tiers -= /obj/effect/proc_holder/spell/vampire/self/specialize
+ vamp.change_subclass(subclass_type)
+ log_admin("[key_name(usr)] has removed [key_name(current)]'s vampire subclass.")
+ message_admins("[key_name_admin(usr)] has removed [key_name_admin(current)]'s vampire subclass.")
+
+ if("full_power_override")
+ var/datum/antagonist/vampire/vamp = has_antag_datum(/datum/antagonist/vampire)
+ if(vamp.subclass.full_power_override)
+ vamp.subclass.full_power_override = FALSE
+ for(var/power in vamp.powers)
+ if(!is_type_in_list(power, vamp.subclass.fully_powered_abilities))
+ continue
+ vamp.remove_ability(power)
+ else
+ vamp.subclass.full_power_override = TRUE
+
+ vamp.check_full_power_upgrade()
+ log_admin("[key_name(usr)] set [key_name(current)]'s vampire 'full_power_overide' to [vamp.subclass.full_power_override].")
+ message_admins("[key_name_admin(usr)] set [key_name_admin(current)]'s vampire 'full_power_overide' to [vamp.subclass.full_power_override].")
+
if("autoobjectives")
var/datum/antagonist/vampire/V = has_antag_datum(/datum/antagonist/vampire)
V.give_objectives()
diff --git a/code/modules/antagonists/vampire/vamp_datum.dm b/code/modules/antagonists/vampire/vamp_datum.dm
index 3de37efd197..6ac2d30eaa3 100644
--- a/code/modules/antagonists/vampire/vamp_datum.dm
+++ b/code/modules/antagonists/vampire/vamp_datum.dm
@@ -90,8 +90,7 @@
/datum/antagonist/vampire/remove_innate_effects(mob/living/mob_override)
mob_override = ..()
- for(var/P in powers)
- remove_ability(P)
+ remove_all_powers()
var/datum/hud/hud = mob_override.hud_used
if(hud?.vampire_blood_display)
hud.remove_vampire_hud()
@@ -154,6 +153,39 @@
#undef BLOOD_GAINED_MODIFIER
+/**
+ * Remove the vampire's current subclass and add the specified one.
+ *
+ * Arguments:
+ * * new_subclass_type - a [/datum/vampire_subclass] typepath
+ */
+/datum/antagonist/vampire/proc/change_subclass(new_subclass_type)
+ if(isnull(new_subclass_type))
+ return
+ clear_subclass(FALSE)
+ add_subclass(new_subclass_type, log_choice = FALSE)
+
+/**
+ * Remove and delete the vampire's current subclass and all associated abilities.
+ *
+ * Arguments:
+ * * give_specialize_power - if the [specialize][/obj/effect/proc_holder/spell/vampire/self/specialize] power should be given back or not
+ */
+/datum/antagonist/vampire/proc/clear_subclass(give_specialize_power = TRUE)
+ if(give_specialize_power)
+ // Choosing a subclass in the first place removes this from `upgrade_tiers`, so add it back if needed.
+ upgrade_tiers[/obj/effect/proc_holder/spell/vampire/self/specialize] = 150
+ remove_all_powers()
+ QDEL_NULL(subclass)
+ check_vampire_upgrade()
+
+/**
+ * Removes all of the vampire's current powers.
+ */
+/datum/antagonist/vampire/proc/remove_all_powers()
+ for(var/power in powers)
+ remove_ability(power)
+
/datum/antagonist/vampire/proc/check_vampire_upgrade(announce = TRUE)
var/list/old_powers = powers.Copy()
@@ -173,7 +205,7 @@
/datum/antagonist/vampire/proc/check_full_power_upgrade()
- if(subclass.full_power_overide || (length(drained_humans) >= FULLPOWER_DRAINED_REQUIREMENT && bloodtotal >= FULLPOWER_BLOODTOTAL_REQUIREMENT))
+ if(subclass.full_power_override || (length(drained_humans) >= FULLPOWER_DRAINED_REQUIREMENT && bloodtotal >= FULLPOWER_BLOODTOTAL_REQUIREMENT))
subclass.add_full_power_abilities(src)
diff --git a/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm b/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm
index b08489cbdd4..7075c941d77 100644
--- a/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm
+++ b/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm
@@ -143,11 +143,12 @@
vamp.remove_ability(src)
-/datum/antagonist/vampire/proc/add_subclass(subclass_to_add, announce = TRUE)
+/datum/antagonist/vampire/proc/add_subclass(subclass_to_add, announce = TRUE, log_choice = TRUE)
var/datum/vampire_subclass/new_subclass = new subclass_to_add
subclass = new_subclass
check_vampire_upgrade(announce)
- SSblackbox.record_feedback("nested tally", "vampire_subclasses", 1, list("[new_subclass.name]"))
+ if(log_choice)
+ SSblackbox.record_feedback("nested tally", "vampire_subclasses", 1, list("[new_subclass.name]"))
/obj/effect/proc_holder/spell/vampire/glare
name = "Glare"
diff --git a/code/modules/antagonists/vampire/vampire_subclasses.dm b/code/modules/antagonists/vampire/vampire_subclasses.dm
index c4e290af120..1927ff73f4b 100644
--- a/code/modules/antagonists/vampire/vampire_subclasses.dm
+++ b/code/modules/antagonists/vampire/vampire_subclasses.dm
@@ -9,7 +9,8 @@
var/improved_rejuv_healing = FALSE
/// maximun number of thralls a vampire may have at a time. incremented as they grow stronger, up to a cap at full power.
var/thrall_cap = 1
- var/full_power_overide = FALSE
+ /// If true, lets the vampire have access to their full power abilities without meeting the blood requirement, or needing a certain number of drained humans.
+ var/full_power_override = FALSE
/datum/vampire_subclass/proc/add_subclass_ability(datum/antagonist/vampire/vamp)
for(var/thing in standard_powers)