Vampire Gamemode!

This commit is contained in:
ZomgPonies
2013-12-13 19:38:49 -05:00
parent 25becb2c49
commit 912601a30d
22 changed files with 1013 additions and 25 deletions
+43 -3
View File
@@ -52,7 +52,7 @@ datum/mind
var/datum/faction/faction //associated faction
var/datum/changeling/changeling //changeling holder
var/datum/vampire/vampire //vampire holder
var/rev_cooldown = 0
// the world.time since the mob has been brigged, or -1 if not at all
@@ -128,6 +128,7 @@ datum/mind
"cult",
"wizard",
"changeling",
"vampire",
"nuclear",
"traitor", // "traitorchan",
"monkey",
@@ -222,6 +223,20 @@ datum/mind
// text += "<br>All the changelings are dead! Restart in [round((changeling.TIME_TO_GET_REVIVED-(world.time-changeling.changelingdeathtime))/10)] seconds."
sections["changeling"] = text
/** VAMPIRE ***/
text = "vampire"
if (ticker.mode.config_tag=="vampire")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (src in ticker.mode.vampires)
text += "<b>YES</b>|<a href='?src=\ref[src];vampire=clear'>no</a>"
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=\ref[src];vampire=autoobjectives'>Randomize!</a>"
else
text += "<a href='?src=\ref[src];vampire=vampire'>yes</a>|<b>NO</b>"
sections["vampire"] = text
/** NUCLEAR ***/
text = "nuclear"
if (ticker.mode.config_tag=="nuclear")
@@ -387,7 +402,7 @@ datum/mind
if(!def_value)//If it's a custom objective, it will be an empty string.
def_value = "custom"
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "nuclear", "capture", "absorb", "custom")
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "blood", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "nuclear", "capture", "absorb", "custom")
if (!new_obj_type) return
var/datum/objective/new_objective = null
@@ -455,7 +470,7 @@ datum/mind
if (!steal.select_target())
return
if("download","capture","absorb")
if("download","capture","absorb", "blood")
var/def_num
if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
def_num = objective.target_amount
@@ -474,6 +489,9 @@ datum/mind
if("absorb")
new_objective = new /datum/objective/absorb
new_objective.explanation_text = "Absorb [target_number] compatible genomes."
if("blood")
new_objective = new /datum/objective/blood
new_objective.explanation_text = "Accumulate atleast [target_number] units of blood in total."
new_objective.owner = src
new_objective.target_amount = target_number
@@ -735,6 +753,28 @@ datum/mind
updateappearance(current, current.dna.uni_identity)
domutcheck(current, null)
else if (href_list["vampire"])
switch(href_list["vampire"])
if("clear")
if(src in ticker.mode.vampires)
ticker.mode.vampires -= src
special_role = null
current.remove_vampire_powers()
if(vampire) del(vampire)
current << "<FONT color='red' size = 3><B>You grow weak and lose your powers! You are no longer a vampire and are stuck in your current form!</B></FONT>"
log_admin("[key_name_admin(usr)] has de-vampired [current].")
if("vampire")
if(!(src in ticker.mode.vampires))
ticker.mode.vampires += src
ticker.mode.grant_vampire_powers(current)
special_role = "Vampire"
current << "<B><font color='red'>Your powers are awoken. Your lust for blood grows... You are a Vampire!</font></B>"
log_admin("[key_name_admin(usr)] has vampired [current].")
if("autoobjectives")
ticker.mode.forge_vampire_objectives(src)
usr << "\blue The objectives for vampire [key] have been generated. You can edit them and announce manually."
else if (href_list["nuclear"])
switch(href_list["nuclear"])
if("clear")
+12
View File
@@ -745,3 +745,15 @@ datum/objective/absorb
/*-------ENDOF CULTIST------*/
*/
datum/objective/blood
proc/gen_amount_goal(low = 150, high = 400)
target_amount = rand(low,high)
target_amount = round(round(target_amount/5)*5)
explanation_text = "Accumulate atleast [target_amount] units of blood in total."
return target_amount
check_completion()
if(owner && owner.vampire && owner.vampire.bloodtotal && owner.vampire.bloodtotal >= target_amount)
return 1
else
return 0
+409
View File
@@ -0,0 +1,409 @@
//This is the gamemode file for the ported goon gamemode vampires.
//They get a traitor objective and a blood sucking objective
/datum/game_mode
var/list/datum/mind/vampires = list()
var/list/datum/mind/enthralled = list() //those controlled by a vampire
var/list/thralls = list() //vammpires controlling somebody
/datum/game_mode/vampire
name = "vampire"
config_tag = "vampire"
restricted_jobs = list("AI", "Cyborg", "Mobile MMI", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain") //Consistent screening has filtered all infiltration attempts on high value jobs
protected_jobs = list()
required_players = 1
required_players_secret = 15
required_enemies = 1
recommended_enemies = 4
uplink_welcome = "Syndicate Uplink Console:"
uplink_uses = 10
var/const/prob_int_murder_target = 50 // intercept names the assassination target half the time
var/const/prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target
var/const/prob_right_murder_target_h = 50 // upper bound on probability of naimg the right assassination target
var/const/prob_int_item = 50 // intercept names the theft target half the time
var/const/prob_right_item_l = 25 // lower bound on probability of naming right theft target
var/const/prob_right_item_h = 50 // upper bound on probability of naming the right theft target
var/const/prob_int_sab_target = 50 // intercept names the sabotage target half the time
var/const/prob_right_sab_target_l = 25 // lower bound on probability of naming right sabotage target
var/const/prob_right_sab_target_h = 50 // upper bound on probability of naming right sabotage target
var/const/prob_right_killer_l = 25 //lower bound on probability of naming the right operative
var/const/prob_right_killer_h = 50 //upper bound on probability of naming the right operative
var/const/prob_right_objective_l = 25 //lower bound on probability of determining the objective correctly
var/const/prob_right_objective_h = 50 //upper bound on probability of determining the objective correctly
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
var/vampire_amount = 4
/datum/game_mode/vampire/announce()
world << "<B>The current game mode is - Vampires!</B>"
world << "<B>There are Vampires from Space Transylvania on the station, keep your blood close and neck safe!</B>"
/datum/game_mode/vampire/pre_setup()
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
var/list/datum/mind/possible_vampires = get_players_for_role(BE_VAMPIRE)
for(var/datum/mind/player in possible_vampires)
for(var/job in restricted_jobs)//Removing robots from the list
if(player.assigned_role == job)
possible_vampires -= player
vampire_amount = 1 + round(num_players() / 10)
if(possible_vampires.len>0)
for(var/i = 0, i < vampire_amount, i++)
if(!possible_vampires.len) break
var/datum/mind/vampire = pick(possible_vampires)
possible_vampires -= vampire
vampires += vampire
modePlayer += vampires
return 1
else
return 0
/datum/game_mode/vampire/post_setup()
for(var/datum/mind/vampire in vampires)
grant_vampire_powers(vampire.current)
vampire.special_role = "Vampire"
forge_vampire_objectives(vampire)
greet_vampire(vampire)
spawn (rand(waittime_l, waittime_h))
send_intercept()
..()
return
/datum/game_mode/proc/auto_declare_completion_vampire()
if(traitors.len)
var/text = "<FONT size = 2><B>The vampires were:</B></FONT>"
for(var/datum/mind/vampire in vampires)
var/traitorwin = 1
text += "<br>[vampire.key] was [vampire.name] ("
if(vampire.current)
if(vampire.current.stat == DEAD)
text += "died"
else
text += "survived"
if(vampire.current.real_name != vampire.name)
text += " as [vampire.current.real_name]"
else
text += "body destroyed"
text += ")"
if(vampire.objectives.len)//If the traitor had no objectives, don't need to process this.
var/count = 1
for(var/datum/objective/objective in vampire.objectives)
if(objective.check_completion())
text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font>"
feedback_add_details("traitor_objective","[objective.type]|SUCCESS")
else
text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='red'>Fail.</font>"
feedback_add_details("traitor_objective","[objective.type]|FAIL")
traitorwin = 0
count++
var/special_role_text
if(vampire.special_role)
special_role_text = lowertext(vampire.special_role)
else
special_role_text = "antagonist"
if(traitorwin)
text += "<br><font color='green'><B>The [special_role_text] was successful!</B></font>"
feedback_add_details("traitor_success","SUCCESS")
else
text += "<br><font color='red'><B>The [special_role_text] has failed!</B></font>"
feedback_add_details("traitor_success","FAIL")
world << text
return 1
/datum/game_mode/proc/auto_declare_completion_enthralled()
if(traitors.len)
var/text = "<FONT size = 2><B>The Enthralled were:</B></FONT>"
for(var/datum/mind/enthralled in enthralled)
text += "<br>[enthralled.key] was [enthralled.name] ("
if(enthralled.current)
if(enthralled.current.stat == DEAD)
text += "died"
else
text += "survived"
if(enthralled.current.real_name != enthralled.name)
text += " as [enthralled.current.real_name]"
else
text += "body destroyed"
text += ")"
world << text
return 1
/datum/game_mode/proc/forge_vampire_objectives(var/datum/mind/vampire)
//Objectives are traitor objectives plus blood objectives
var/datum/objective/blood/blood_objective = new
blood_objective.owner = vampire
blood_objective.gen_amount_goal(150, 400)
vampire.objectives += blood_objective
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = vampire
kill_objective.find_target()
vampire.objectives += kill_objective
var/datum/objective/steal/steal_objective = new
steal_objective.owner = vampire
steal_objective.find_target()
vampire.objectives += steal_objective
switch(rand(1,100))
if(1 to 80)
if (!(locate(/datum/objective/escape) in vampire.objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = vampire
vampire.objectives += escape_objective
else
if (!(locate(/datum/objective/survive) in vampire.objectives))
var/datum/objective/survive/survive_objective = new
survive_objective.owner = vampire
vampire.objectives += survive_objective
return
/datum/game_mode/proc/grant_vampire_powers(mob/living/carbon/vampire_mob)
if(!istype(vampire_mob)) return
vampire_mob.make_vampire()
/datum/game_mode/proc/greet_vampire(var/datum/mind/vampire, var/you_are=1)
var/dat
if (you_are)
dat = "<B>\red You are a Vampire! \black</br></B>"
dat += {"To bite someone, target the head and use harm intent with an empty hand. Drink blood to gain new powers.
You are weak to holy things and starlight. Don't go into space and avoid the Chaplain, the chapel and especially Holy Water."}
vampire.current << dat
vampire.current << "<B>You must complete the following tasks:</B>"
if (vampire.current.mind)
if (vampire.current.mind.assigned_role == "Clown")
vampire.current << "Your lust for blood has allowed you to overcome your clumsy nature allowing you to wield weapons without harming yourself."
vampire.current.mutations.Remove(CLUMSY)
var/obj_count = 1
for(var/datum/objective/objective in vampire.objectives)
vampire.current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
return
/datum/vampire
var/bloodtotal = 0 // CHANGE TO ZERO WHEN PLAYTESTING HAPPENS
var/bloodusable = 0 // CHANGE TO ZERO WHEN PLAYTESTING HAPPENS
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/mob/living/carbon/human/draining // who the vampire is draining of blood
/datum/vampire/New(gend = FEMALE)
gender = gend
/mob/proc/make_vampire()
if(!mind) return
if(!mind.vampire)
mind.vampire = new /datum/vampire(gender)
mind.vampire.owner = src
verbs += /client/proc/vampire_rejuvinate
verbs += /client/proc/vampire_hypnotise
verbs += /client/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
mind.vampire.powers.Add(i)
/mob/proc/remove_vampire_powers()
for(var/handler in typesof(/client/proc))
if(findtext("[handler]","vampire_"))
verbs -= handler
/mob/proc/handle_bloodsucking(mob/living/carbon/human/H)
src.mind.vampire.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()]\] <font color='red'>Bit [src.name] ([src.ckey]) in the neck and draining their blood</font>")
H.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been bit in the neck by [src.name] ([src.ckey])</font>")
log_attack("[src.name] ([src.ckey]) bit [H.name] ([H.ckey]) in the neck")
src.visible_message("\red <b>[src.name] bites [H.name]'s neck!<b>", "\red <b>You bite [H.name]'s neck and begin to drain their blood.", "\blue You hear a soft puncture and a wet sucking noise")
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
if(!H.vessel.get_reagent_amount("blood"))
src << "\red They've got no blood left to give."
break
if(H.stat < 2) //alive
blood = min(10, H.vessel.get_reagent_amount("blood"))// if they have less than 10 blood, give them the remnant else they get 10 blood
src.mind.vampire.bloodtotal += blood
src.mind.vampire.bloodusable += blood
H.adjustCloneLoss(5) // beep boop 10 damage
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 <b>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)
src.mind.vampire.draining = null
src << "\blue You stop draining [H.name] of blood."
return 1
/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()
// 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.
// 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)
// 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)
// Commented out until we can figured out a way to stop this from spamming.
//src << "\blue Your rejuvination abilities have improved and will now heal you over time when used."
// 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/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/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/proc/vampire_cloak
if(VAMP_BATS)
src << "\blue You have gained the Summon Bats ability."
verbs += /client/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/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/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/proc/vampire_enthrall
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 greatyl."
//no verb
//prepare for copypaste
/datum/game_mode/proc/update_vampire_icons_added(datum/mind/vampire_mind)
var/ref = "\ref[vampire_mind]"
if(ref in thralls)
if(vampire_mind.current)
if(vampire_mind.current.client)
var/I = image('icons/mob/mob.dmi', loc = vampire_mind.current, icon_state = "vampire")
vampire_mind.current.client.images += I
for(var/headref in thralls)
for(var/datum/mind/t_mind in thralls[headref])
var/datum/mind/head = locate(headref)
if(head)
if(head.current)
if(head.current.client)
var/I = image('icons/mob/mob.dmi', loc = t_mind.current, icon_state = "vampthrall")
head.current.client.images += I
if(t_mind.current)
if(t_mind.current.client)
var/I = image('icons/mob/mob.dmi', loc = head.current, icon_state = "vampire")
t_mind.current.client.images += I
if(t_mind.current)
if(t_mind.current.client)
var/I = image('icons/mob/mob.dmi', loc = t_mind.current, icon_state = "vampthrall")
t_mind.current.client.images += I
/datum/game_mode/proc/update_vampire_icons_removed(datum/mind/vampire_mind)
for(var/headref in thralls)
var/datum/mind/head = locate(headref)
for(var/datum/mind/t_mind in thralls[headref])
if(t_mind.current)
if(t_mind.current.client)
for(var/image/I in t_mind.current.client.images)
if((I.icon_state == "vampthrall" || I.icon_state == "vampire") && I.loc == vampire_mind.current)
//world.log << "deleting [vampire_mind] overlay"
del(I)
if(head)
//world.log << "found [head.name]"
if(head.current)
if(head.current.client)
for(var/image/I in head.current.client.images)
if((I.icon_state == "vampthrall" || I.icon_state == "vampire") && I.loc == vampire_mind.current)
//world.log << "deleting [vampire_mind] overlay"
del(I)
if(vampire_mind.current)
if(vampire_mind.current.client)
for(var/image/I in vampire_mind.current.client.images)
if(I.icon_state == "vampthrall" || I.icon_state == "vampire")
del(I)
/datum/game_mode/proc/remove_vampire_mind(datum/mind/vampire_mind, datum/mind/head)
//var/list/removal
if(!istype(head))
head = vampire_mind //workaround for removing a thrall's control over the enthralled
var/ref = "\ref[head]"
if(ref in thralls)
thralls[ref] -= vampire_mind
enthralled -= vampire_mind
vampire_mind.special_role = null
update_vampire_icons_removed(vampire_mind)
//world << "Removed [vampire_mind.current.name] from vampire shit"
vampire_mind.current << "\red <FONT size = 3><B>The fog clouding your mind clears. You remember nothing from the moment you were enthralled until now.</B></FONT>"
@@ -0,0 +1,370 @@
//This should hold all the vampire related powers
/mob/proc/vampire_power(required_blood=0, max_stat=0)
if(!src.mind) return 0
if(!ishuman(src))
src << "<span class='warning'>You are in too weak of a form to do this!</span>"
return 0
var/datum/vampire/vampire = src.mind.vampire
if(!vampire)
world.log << "[src] has vampire verbs but isn't a vampire."
return 0
if(src.stat > max_stat)
src << "<span class='warning'>You are incapacitated.</span>"
return 0
if(vampire.bloodusable < required_blood)
src << "<span class='warning'>You require at least [required_blood] units of usable blood to do that!</span>"
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(AStar(src.loc, M.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, active_range)) //If a path exists, good!
return 1
return 0
/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 oview(active_range))
victims += C
var/mob/living/carbon/T = input(src, "Victim?") as null|anything in victims
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
/client/proc/vampire_rejuvinate()
set category = "Vampire"
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.weakened = 0
M.current.stunned = 0
M.current.paralysis = 0
//M.vampire.bloodusable -= 10
M.current << "\blue You flush your system with clean blood and remove any incapacitating effects."
M.current.verbs -= /client/proc/vampire_rejuvinate
spawn(200)
M.current.verbs += /client/proc/vampire_rejuvinate
/client/proc/vampire_hypnotise()
set category = "Vampire"
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
var/mob/living/carbon/C = M.current.vampire_active(20, 0, 1)
if(!C) return
M.current.visible_message("<span class='warning'>[M]'s eyes flash briefly as he stares into [C.name]'s eyes</span>")
M.current.remove_vampire_blood(20)
M.current.verbs -= /client/proc/vampire_hypnotise
spawn(1800)
M.current.verbs += /client/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
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(20)
C.Stun(20)
C.stuttering = 20
else
M.current << "\red You broke your gaze."
return
/client/proc/vampire_disease()
set category = "Vampire"
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
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 <b>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(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)*/
C.help_shake_act(M.current) // i use da colon
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 = 10
infect_virus2(C,shutdown,0)
M.current.remove_vampire_blood(100)
M.current.verbs -= /client/proc/vampire_disease
spawn(1800) M.current.verbs += /client/proc/vampire_disease
/client/proc/vampire_glare()
set category = "Vampire"
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 <b>[M.current]'s eyes emit a blinding flash!")
//M.vampire.bloodusable -= 10
M.current.verbs -= /client/proc/vampire_glare
spawn(300)
M.current.verbs += /client/proc/vampire_glare
if(istype(M.current:glasses, /obj/item/clothing/glasses/sunglasses/blindfold))
M.current << "<span class='warning'>You're blindfolded</span>"
return
for(var/mob/living/carbon/C in oview(1))
if(C.mind && C.mind.vampire) continue
if(!M.current.vampire_can_reach(C, 1)) continue
C.Stun(8)
C.Weaken(8)
C.stuttering = 20
C << "\red You are blinded by [M.current]'s glare"
/client/proc/vampire_shapeshift()
set category = "Vampire"
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("<span class='warning'>[M.current] transforms!</span>")
M.current.client.prefs.real_name = random_name(M.current.gender)
M.current.client.prefs.randomize_appearance_for(M.current)
M.current.regenerate_icons()
M.current.remove_vampire_blood(50)
M.current.verbs -= /client/proc/vampire_shapeshift
spawn(1800) M.current.verbs += /client/proc/vampire_shapeshift
/client/proc/vampire_screech()
set category = "Vampire"
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 ohearers(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
C << "<span class='warning'><font size='3'><b>You hear a ear piercing shriek and your senses dull!</font></b></span>"
C.Weaken(8)
C.ear_deaf = 20
C.stuttering = 20
C.Stun(8)
C.make_jittery(150)
for(var/obj/structure/window/W in oview(3))
new W.shardtype(W.loc)
if(W.reinf) new /obj/item/stack/rods(W.loc)
del(W)
playsound(M.current.loc, 'sound/effects/creepyshriek.ogg', 100, 1)
M.current.remove_vampire_blood(30)
M.current.verbs -= /client/proc/vampire_screech
spawn(1800) M.current.verbs += /client/proc/vampire_screech
/client/proc/vampire_enthrall()
set category = "Vampire"
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 << "<span class='warning'>You feel the tendrils of evil invade your mind.</span>"
if(!ishuman(C))
M.current << "\red You can only enthrall humans"
return
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)
else
M.current << "\red You or your target either moved or you dont have enough usable blood."
return
M.current.verbs -= /client/proc/vampire_enthrall
spawn(1800) M.current.verbs += /client/proc/vampire_enthrall
/client/proc/vampire_cloak()
set category = "Vampire"
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)
if(!istype(T))
return 0
if(!mind.vampire.iscloaking)
alpha = 255
return 0
if(T.lighting_lumcount <= 2)
alpha = round((255 * 0.15))
return 1
else
alpha = round((255 * 0.80))
/mob/proc/can_enthrall(mob/living/carbon/C)
if(!C)
world.log << "something bad happened on enthralling a mob src is [src] [src.key] \ref[src]"
return 0
if(!C.mind)
src << "\red [C.name]'s mind is not there for you to enthrall."
return 0
if(/obj/item/weapon/implant/traitor in C.contents || /obj/item/weapon/implant/loyalty in C.contents || C.mind in ticker.mode.vampires || C.mind.vampire || C.mind in ticker.mode.enthralled)
C.visible_message("[C] seems to resist the takeover!", "You feel a familiar sensation in your skull that quickly dissipates.")
return 0
if(!ishuman(C))
src << "\red You can only enthrall humans!"
return 0
return 1
/mob/proc/handle_enthrall(mob/living/carbon/human/H as mob)
if(!istype(H))
src << "<b>\red SOMETHING WENT WRONG, YELL AT POMF OR NEXIS</b>"
return 0
var/ref = "\ref[src.mind]"
if(!(ref in ticker.mode.thralls))
ticker.mode.thralls[ref] = list(H.mind)
ticker.mode.enthralled.Add(H.mind)
ticker.mode.enthralled[H.mind] = src.mind
H.mind.special_role = "VampThrall"
H << "<b>\red You have been Enthralled by [name]. Follow their every command.</b>"
src << "\red You have successfully Enthralled [H.name]. <i>If they refuse to do as you say just adminhelp.</i>"
ticker.mode.update_vampire_icons_added(H.mind)
ticker.mode.update_vampire_icons_added(src.mind)
log_admin("[ckey(src.key)] has mind-slaved [ckey(H.key)].")
/client/proc/vampire_bats()
set category = "Vampire"
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)) // 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/proc/vampire_bats
spawn(1200) M.current.verbs += /client/proc/vampire_bats
/client/proc/vampire_jaunt()
//AHOY COPY PASTE INCOMING
set category = "Vampire"
set name = "Mist Form (30)"
set desc = "You take on the form of mist for a short period of time."
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()
spawn(0)
var/mobloc = get_turf(M.current.loc)
var/obj/effect/dummy/spell_jaunt/holder = new /obj/effect/dummy/spell_jaunt( mobloc )
var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc )
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()
flick("liquify",animation)
M.current.loc = holder
M.current.client.eye = holder
var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread()
steam.set_up(10, 0, mobloc)
steam.start()
sleep(jaunt_duration)
mobloc = get_turf(M.current.loc)
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
del(animation)
del(holder)
M.current.remove_vampire_blood(30)
M.current.verbs -= /client/proc/vampire_jaunt
spawn(600) M.current.verbs += /client/proc/vampire_jaunt
/mob/proc/remove_vampire_blood(amount = 0)
var/bloodold
if(!mind || !mind.vampire)
return
bloodold = mind.vampire.bloodusable
mind.vampire.bloodusable = max(0, (mind.vampire.bloodusable - amount))
if(bloodold != mind.vampire.bloodusable)
src << "\blue <b>You have [mind.vampire.bloodusable] left to use.</b>"
+10 -9
View File
@@ -227,20 +227,21 @@
var/datum/gas_mixture/gas = location.remove_air(0.25*environment.total_moles)
var/heat_capacity = 0
var/energy_used
if(gas)
heat_capacity = gas.heat_capacity()
var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE)
energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE)
//Use power. Assuming that each power unit represents 1000 watts....
use_power(energy_used/1000, ENVIRON)
//Use power. Assuming that each power unit represents 1000 watts....
use_power(energy_used/1000, ENVIRON)
//We need to cool ourselves.
if(environment.temperature > target_temperature)
gas.temperature -= energy_used/heat_capacity
else
gas.temperature += energy_used/heat_capacity
//We need to cool ourselves.
if(environment.temperature > target_temperature)
gas.temperature -= energy_used/heat_capacity
else
gas.temperature += energy_used/heat_capacity
environment.merge(gas)
environment.merge(gas)
if(abs(environment.temperature - target_temperature) <= 0.5)
regulating_temperature = 0
+1
View File
@@ -17,6 +17,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
"ninja" = "true", // 10
"vox raider" = IS_MODE_COMPILED("heist"), // 11
"diona" = 1, // 12
"vampire" = IS_MODE_COMPILED("vampire") // 13
)
var/const/MAX_SAVE_SLOTS = 10
@@ -168,6 +168,10 @@ Works together with spawning an observer, noted above.
U.client.images += image(tempHud,target,"huddeathsquad")
if("Ninja")
U.client.images += image(tempHud,target,"hudninja")
if("Vampire")
U.client.images += image(tempHud,target,"vampire")
if("VampThrall")
U.client.images += image(tempHud,target,"vampthrall")
else//If we don't know what role they have but they have one.
U.client.images += image(tempHud,target,"hudunknown1")
else//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud.
@@ -90,6 +90,24 @@
if("hurt")
//Vampire code
if(M.zone_sel && M.zone_sel.selecting == "head" && src != M)
if(M.mind && M.mind.vampire && (M.mind in ticker.mode.vampires) && !M.mind.vampire.draining)
if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH)))
M << "\red Remove their mask!"
return 0
if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH)))
M << "\red Remove your mask!"
return 0
if(mind && mind.vampire && (mind in ticker.mode.vampires))
M << "\red Your fangs fail to pierce [src.name]'s cold flesh"
return 0
//we're good to suck the blood, blaah
M.handle_bloodsucking(src)
return
//end vampire codes
M.attack_log += text("\[[time_stamp()]\] <font color='red'>[M.species.attack_verb]ed [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been [M.species.attack_verb]ed by [M.name] ([M.ckey])</font>")
@@ -125,6 +125,9 @@
for(var/obj/item/weapon/grab/G in src)
G.process()
if(mind && mind.vampire)
handle_vampire_cloak()
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
..()
@@ -403,6 +406,11 @@
internals.icon_state = "internal0"
return null
// USED IN DEATHWHISPERS
proc/isInCrit()
// Health is in deep shit and we're not already dead
return health <= 0 && stat != 2
proc/handle_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
@@ -1222,6 +1230,13 @@
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_ONE
if(mind && mind.vampire)
if((VAMP_VISION in mind.vampire.powers) && !(VAMP_FULL in mind.vampire.powers))
sight |= SEE_MOBS
if((VAMP_FULL in mind.vampire.powers))
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(XRAY in mutations)
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
@@ -89,7 +89,7 @@
var/list/heard_a = list() // understood us
var/list/heard_b = list() // didn't understand us
var/and_passes_on=""
if(!said_last_words)
if(!said_last_words && src.isInCrit())
and_passes_on=" - and passes on"
said_last_words=src.stat
@@ -153,6 +153,6 @@
M.show_message(rendered, 2)
if(said_last_words)
src.stat = 2
src.death()
src.death(0)
src.regenerate_icons()
@@ -0,0 +1,59 @@
/mob/living/simple_animal/hostile/scarybat
name = "space bat"
desc = "A cute little blood sucking bat that looks pretty pissed."
icon_state = "scarybat"
icon_living = "scarybat"
icon_dead = "scarybat-dead"
icon_gib = "scarybat-dead"
speak_chance = 0
turns_per_move = 3
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
speed = 4
maxHealth = 20
health = 20
harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'
//Space carp aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
// break_stuff_probability = 2
faction = "scarybat"
var/mob/living/owner
/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob)
..()
if(istype(L))
owner = L
/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0)
return ..() //No drifting in space for space carp! //original comments do not steal
/mob/living/simple_animal/hostile/scarybat/FindTarget()
. = ..()
if(.)
emote("flutters towards [.]")
/mob/living/simple_animal/hostile/scarybat/AttackingTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Stun(1)
L.visible_message("<span class='danger'>\the [src] scares \the [L]!</span>")
@@ -26,6 +26,8 @@
if(isliving(A))
var/mob/living/L = A
if(istype(src, /mob/living/simple_animal/hostile/scarybat))
if(src:owner == L) continue
if(L.faction == src.faction && !attack_same)
continue
else if(L in friends)
+40 -8
View File
@@ -225,6 +225,14 @@ datum
if(!istype(M, /mob/living))
return
// Put out fire
if(method == TOUCH)
M.adjust_fire_stacks(-(volume / 10))
if(M.fire_stacks <= 0)
M.ExtinguishMob()
return
// Grays treat water like acid.
if(ishuman(M))
var/mob/living/carbon/human/H = M
@@ -297,14 +305,6 @@ datum
if(!cube.wrapped)
cube.Expand()
return
reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with water can help put them out!
if(!istype(M, /mob/living))
return
if(method == TOUCH)
M.adjust_fire_stacks(-(volume / 10))
if(M.fire_stacks <= 0)
M.ExtinguishMob()
return
lube
name = "Space Lube"
@@ -600,7 +600,39 @@ datum
ticker.mode.remove_cultist(M.mind)
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue []'s eyes blink and become clearer.", M), 1) // So observers know it worked.
// Vamps react to this like acid
if((M.mind in ticker.mode.vampires) && prob(10))
if(!M) M = holder.my_atom
M.adjustToxLoss(1*REM)
M.take_organ_damage(0, 1*REM)
holder.remove_reagent(src.id, 10 * REAGENTS_METABOLISM) //high metabolism to prevent extended uncult rolls.
reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with water can help put them out!
// Vamps react to this like acid
if(ishuman(M))
if((M.mind in ticker.mode.vampires))
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
if(H.head)
H << "\red Your helmet protects you from the holy water!"
return
if(!M.unacidable)
if(prob(15) && volume >= 30)
var/datum/organ/external/affecting = H.get_organ("head")
if(affecting)
if(affecting.take_damage(25, 0))
H.UpdateDamageIcon()
H.status_flags |= DISFIGURED
H.emote("scream")
else
M.take_organ_damage(min(15, volume * 2)) // uses min() and volume to make sure they aren't being sprayed in trace amounts (1 unit != insta rape) -- Doohl
else
if(!M.unacidable)
M.take_organ_damage(min(15, volume * 2))
return
serotrotium
+2
View File
@@ -100,6 +100,8 @@
disease.stageprob = stageprob
disease.antigen = antigen
disease.uniqueID = uniqueID
disease.speed = speed
disease.stage = stage
for(var/datum/disease2/effectholder/holder in effects)
var/datum/disease2/effectholder/newholder = new /datum/disease2/effectholder
newholder.effect = new holder.effect.type
+5 -1
View File
@@ -141,7 +141,11 @@
H << "<span class='notice'>You can't feel your [E.display_name] anymore...</span>"
for (var/datum/organ/external/C in E.children)
C.status |= ORGAN_DEAD
mob.adjustToxLoss(15*multiplier)
H.update_body(1)
if(multiplier < 1) multiplier = 1
H.adjustToxLoss(10*multiplier)
vampire
stage = 3
deactivate(var/mob/living/carbon/mob,var/multiplier)
if(istype(mob, /mob/living/carbon/human))
+18 -2
View File
@@ -665,6 +665,7 @@ var/list/TAGGERLOCATIONS = list("Disposals",
#define BE_NINJA 1024
#define BE_VOX 2048
#define BE_PLANT 4096
#define BE_VAMPIRE 8192
var/list/be_special_flags = list(
"Traitor" = BE_TRAITOR,
@@ -679,7 +680,8 @@ var/list/be_special_flags = list(
"Monkey" = BE_MONKEY,
"Ninja" = BE_NINJA,
"Vox" = BE_VOX,
"Diona" = BE_PLANT
"Diona" = BE_PLANT,
"Vampire" = BE_VAMPIRE
)
#define AGE_MIN 17 //youngest a character can be
@@ -771,4 +773,18 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
//Flags for zone sleeping
#define ZONE_ACTIVE 1
#define ZONE_SLEEPING 0
#define ZONE_SLEEPING 0
// 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_FULL 12