diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm index 5442c621e1b..11500e125e4 100644 --- a/code/__DEFINES/mob.dm +++ b/code/__DEFINES/mob.dm @@ -1,17 +1,3 @@ -// Vampire power defines -#define VAMP_REJUV 1 -#define VAMP_GLARE 2 -#define VAMP_HYPNO 3 -#define VAMP_SHAPE 4 -#define VAMP_VISION 5 -#define VAMP_DISEASE 6 -#define VAMP_CLOAK 7 -#define VAMP_BATS 8 -#define VAMP_SCREAM 9 -#define VAMP_JAUNT 10 -#define VAMP_SLAVE 11 -#define VAMP_BLINK 12 -#define VAMP_FULL 13 ///////////////////ORGAN DEFINES/////////////////// // Organ defines. diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 56d8fac2d57..cfe913bd94e 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -886,9 +886,10 @@ if(src in ticker.mode.vampires) ticker.mode.vampires -= src special_role = null - current.remove_vampire_powers() + if(vampire) + vampire.remove_vampire_powers() + qdel(vampire) ticker.mode.update_vampire_icons_removed(src) - if(vampire) qdel(vampire) current << "You grow weak and lose your powers! You are no longer a vampire and are stuck in your current form!" log_admin("[key_name(usr)] has de-vampired [key_name(current)]") message_admins("[key_name_admin(usr)] has de-vampired [key_name_admin(current)]") diff --git a/code/datums/spell.dm b/code/datums/spell.dm index f129f085bdc..31da89fd424 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -88,10 +88,9 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin user << "Not when you're incapacitated." return 0 - if(ishuman(user)) - if(user.is_muzzled()) - user << "Mmmf mrrfff!" - return 0 + if(ishuman(user) && (invocation_type == "whisper" || invocation_type == "shout") && user.is_muzzled()) + user << "Mmmf mrrfff!" + return 0 var/obj/effect/proc_holder/spell/noclothes/spell = locate() in (user.spell_list | (user.mind ? user.mind.spell_list : list())) if(clothes_req && !(spell && istype(spell)))//clothes check if(!istype(user, /mob/living/carbon/human)) diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 7d304204613..264a280e3e0 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -37,7 +37,6 @@ var/vampire_amount = 4 - /datum/game_mode/vampire/announce() world << "The current game mode is - Vampires!" world << "There are Vampires from Space Transylvania on the station, keep your blood close and neck safe!" @@ -171,7 +170,8 @@ return /datum/game_mode/proc/grant_vampire_powers(mob/living/carbon/vampire_mob) - if(!istype(vampire_mob)) return + if(!istype(vampire_mob)) + return vampire_mob.make_vampire() /datum/game_mode/proc/greet_vampire(var/datum/mind/vampire, var/you_are=1) @@ -200,188 +200,131 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha var/mob/living/owner = null var/gender = FEMALE var/iscloaking = 0 // handles the vampire cloak toggle - var/list/powers = list() // list of available powers and passives, see defines in setup.dm + var/list/powers = list() // list of available powers and passives var/mob/living/carbon/human/draining // who the vampire is draining of blood var/nullified = 0 //Nullrod makes them useless for a short while. - var/upgradedRegen = 0 + var/list/upgrade_tiers = list( + /obj/effect/proc_holder/spell/vampire/self/rejuvenate = 0, + /obj/effect/proc_holder/spell/vampire/targetted/hypnotise = 0, + /obj/effect/proc_holder/spell/vampire/mob_aoe/glare = 0, + /datum/vampire_passive/vision = 100, + /obj/effect/proc_holder/spell/vampire/self/shapeshift = 100, + /obj/effect/proc_holder/spell/vampire/self/cloak = 150, + /obj/effect/proc_holder/spell/vampire/targetted/disease = 150, + /obj/effect/proc_holder/spell/vampire/bats = 200, + /obj/effect/proc_holder/spell/vampire/self/screech = 200, + /datum/vampire_passive/regen = 200, + /obj/effect/proc_holder/spell/vampire/shadowstep = 250, + /obj/effect/proc_holder/spell/vampire/self/jaunt = 300, + /obj/effect/proc_holder/spell/vampire/targetted/enthrall = 300, + /datum/vampire_passive/full = 500) + /datum/vampire/New(gend = FEMALE) gender = gend +/datum/vampire/proc/force_add_ability(path) + var/spell = new path(owner) + if(istype(spell, /obj/effect/proc_holder/spell)) + owner.mind.AddSpell(spell) + powers += spell + +/datum/vampire/proc/get_ability(path) + for(var/P in powers) + var/datum/power = P + if(power.type == path) + return power + return null + +/datum/vampire/proc/add_ability(path) + if(!get_ability(path)) + force_add_ability(path) + +/datum/vampire/proc/remove_ability(path) + var/A = get_ability(path) + if(A) + powers -= A + owner.mind.spell_list.Remove(A) + qdel(A) + /mob/proc/make_vampire() - if(!mind) return + if(!mind) + return + var/datum/vampire/vamp if(!mind.vampire) - mind.vampire = new /datum/vampire(gender) - mind.vampire.owner = src - verbs += /client/vampire/proc/vampire_rejuvinate - verbs += /client/vampire/proc/vampire_hypnotise - verbs += /client/vampire/proc/vampire_glare - //testing purposes REMOVE BEFORE PUSH TO MASTER - /*for(var/handler in typesof(/client/proc)) - if(findtext("[handler]","vampire_")) - verbs += handler*/ - for(var/i = 1; i <= 3; i++) // CHANGE TO 3 RATHER THAN 12 AFTER TESTING IS DONE - if(!(i in mind.vampire.powers)) - mind.vampire.powers.Add(i) + vamp = new /datum/vampire(gender) + vamp.owner = src + mind.vampire = vamp + else + vamp = mind.vampire + vamp.powers.Cut() + vamp.check_vampire_upgrade(0) - for(var/n in mind.vampire.powers) - switch(n) - if(VAMP_SHAPE) - verbs += /client/vampire/proc/vampire_shapeshift - if(VAMP_VISION) - continue - if(VAMP_DISEASE) - verbs += /client/vampire/proc/vampire_disease - if(VAMP_CLOAK) - verbs += /client/vampire/proc/vampire_cloak - if(VAMP_BATS) - verbs += /client/vampire/proc/vampire_bats - if(VAMP_SCREAM) - verbs += /client/vampire/proc/vampire_screech - if(VAMP_JAUNT) - verbs += /client/vampire/proc/vampire_jaunt - if(VAMP_BLINK) - verbs += /client/vampire/proc/vampire_shadowstep - if(VAMP_SLAVE) - verbs += /client/vampire/proc/vampire_enthrall - if(VAMP_FULL) - continue -/mob/proc/remove_vampire_powers() - for(var/handler in typesof(/client/vampire/proc)) - if(findtext("[handler]","vampire_")) - verbs -= handler +/datum/vampire/proc/remove_vampire_powers() + for(var/P in powers) + remove_ability(P) + owner.alpha = 255 -/mob/proc/handle_bloodsucking(mob/living/carbon/human/H) - src.mind.vampire.draining = H +/datum/vampire/proc/handle_bloodsucking(mob/living/carbon/human/H) + draining = H var/blood = 0 - var/bloodtotal = 0 //used to see if we increased our blood total - var/bloodusable = 0 //used to see if we increased our blood usable - src.attack_log += text("\[[time_stamp()]\] Bit [src.name] ([src.ckey]) in the neck and draining their blood") - H.attack_log += text("\[[time_stamp()]\] Has been bit in the neck by [src.name] ([src.ckey])") - log_attack("[src.name] ([src.ckey]) bit [H.name] ([H.ckey]) in the neck") - src.visible_message("\red [src.name] bites [H.name]'s neck!", "\red You bite [H.name]'s neck and begin to drain their blood.", "\blue You hear a soft puncture and a wet sucking noise") - if(!iscarbon(src)) + var/old_bloodtotal = 0 //used to see if we increased our blood total + var/old_bloodusable = 0 //used to see if we increased our blood usable + owner.attack_log += text("\[[time_stamp()]\] Bit [H] ([H.ckey]) in the neck and draining their blood") + H.attack_log += text("\[[time_stamp()]\] Has been bit in the neck by [owner] ([owner.ckey])") + log_attack("[owner] ([owner.ckey]) bit [H] ([H.ckey]) in the neck") + owner.visible_message("[owner] bites [H]'s neck!", "You bite [H]'s neck and begin to drain their blood.", "You hear a soft puncture and a wet sucking noise.") + if(!iscarbon(owner)) H.LAssailant = null else - H.LAssailant = src - while(do_mob(src, H, 50)) - if(!mind.vampire || !(mind in ticker.mode.vampires)) - src << "\red Your fangs have disappeared!" - return 0 - bloodtotal = src.mind.vampire.bloodtotal - bloodusable = src.mind.vampire.bloodusable + H.LAssailant = owner + while(do_mob(owner, H, 50)) + if(!(owner.mind in ticker.mode.vampires)) + owner << "Your fangs have disappeared!" + return + old_bloodtotal = bloodtotal + old_bloodusable = bloodusable if(!H.vessel.get_reagent_amount("blood")) - src << "\red They've got no blood left to give." + src << "They've got no blood left to give." break - if(H.stat < 2) //alive + if(H.stat < DEAD) blood = min(20, H.vessel.get_reagent_amount("blood")) // if they have less than 20 blood, give them the remnant else they get 20 blood - src.mind.vampire.bloodtotal += blood/2 //divide by 2 to counted the double suction since removing cloneloss -Melandor0 - src.mind.vampire.bloodusable += blood/2 - //H.adjust CloneLoss(10) No cloneloss -Melandor0 + bloodtotal += blood / 2 //divide by 2 to counted the double suction since removing cloneloss -Melandor0 + bloodusable += blood / 2 else blood = min(5, H.vessel.get_reagent_amount("blood")) // The dead only give 5 bloods - src.mind.vampire.bloodtotal += blood - if(bloodtotal != src.mind.vampire.bloodtotal) - src << "\blue You have accumulated [src.mind.vampire.bloodtotal] [src.mind.vampire.bloodtotal > 1 ? "units" : "unit"] of blood[src.mind.vampire.bloodusable != bloodusable ?", and have [src.mind.vampire.bloodusable] left to use" : "."]" - check_vampire_upgrade(mind) - H.vessel.remove_reagent("blood",25) - if(ishuman(src)) - var/mob/living/carbon/human/V = src - V.nutrition = min(450,V.nutrition+(blood/2)) + bloodtotal += blood + if(old_bloodtotal != bloodtotal) + owner << "You have accumulated [bloodtotal] [bloodtotal > 1 ? "units" : "unit"] of blood[bloodusable != old_bloodusable ? ", and have [bloodusable] left to use" : ""]." + check_vampire_upgrade() + H.vessel.remove_reagent("blood", 25) + if(ishuman(owner)) + var/mob/living/carbon/human/V = owner + V.nutrition = min(450, V.nutrition + (blood / 2)) - src.mind.vampire.draining = null - src << "\blue You stop draining [H.name] of blood." - return 1 + draining = null + owner << "You stop draining [H.name] of blood." -/mob/proc/check_vampire_upgrade(datum/mind/v) - if(!v) return - if(!v.vampire) return - var/datum/vampire/vamp = v.vampire - var/list/old_powers = vamp.powers.Copy() +/datum/vampire/proc/check_vampire_upgrade(announce = 1) + var/list/old_powers = powers.Copy() - // This used to be a switch statement. - // Don't use switch statements for shit like this, since blood can be any random-ass value. - // if(100) requires the blood to be at EXACTLY 100 units to trigger. - // if(blud >= 100) activates when blood is at or over 100 units. - // TODO: Make this modular. + for(var/ptype in upgrade_tiers) + var/level = upgrade_tiers[ptype] + if(bloodtotal >= level) + add_ability(ptype) - // TIER 1 - if(vamp.bloodtotal >= 100) - if(!(VAMP_VISION in vamp.powers)) - vamp.powers.Add(VAMP_VISION) - if(!(VAMP_SHAPE in vamp.powers)) - vamp.powers.Add(VAMP_SHAPE) + if(announce) + announce_new_power(old_powers) - // TIER 2 - if(vamp.bloodtotal >= 150) - if(!(VAMP_CLOAK in vamp.powers)) - vamp.powers.Add(VAMP_CLOAK) - if(!(VAMP_DISEASE in vamp.powers)) - vamp.powers.Add(VAMP_DISEASE) - - // TIER 3 - if(vamp.bloodtotal >= 200) - if(!(VAMP_BATS in vamp.powers)) - vamp.powers.Add(VAMP_BATS) - if(!(VAMP_SCREAM in vamp.powers)) - vamp.powers.Add(VAMP_SCREAM) - if(!(vamp.upgradedRegen)) // to prevent spamming - src << "Your rejuvination abilities have improved and will now heal you over time when used." - vamp.upgradedRegen = 1 - - // TIER 3.5 (/vg/) - if(vamp.bloodtotal >= 250) - if(!(VAMP_BLINK in vamp.powers)) - vamp.powers.Add(VAMP_BLINK) - - // TIER 4 - if(vamp.bloodtotal >= 300) - if(!(VAMP_JAUNT in vamp.powers)) - vamp.powers.Add(VAMP_JAUNT) - if(!(VAMP_SLAVE in vamp.powers)) - vamp.powers.Add(VAMP_SLAVE) - - // TIER 5 - if(vamp.bloodtotal >= 500) - if(!(VAMP_FULL in vamp.powers)) - vamp.powers.Add(VAMP_FULL) - - announce_new_power(old_powers, vamp.powers) - -/mob/proc/announce_new_power(list/old_powers, list/new_powers) - for(var/n in new_powers) - if(!(n in old_powers)) - switch(n) - if(VAMP_SHAPE) - src << "\blue You have gained the shapeshifting ability, at the cost of stored blood you can change your form permanently." - verbs += /client/vampire/proc/vampire_shapeshift - if(VAMP_VISION) - src << "\blue Your vampiric vision has improved." - //no verb - if(VAMP_DISEASE) - src << "\blue You have gained the Diseased Touch ability which causes those you touch to die shortly after unless treated medically." - verbs += /client/vampire/proc/vampire_disease - if(VAMP_CLOAK) - src << "\blue You have gained the Cloak of Darkness ability which when toggled makes you near invisible in the shroud of darkness." - verbs += /client/vampire/proc/vampire_cloak - if(VAMP_BATS) - src << "\blue You have gained the Summon Bats ability." - verbs += /client/vampire/proc/vampire_bats // work in progress - if(VAMP_SCREAM) - src << "\blue You have gained the Chriopteran Screech ability which stuns anything with ears in a large radius and shatters glass in the process." - verbs += /client/vampire/proc/vampire_screech - if(VAMP_JAUNT) - src << "\blue You have gained the Mist Form ability which allows you to take on the form of mist for a short period and pass over any obstacle in your path." - verbs += /client/vampire/proc/vampire_jaunt - if(VAMP_SLAVE) - src << "\blue You have gained the Enthrall ability which at a heavy blood cost allows you to enslave a human that is not loyal to any other for a random period of time." - verbs += /client/vampire/proc/vampire_enthrall - if(VAMP_BLINK) - src << "\blue You have gained the ability to shadowstep, which makes you disappear into nearby shadows at the cost of blood." - verbs += /client/vampire/proc/vampire_shadowstep - if(VAMP_FULL) - src << "\blue You have reached your full potential and are no longer weak to the effects of anything holy and your vision has been improved greatly." - //no verb +/datum/vampire/proc/announce_new_power(list/old_powers) + for(var/p in powers) + if(!(p in old_powers)) + if(istype(p, /obj/effect/proc_holder/spell/vampire)) + var/obj/effect/proc_holder/spell/vampire/power = p + owner << "[power.gain_desc]" + else if(istype(p, /datum/vampire_passive)) + var/datum/vampire_passive/power = p + owner << "[power.gain_desc]" //prepare for copypaste /datum/game_mode/proc/update_vampire_icons_added(datum/mind/vampire_mind) @@ -411,55 +354,79 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha //world << "Removed [vampire_mind.current.name] from vampire shit" vampire_mind.current << "\red The fog clouding your mind clears. You remember nothing from the moment you were enthralled until now." -/mob/living/carbon/human/proc/check_sun() - - var/ax = x - var/ay = y +/datum/vampire/proc/check_sun() + var/ax = owner.x + var/ay = owner.y for(var/i = 1 to 20) ax += sun.dx ay += sun.dy - var/turf/T = locate( round(ax,0.5),round(ay,0.5),z) + var/turf/T = locate(round(ax, 0.5), round(ay, 0.5), owner.z) - if(T.x == 1 || T.x==world.maxx || T.y==1 || T.y==world.maxy) + if(T.x == 1 || T.x == world.maxx || T.y == 1 || T.y == world.maxy) break if(T.density) return vamp_burn() -/mob/living/carbon/human/proc/handle_vampire() - if(hud_used) - if(!hud_used.vampire_blood_display) - hud_used.vampire_hud() - hud_used.vampire_blood_display.maptext = "
[mind.vampire.bloodusable]
" +/datum/vampire/proc/handle_vampire() + if(owner.hud_used) + var/datum/hud/hud = owner.hud_used + if(!hud.vampire_blood_display) + hud.vampire_hud() + hud.vampire_blood_display.maptext = "
[bloodusable]
" handle_vampire_cloak() - if(istype(loc, /turf/space)) + if(istype(owner.loc, /turf/space)) check_sun() - if(istype(loc.loc, /area/chapel) && !(VAMP_FULL in src.mind.vampire.powers)) + if(istype(owner.loc.loc, /area/chapel) && !get_ability(/datum/vampire_passive/full)) vamp_burn() - mind.vampire.nullified = max(0, mind.vampire.nullified - 1) + nullified = max(0, nullified - 1) -mob/living/carbon/human/proc/vamp_burn() - if(prob(35)) - switch(health) - if(80 to 100) - src << "\red Your skin flakes away..." - if(60 to 80) - src << "Your skin sizzles!" - if((-INFINITY) to 60) - if(!on_fire) - src << "\red Your skin catches fire!" - else - src << "\red You continue to burn!" - fire_stacks += 5 - IgniteMob() - emote("scream") +/datum/vampire/proc/handle_vampire_cloak() + if(!ishuman(owner)) + owner.alpha = 255 + return + var/turf/simulated/T = get_turf(owner) + var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T + var/light_available + if(L) + light_available = L.get_clamped_lum(0.5) * 10 else - switch(health) + light_available = 10 + + if(!istype(T)) + return 0 + + if(!iscloaking) + owner.alpha = 255 + return 0 + if(light_available <= 2) + owner.alpha = round((255 * 0.15)) + return 1 + else + owner.alpha = round((255 * 0.80)) + +/datum/vampire/proc/vamp_burn() + if(prob(35)) + switch(owner.health) + if(80 to 100) + owner << "Your skin flakes away..." + if(60 to 80) + owner << "Your skin sizzles!" if((-INFINITY) to 60) - fire_stacks++ - IgniteMob() - adjustFireLoss(3) - return + if(!owner.on_fire) + owner << "Your skin catches fire!" + else + owner << "You continue to burn!" + owner.fire_stacks += 5 + owner.IgniteMob() + owner.emote("scream") + else + switch(owner.health) + if((-INFINITY) to 60) + owner.fire_stacks++ + owner.IgniteMob() + owner.adjustFireLoss(3) + return \ No newline at end of file diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 5794b144d51..d8dc1211b7b 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -1,296 +1,307 @@ //This should hold all the vampire related powers +/obj/effect/proc_holder/spell/vampire + panel = "Vampire" + school = "vampire" + clothes_req = 0 + range = 1 + charge_max = 1800 + action_background_icon_state = "bg_vampire" + var/required_blood = 0 + var/gain_desc = null -/mob/proc/vampire_power(required_blood=0, max_stat=0) +/obj/effect/proc_holder/spell/vampire/New() + ..() + if(!gain_desc) + gain_desc = "You have gained \the [src] ability." - if(!src.mind) return 0 - if(!ishuman(src)) - src << "You are in too weak of a form to do this!" +/obj/effect/proc_holder/spell/vampire/cast_check(skipcharge = 0, mob/living/user = usr) + if(!user.mind) + return 0 + if(!ishuman(user)) + user << "You are in too weak of a form to do this!" return 0 - var/datum/vampire/vampire = src.mind.vampire + var/datum/vampire/vampire = user.mind.vampire if(!vampire) - log_to_dd("[src] has vampire verbs but isn't a vampire.") return 0 - var/fullpower = (VAMP_FULL in vampire.powers) + var/fullpower = vampire.get_ability(/datum/vampire_passive/full) - if(src.stat > max_stat) - src << "You are incapacitated." + if(user.stat >= DEAD) + user << "Not when you're dead!" return 0 - if(vampire.nullified) - if(!fullpower) - src << "Something is blocking your powers!" - return 0 + if(vampire.nullified && !fullpower) + user << "Something is blocking your powers!" + return 0 if(vampire.bloodusable < required_blood) - src << "You require at least [required_blood] units of usable blood to do that!" + user << "You require at least [required_blood] units of usable blood to do that!" return 0 //chapel check - if(istype(loc.loc, /area/chapel)) - if(!fullpower) - src << "Your powers are useless on this holy ground." - return 0 - return 1 + if(istype(loc.loc, /area/chapel) && !fullpower) + user << "Your powers are useless on this holy ground." + return 0 + return ..() -/mob/proc/vampire_affected(datum/mind/M) +/obj/effect/proc_holder/spell/vampire/can_cast(mob/user = usr) + if(!user.mind) + return 0 + if(!ishuman(user)) + return 0 + + var/datum/vampire/vampire = user.mind.vampire + + if(!vampire) + return 0 + + var/fullpower = vampire.get_ability(/datum/vampire_passive/full) + + if(user.stat >= DEAD) + return 0 + + if(vampire.nullified && !fullpower) + return 0 + if(vampire.bloodusable < required_blood) + return 0 + if(istype(loc.loc, /area/chapel) && !fullpower) + return 0 + return ..() + +/obj/effect/proc_holder/spell/vampire/proc/affects(mob/target, mob/user = usr) //Other vampires aren't affected - if(mind && mind.vampire) return 0 + if(target.mind && target.mind.vampire) + return 0 //Vampires who have reached their full potential can affect nearly everything - if(M && M.vampire && (VAMP_FULL in M.vampire.powers)) + if(user.mind.vampire.get_ability(/datum/vampire_passive/full)) return 1 //Chaplains are resistant to vampire powers - if(mind && mind.assigned_role == "Chaplain") + if(target.mind && target.mind.assigned_role == "Chaplain") return 0 return 1 -/mob/proc/vampire_can_reach(mob/M as mob, active_range = 1) - if(M.loc == src.loc) return 1 //target and source are in the same thing - if(!isturf(src.loc) || !isturf(M.loc)) return 0 //One is inside, the other is outside something. - if(Adjacent(M))//if(AStar(src.loc, M.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, active_range)) //If a path exists, good! - return 1 - return 0 +/obj/effect/proc_holder/spell/vampire/proc/can_reach(mob/M as mob) + if(M.loc == usr.loc) + return 1 //target and source are in the same thing + return M in oview_or_orange(range, usr, selection_type) -/mob/proc/vampire_active(required_blood=0, max_stat=0, active_range=1) - var/pass = vampire_power(required_blood, max_stat) - if(!pass) return - var/datum/vampire/vampire = mind.vampire - if(!vampire) return - var/list/victims = list() - for(var/mob/living/carbon/C in view(active_range)) - victims += C - var/mob/living/carbon/T = input(src, "Victim?") as null|anything in victims +/obj/effect/proc_holder/spell/vampire/before_cast(list/targets) + // sanity check before we cast + if(!usr.mind || !usr.mind.vampire) + targets.Cut() + return - if(!T) return - if(!(T in view(active_range))) return - if(!vampire_can_reach(T, active_range)) return - if(!vampire_power(required_blood, max_stat)) return - return T + if(!required_blood) + return -/client/vampire/proc/vampire_rejuvinate() - set category = "Abilities" - set name = "Rejuvinate " - set desc= "Flush your system with spare blood to remove any incapacitating effects" - var/datum/mind/M = usr.mind - if(!M) return - if(M.current.vampire_power(0, 1)) - M.current.SetWeakened(0) - M.current.SetStunned(0) - M.current.SetParalysis(0) - M.current.adjustStaminaLoss(-75) - //M.vampire.bloodusable -= 10 - M.current << "\blue You flush your system with clean blood and remove any incapacitating effects." - spawn(1) - if(M.vampire.bloodtotal >= 200) - for(var/i = 0; i < 5; i++) - M.current.adjustBruteLoss(-2) - M.current.adjustOxyLoss(-5) - M.current.adjustToxLoss(-2) - M.current.adjustFireLoss(-2) - sleep(35) - M.current.verbs -= /client/vampire/proc/vampire_rejuvinate - spawn(200) - M.current.verbs += /client/vampire/proc/vampire_rejuvinate + // enforce blood + var/datum/vampire/vampire = usr.mind.vampire -/client/vampire/proc/vampire_hypnotise() - set category = "Abilities" - set name = "Hypnotise (20)" - set desc= "A piercing stare that incapacitates your victim for a good length of time." - var/datum/mind/M = usr.mind - if(!M) return + if(required_blood <= vampire.bloodusable) + vampire.bloodusable -= required_blood + else + // stop!! + targets.Cut() - var/mob/living/carbon/C = M.current.vampire_active(20, 0, 1) + if(targets.len) + usr << "You have [vampire.bloodusable] left to use." - if(!C) return - M.current.visible_message("[M]'s eyes flash briefly as he stares into [C.name]'s eyes") - M.current.remove_vampire_blood(20) - M.current.verbs -= /client/vampire/proc/vampire_hypnotise - spawn(1800) - M.current.verbs += /client/vampire/proc/vampire_hypnotise - if(do_mob(M.current, C, 50)) - if(C.mind && C.mind.vampire) - M.current << "\red Your piercing gaze fails to knock out [C.name]." - C << "\blue [M.current]'s feeble gaze is ineffective." - return +/obj/effect/proc_holder/spell/vampire/targetted/choose_targets(mob/user = usr) + var/list/possible_targets[0] + for(var/mob/living/carbon/C in oview_or_orange(range, user, selection_type)) + possible_targets += C + var/mob/living/carbon/T = input(user, "Choose your victim.", name) as null|mob in possible_targets + + if(!T || !can_reach(T)) + revert_cast(user) + return + + perform(list(T)) + +/obj/effect/proc_holder/spell/vampire/self/choose_targets(mob/user = usr) + perform(list(user)) + +/obj/effect/proc_holder/spell/vampire/mob_aoe/choose_targets(mob/user = usr) + var/list/targets[0] + for(var/mob/living/carbon/C in oview_or_orange(range, user, selection_type)) + targets += C + + if(!targets.len) + revert_cast(user) + return + + perform(targets) + +/datum/vampire_passive + var/gain_desc + +/datum/vampire_passive/New() + ..() + if(!gain_desc) + gain_desc = "You have gained \the [src] ability." + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +/obj/effect/proc_holder/spell/vampire/self/rejuvenate + name = "Rejuvenate" + desc= "Flush your system with spare blood to remove any incapacitating effects." + action_icon_state = "vampire_rejuvinate" + charge_max = 200 + stat_allowed = 1 + +/obj/effect/proc_holder/spell/vampire/self/rejuvenate/cast() + var/mob/living/U = usr + + usr.SetWeakened(0) + usr.SetStunned(0) + usr.SetParalysis(0) + U.adjustStaminaLoss(-75) + usr << "You flush your system with clean blood and remove any incapacitating effects." + spawn(1) + if(usr.mind.vampire.get_ability(/datum/vampire_passive/regen)) + for(var/i = 1 to 5) + U.adjustBruteLoss(-2) + U.adjustOxyLoss(-5) + U.adjustToxLoss(-2) + U.adjustFireLoss(-2) + sleep(35) + +/obj/effect/proc_holder/spell/vampire/targetted/hypnotise + name = "Hypnotise (20)" + desc= "A piercing stare that incapacitates your victim for a good length of time." + action_icon_state = "vampire_hypnotise" + required_blood = 20 + +/obj/effect/proc_holder/spell/vampire/targetted/hypnotise/cast(list/targets) + for(var/mob/living/target in targets) + usr.visible_message("[usr]'s eyes flash briefly as he stares into [target]'s eyes") + if(do_mob(usr, target, 50)) + if(!affects(target)) + usr << "Your piercing gaze fails to knock out [target]." + target << "\blue [usr]'s feeble gaze is ineffective." + else + usr << "Your piercing gaze knocks out [target]." + target << "You find yourself unable to move and barely able to speak." + target.Weaken(10) + target.Stun(10) + target.stuttering = 10 else - M.current << "\red Your piercing gaze knocks out [C.name]." - C << "\red You find yourself unable to move and barely able to speak" - C.Weaken(10) - C.Stun(10) - C.stuttering = 10 - else - M.current << "\red You broke your gaze." + revert_cast(usr) + usr << "You broke your gaze." + +/obj/effect/proc_holder/spell/vampire/targetted/disease + name = "Diseased Touch (100)" + desc = "Touches your victim with infected blood giving them the Shutdown Syndrome which quickly shutsdown their major organs resulting in a quick painful death." + gain_desc = "You have gained the Diseased Touch ability which causes those you touch to die shortly after unless treated medically." + action_icon_state = "vampire_disease" + required_blood = 100 + +/obj/effect/proc_holder/spell/vampire/targetted/disease/cast(list/targets) + for(var/mob/living/carbon/target in targets) + usr << "You stealthily infect [target] with your diseased touch." + target.help_shake_act(usr) + if(!affects(target)) + usr << "They seem to be unaffected." + continue + var/datum/disease2/disease/shutdown = new /datum/disease2/disease + var/datum/disease2/effectholder/holder = new /datum/disease2/effectholder + var/datum/disease2/effect/organs/vampire/O = new /datum/disease2/effect/organs/vampire + holder.effect += O + holder.chance = 10 + shutdown.infectionchance = 100 + shutdown.antigen |= text2num(pick(ANTIGENS)) + shutdown.antigen |= text2num(pick(ANTIGENS)) + shutdown.spreadtype = "None" + shutdown.uniqueID = rand(0,10000) + shutdown.effects += holder + shutdown.speed = 1 + shutdown.stage = 2 + shutdown.clicks = 185 + infect_virus2(target, shutdown, 0) + +/obj/effect/proc_holder/spell/vampire/mob_aoe/glare + name = "Glare" + desc = "A scary glare that incapacitates people for a short while around you." + action_icon_state = "vampire_glare" + charge_max = 300 + stat_allowed = 1 + +/obj/effect/proc_holder/spell/vampire/mob_aoe/glare/cast(list/targets) + usr.visible_message("[usr]'s eyes emit a blinding flash!") + if(istype(usr:glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) + usr << "You're blindfolded!" return + for(var/mob/living/target in targets) + if(!affects(target)) + continue + target.Stun(5) + target.Weaken(5) + target.stuttering = 20 + target << "You are blinded by [usr]'s glare." -/client/vampire/proc/vampire_disease() - set category = "Abilities" - set name = "Diseased Touch (100)" - set desc = "Touches your victim with infected blood giving them the Shutdown Syndrome which quickly shutsdown their major organs resulting in a quick painful death." - var/datum/mind/M = usr.mind - if(!M) return +/obj/effect/proc_holder/spell/vampire/self/shapeshift + name = "Shapeshift (50)" + desc = "Changes your name and appearance at the cost of 50 blood and has a cooldown of 3 minutes." + gain_desc = "You have gained the shapeshifting ability, at the cost of stored blood you can change your form permanently." + action_icon_state = "genetic_poly" + required_blood = 50 - var/mob/living/carbon/C = M.current.vampire_active(100, 0, 1) - if(!C) return - if(!M.current.vampire_can_reach(C, 1)) - M.current << "\red You cannot touch [C.name] from where you are standing!" - return - M.current << "\red You stealthily infect [C.name] with your diseased touch." - /*var/t_him = "it" - if (src.gender == MALE) - t_him = "him" - else if (src.gender == FEMALE) - t_him = "her" - M.current.visible_message("\blue [M] shakes [src] trying to wake [t_him] up!" ) - playsound(get_turf(src), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)*/ - C.help_shake_act(M.current) // i use da colon - if(!C.vampire_affected(M)) - M.current << "\red They seem to be unaffected." - return - var/datum/disease2/disease/shutdown = new /datum/disease2/disease - var/datum/disease2/effectholder/holder = new /datum/disease2/effectholder - var/datum/disease2/effect/organs/vampire/O = new /datum/disease2/effect/organs/vampire - holder.effect += O - holder.chance = 10 - shutdown.infectionchance = 100 - shutdown.antigen |= text2num(pick(ANTIGENS)) - shutdown.antigen |= text2num(pick(ANTIGENS)) - shutdown.spreadtype = "None" - shutdown.uniqueID = rand(0,10000) - shutdown.effects += holder - shutdown.speed = 1 - shutdown.stage = 2 - shutdown.clicks = 185 - infect_virus2(C,shutdown,0) - M.current.remove_vampire_blood(100) - M.current.verbs -= /client/vampire/proc/vampire_disease - spawn(1800) M.current.verbs += /client/vampire/proc/vampire_disease +/obj/effect/proc_holder/spell/vampire/self/shapeshift/cast() + usr.visible_message("[usr] transforms!") + usr.client.prefs.real_name = usr.generate_name() + usr.client.prefs.random_character() + usr.client.prefs.copy_to(usr) + usr.regenerate_icons() -/client/vampire/proc/vampire_glare() - set category = "Abilities" - set name = "Glare" - set desc= "A scary glare that incapacitates people for a short while around you." - var/datum/mind/M = usr.mind - if(!M) return - if(M.current.vampire_power(0, 1)) - M.current.visible_message("\red [M.current]'s eyes emit a blinding flash!") - //M.vampire.bloodusable -= 10 - M.current.verbs -= /client/vampire/proc/vampire_glare - spawn(300) - M.current.verbs += /client/vampire/proc/vampire_glare - if(istype(M.current:glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) - M.current << "You're blindfolded!" - return - for(var/mob/living/carbon/C in view(1)) - if(!C.vampire_affected(M)) continue - if(!M.current.vampire_can_reach(C, 1)) continue - C.Stun(5) - C.Weaken(5) - C.stuttering = 20 - C << "\red You are blinded by [M.current]'s glare" +/obj/effect/proc_holder/spell/vampire/self/screech + name = "Chiroptean Screech (30)" + desc = "An extremely loud shriek that stuns nearby humans and breaks windows as well." + gain_desc = "You have gained the Chriopteran Screech ability which stuns anything with ears in a large radius and shatters glass in the process." + action_icon_state = "vampire_screech" + required_blood = 30 -/client/vampire/proc/vampire_shapeshift() - set category = "Abilities" - set name = "Shapeshift (50)" - set desc = "Changes your name and appearance at the cost of 50 blood and has a cooldown of 3 minutes." - var/datum/mind/M = usr.mind - if(!M) return - if(M.current.vampire_power(50, 0)) - M.current.visible_message("[M.current.name] transforms!") - M.current.client.prefs.real_name = M.current.generate_name() //random_name(M.current.gender) - M.current.client.prefs.random_character() - M.current.client.prefs.copy_to(M.current) - M.current.regenerate_icons() - M.current.remove_vampire_blood(50) - M.current.verbs -= /client/vampire/proc/vampire_shapeshift - spawn(1800) M.current.verbs += /client/vampire/proc/vampire_shapeshift +/obj/effect/proc_holder/spell/vampire/self/screech/cast() + usr.visible_message("[usr] lets out an ear piercing shriek!", "You let out a loud shriek.", "You hear a loud painful shriek!") + for(var/mob/living/carbon/C in hearers(4)) + if(C == usr) + continue + if(ishuman(C) && (C:l_ear || C:r_ear) && istype((C:l_ear || C:r_ear), /obj/item/clothing/ears/earmuffs)) + continue + if(!affects(C)) + continue + C << "You hear a ear piercing shriek and your senses dull!" + C.Weaken(4) + C.ear_deaf = 20 + C.stuttering = 20 + C.Stun(4) + C.Jitter(150) + for(var/obj/structure/window/W in view(4)) + W.destroy() + playsound(usr.loc, 'sound/effects/creepyshriek.ogg', 100, 1) -/client/vampire/proc/vampire_screech() - set category = "Abilities" - set name = "Chiroptean Screech (30)" - set desc = "An extremely loud shriek that stuns nearby humans and breaks windows as well." - var/datum/mind/M = usr.mind - if(!M) return - if(M.current.vampire_power(30, 0)) - M.current.visible_message("\red [M.current.name] lets out an ear piercing shriek!", "\red You let out a loud shriek.", "\red You hear a loud painful shriek!") - for(var/mob/living/carbon/C in hearers(4, M.current)) - if(C == M.current) continue - if(ishuman(C) && (C:l_ear || C:r_ear) && istype((C:l_ear || C:r_ear), /obj/item/clothing/ears/earmuffs)) continue - if(!C.vampire_affected(M)) continue - C << "You hear a ear piercing shriek and your senses dull!" - C.Weaken(4) - C.ear_deaf = 20 - C.stuttering = 20 - C.Stun(4) - C.Jitter(150) - for(var/obj/structure/window/W in view(4)) - W.destroy() - playsound(M.current.loc, 'sound/effects/creepyshriek.ogg', 100, 1) - M.current.remove_vampire_blood(30) - M.current.verbs -= /client/vampire/proc/vampire_screech - spawn(1800) M.current.verbs += /client/vampire/proc/vampire_screech +/obj/effect/proc_holder/spell/vampire/targetted/enthrall + name = "Enthrall (300)" + desc = "You use a large portion of your power to sway those loyal to none to be loyal to you only." + gain_desc = "You have gained the Enthrall ability which at a heavy blood cost allows you to enslave a human that is not loyal to any other for a random period of time." + action_icon_state = "vampire_enthrall" + required_blood = 300 -/client/vampire/proc/vampire_enthrall() - set category = "Abilities" - set name = "Enthrall (300)" - set desc = "You use a large portion of your power to sway those loyal to none to be loyal to you only." - var/datum/mind/M = usr.mind - if(!M) return - var/mob/living/carbon/C = M.current.vampire_active(300, 0, 1) - if(!C) return - M.current.visible_message("\red [M.current.name] bites [C.name]'s neck!", "\red You bite [C.name]'s neck and begin the flow of power.") - C << "You feel the tendrils of evil invade your mind." - if(!ishuman(C)) - M.current << "\red You can only enthrall humans" - return +/obj/effect/proc_holder/spell/vampire/targetted/enthrall/cast(list/targets) + for(var/mob/living/target in targets) + usr.visible_message("[usr] bites [target]'s neck!", "You bite [target]'s neck and begin the flow of power.") + target << "You feel the tendrils of evil invade your mind." + if(!ishuman(target)) + usr << "You can only enthrall humans." + break + if(do_mob(usr, target, 50)) + if(can_enthrall(usr, target)) + handle_enthrall(usr, target) + else + revert_cast(usr) + usr << "You or your target either moved or you dont have enough usable blood." - if(do_mob(M.current, C, 50)) - if(M.current.can_enthrall(C) && M.current.vampire_power(300, 0)) // recheck - M.current.handle_enthrall(C) - M.current.remove_vampire_blood(300) - M.current.verbs -= /client/vampire/proc/vampire_enthrall - spawn(1800) M.current.verbs += /client/vampire/proc/vampire_enthrall - else - M.current << "\red You or your target either moved or you dont have enough usable blood." - return - - - -/client/vampire/proc/vampire_cloak() - set category = "Abilities" - set name = "Cloak of Darkness (toggle)" - set desc = "Toggles whether you are currently cloaking yourself in darkness." - var/datum/mind/M = usr.mind - if(!M) return - if(M.current.vampire_power(0, 0)) - M.vampire.iscloaking = !M.vampire.iscloaking - M.current << "\blue You will now be [M.vampire.iscloaking ? "hidden" : "seen"] in darkness." - -/mob/proc/handle_vampire_cloak() - if(!mind || !mind.vampire || !ishuman(src)) - alpha = 255 - return - var/turf/simulated/T = get_turf(src) - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - var/light_available - if(L) - light_available = L.get_clamped_lum(0.5)*10 - else - light_available = 10 - - if(!istype(T)) - return 0 - - if(!mind.vampire.iscloaking) - alpha = 255 - return 0 - if(light_available <= 2) - alpha = round((255 * 0.15)) - return 1 - else - alpha = round((255 * 0.80)) - -/mob/proc/can_enthrall(mob/living/carbon/C) +/obj/effect/proc_holder/spell/vampire/targetted/enthrall/proc/can_enthrall(mob/living/user, mob/living/carbon/C) var/enthrall_safe = 0 for(var/obj/item/weapon/implant/loyalty/L in C) if(L && L.implanted) @@ -301,197 +312,226 @@ enthrall_safe = 1 break if(!C) - log_to_dd("something bad happened on enthralling a mob src is [src] [src.key] \ref[src]") + log_to_dd("something bad happened on enthralling a mob, attacker is [user] [user.key] \ref[user]") return 0 if(!C.mind) - src << "\red [C.name]'s mind is not there for you to enthrall." + user << "" return 0 if(enthrall_safe || ( C.mind in ticker.mode.vampires )||( C.mind.vampire )||( C.mind in ticker.mode.vampire_enthralled )) - C.visible_message("\red [C] seems to resist the takeover!", "\blue You feel a familiar sensation in your skull that quickly dissipates.") + C.visible_message("[C] seems to resist the takeover!", "You feel a familiar sensation in your skull that quickly dissipates.") return 0 - if(!C.vampire_affected(mind)) - C.visible_message("\red [C] seems to resist the takeover!", "\blue Your faith of [ticker.Bible_deity_name] has kept your mind clear of all evil") + if(!affects(C)) + C.visible_message("[C] seems to resist the takeover!", "Your faith of [ticker.Bible_deity_name] has kept your mind clear of all evil.") if(!ishuman(C)) - src << "\red You can only enthrall humans!" + user << "You can only enthrall humans!" return 0 return 1 -/mob/proc/handle_enthrall(mob/living/carbon/human/H as mob) +/obj/effect/proc_holder/spell/vampire/targetted/enthrall/proc/handle_enthrall(mob/living/user, mob/living/carbon/human/H as mob) if(!istype(H)) - src << "\red SOMETHING WENT WRONG, YELL AT POMF OR NEXIS" return 0 - var/ref = "\ref[src.mind]" + var/ref = "\ref[user.mind]" if(!(ref in ticker.mode.vampire_thralls)) ticker.mode.vampire_thralls[ref] = list(H.mind) else ticker.mode.vampire_thralls[ref] += H.mind ticker.mode.update_vampire_icons_added(H.mind) - ticker.mode.update_vampire_icons_added(src.mind) - var/datum/mindslaves/slaved = src.mind.som + ticker.mode.update_vampire_icons_added(user.mind) + var/datum/mindslaves/slaved = user.mind.som H.mind.som = slaved slaved.serv += H - slaved.add_serv_hud(src.mind,"vampire")//handles master servent icons - slaved.add_serv_hud(H.mind,"vampthrall") + slaved.add_serv_hud(user.mind, "vampire")//handles master servent icons + slaved.add_serv_hud(H.mind, "vampthrall") ticker.mode.vampire_enthralled.Add(H.mind) - ticker.mode.vampire_enthralled[H.mind] = src.mind + ticker.mode.vampire_enthralled[H.mind] = user.mind H.mind.special_role = "VampThrall" - H << "\red You have been Enthralled by [name]. Follow their every command." - src << "\red You have successfully Enthralled [H.name]. If they refuse to do as you say just adminhelp." - log_admin("[ckey(src.key)] has mind-slaved [ckey(H.key)].") + H << "You have been Enthralled by [user]. Follow their every command." + src << "You have successfully Enthralled [H]. If they refuse to do as you say just adminhelp." + log_admin("[ckey(user.key)] has mind-slaved [ckey(H.key)].") -/client/vampire/proc/vampire_bats() - set category = "Abilities" - set name = "Summon Bats (75)" - set desc = "You summon a pair of space bats who attack nearby targets until they or their target is dead." - var/datum/mind/M = usr.mind - if(!M) return - if(M.current.vampire_power(75, 0)) - var/list/turf/locs = new - var/number = 0 - for(var/direction in alldirs) //looking for bat spawns - if(locs.len == 2) //we found 2 locations and thats all we need - break - var/turf/T = get_step(M.current,direction) //getting a loc in that direction - if(AStar(M.current.loc, T, /turf/proc/AdjacentTurfs, /turf/proc/Distance, 1, simulated_only = 0)) // if a path exists, so no dense objects in the way its valid salid - locs += T - if(locs.len) - for(var/turf/tospawn in locs) - number++ - new /mob/living/simple_animal/hostile/scarybat(tospawn, M.current) - if(number != 2) //if we only found one location, spawn one on top of our tile so we dont get stacked bats - new /mob/living/simple_animal/hostile/scarybat(M.current.loc, M.current) - else // we had no good locations so make two on top of us - new /mob/living/simple_animal/hostile/scarybat(M.current.loc, M.current) - new /mob/living/simple_animal/hostile/scarybat(M.current.loc, M.current) - M.current.remove_vampire_blood(75) - M.current.verbs -= /client/vampire/proc/vampire_bats - spawn(1200) M.current.verbs += /client/vampire/proc/vampire_bats +/obj/effect/proc_holder/spell/vampire/self/cloak + name = "Cloak of Darkness" + desc = "Toggles whether you are currently cloaking yourself in darkness." + gain_desc = "You have gained the Cloak of Darkness ability which when toggled makes you near invisible in the shroud of darkness." + action_icon_state = "vampire_cloak" + charge_max = 10 -/client/vampire/proc/vampire_jaunt() - //AHOY COPY PASTE INCOMING - set category = "Abilities" - set name = "Mist Form (30)" - set desc = "You take on the form of mist for a short period of time." +/obj/effect/proc_holder/spell/vampire/self/cloak/New() + ..() + update_name() + +/obj/effect/proc_holder/spell/vampire/self/cloak/proc/update_name() + var/mob/living/user = loc + if(!ishuman(user) || !user.mind || !user.mind.vampire) + return + name = "[initial(name)] ([user.mind.vampire.iscloaking ? "Deactivate" : "Activate"])" + +/obj/effect/proc_holder/spell/vampire/self/cloak/cast() + var/datum/vampire/V = usr.mind.vampire + V.iscloaking = !V.iscloaking + update_name() + usr << "You will now be [V.iscloaking ? "hidden" : "seen"] in darkness." + +/obj/effect/proc_holder/spell/vampire/bats + name = "Summon Bats (75)" + desc = "You summon a pair of space bats who attack nearby targets until they or their target is dead." + gain_desc = "You have gained the Summon Bats ability." + action_icon_state = "vampire_bats" + charge_max = 1200 + required_blood = 75 + var/num_bats = 2 + +/obj/effect/proc_holder/spell/vampire/bats/choose_targets(mob/user = usr) + var/list/turf/locs = new + for(var/direction in alldirs) //looking for bat spawns + if(locs.len == num_bats) //we found 2 locations and thats all we need + break + var/turf/T = get_step(usr, direction) //getting a loc in that direction + if(AStar(usr.loc, T, /turf/proc/AdjacentTurfs, /turf/proc/Distance, 1, simulated_only = 0)) // if a path exists, so no dense objects in the way its valid salid + locs += T + + // pad with player location + for(var/i = locs.len + 1 to num_bats) + locs += user.loc + + perform(locs) + +/obj/effect/proc_holder/spell/vampire/bats/cast(list/targets) + for(var/T in targets) + new /mob/living/simple_animal/hostile/scarybat(T, usr) + +/obj/effect/proc_holder/spell/vampire/self/jaunt + name = "Mist Form (30)" + desc = "You take on the form of mist for a short period of time." + gain_desc = "You have gained the Mist Form ability which allows you to take on the form of mist for a short period and pass over any obstacle in your path." + action_icon_state = "jaunt" + charge_max = 600 + required_blood = 30 var/jaunt_duration = 50 //in deciseconds - var/datum/mind/M = usr.mind - if(!M) return - if(M.current.vampire_power(30, 0)) - if(M.current.buckled) M.current.buckled.unbuckle_mob() - spawn(0) - var/originalloc = get_turf(M.current.loc) - var/obj/effect/dummy/spell_jaunt/holder = new /obj/effect/dummy/spell_jaunt( originalloc ) - var/atom/movable/overlay/animation = new /atom/movable/overlay( originalloc ) - animation.name = "water" - animation.density = 0 - animation.anchored = 1 - animation.icon = 'icons/mob/mob.dmi' - animation.icon_state = "liquify" - animation.layer = 5 - animation.master = holder - M.current.ExtinguishMob() - if(M.current.buckled) - M.current.buckled.unbuckle_mob() - flick("liquify",animation) - M.current.loc = holder - M.current.client.eye = holder - var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread() - steam.set_up(10, 0, originalloc) - steam.start() - sleep(jaunt_duration) - var/mobloc = get_turf(M.current.loc) - if(get_area(mobloc) == /area/security/armoury/gamma) - M << "A strange energy repels you!" - mobloc = originalloc - animation.loc = mobloc - steam.location = mobloc - steam.start() - M.current.canmove = 0 - sleep(20) - flick("reappear",animation) - sleep(5) - if(!M.current.Move(mobloc)) - for(var/direction in list(1,2,4,8,5,6,9,10)) - var/turf/T = get_step(mobloc, direction) - if(T) - if(M.current.Move(T)) - break - M.current.canmove = 1 - M.current.client.eye = M.current - qdel(animation) - qdel(holder) - M.current.remove_vampire_blood(30) - M.current.verbs -= /client/vampire/proc/vampire_jaunt - spawn(600) M.current.verbs += /client/vampire/proc/vampire_jaunt +/obj/effect/proc_holder/spell/vampire/self/jaunt/cast() + if(usr.buckled) + usr.buckled.unbuckle_mob() + spawn(0) + var/mob/living/U = usr + var/originalloc = get_turf(usr.loc) + var/obj/effect/dummy/spell_jaunt/holder = new /obj/effect/dummy/spell_jaunt(originalloc) + var/atom/movable/overlay/animation = new /atom/movable/overlay(originalloc) + animation.name = "water" + animation.density = 0 + animation.anchored = 1 + animation.icon = 'icons/mob/mob.dmi' + animation.icon_state = "liquify" + animation.layer = 5 + animation.master = holder + U.ExtinguishMob() + if(usr.buckled) + usr.buckled.unbuckle_mob() + flick("liquify", animation) + usr.forceMove(holder) + usr.client.eye = holder + var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread() + steam.set_up(10, 0, originalloc) + steam.start() + sleep(jaunt_duration) + var/mobloc = get_turf(usr.loc) + if(get_area(mobloc) == /area/security/armoury/gamma) + usr << "A strange energy repels you!" + mobloc = originalloc + animation.loc = mobloc + steam.location = mobloc + steam.start() + usr.canmove = 0 + sleep(20) + flick("reappear",animation) + sleep(5) + if(!usr.Move(mobloc)) + for(var/direction in list(1,2,4,8,5,6,9,10)) + var/turf/T = get_step(mobloc, direction) + if(T) + if(usr.Move(T)) + break + usr.canmove = 1 + usr.client.eye = usr + qdel(animation) + qdel(holder) // Blink for vamps // Less smoke spam. -/client/vampire/proc/vampire_shadowstep() - set category = "Abilities" - set name = "Shadowstep (30)" - set desc = "Vanish into the shadows." - var/datum/mind/M = usr.mind - if(!M) return +/obj/effect/proc_holder/spell/vampire/shadowstep + name = "Shadowstep (30)" + desc = "Vanish into the shadows." + gain_desc = "You have gained the ability to shadowstep, which makes you disappear into nearby shadows at the cost of blood." + action_icon_state = "blink" + charge_max = 20 + required_blood = 30 // Teleport radii var/inner_tele_radius = 0 var/outer_tele_radius = 6 - // Maximum lighting_lumcount. var/max_lum = 1 - if(M.current.vampire_power(30, 0)) - if(M.current.buckled) M.current.buckled.unbuckle_mob() - spawn(0) - var/list/turfs = new/list() - for(var/turf/T in range(usr,outer_tele_radius)) - if(T in range(usr,inner_tele_radius)) continue - if(istype(T,/turf/space)) continue - if(T.density) continue - if(T.x>world.maxx-outer_tele_radius || T.xworld.maxy-outer_tele_radius || T.y world.maxx-outer_tele_radius || T.x < outer_tele_radius) + continue //putting them at the edge is dumb + if(T.y > world.maxy-outer_tele_radius || T.y < outer_tele_radius) + continue - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - var/lightingcount = L.get_clamped_lum(0.5)*10 + var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T + var/lightingcount = L.get_clamped_lum(0.5) * 10 - // LIGHTING CHECK - if(lightingcount > max_lum) continue - turfs += T + // LIGHTING CHECK + if(lightingcount > max_lum) + continue + turfs += T - if(!turfs.len) - usr << "\red You cannot find darkness to step to." - return - - var/turf/picked = pick(turfs) - - if(!picked || !isturf(picked)) - return - M.current.ExtinguishMob() - if(M.current.buckled) - M.current.buckled.unbuckle_mob() - var/atom/movable/overlay/animation = new /atom/movable/overlay( get_turf(usr) ) - animation.name = usr.name - animation.density = 0 - animation.anchored = 1 - animation.icon = usr.icon - animation.alpha = 127 - animation.layer = 5 - //animation.master = src - usr.loc = picked - spawn(10) - qdel(animation) - M.current.remove_vampire_blood(30) - M.current.verbs -= /client/vampire/proc/vampire_shadowstep - spawn(20) - M.current.verbs += /client/vampire/proc/vampire_shadowstep - -/mob/proc/remove_vampire_blood(amount = 0) - var/bloodold - if(!mind || !mind.vampire) + if(!turfs.len) + revert_cast(user) + user << "\red You cannot find darkness to step to." return - bloodold = mind.vampire.bloodusable - mind.vampire.bloodusable = max(0, (mind.vampire.bloodusable - amount)) - if(bloodold != mind.vampire.bloodusable) - src << "\blue You have [mind.vampire.bloodusable] left to use." \ No newline at end of file + + perform(turfs) + +/obj/effect/proc_holder/spell/vampire/shadowstep/cast(list/targets) + if(usr.buckled) + usr.buckled.unbuckle_mob() + spawn(0) + var/turf/picked = pick(targets) + + if(!picked || !isturf(picked)) + return + var/mob/living/U = usr + U.ExtinguishMob() + if(usr.buckled) + usr.buckled.unbuckle_mob() + var/atom/movable/overlay/animation = new /atom/movable/overlay(get_turf(usr)) + animation.name = usr.name + animation.density = 0 + animation.anchored = 1 + animation.icon = usr.icon + animation.alpha = 127 + animation.layer = 5 + //animation.master = src + usr.forceMove(picked) + spawn(10) + qdel(animation) + +/datum/vampire_passive/regen + gain_desc = "Your rejuvination abilities have improved and will now heal you over time when used." + +/datum/vampire_passive/vision + gain_desc = "Your vampiric vision has improved." + +/datum/vampire_passive/full + gain_desc = "You have reached your full potential and are no longer weak to the effects of anything holy and your vision has been improved greatly." diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index f0579af36b4..9202405cb2f 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -55,7 +55,7 @@ if(M.mind) if(M.mind.vampire) if(ishuman(M)) - if(!(VAMP_FULL in M.mind.vampire.powers)) + if(!M.mind.vampire.get_ability(/datum/vampire_passive/full)) M << "The nullrod's power interferes with your own!" M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) ..() diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index e8ca0524f01..fa4e557a200 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -135,7 +135,7 @@ M << "Blood from a monkey is useless!" return 0 //we're good to suck the blood, blaah - M.handle_bloodsucking(src) + M.mind.vampire.handle_bloodsucking(src) add_logs(src, M, "vampirebit") msg_admin_attack("[key_name_admin(M)] vampirebit [key_name_admin(src)]") return diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 22c7ed648ae..7ed777ebf77 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -88,7 +88,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc pulse = handle_pulse() if(mind && mind.vampire) - handle_vampire() + mind.vampire.handle_vampire() if(life_tick == 1) regenerate_icons() // Make sure the inventory updates diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 2aa84f9c95e..dddd2522ff2 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -423,14 +423,12 @@ H.see_invisible = SEE_INVISIBLE_LIVING if(H.mind && H.mind.vampire) - if((VAMP_VISION in H.mind.vampire.powers) && (!(VAMP_FULL in H.mind.vampire.powers))) - H.sight |= SEE_MOBS - - else if(VAMP_FULL in H.mind.vampire.powers) + if(H.mind.vampire.get_ability(/datum/vampire_passive/full)) H.sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS H.see_in_dark = 8 H.see_invisible = SEE_INVISIBLE_MINIMUM - + else if(H.mind.vampire.get_ability(/datum/vampire_passive/vision)) + H.sight |= SEE_MOBS if(XRAY in H.mutations) H.sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS diff --git a/code/modules/reagents/oldchem/reagents/reagents_water.dm b/code/modules/reagents/oldchem/reagents/reagents_water.dm index b7c296443b5..c0b2de12fc3 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_water.dm +++ b/code/modules/reagents/oldchem/reagents/reagents_water.dm @@ -264,44 +264,40 @@ M.stuttering = 0 M.confused = 0 return - if(ishuman(M) && M.mind) . - if(((M.mind in ticker.mode.vampires) || M.mind.vampire) && (!(VAMP_FULL in M.mind.vampire.powers)) && prob(80)) - switch(data) - if(1 to 4) - M << "Something sizzles in your veins!" - M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) - if(5 to 12) - M << "You feel an intense burning inside of you!" - M.adjustFireLoss(1) - M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) - if(13 to INFINITY) - M << "You suddenly ignite in a holy fire!" - for(var/mob/O in viewers(M, null)) - O.show_message(text("[] suddenly bursts into flames!", M), 1) - M.fire_stacks = min(5,M.fire_stacks + 3) - M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire - M.adjustFireLoss(3) //Hence the other damages... ain't I a bastard? - M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) + if(ishuman(M) && M.mind && M.mind.vampire && !M.mind.vampire.get_ability(/datum/vampire_passive/full) && prob(80)) + switch(data) + if(1 to 4) + M << "Something sizzles in your veins!" + M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) + if(5 to 12) + M << "You feel an intense burning inside of you!" + M.adjustFireLoss(1) + M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) + if(13 to INFINITY) + M << "You suddenly ignite in a holy fire!" + for(var/mob/O in viewers(M, null)) + O.show_message(text("[] suddenly bursts into flames!", M), 1) + M.fire_stacks = min(5,M.fire_stacks + 3) + M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire + M.adjustFireLoss(3) //Hence the other damages... ain't I a bastard? + M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) ..() - return /datum/reagent/holywater/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) // Vampires have their powers weakened by holy water applied to the skin. - if(ishuman(M)) - if((M.mind in ticker.mode.vampires) && !(VAMP_FULL in M.mind.vampire.powers)) - var/mob/living/carbon/human/H=M - if(method == TOUCH) - if(H.wear_mask) - H << "\red Your mask protects you from the holy water!" - return - else if(H.head) - H << "\red Your helmet protects you from the holy water!" - return - else - M << "Something holy interferes with your powers!" - M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) - return + if(ishuman(M) && M.mind && M.mind.vampire && !M.mind.vampire.get_ability(/datum/vampire_passive/full)) + var/mob/living/carbon/human/H=M + if(method == TOUCH) + if(H.wear_mask) + H << "\red Your mask protects you from the holy water!" + return + else if(H.head) + H << "\red Your helmet protects you from the holy water!" + return + else + M << "Something holy interferes with your powers!" + M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) /datum/reagent/holywater/reaction_turf(var/turf/simulated/T, var/volume) diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index a45ae88ca58..22d7d9cd166 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ