Merge remote-tracking branch 'upstream/dev' into PCAILaws

This commit is contained in:
PsiOmega
2015-03-22 17:26:09 +01:00
170 changed files with 8437 additions and 14531 deletions

View File

@@ -937,42 +937,19 @@ var/global/floorIsLava = 0
return 0
if (!istype(M))
return 0
if((M.mind in ticker.mode.head_revolutionaries) || (M.mind in ticker.mode.revolutionaries))
if (ticker.mode.config_tag == "revolution")
return 2
return 1
if(M.mind in ticker.mode.cult)
if (ticker.mode.config_tag == "cult")
return 2
return 1
if(M.mind in ticker.mode.malf_ai)
if (ticker.mode.config_tag == "malfunction")
return 2
return 1
if(M.mind in ticker.mode.syndicates)
if (ticker.mode.config_tag == "mercenary")
return 2
return 1
if(M.mind in ticker.mode.wizards)
if (ticker.mode.config_tag == "wizard")
return 2
return 1
if(M.mind in ticker.mode.changelings)
if (ticker.mode.config_tag == "changeling")
return 2
return 1
for(var/datum/disease/D in M.viruses)
if(istype(D, /datum/disease/jungle_fever))
if (ticker.mode.config_tag == "monkey")
return 2
if(M.mind)
if(ticker.mode.antag_templates && ticker.mode.antag_templates.len)
for(var/datum/antagonist/antag in ticker.mode.antag_templates)
if(antag.is_antagonist(M.mind))
return 2
else if(M.mind.special_role)
return 1
if(isrobot(M))
var/mob/living/silicon/robot/R = M
if(R.emagged)
return 1
if(M.mind&&M.mind.special_role)//If they have a mind and special role, they are some type of traitor or antagonist.
return 1
return 0
@@ -1070,11 +1047,87 @@ var/global/floorIsLava = 0
M.mind.edit_memory()
feedback_add_details("admin_verb","STP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/show_game_mode()
set category = "Admin"
set desc = "Show the current round configuration."
set name = "Show Game Mode"
if(!ticker || !ticker.mode)
alert("Not before roundstart!", "Alert")
return
var/out = "<font size=3><b>Current mode: [ticker.mode.name] (<a href='?src=\ref[ticker.mode];debug_antag=self'>[ticker.mode.config_tag]</a>)</b></font><br/>"
out += "<hr>"
if(ticker.mode.ert_disabled)
out += "<b>Emergency Response Teams:</b> <a href='?src=\ref[ticker.mode];toggle=ert'>disabled</a>"
else
out += "<b>Emergency Response Teams:</b> <a href='?src=\ref[ticker.mode];toggle=ert'>enabled</a>"
out += "<br/>"
if(ticker.mode.deny_respawn)
out += "<b>Respawning:</b> <a href='?src=\ref[ticker.mode];toggle=respawn'>disallowed</a>"
else
out += "<b>Respawning:</b> <a href='?src=\ref[ticker.mode];toggle=respawn'>allowed</a>"
out += "<br/>"
out += "<b>Shuttle delay multiplier:</b> <a href='?src=\ref[ticker.mode];set=shuttle_delay'>[ticker.mode.shuttle_delay]</a><br/>"
if(ticker.mode.auto_recall_shuttle)
out += "<b>Shuttle auto-recall:</b> <a href='?src=\ref[ticker.mode];toggle=shuttle_recall'>enabled</a>"
else
out += "<b>Shuttle auto-recall:</b> <a href='?src=\ref[ticker.mode];toggle=shuttle_recall'>disabled</a>"
out += "<br/><br/>"
if(ticker.mode.event_delay_mod_moderate)
out += "<b>Moderate event time modifier:</b> <a href='?src=\ref[ticker.mode];set=event_modifier_moderate'>[ticker.mode.event_delay_mod_moderate]</a><br/>"
else
out += "<b>Moderate event time modifier:</b> <a href='?src=\ref[ticker.mode];set=event_modifier_moderate'>unset</a><br/>"
if(ticker.mode.event_delay_mod_major)
out += "<b>Major event time modifier:</b> <a href='?src=\ref[ticker.mode];set=event_modifier_severe'>[ticker.mode.event_delay_mod_major]</a><br/>"
else
out += "<b>Major event time modifier:</b> <a href='?src=\ref[ticker.mode];set=event_modifier_severe'>unset</a><br/>"
out += "<hr>"
if(ticker.mode.antag_tag)
out += "<b>Core antag id:</b> <a href='?src=\ref[ticker.mode];debug_antag=[ticker.mode.antag_tag]'>[ticker.mode.antag_tag]</a>.</br>"
if(ticker.mode.round_autoantag)
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b> ([ticker.mode.antag_prob]% spawn chance)"
if(ticker.mode.antag_scaling_coeff)
out += " (scaling with <a href='?src=\ref[ticker.mode];set=antag_scaling'>[ticker.mode.antag_scaling_coeff]</a>)"
out += "<br/>"
else
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>disabled</a></b>.<br/>"
out += "<b>All antag ids:</b>"
if(ticker.mode.antag_templates && ticker.mode.antag_templates.len).
var/playercount = ticker.mode.num_players()
for(var/datum/antagonist/antag in ticker.mode.antag_templates)
var/cur_max_antags
if(ticker.mode.antag_tag && antag.id == ticker.mode.antag_tag)
cur_max_antags = antag.max_antags_round
else
cur_max_antags = antag.max_antags
if(ticker.mode.antag_scaling_coeff)
cur_max_antags = Clamp((playercount/ticker.mode.antag_scaling_coeff), 1, cur_max_antags)
out += " <a href='?src=\ref[ticker.mode];debug_antag=[antag.id]'>[antag.id]</a>"
out += " ([antag.get_antag_count()]/[cur_max_antags]) "
out += " <a href='?src=\ref[ticker.mode];remove_antag_type=[antag.id]'>\[-\]</a><br/>"
else
out += " None."
out += " <a href='?src=\ref[ticker.mode];add_antag_type=1'>\[+\]</a><br/>"
usr << browse(out, "window=edit_mode[src]")
feedback_add_details("admin_verb","SGM")
/datum/admins/proc/toggletintedweldhelmets()
set category = "Debug"
set desc="Reduces view range when wearing welding helmets"
set name="Toggle tinted welding helmes"
set name="Toggle tinted welding helmets."
config.welder_vision = !( config.welder_vision )
if (config.welder_vision)
world << "<B>Reduced welder vision has been enabled!</B>"

View File

@@ -15,6 +15,7 @@ var/list/admin_verbs_admin = list(
/client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/
/client/proc/invisimin, /*allows our mob to go invisible/visible*/
// /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage
/datum/admins/proc/show_game_mode, /*Configuration window for the current game mode.*/
/datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/
/datum/admins/proc/toggleguests, /*toggles whether guests can join the current game*/
/datum/admins/proc/announce, /*priority announce something to all clients.*/
@@ -101,10 +102,8 @@ var/list/admin_verbs_fun = list(
/client/proc/drop_bomb,
/client/proc/everyone_random,
/client/proc/cinematic,
/client/proc/one_click_antag,
/datum/admins/proc/toggle_aliens,
/datum/admins/proc/toggle_space_ninja,
/client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
/client/proc/cmd_admin_add_random_ai_law,
/client/proc/make_sound,
@@ -152,6 +151,7 @@ var/list/admin_verbs_debug = list(
/client/proc/cmd_debug_make_powernets,
/client/proc/kill_airgroup,
/client/proc/debug_controller,
/client/proc/debug_antagonist_template,
/client/proc/cmd_debug_mob_lists,
/client/proc/cmd_admin_delete,
/client/proc/cmd_debug_del_all,
@@ -219,7 +219,6 @@ var/list/admin_verbs_hideable = list(
/client/proc/cinematic,
/datum/admins/proc/toggle_aliens,
/datum/admins/proc/toggle_space_ninja,
/client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
/client/proc/cmd_admin_add_random_ai_law,
/client/proc/cmd_admin_create_centcom_report,
@@ -566,22 +565,6 @@ var/list/admin_verbs_mentor = list(
message_admins("\blue [ckey] creating an admin explosion at [epicenter.loc].")
feedback_add_details("admin_verb","DB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/give_spell(mob/T as mob in mob_list) // -- Urist
set category = "Fun"
set name = "Give Spell"
set desc = "Gives a spell to a mob."
var/list/spell_names = list()
for(var/v in spells)
// "/obj/effect/proc_holder/spell/" 30 symbols ~Intercross21
spell_names.Add(copytext("[v]", 31, 0))
var/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_names
if(!S) return
var/path = text2path("/obj/effect/proc_holder/spell/[S]")
T.spell_list += new path
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1)
/client/proc/give_disease(mob/T as mob in mob_list) // -- Giacom
set category = "Fun"
set name = "Give Disease (old)"

View File

@@ -410,80 +410,8 @@
dat += "Launching now..."
dat += "<a href='?src=\ref[src];delay_round_end=1'>[ticker.delay_end ? "End Round Normally" : "Delay Round End"]</a><br>"
if(ticker.mode.syndicates.len)
dat += "<br><table cellspacing=5><tr><td><B>Mercenaries</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.syndicates)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
else
dat += "<tr><td><i>Mercenary not found!</i></td></tr>"
dat += "</table><br><table><tr><td><B>Nuclear Disk(s)</B></td></tr>"
for(var/obj/item/weapon/disk/nuclear/N in world)
dat += "<tr><td>[N.name], "
var/atom/disk_loc = N.loc
while(!istype(disk_loc, /turf))
if(istype(disk_loc, /mob))
var/mob/M = disk_loc
dat += "carried by <a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> "
if(istype(disk_loc, /obj))
var/obj/O = disk_loc
dat += "in \a [O.name] "
disk_loc = disk_loc.loc
dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])</td></tr>"
dat += "</table>"
if(ticker.mode.head_revolutionaries.len || ticker.mode.revolutionaries.len)
dat += "<br><table cellspacing=5><tr><td><B>Revolutionaries</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.head_revolutionaries)
var/mob/M = N.current
if(!M)
dat += "<tr><td><i>Head Revolutionary not found!</i></td></tr>"
else
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
for(var/datum/mind/N in ticker.mode.revolutionaries)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
for(var/datum/mind/N in ticker.mode.get_living_heads())
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
var/turf/mob_loc = get_turf(M)
dat += "<td>[mob_loc.loc]</td></tr>"
else
dat += "<tr><td><i>Head not found!</i></td></tr>"
dat += "</table>"
if(ticker.mode.changelings.len)
dat += check_role_table("Changelings", ticker.mode.changelings, src)
if(ticker.mode.wizards.len)
dat += check_role_table("Wizards", ticker.mode.wizards, src)
if(ticker.mode.raiders.len)
dat += check_role_table("Raiders", ticker.mode.raiders, src)
if(ticker.mode.ninjas.len)
dat += check_role_table("Ninjas", ticker.mode.ninjas, src)
if(ticker.mode.cult.len)
dat += check_role_table("Cultists", ticker.mode.cult, src, 0)
if(ticker.mode.traitors.len)
dat += check_role_table("Traitors", ticker.mode.traitors, src)
if(ticker.mode.borers.len)
dat += check_role_table("Cortical Borers", ticker.mode.borers, src)
var/datum/game_mode/mutiny/mutiny = get_mutiny_mode()
if(mutiny)
dat += mutiny.check_antagonists_ui(src)
//todo
dat += "</body></html>"
usr << browse(dat, "window=roundstatus;size=400x500")

View File

@@ -10,49 +10,8 @@
check_antagonists()
return
if(href_list["makeAntag"])
switch(href_list["makeAntag"])
if("1")
log_admin("[key_name(usr)] has spawned a traitor.")
if(!src.makeTraitors())
usr << "\red Unfortunately there weren't enough candidates available."
if("2")
log_admin("[key_name(usr)] has spawned a changeling.")
if(!src.makeChanglings())
usr << "\red Unfortunately there weren't enough candidates available."
if("3")
log_admin("[key_name(usr)] has spawned revolutionaries.")
if(!src.makeRevs())
usr << "\red Unfortunately there weren't enough candidates available."
if("4")
log_admin("[key_name(usr)] has spawned a cultists.")
if(!src.makeCult())
usr << "\red Unfortunately there weren't enough candidates available."
if("5")
log_admin("[key_name(usr)] has spawned a malf AI.")
if(!src.makeMalfAImode())
usr << "\red Unfortunately there weren't enough candidates available."
if("6")
log_admin("[key_name(usr)] has spawned a wizard.")
if(!src.makeWizard())
usr << "\red Unfortunately there weren't enough candidates available."
if("7")
log_admin("[key_name(usr)] has spawned a nuke team.")
if(!src.makeNukeTeam())
usr << "\red Unfortunately there weren't enough candidates available."
if("8")
log_admin("[key_name(usr)] has spawned a ninja.")
src.makeSpaceNinja()
if("9")
log_admin("[key_name(usr)] has spawned aliens.")
src.makeAliens()
if("10")
log_admin("[key_name(usr)] has spawned a death squad.")
if("11")
log_admin("[key_name(usr)] has spawned vox raiders.")
if(!src.makeVoxRaiders())
usr << "\red Unfortunately there weren't enough candidates available."
else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"] || href_list["dbsearchip"] || href_list["dbsearchcid"] || href_list["dbsearchbantype"])
if(href_list["dbsearchckey"] || href_list["dbsearchadmin"])
var/adminckey = href_list["dbsearchadmin"]
var/playerckey = href_list["dbsearchckey"]
var/playerip = href_list["dbsearchip"]
@@ -586,69 +545,15 @@
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ffeeaa'><th colspan='10'><a href='?src=\ref[src];jobban3=Syndicate;jobban4=\ref[M]'>Antagonist Positions</a></th></tr><tr align='center'>"
//Traitor
if(jobban_isbanned(M, "traitor") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=traitor;jobban4=\ref[M]'><font color=red>[replacetext("Traitor", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=traitor;jobban4=\ref[M]'>[replacetext("Traitor", " ", "&nbsp")]</a></td>"
//Changeling
if(jobban_isbanned(M, "changeling") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=changeling;jobban4=\ref[M]'><font color=red>[replacetext("Changeling", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=changeling;jobban4=\ref[M]'>[replacetext("Changeling", " ", "&nbsp")]</a></td>"
//Nuke Operative
if(jobban_isbanned(M, "operative") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=operative;jobban4=\ref[M]'><font color=red>[replacetext("Mercenary", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=operative;jobban4=\ref[M]'>[replacetext("Mercenary", " ", "&nbsp")]</a></td>"
//Revolutionary
if(jobban_isbanned(M, "revolutionary") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=revolutionary;jobban4=\ref[M]'><font color=red>[replacetext("Revolutionary", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=revolutionary;jobban4=\ref[M]'>[replacetext("Revolutionary", " ", "&nbsp")]</a></td>"
jobs += "</tr><tr align='center'>" //Breaking it up so it fits nicer on the screen every 5 entries
//Cultist
if(jobban_isbanned(M, "cultist") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=cultist;jobban4=\ref[M]'><font color=red>[replacetext("Cultist", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=cultist;jobban4=\ref[M]'>[replacetext("Cultist", " ", "&nbsp")]</a></td>"
//Wizard
if(jobban_isbanned(M, "wizard") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=wizard;jobban4=\ref[M]'><font color=red>[replacetext("Wizard", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=wizard;jobban4=\ref[M]'>[replacetext("Wizard", " ", "&nbsp")]</a></td>"
//ERT
if(jobban_isbanned(M, "Emergency Response Team") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Emergency Response Team;jobban4=\ref[M]'><font color=red>Emergency Response Team</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Emergency Response Team;jobban4=\ref[M]'>Emergency Response Team</a></td>"
/* //Malfunctioning AI //Removed Malf-bans because they're a pain to impliment
if(jobban_isbanned(M, "malf AI") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=malf AI;jobban4=\ref[M]'><font color=red>[replacetext("Malf AI", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=malf AI;jobban4=\ref[M]'>[replacetext("Malf AI", " ", "&nbsp")]</a></td>"
//Alien
if(jobban_isbanned(M, "alien candidate") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=alien candidate;jobban4=\ref[M]'><font color=red>[replacetext("Alien", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=alien candidate;jobban4=\ref[M]'>[replacetext("Alien", " ", "&nbsp")]</a></td>"
//Infested Monkey
if(jobban_isbanned(M, "infested monkey") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=infested monkey;jobban4=\ref[M]'><font color=red>[replacetext("Infested Monkey", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=infested monkey;jobban4=\ref[M]'>[replacetext("Infested Monkey", " ", "&nbsp")]</a></td>"
*/
// Antagonists.
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
if(!antag || !antag.bantype)
continue
if(jobban_isbanned(M, "[antag.bantype]") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[antag.bantype];jobban4=\ref[M]'><font color=red>[replacetext("[antag.role_text]", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[antag.bantype];jobban4=\ref[M]'>[replacetext("[antag.role_text]", " ", "&nbsp")]</a></td>"
jobs += "</tr></table>"
@@ -660,16 +565,7 @@
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Dionaea;jobban4=\ref[M]'><font color=red>Dionaea</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Dionaea;jobban4=\ref[M]'>Dionaea</a></td>"
if(jobban_isbanned(M, "Borer"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Borer;jobban4=\ref[M]'><font color=red>Borer</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Borer;jobban4=\ref[M]'>Borer</a></td>"
jobs += "</tr></table>"
body = "<body>[jobs]</body>"
dat = "<tt>[header][body]</tt>"
usr << browse(dat, "window=jobban2;size=800x490")
@@ -1900,13 +1796,13 @@
feedback_add_details("admin_secrets_fun_used","Aliens")
log_admin("[key_name(usr)] spawned an alien infestation", 1)
message_admins("\blue [key_name_admin(usr)] attempted an alien infestation", 1)
new /datum/event/alien_infestation
xenomorphs.random_spawn()
if("borers")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Borers")
log_admin("[key_name(usr)] spawned a cortical borer infestation.", 1)
message_admins("\blue [key_name_admin(usr)] spawned a cortical borer infestation.", 1)
new /datum/event/borer_infestation
borers.random_spawn()
if("power")
feedback_inc("admin_secrets_fun_used",1)
@@ -1994,40 +1890,6 @@
//teleport security person
H.loc = pick(prisonsecuritywarp)
prisonwarped += H
if("traitor_all")
if(!ticker)
alert("The game hasn't started yet!")
return
var/objective = sanitize(copytext(input("Enter an objective"),1,MAX_MESSAGE_LEN))
if(!objective)
return
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","TA([objective])")
for(var/mob/living/carbon/human/H in player_list)
if(H.stat == 2 || !H.client || !H.mind) continue
if(is_special_character(H)) continue
//traitorize(H, objective, 0)
ticker.mode.traitors += H.mind
H.mind.special_role = "traitor"
var/datum/objective/new_objective = new
new_objective.owner = H
new_objective.explanation_text = objective
H.mind.objectives += new_objective
ticker.mode.greet_traitor(H.mind)
//ticker.mode.forge_traitor_objectives(H.mind)
ticker.mode.finalize_traitor(H.mind)
for(var/mob/living/silicon/A in player_list)
ticker.mode.traitors += A.mind
A.mind.special_role = "traitor"
var/datum/objective/new_objective = new
new_objective.owner = A
new_objective.explanation_text = objective
A.mind.objectives += new_objective
ticker.mode.greet_traitor(A.mind)
ticker.mode.finalize_traitor(A.mind)
message_admins("\blue [key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]", 1)
log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]")
if("launchshuttle")
if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created.
@@ -2252,8 +2114,7 @@
if("aliens")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","AL")
if(config.aliens_allowed)
new /datum/event/alien_infestation
if(xenomorphs.random_spawn())
message_admins("[key_name_admin(usr)] has spawned aliens", 1)
if("spiders")
feedback_inc("admin_secrets_fun_used",1)
@@ -2269,12 +2130,6 @@
else
communications_blackout(1)
message_admins("[key_name_admin(usr)] triggered a communications blackout.", 1)
if("spaceninja")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SN")
if(config.ninjas_allowed)
if(space_ninja_arrival())//If the ninja is actually spawned. They may not be depending on a few factors.
message_admins("[key_name_admin(usr)] has sent in a space ninja", 1)
if("carp")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","C")
@@ -2453,7 +2308,7 @@
if("onlyone")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","OO")
usr.client.only_one()
only_one()
message_admins("[key_name_admin(usr)] has triggered a battle to the death (only one)")
if(usr)
log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]")

View File

@@ -729,10 +729,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.equip_to_slot_or_del(W, slot_wear_id)
if("death commando")//Was looking to add this for a while.
M.equip_death_commando()
deathsquad.equip(M)
if("syndicate commando")
M.equip_syndicate_commando()
commandos.equip(M)
if("nanotrasen representative")
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform)

View File

@@ -1,528 +0,0 @@
client/proc/one_click_antag()
set name = "Create Antagonist"
set desc = "Auto-create an antagonist of your choice"
set category = "Admin"
if(holder)
holder.one_click_antag()
return
/datum/admins/proc/one_click_antag()
var/dat = {"<B>One-click Antagonist</B><br>
<a href='?src=\ref[src];makeAntag=1'>Make Traitors</a><br>
<a href='?src=\ref[src];makeAntag=2'>Make Changlings</a><br>
<a href='?src=\ref[src];makeAntag=3'>Make Revs</a><br>
<a href='?src=\ref[src];makeAntag=4'>Make Cult</a><br>
<a href='?src=\ref[src];makeAntag=5'>Make Malf AI</a><br>
<a href='?src=\ref[src];makeAntag=6'>Make Wizard (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=11'>Make Vox Raiders (Requires Ghosts)</a><br>
"}
/* These dont work just yet
Ninja, aliens and deathsquad I have not looked into yet
Nuke team is getting a null mob returned from makebody() (runtime error: null.mind. Line 272)
<a href='?src=\ref[src];makeAntag=7'>Make Nuke Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=8'>Make Space Ninja (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=9'>Make Aliens (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=10'>Make Deathsquad (Syndicate) (Requires Ghosts)</a><br>
"}
*/
usr << browse(dat, "window=oneclickantag;size=400x400")
return
/datum/admins/proc/makeMalfAImode()
var/list/mob/living/silicon/AIs = list()
var/mob/living/silicon/malfAI = null
var/datum/mind/themind = null
for(var/mob/living/silicon/ai/ai in player_list)
if(ai.client)
AIs += ai
if(AIs.len)
malfAI = pick(AIs)
if(malfAI)
themind = malfAI.mind
themind.make_AI_Malf()
return 1
return 0
/datum/admins/proc/makeTraitors()
var/datum/game_mode/traitor/temp = new
if(config.protect_roles_from_antagonist)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in player_list)
if(applicant.client.prefs.be_special & BE_TRAITOR)
if(!applicant.stat)
if(applicant.mind)
if (!applicant.mind.special_role)
if(!jobban_isbanned(applicant, "traitor") && !jobban_isbanned(applicant, "Syndicate"))
if(!(applicant.job in temp.restricted_jobs))
candidates += applicant
if(candidates.len)
var/numTraitors = min(candidates.len, 3)
for(var/i = 0, i<numTraitors, i++)
H = pick(candidates)
H.mind.make_Traitor()
candidates.Remove(H)
return 1
return 0
/datum/admins/proc/makeChanglings()
var/datum/game_mode/changeling/temp = new
if(config.protect_roles_from_antagonist)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in player_list)
if(applicant.client.prefs.be_special & BE_CHANGELING)
if(!applicant.stat)
if(applicant.mind)
if (!applicant.mind.special_role)
if(!jobban_isbanned(applicant, "changeling") && !jobban_isbanned(applicant, "Syndicate"))
if(!(applicant.job in temp.restricted_jobs))
candidates += applicant
if(candidates.len)
var/numChanglings = min(candidates.len, 3)
for(var/i = 0, i<numChanglings, i++)
H = pick(candidates)
H.mind.make_Changling()
candidates.Remove(H)
return 1
return 0
/datum/admins/proc/makeRevs()
var/datum/game_mode/revolution/temp = new
if(config.protect_roles_from_antagonist)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in player_list)
if(applicant.client.prefs.be_special & BE_REV)
if(applicant.stat == CONSCIOUS)
if(applicant.mind)
if(!applicant.mind.special_role)
if(!jobban_isbanned(applicant, "revolutionary") && !jobban_isbanned(applicant, "Syndicate"))
if(!(applicant.job in temp.restricted_jobs))
candidates += applicant
if(candidates.len)
var/numRevs = min(candidates.len, 3)
for(var/i = 0, i<numRevs, i++)
H = pick(candidates)
H.mind.make_Rev()
candidates.Remove(H)
return 1
return 0
/datum/admins/proc/makeWizard()
var/list/mob/dead/observer/candidates = list()
var/mob/dead/observer/theghost = null
var/time_passed = world.time
for(var/mob/dead/observer/G in player_list)
if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
spawn(0)
switch(alert(G, "Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No"))
if("Yes")
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
return
candidates += G
if("No")
return
else
return
sleep(300)
if(candidates.len)
shuffle(candidates)
for(var/mob/i in candidates)
if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
theghost = i
break
if(theghost)
var/mob/living/carbon/human/new_character=makeBody(theghost)
new_character.mind.make_Wizard()
return 1
return 0
/datum/admins/proc/makeCult()
var/datum/game_mode/cult/temp = new
if(config.protect_roles_from_antagonist)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in player_list)
if(applicant.client.prefs.be_special & BE_CULTIST)
if(applicant.stat == CONSCIOUS)
if(applicant.mind)
if(!applicant.mind.special_role)
if(!jobban_isbanned(applicant, "cultist") && !jobban_isbanned(applicant, "Syndicate"))
if(!(applicant.job in temp.restricted_jobs))
candidates += applicant
if(candidates.len)
var/numCultists = min(candidates.len, 4)
for(var/i = 0, i<numCultists, i++)
H = pick(candidates)
H.mind.make_Cultist()
candidates.Remove(H)
temp.grant_runeword(H)
return 1
return 0
/datum/admins/proc/makeNukeTeam()
var/list/mob/dead/observer/candidates = list()
var/mob/dead/observer/theghost = null
var/time_passed = world.time
for(var/mob/dead/observer/G in player_list)
if(!jobban_isbanned(G, "operative") && !jobban_isbanned(G, "Syndicate"))
spawn(0)
switch(alert(G,"Do you wish to be considered for a nuke team being sent in?","Please answer in 30 seconds!","Yes","No"))
if("Yes")
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
return
candidates += G
if("No")
return
else
return
sleep(300)
if(candidates.len)
var/numagents = 5
var/agentcount = 0
for(var/i = 0, i<numagents,i++)
shuffle(candidates) //More shuffles means more randoms
for(var/mob/j in candidates)
if(!j || !j.client)
candidates.Remove(j)
continue
theghost = candidates
candidates.Remove(theghost)
var/mob/living/carbon/human/new_character=makeBody(theghost)
new_character.mind.make_Nuke()
agentcount++
if(agentcount < 1)
return 0
var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb")
var/obj/effect/landmark/closet_spawn = locate("landmark*Nuclear-Closet")
var/nuke_code = "[rand(10000, 99999)]"
if(nuke_spawn)
var/obj/item/weapon/paper/P = new
P.info = "Sadly, your employers could not get you a nuclear bomb. They have, however, acquired the arming code for the station's onboard nuke. The nuclear authorization code is: <b>[nuke_code]</b>"
P.name = "nuclear bomb code and instructions"
P.loc = nuke_spawn.loc
if(closet_spawn)
new /obj/structure/closet/syndicate/nuclear(closet_spawn.loc)
for (var/obj/effect/landmark/A in /area/syndicate_station/start)//Because that's the only place it can BE -Sieve
if (A.name == "Syndicate-Gear-Closet")
new /obj/structure/closet/syndicate/personal(A.loc)
del(A)
continue
if (A.name == "Syndicate-Bomb")
new /obj/effect/spawner/newbomb/timer/syndicate(A.loc)
del(A)
continue
for(var/datum/mind/synd_mind in ticker.mode.syndicates)
if(synd_mind.current)
if(synd_mind.current.client)
for(var/image/I in synd_mind.current.client.images)
if(I.icon_state == "synd")
del(I)
for(var/datum/mind/synd_mind in ticker.mode.syndicates)
if(synd_mind.current)
if(synd_mind.current.client)
for(var/datum/mind/synd_mind_1 in ticker.mode.syndicates)
if(synd_mind_1.current)
var/I = image('icons/mob/mob.dmi', loc = synd_mind_1.current, icon_state = "synd")
synd_mind.current.client.images += I
for (var/obj/machinery/nuclearbomb/bomb in world)
bomb.r_code = nuke_code // All the nukes are set to this code.
return 1
/datum/admins/proc/makeAliens()
alien_infestation(3)
return 1
/datum/admins/proc/makeSpaceNinja()
space_ninja_arrival()
return 1
/datum/admins/proc/makeDeathsquad()
var/list/mob/dead/observer/candidates = list()
var/mob/dead/observer/theghost = null
var/time_passed = world.time
var/input = "Purify the station."
if(prob(10))
input = "Save Runtime and any other cute things on the station."
var/syndicate_leader_selected = 0 //when the leader is chosen. The last person spawned.
//Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos.
for(var/mob/dead/observer/G in player_list)
spawn(0)
switch(alert(G,"Do you wish to be considered for an elite mercenary strike team being sent in?","Please answer in 30 seconds!","Yes","No"))
if("Yes")
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
return
candidates += G
if("No")
return
else
return
sleep(300)
for(var/mob/dead/observer/G in candidates)
if(!G.key)
candidates.Remove(G)
if(candidates.len)
var/numagents = 6
//Spawns commandos and equips them.
for (var/obj/effect/landmark/L in /area/syndicate_mothership/elite_squad)
if(numagents<=0)
break
if (L.name == "Syndicate-Commando")
syndicate_leader_selected = numagents == 1?1:0
var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, syndicate_leader_selected)
while((!theghost || !theghost.client) && candidates.len)
theghost = pick(candidates)
candidates.Remove(theghost)
if(!theghost)
del(new_syndicate_commando)
break
new_syndicate_commando.key = theghost.key
new_syndicate_commando.internal = new_syndicate_commando.s_store
new_syndicate_commando.internals.icon_state = "internal1"
//So they don't forget their code or mission.
new_syndicate_commando << "\blue You are an Elite Mercenary. [!syndicate_leader_selected?"commando":"<B>LEADER</B>"] in the service of criminal elements hostile to NanoTrasen. \nYour current mission is: \red<B> [input]</B>"
numagents--
if(numagents >= 6)
return 0
for (var/obj/effect/landmark/L in /area/shuttle/syndicate_elite)
if (L.name == "Syndicate-Commando-Bomb")
new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
return 1
/datum/admins/proc/makeBody(var/mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
if(!G_found || !G_found.key) return
//First we spawn a dude.
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
new_character.gender = pick(MALE,FEMALE)
var/datum/preferences/A = new()
A.randomize_appearance_for(new_character)
if(new_character.gender == MALE)
new_character.real_name = "[pick(first_names_male)] [pick(last_names)]"
else
new_character.real_name = "[pick(first_names_female)] [pick(last_names)]"
new_character.name = new_character.real_name
new_character.age = rand(17,45)
new_character.dna.ready_dna(new_character)
new_character.key = G_found.key
return new_character
/datum/admins/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0)
var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc)
var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major")
var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/syndicate_commando_name = pick(last_names)
new_syndicate_commando.gender = pick(MALE, FEMALE)
var/datum/preferences/A = new()//Randomize appearance for the commando.
A.randomize_appearance_for(new_syndicate_commando)
new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]"
new_syndicate_commando.name = new_syndicate_commando.real_name
new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45)
new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA.
//Creates mind stuff.
new_syndicate_commando.mind_initialize()
new_syndicate_commando.mind.assigned_role = "MODE"
new_syndicate_commando.mind.special_role = "Mercenary"
//Adds them to current traitor list. Which is really the extra antagonist list.
ticker.mode.traitors += new_syndicate_commando.mind
new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected)
return new_syndicate_commando
/datum/admins/proc/makeVoxRaiders()
var/list/mob/dead/observer/candidates = list()
var/mob/dead/observer/theghost = null
var/time_passed = world.time
var/input = "Disregard shinies, acquire hardware."
var/leader_chosen = 0 //when the leader is chosen. The last person spawned.
//Generates a list of candidates from active ghosts.
for(var/mob/dead/observer/G in player_list)
spawn(0)
switch(alert(G,"Do you wish to be considered for a vox raiding party arriving on the station?","Please answer in 30 seconds!","Yes","No"))
if("Yes")
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
return
candidates += G
if("No")
return
else
return
sleep(300) //Debug.
for(var/mob/dead/observer/G in candidates)
if(!G.key)
candidates.Remove(G)
if(candidates.len)
var/max_raiders = 1
var/raiders = max_raiders
//Spawns vox raiders and equips them.
for (var/obj/effect/landmark/L in world)
if(L.name == "voxstart")
if(raiders<=0)
break
var/mob/living/carbon/human/new_vox = create_vox_raider(L, leader_chosen)
while((!theghost || !theghost.client) && candidates.len)
theghost = pick(candidates)
candidates.Remove(theghost)
if(!theghost)
del(new_vox)
break
new_vox.key = theghost.key
new_vox << "\blue You are a Vox Primalis, fresh out of the Shoal. Your ship has arrived at a human-meat system hosting the NSV Exodus... or was it the Luna? NSS? Utopia? Nobody is really sure, who cares about stupid meat-names anyway? Everyone is raring to start pillaging! Your current goal is: \red<B> [input]</B>"
new_vox << "\red Don't forget to turn on your nitrogen internals!"
raiders--
if(raiders > max_raiders)
return 0
else
return 0
return 1
/datum/admins/proc/create_vox_raider(obj/spawn_location, leader_chosen = 0)
var/mob/living/carbon/human/new_vox = new(spawn_location.loc, "Vox")
new_vox.gender = pick(MALE, FEMALE)
new_vox.h_style = "Short Vox Quills"
new_vox.regenerate_icons()
var/sounds = rand(2,10)
var/i = 0
var/newname = ""
while(i<=sounds)
i++
newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah"))
new_vox.real_name = capitalize(newname)
new_vox.name = new_vox.real_name
new_vox.age = rand(12,20)
new_vox.dna.ready_dna(new_vox) // Creates DNA.
new_vox.mind_initialize()
new_vox.mind.assigned_role = "MODE"
new_vox.mind.special_role = "Vox Raider"
new_vox.mutations |= NOCLONE //Stops the station crew from messing around with their DNA.
if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist ) ) )
var/datum/game_mode/heist/M = ticker.mode
if(new_vox.internal_organs_by_name["stack"])
cortical_stacks |= new_vox.internal_organs_by_name["stack"]
M.raiders[new_vox.mind] = new_vox.internal_organs_by_name["stack"]
ticker.mode.traitors += new_vox.mind
new_vox.equip_vox_raider()
return new_vox

View File

@@ -1,47 +0,0 @@
/client/proc/only_one()
if(!ticker)
alert("The game hasn't started yet!")
return
for(var/mob/living/carbon/human/H in player_list)
if(H.stat == 2 || !(H.client)) continue
if(is_special_character(H)) continue
ticker.mode.traitors += H.mind
H.mind.special_role = "traitor"
var/datum/objective/steal/steal_objective = new
steal_objective.owner = H.mind
steal_objective.set_target("nuclear authentication disk")
H.mind.objectives += steal_objective
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = H.mind
H.mind.objectives += hijack_objective
H << "<B>You are the traitor.</B>"
show_objectives(H.mind)
for (var/obj/item/I in H)
if (istype(I, /obj/item/weapon/implant))
continue
del(I)
H.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(H), slot_l_ear)
H.equip_to_slot_or_del(new /obj/item/clothing/head/beret(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/weapon/claymore(H), slot_l_hand)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(H.loc), slot_l_store)
var/obj/item/weapon/card/id/W = new(H)
W.name = "[H.real_name]'s ID Card"
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Highlander"
W.registered_name = H.real_name
H.equip_to_slot_or_del(W, slot_wear_id)
message_admins("\blue [key_name_admin(usr)] used THERE CAN BE ONLY ONE!", 1)
log_admin("[key_name(usr)] used there can be only one.")

View File

@@ -445,50 +445,12 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/player_key = G_found.key
//Now for special roles and equipment.
switch(new_character.mind.special_role)
if("traitor")
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)
ticker.mode.equip_traitor(new_character)
if("Wizard")
new_character.loc = pick(wizardstart)
//ticker.mode.learn_basic_spells(new_character)
ticker.mode.equip_wizard(new_character)
if("Mercenary")
var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn")
if(synd_spawn)
new_character.loc = get_turf(synd_spawn)
call(/datum/game_mode/proc/equip_syndicate)(new_character)
if("Ninja")
new_character.equip_space_ninja()
if(ninjastart.len == 0)
new_character << "<B>\red A proper starting location for you could not be found, please report this bug!</B>"
new_character << "<B>\red Attempting to place at a carpspawn.</B>"
for(var/obj/effect/landmark/L in landmarks_list)
if(L.name == "carpspawn")
ninjastart.Add(L)
if(ninjastart.len == 0 && latejoin.len > 0)
new_character << "<B>\red Still no spawneable locations could be found. Defaulting to latejoin.</B>"
new_character.loc = pick(latejoin)
else if (ninjastart.len == 0)
new_character << "<B>\red Still no spawneable locations could be found. Aborting.</B>"
if("Death Commando")//Leaves them at late-join spawn.
new_character.equip_death_commando()
new_character.internal = new_character.s_store
new_character.internals.icon_state = "internal1"
else//They may also be a cyborg or AI.
switch(new_character.mind.assigned_role)
if("Cyborg")//More rigging to make em' work and check if they're traitor.
new_character = new_character.Robotize()
if(new_character.mind.special_role=="traitor")
call(/datum/game_mode/proc/add_law_zero)(new_character)
if("AI")
new_character = new_character.AIize()
if(new_character.mind.special_role=="traitor")
call(/datum/game_mode/proc/add_law_zero)(new_character)
//Add aliens.
else
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
var/datum/antagonist/antag_data = get_antag_data(new_character.mind.special_role)
if(antag_data)
antag_data.add_antagonist(new_character.mind)
antag_data.place_mob(new_character)
else
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)
//Announces the character on all the systems, based on the record.
if(!issilicon(new_character))//If they are not a cyborg/AI.

View File

@@ -1,174 +1,55 @@
//STRIKE TEAMS
var/const/commandos_possible = 6 //if more Commandos are needed in the future
var/global/sent_strike_team = 0
/client/proc/strike_team()
set category = "Fun"
set name = "Spawn Strike Team"
set desc = "Spawns a death squad if you want to run an admin event."
if(!src.holder)
src << "Only administrators may use this command."
return
if(!ticker)
usr << "<font color='red'>The game hasn't started yet!</font>"
return
if(world.time < 6000)
usr << "<font color='red'>There are [(6000-world.time)/10] seconds remaining before it may be called.</font>"
return
if(sent_strike_team == 1)
usr << "<font color='red'>CentCom is already sending a team.</font>"
var/datum/antagonist/deathsquad/team
var/choice = input(usr, "Select type of strike team:") as null|anything in list("Death Squad", "Mercenaries")
if(!choice)
return
if(alert("Do you want to send in the CentCom death squad? Once enabled, this is irreversible.",,"Yes","No")!="Yes")
switch(choice)
if("Death Squad")
team = deathsquad
if("Mercenaries")
team = commandos
else
return
if(team.deployed)
usr << "<font color='red'>Someone is already sending a team.</font>"
return
if(alert("Do you want to send in a strike team? Once enabled, this is irreversible.",,"Yes","No")!="Yes")
return
alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.")
var/input = null
while(!input)
input = sanitize(copytext(input(src, "Please specify which mission the death commando squad shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN))
if(!input)
choice = null
while(!choice)
choice = sanitize(copytext(input(src, "Please specify which mission the strike team shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN))
if(!choice)
if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
return
if(sent_strike_team)
if(team.deployed)
usr << "Looks like someone beat you to it."
return
sent_strike_team = 1
if (emergency_shuttle.can_recall())
emergency_shuttle.recall()
var/commando_number = commandos_possible //for selecting a leader
var/leader_selected = 0 //when the leader is chosen. The last person spawned.
//Code for spawning a nuke auth code.
var/nuke_code
var/temp_code
for(var/obj/machinery/nuclearbomb/N in world)
temp_code = text2num(N.r_code)
if(temp_code)//if it's actually a number. It won't convert any non-numericals.
nuke_code = N.r_code
break
//Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos.
var/list/candidates = list() //candidates for being a commando out of all the active ghosts in world.
var/list/commandos = list() //actual commando ghosts as picked by the user.
for(var/mob/dead/observer/G in player_list)
if(!G.client.holder && !G.client.is_afk()) //Whoever called/has the proc won't be added to the list.
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
candidates += G.key
for(var/i=commandos_possible,(i>0&&candidates.len),i--)//Decrease with every commando selected.
var/candidate = input("Pick characters to spawn as the commandos. This will go on until there either no more ghosts to pick from or the slots are full.", "Active Players") as null|anything in candidates //It will auto-pick a person when there is only one candidate.
candidates -= candidate //Subtract from candidates.
commandos += candidate//Add their ghost to commandos.
//Spawns commandos and equips them.
for(var/obj/effect/landmark/L in landmarks_list)
if(commando_number<=0) break
if (L.name == "Commando")
leader_selected = commando_number == 1?1:0
var/mob/living/carbon/human/new_commando = create_death_commando(L, leader_selected)
if(commandos.len)
new_commando.key = pick(commandos)
commandos -= new_commando.key
new_commando.internal = new_commando.s_store
new_commando.internals.icon_state = "internal1"
//So they don't forget their code or mission.
if(nuke_code)
new_commando.mind.store_memory("<B>Nuke Code:</B> \red [nuke_code].")
new_commando.mind.store_memory("<B>Mission:</B> \red [input].")
new_commando << "\blue You are a Special Ops. [!leader_selected?"commando":"<B>LEADER</B>"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: \red<B>[input]</B>"
commando_number--
//Spawns the rest of the commando gear.
for (var/obj/effect/landmark/L in landmarks_list)
if (L.name == "Commando_Manual")
//new /obj/item/weapon/gun/energy/pulse_rifle(L.loc)
var/obj/item/weapon/paper/P = new(L.loc)
P.info = "<p><b>Good morning soldier!</b>. This compact guide will familiarize you with standard operating procedure. There are three basic rules to follow:<br>#1 Work as a team.<br>#2 Accomplish your objective at all costs.<br>#3 Leave no witnesses.<br>You are fully equipped and stocked for your mission--before departing on the Spec. Ops. Shuttle due South, make sure that all operatives are ready. Actual mission objective will be relayed to you by Central Command through your headsets.<br>If deemed appropriate, Central Command will also allow members of your team to equip assault power-armor for the mission. You will find the armor storage due West of your position. Once you are ready to leave, utilize the Special Operations shuttle console and toggle the hull doors via the other console.</p><p>In the event that the team does not accomplish their assigned objective in a timely manner, or finds no other way to do so, attached below are instructions on how to operate a Nanotrasen Nuclear Device. Your operations <b>LEADER</b> is provided with a nuclear authentication disk and a pin-pointer for this reason. You may easily recognize them by their rank: Lieutenant, Captain, or Major. The nuclear device itself will be present somewhere on your destination.</p><p>Hello and thank you for choosing Nanotrasen for your nuclear information needs. Today's crash course will deal with the operation of a Fission Class Nanotrasen made Nuclear Device.<br>First and foremost, <b>DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.</b> Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done to unbolt it one must completely log in which at this time may not be possible.<br>To make the device functional:<br>#1 Place bomb in designated detonation zone<br> #2 Extend and anchor bomb (attack with hand).<br>#3 Insert Nuclear Auth. Disk into slot.<br>#4 Type numeric code into keypad ([nuke_code]).<br>Note: If you make a mistake press R to reset the device.<br>#5 Press the E button to log onto the device.<br>You now have activated the device. To deactivate the buttons at anytime, for example when you have already prepped the bomb for detonation, remove the authentication disk OR press the R on the keypad. Now the bomb CAN ONLY be detonated using the timer. A manual detonation is not an option.<br>Note: Toggle off the <b>SAFETY</b>.<br>Use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.<br>Note: <b>THE BOMB IS STILL SET AND WILL DETONATE</b><br>Now before you remove the disk if you need to move the bomb you can: Toggle off the anchor, move it, and re-anchor.</p><p>The nuclear authorization code is: <b>[nuke_code ? nuke_code : "None provided"]</b></p><p><b>Good luck, soldier!</b></p>"
P.name = "Spec. Ops. Manual"
for (var/obj/effect/landmark/L in landmarks_list)
if (L.name == "Commando-Bomb")
new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
del(L)
message_admins("\blue [key_name_admin(usr)] has spawned a CentCom strike squad.", 1)
log_admin("[key_name(usr)] used Spawn Death Squad.")
return 1
/client/proc/create_death_commando(obj/spawn_location, leader_selected = 0)
var/mob/living/carbon/human/new_commando = new(spawn_location.loc)
var/commando_leader_rank = pick("Lieutenant", "Captain", "Major")
var/commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/commando_name = pick(last_names)
new_commando.gender = pick(MALE, FEMALE)
var/datum/preferences/A = new()//Randomize appearance for the commando.
A.randomize_appearance_for(new_commando)
new_commando.real_name = "[!leader_selected ? commando_rank : commando_leader_rank] [commando_name]"
new_commando.age = !leader_selected ? rand(23,35) : rand(35,45)
new_commando.dna.ready_dna(new_commando)//Creates DNA.
//Creates mind stuff.
new_commando.mind_initialize()
new_commando.mind.assigned_role = "MODE"
new_commando.mind.special_role = "Death Commando"
ticker.mode.traitors |= new_commando.mind//Adds them to current traitor list. Which is really the extra antagonist list.
new_commando.equip_death_commando(leader_selected)
return new_commando
/mob/living/carbon/human/proc/equip_death_commando(leader_selected = 0)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src)
R.set_frequency(DTH_FREQ)
equip_to_slot_or_del(R, slot_l_ear)
if (leader_selected == 0)
equip_to_slot_or_del(new /obj/item/clothing/under/color/green(src), slot_w_uniform)
else
equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/clothing/suit/armor/swat(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head)
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses)
equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back)
equip_to_slot_or_del(new /obj/item/weapon/storage/box(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/ammo_magazine/a357(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack)
if (!leader_selected)
equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/disk/nuclear(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/weapon/grenade/flashbang(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(src), slot_belt)
equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(src), slot_r_hand)
implant_loyalty(src)
var/obj/item/weapon/card/id/W = new(src)
W.name = "[real_name]'s ID Card"
W.icon_state = "centcom"
W.access = get_all_accesses()//They get full station access.
W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)//Let's add their alloted CentCom access.
W.assignment = "Death Commando"
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
return 1
team.attempt_spawn(1)

View File

@@ -1,178 +0,0 @@
//STRIKE TEAMS
var/const/syndicate_commandos_possible = 6 //if more Commandos are needed in the future
var/global/sent_syndicate_strike_team = 0
/client/proc/syndicate_strike_team()
set category = "Fun"
set name = "Spawn Mercenary Strike Team"
set desc = "Spawns a squad of commandos in the Syndicate Mothership if you want to run an admin event."
if(!src.holder)
src << "Only administrators may use this command."
return
if(!ticker)
alert("The game hasn't started yet!")
return
// if(world.time < 6000)
// alert("Not so fast, buddy. Wait a few minutes until the game gets going. There are [(6000-world.time)/10] seconds remaining.")
// return
if(sent_syndicate_strike_team == 1)
alert("Criminal elements are already sending a team, Mr. Dumbass.")
return
if(alert("Do you want to send in the Mercenary Strike Team? Once enabled, this is irreversible.",,"Yes","No")=="No")
return
alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned mercs have internals cameras which are viewable through a monitor inside the Syndicate Mothership Bridge. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.")
var/input = null
while(!input)
input = sanitize(copytext(input(src, "Please specify which mission the strike team shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN))
if(!input)
if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
return
if(sent_syndicate_strike_team)
src << "Looks like someone beat you to it."
return
sent_syndicate_strike_team = 1
//if (emergency_shuttle.can_recall())
// emergency_shuttle.recall() //why, exactly? Admins can do this themselves.
var/syndicate_commando_number = syndicate_commandos_possible //for selecting a leader
var/syndicate_leader_selected = 0 //when the leader is chosen. The last person spawned.
//Code for spawning a nuke auth code.
var/nuke_code
var/temp_code
for(var/obj/machinery/nuclearbomb/N in world)
temp_code = text2num(N.r_code)
if(temp_code)//if it's actually a number. It won't convert any non-numericals.
nuke_code = N.r_code
break
//Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos.
var/list/candidates = list() //candidates for being a commando out of all the active ghosts in world.
var/list/commandos = list() //actual commando ghosts as picked by the user.
for(var/mob/dead/observer/G in player_list)
if(!G.client.holder && !G.client.is_afk()) //Whoever called/has the proc won't be added to the list.
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
candidates += G.key
for(var/i=commandos_possible,(i>0&&candidates.len),i--)//Decrease with every commando selected.
var/candidate = input("Pick characters to spawn as the commandos. This will go on until there either no more ghosts to pick from or the slots are full.", "Active Players") as null|anything in candidates //It will auto-pick a person when there is only one candidate.
candidates -= candidate //Subtract from candidates.
commandos += candidate//Add their ghost to commandos.
//Spawns commandos and equips them.
for(var/obj/effect/landmark/L in landmarks_list)
if(syndicate_commando_number<=0) break
if (L.name == "Syndicate-Commando")
syndicate_leader_selected = syndicate_commando_number == 1?1:0
var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, syndicate_leader_selected)
if(commandos.len)
new_syndicate_commando.key = pick(commandos)
commandos -= new_syndicate_commando.key
new_syndicate_commando.internal = new_syndicate_commando.s_store
new_syndicate_commando.internals.icon_state = "internal1"
//So they don't forget their code or mission.
if(nuke_code)
new_syndicate_commando.mind.store_memory("<B>Nuke Code:</B> \red [nuke_code].")
new_syndicate_commando.mind.store_memory("<B>Mission:</B> \red [input].")
new_syndicate_commando << "\blue You are an Elite Mercenary. [!syndicate_leader_selected?"commando":"<B>LEADER</B>"] in the service of criminal elements hostile to NanoTrasen. \nYour current mission is: \red<B>[input]</B>"
syndicate_commando_number--
//Spawns the rest of the commando gear.
// for (var/obj/effect/landmark/L)
// if (L.name == "Commando_Manual")
//new /obj/item/weapon/gun/energy/pulse_rifle(L.loc)
// var/obj/item/weapon/paper/P = new(L.loc)
// P.info = "<p><b>Good morning soldier!</b>. This compact guide will familiarize you with standard operating procedure. There are three basic rules to follow:<br>#1 Work as a team.<br>#2 Accomplish your objective at all costs.<br>#3 Leave no witnesses.<br>You are fully equipped and stocked for your mission--before departing on the Spec. Ops. Shuttle due South, make sure that all operatives are ready. Actual mission objective will be relayed to you by Central Command through your headsets.<br>If deemed appropriate, Central Command will also allow members of your team to equip assault power-armor for the mission. You will find the armor storage due West of your position. Once you are ready to leave, utilize the Special Operations shuttle console and toggle the hull doors via the other console.</p><p>In the event that the team does not accomplish their assigned objective in a timely manner, or finds no other way to do so, attached below are instructions on how to operate a Nanotrasen Nuclear Device. Your operations <b>LEADER</b> is provided with a nuclear authentication disk and a pin-pointer for this reason. You may easily recognize them by their rank: Lieutenant, Captain, or Major. The nuclear device itself will be present somewhere on your destination.</p><p>Hello and thank you for choosing Nanotrasen for your nuclear information needs. Today's crash course will deal with the operation of a Fission Class Nanotrasen made Nuclear Device.<br>First and foremost, <b>DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.</b> Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done to unbolt it one must completely log in which at this time may not be possible.<br>To make the device functional:<br>#1 Place bomb in designated detonation zone<br> #2 Extend and anchor bomb (attack with hand).<br>#3 Insert Nuclear Auth. Disk into slot.<br>#4 Type numeric code into keypad ([nuke_code]).<br>Note: If you make a mistake press R to reset the device.<br>#5 Press the E button to log onto the device.<br>You now have activated the device. To deactivate the buttons at anytime, for example when you have already prepped the bomb for detonation, remove the authentication disk OR press the R on the keypad. Now the bomb CAN ONLY be detonated using the timer. A manual detonation is not an option.<br>Note: Toggle off the <b>SAFETY</b>.<br>Use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.<br>Note: <b>THE BOMB IS STILL SET AND WILL DETONATE</b><br>Now before you remove the disk if you need to move the bomb you can: Toggle off the anchor, move it, and re-anchor.</p><p>The nuclear authorization code is: <b>[nuke_code ? nuke_code : "None provided"]</b></p><p><b>Good luck, soldier!</b></p>"
// P.name = "Spec. Ops. Manual"
for (var/obj/effect/landmark/L in landmarks_list)
if (L.name == "Syndicate-Commando-Bomb")
new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
del(L)
message_admins("\blue [key_name_admin(usr)] has spawned a mercenary strike squad.", 1)
log_admin("[key_name(usr)] used Spawn Mercenary Squad.")
feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0)
var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc)
var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major")
var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/syndicate_commando_name = pick(last_names)
new_syndicate_commando.gender = pick(MALE, FEMALE)
var/datum/preferences/A = new()//Randomize appearance for the commando.
A.randomize_appearance_for(new_syndicate_commando)
new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]"
new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45)
new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA.
//Creates mind stuff.
new_syndicate_commando.mind_initialize()
new_syndicate_commando.mind.assigned_role = "MODE"
new_syndicate_commando.mind.special_role = "Mercenary"
ticker.mode.traitors |= new_syndicate_commando.mind //Adds them to current traitor list. Which is really the extra antagonist list.
new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected)
del(spawn_location)
return new_syndicate_commando
/mob/living/carbon/human/proc/equip_syndicate_commando(syndicate_leader_selected = 0)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(src)
R.set_frequency(SYND_FREQ) //Same frequency as the syndicate team in Nuke mode.
equip_to_slot_or_del(R, slot_l_ear)
equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
if (!syndicate_leader_selected)
equip_to_slot_or_del(new /obj/item/clothing/suit/space/syndicate/black(src), slot_wear_suit)
else
equip_to_slot_or_del(new /obj/item/clothing/suit/space/syndicate/black/red(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves)
if (!syndicate_leader_selected)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/syndicate/black(src), slot_head)
else
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/syndicate/black/red(src), slot_head)
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses)
equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back)
equip_to_slot_or_del(new /obj/item/weapon/storage/box(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/ammo_magazine/c45(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack)
if (!syndicate_leader_selected)
equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/disk/nuclear(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/weapon/grenade/empgrenade(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/silenced(src), slot_belt)
equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(src), slot_r_hand) //Will change to something different at a later time -- Superxpdude
var/obj/item/weapon/card/id/syndicate/W = new(src) //Untrackable by AI
W.name = "[real_name]'s ID Card"
W.icon_state = "id"
W.access = get_all_accesses()//They get full station access because obviously the syndicate has HAAAX, and can make special IDs for their most elite members.
W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage, access_syndicate)//Let's add their forged CentCom access and syndicate access.
W.assignment = "Mercenary"
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
return 1

View File

@@ -1,69 +0,0 @@
var/global/vox_tick = 1
/mob/living/carbon/human/proc/equip_vox_raider()
var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(src)
R.set_frequency(SYND_FREQ)
equip_to_slot_or_del(R, slot_l_ear)
equip_to_slot_or_del(new /obj/item/clothing/under/vox/vox_robes(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(src), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES.
equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow/vox(src), slot_gloves) // AS ABOVE.
switch(vox_tick)
if(1) // Vox raider!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/carapace(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/carapace(src), slot_head)
equip_to_slot_or_del(new /obj/item/weapon/melee/baton/loaded(src), slot_belt)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
equip_to_slot_or_del(new /obj/item/device/chameleon(src), slot_l_store)
var/obj/item/weapon/gun/launcher/spikethrower/W = new(src)
equip_to_slot_or_del(W, slot_r_hand)
if(2) // Vox engineer!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/pressure(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/pressure(src), slot_head)
equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt)
equip_to_slot_or_del(new /obj/item/clothing/glasses/meson(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
equip_to_slot_or_del(new /obj/item/weapon/storage/box/emps(src), slot_r_hand)
equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand)
if(3) // Vox saboteur!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/stealth(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/stealth(src), slot_head)
equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
equip_to_slot_or_del(new /obj/item/weapon/card/emag(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/dartgun/vox/raider(src), slot_r_hand)
equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand)
if(4) // Vox medic!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/medic(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/medic(src), slot_head)
equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt) // Who needs actual surgical tools?
equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
equip_to_slot_or_del(new /obj/item/weapon/circular_saw(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/dartgun/vox/medical, slot_r_hand)
equip_to_slot_or_del(new /obj/item/clothing/mask/breath(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(src), slot_back)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store)
var/obj/item/weapon/card/id/syndicate/C = new(src)
C.name = "[real_name]'s Legitimate Human ID Card"
C.icon_state = "id"
C.access = list(access_syndicate)
C.assignment = "Trader"
C.registered_name = real_name
C.registered_user = src
var/obj/item/weapon/storage/wallet/W = new(src)
W.handle_item_insertion(C)
spawn_money(rand(50,150)*10,W)
equip_to_slot_or_del(W, slot_wear_id)
vox_tick++
if (vox_tick > 4) vox_tick = 1
return 1

View File

@@ -15,7 +15,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
"cultist" = IS_MODE_COMPILED("cult"), // 8
"infested monkey" = IS_MODE_COMPILED("monkey"), // 9
"ninja" = "true", // 10
"vox raider" = IS_MODE_COMPILED("heist"), // 11
"raider" = IS_MODE_COMPILED("heist"), // 11
"diona" = 1, // 12
"mutineer" = IS_MODE_COMPILED("mutiny"), // 13
"pAI candidate" = 1, // -- TLE // 14

View File

@@ -43,6 +43,10 @@
siemens_coefficient = 0.7
body_parts_covered = FACE|EYES
/obj/item/clothing/mask/gas/swat/vox
name = "\improper alien mask"
desc = "Clearly not designed for a human face."
/obj/item/clothing/mask/gas/syndicate
name = "tactical mask"
desc = "A close-fitting tactical mask that can be connected to an air supply."

View File

@@ -94,7 +94,6 @@
req_access = list(access_syndicate)
initial_modules = list(
/obj/item/rig_module/teleporter,
/obj/item/rig_module/stealth_field,
/obj/item/rig_module/vision
)

View File

@@ -13,7 +13,7 @@
item_state = "w_suit"
/obj/item/clothing/under/captain_fly
name = "rogue captains uniform"
name = "rogue's uniform"
desc = "For the man who doesn't care because he's still free."
icon_state = "captain_fly"
item_state = "captain_fly"
@@ -154,7 +154,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
/obj/item/clothing/under/gentlesuit
name = "Gentlemans Suit"
name = "gentlemans suit"
desc = "A silk black shirt with a white tie and a matching gray vest and slacks. Feels proper."
icon_state = "gentlesuit"
item_state = "gentlesuit"
@@ -477,14 +477,14 @@
item_color = "tan_suit"
/obj/item/clothing/under/serviceoveralls
name = "Workman outfit"
name = "workman outfit"
desc = "The very image of a working man. Not that you're probably doing work."
icon_state = "mechanic"
item_state = "mechanic"
item_color = "mechanic"
/obj/item/clothing/under/cheongsam
name = "White Cheongsam"
name = "white cheongsam"
desc = "It is a white cheongsam dress."
icon_state = "mai_yang"
item_state = "mai_yang"
@@ -496,4 +496,4 @@
desc = "A bold but yet conservative outfit, red corduroys, navy blazer and a tie."
icon_state = "blue_blazer"
item_state = "blue_blazer"
item_color = "blue_blazer"
item_color = "blue_blazer"

View File

@@ -1,39 +0,0 @@
/var/global/sent_aliens_to_station = 0
/datum/event/alien_infestation
announceWhen = 400
var/spawncount = 1
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
/datum/event/alien_infestation/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
spawncount = rand(1, 2)
sent_aliens_to_station = 1
/datum/event/alien_infestation/announce()
if(successSpawn)
command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
/datum/event/alien_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology
vents += temp_vent
var/list/candidates = get_alien_candidates()
while(spawncount > 0 && vents.len && candidates.len)
var/obj/vent = pick(vents)
var/candidate = pick(candidates)
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.key = candidate
candidates -= candidate
vents -= vent
spawncount--
successSpawn = 1

View File

@@ -1,33 +0,0 @@
//Cortical borer spawn event - care of RobRichards1997 with minor editing by Zuhayr.
/datum/event/borer_infestation
announceWhen = 400
var/spawncount = 5
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
/datum/event/borer_infestation/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
spawncount = rand(1, 3)
/datum/event/borer_infestation/announce()
if(successSpawn)
command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
/datum/event/borer_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
//Stops cortical borers getting stuck in small networks. See: Security, Virology
if(temp_vent.network.normal_members.len > 50)
vents += temp_vent
var/list/candidates = get_alien_candidates()
while(spawncount > 0 && vents.len && candidates.len)
var/obj/vent = pick_n_take(vents)
var/client/C = pick_n_take(candidates)
var/mob/living/simple_animal/borer/new_borer = new(vent.loc)
new_borer.key = C.key
spawncount--
successSpawn = 1

View File

@@ -153,8 +153,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
)
/datum/event_container/major

View File

@@ -45,15 +45,9 @@ var/list/event_last_fired = list()
// Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm
// Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events_Mundane.dm
if(ticker.mode && ticker.mode.name == "calamity") //Calamity mode messes with some events.
possibleEvents[/datum/event/borer_infestation] = 400
possibleEvents[/datum/event/economic_event] = 25
possibleEvents[/datum/event/trivial_news] = 25
possibleEvents[/datum/event/mundane_news] = 25
else
possibleEvents[/datum/event/economic_event] = 300
possibleEvents[/datum/event/trivial_news] = 400
possibleEvents[/datum/event/mundane_news] = 300
possibleEvents[/datum/event/economic_event] = 300
possibleEvents[/datum/event/trivial_news] = 400
possibleEvents[/datum/event/mundane_news] = 300
possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200)
possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50)
@@ -89,10 +83,7 @@ var/list/event_last_fired = list()
if(active_with_role["Security"] > 0)
if(!sent_spiders_to_station)
possibleEvents[/datum/event/spider_infestation] = max(active_with_role["Security"], 5) + 5
if(config.aliens_allowed && !sent_aliens_to_station)
possibleEvents[/datum/event/alien_infestation] = max(active_with_role["Security"], 5) + 2.5
if(!sent_ninja_to_station && config.ninjas_allowed)
possibleEvents[/datum/event/space_ninja] = max(active_with_role["Security"], 5)
possibleEvents[/datum/event/random_antag] = max(active_with_role["Security"], 5) + 2.5
for(var/event_type in event_last_fired) if(possibleEvents[event_type])
var/time_passed = world.time - event_last_fired[event_type]

View File

@@ -0,0 +1,13 @@
// The random spawn proc on the antag datum will handle announcing the spawn and whatnot.
/datum/event/random_antag/announce()
return
/datum/event/random_antag/start()
var/list/valid_types = list()
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
if(antag.flags & ANTAG_RANDSPAWN)
valid_types |= antag
if(valid_types.len)
var/datum/antagonist/antag = pick(valid_types)
antag.random_spawn()

View File

@@ -861,6 +861,7 @@
seed_name = "orange"
display_name = "orange trees"
kitchen_tag = "orange"
chems = list("nutriment" = list(1,20), "orangejuice" = list(1,20))
/datum/seed/citrus/orange/New()
..()

View File

@@ -229,8 +229,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
//world << "DEBUG: ticker not null"
if(ticker.mode.name == "AI malfunction")
//world << "DEBUG: malf mode ticker test"
if(ticker.mode:malf_mode_declared)
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
if(malf.revealed)
stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs.len/3), 0)]")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
@@ -492,8 +492,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/ghosts_can_write
if(ticker.mode.name == "cult")
var/datum/game_mode/cult/C = ticker.mode
if(C.cult.len > config.cult_ghostwriter_req_cultists)
if(cult.current_antagonists.len > config.cult_ghostwriter_req_cultists)
ghosts_can_write = 1
if(!ghosts_can_write)

View File

@@ -65,8 +65,6 @@
if(ticker && ticker.mode)
sql_report_death(src)
ticker.mode.check_win()
if(istype(ticker.mode,/datum/game_mode/heist))
vox_kills++ //Bad vox. Shouldn't be killing humans.
return ..(gibbed,species.death_message)

View File

@@ -48,8 +48,8 @@
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
if(ticker.mode:malf_mode_declared)
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
if(malf.revealed)
stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs/3), 0)]")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
@@ -196,6 +196,7 @@
var/datum/organ/external/affected = M.organs_by_name["head"]
affected.implants += L
L.part = affected
L.implanted(src)
/mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M)
for(var/L in M.contents)

View File

@@ -251,9 +251,6 @@ emp_act
if(prob(I.force))
apply_effect(20, PARALYZE, armor)
visible_message("\red <B>[src] has been knocked unconscious!</B>")
if(src != user && I.damtype == BRUTE)
ticker.mode.remove_revolutionary(mind)
if(bloody)//Apply blood
if(wear_mask)
wear_mask.add_blood(src)
@@ -372,13 +369,13 @@ emp_act
var/obj/item/I = O
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
var/momentum = speed*mass
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throw_source, src)
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
if(!O || !src) return
if(O.loc == src && O.sharp) //Projectile is embedded and suitable for pinning.
@@ -392,7 +389,7 @@ emp_act
/mob/living/carbon/human/embed(var/obj/O, var/def_zone=null)
if(!def_zone) ..()
var/datum/organ/external/affecting = get_organ(def_zone)
if(affecting)
affecting.embed(O)

View File

@@ -1,6 +1,5 @@
/mob/living/carbon/human/Login()
..()
update_hud()
ticker.mode.update_all_synd_icons() //This proc only sounds CPU-expensive on paper. It is O(n^2), but the outer for-loop only iterates through syndicates, which are only prsenet in nuke rounds and even when they exist, there's usually 6 of them.
if(species) species.handle_login_special(src)
return

View File

@@ -6,21 +6,5 @@
mind.active = 1 //indicates that the mind is currently synced with a client
//If they're SSD, remove it so they can wake back up.
player_logged = 0
//Round specific stuff like hud updates
if(ticker && ticker.mode)
switch(ticker.mode.name)
if("revolution")
if((mind in ticker.mode.revolutionaries) || (src.mind in ticker.mode:head_revolutionaries))
ticker.mode.update_rev_icons_added(src.mind)
if("cult")
if(mind in ticker.mode:cult)
ticker.mode.update_cult_icons_added(src.mind)
if("mercenary")
if(mind in ticker.mode:syndicates)
ticker.mode.update_all_synd_icons()
if("mutiny")
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if(mode)
mode.update_all_icons()
update_antag_icons(mind)
return .

View File

@@ -189,7 +189,7 @@ var/list/ai_verbs_default = list(
src << radio_text
if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai)))
if (!(ticker && ticker.mode && (mind in malf.current_antagonists)))
show_laws()
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
@@ -312,17 +312,15 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/is_malf()
if(ticker.mode.name == "AI malfunction")
var/datum/game_mode/malfunction/malf = ticker.mode
for (var/datum/mind/malfai in malf.malf_ai)
for (var/datum/mind/malfai in malf.current_antagonists)
if (mind == malfai)
return malf
return 0
// displays the malf_ai information if the AI is the malf
/mob/living/silicon/ai/show_malf_ai()
var/datum/game_mode/malfunction/malf = is_malf()
if(malf && malf.apcs >= 3)
stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
if(malf && malf.hacked_apcs.len >= 3)
stat(null, "Time until station control secured: [max(malf.hack_time/(malf.hacked_apcs/3), 0)] seconds")
// this verb lets the ai see the stations manifest
/mob/living/silicon/ai/proc/ai_roster()
@@ -585,16 +583,6 @@ var/list/ai_verbs_default = list(
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo4"))
return
/*/mob/living/silicon/ai/proc/corereturn()
set category = "Malfunction"
set name = "Return to Main Core"
var/obj/machinery/power/apc/apc = src.loc
if(!istype(apc))
src << "\blue You are already in your Main Core."
return
apc.malfvacate()*/
//Toggles the luminosity and applies it by re-entereing the camera.
/mob/living/silicon/ai/proc/toggle_camera_light()
set name = "Toggle Camera Light"

View File

@@ -35,7 +35,7 @@
break
callshuttle++
if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || sent_strike_team)
if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction")
callshuttle = 0
if(callshuttle == 3) //if all three conditions are met

View File

@@ -36,9 +36,7 @@ var/global/list/empty_playable_ai_cores = list()
if(mind.objectives.len)
del(mind.objectives)
mind.special_role = null
else
if(ticker.mode.name == "AutoTraitor")
var/datum/game_mode/traitor/autotraitor/current_mode = ticker.mode
current_mode.possible_traitors.Remove(src)
clear_antag_roles(mind)
del(src)

View File

@@ -1,6 +1,3 @@
/mob/living/silicon/Login()
sleeping = 0
if(mind && ticker && ticker.mode)
ticker.mode.remove_cultist(mind, 1)
ticker.mode.remove_revolutionary(mind, 1)
..()

View File

@@ -43,8 +43,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
card.setPersonality(pai)
card.looking_for_personality = 0
ticker.mode.update_cult_icons_removed(card.pai.mind)
ticker.mode.update_rev_icons_removed(card.pai.mind)
if(pai.mind) update_antag_icons(pai.mind)
pai_candidates -= candidate
usr << browse(null, "window=findPai")

View File

@@ -221,16 +221,15 @@
src.healths.icon_state = "health7"
if (src.syndicate && src.client)
if(ticker.mode.name == "traitor")
for(var/datum/mind/tra in ticker.mode.traitors)
if(tra.current)
var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
src.client.images += I
for(var/datum/mind/tra in traitors.current_antagonists)
if(tra.current)
var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
src.client.images += I
src.disconnect_from_ai()
if(src.mind)
if(!src.mind.special_role)
src.mind.special_role = "traitor"
ticker.mode.traitors += src.mind
traitors.current_antagonists |= src.mind
if (src.cells)
if (src.cell)

View File

@@ -2,7 +2,6 @@
..()
regenerate_icons()
show_laws(0)
if(mind) ticker.mode.remove_revolutionary(mind)
winset(src, null, "mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")

View File

@@ -506,15 +506,13 @@
// this function shows information about the malf_ai gameplay type in the status screen
/mob/living/silicon/robot/show_malf_ai()
..()
if(ticker.mode.name == "AI malfunction")
var/datum/game_mode/malfunction/malf = ticker.mode
for (var/datum/mind/malfai in malf.malf_ai)
if(connected_ai)
if(connected_ai.mind == malfai)
if(malf.apcs >= 3)
stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
else if(ticker.mode:malf_mode_declared)
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
for (var/datum/mind/malfai in malf.current_antagonists)
if(connected_ai)
if(connected_ai.mind == malfai)
if(malf.hacked_apcs >= 3)
stat(null, "Time until station control secured: [max(malf.hack_time/(malf.hacked_apcs/3), 0)] seconds")
else if(malf.revealed)
stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs.len/3), 0)]")
return 0

View File

@@ -1,5 +1,3 @@
/datum/game_mode/var/list/borers = list()
/mob/living/simple_animal/borer
name = "cortical borer"
real_name = "cortical borer"
@@ -155,7 +153,7 @@
//If they're not a proper traitor, reset their antag status.
if(host.mind.special_role == "Borer Thrall")
host << "<span class ='danger'>You are no longer an antagonist.</span>"
ticker.mode.borers -= host.mind
borers.hosts -= host.mind
host.mind.special_role = null
src.loc = get_turf(host)

View File

@@ -106,7 +106,7 @@
//Update their traitor status.
if(host.mind)
if(!host.mind.special_role)
ticker.mode.borers |= host.mind
borers.hosts |= host.mind
host.mind.special_role = "Borer Thrall"
host << "<span class='danger'>A creeping lassitude surrounds you. Your mind is being invaded by an alien intelligence and that's just fine.</span>"
host << "<span class = 'danger'>You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head.</span>"

View File

@@ -1,312 +1,309 @@
/mob/living/simple_animal/construct
name = "Construct"
real_name = "Construct"
desc = ""
speak_emote = list("hisses")
emote_hear = list("wails","screeches")
response_help = "thinks better of touching"
response_disarm = "flails at"
response_harm = "punches"
icon_dead = "shade_dead"
speed = -1
a_intent = "harm"
stop_automated_movement = 1
status_flags = CANPUSH
universal_speak = 1
attack_sound = 'sound/weapons/punch1.ogg'
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
faction = "cult"
var/list/construct_spells = list()
/mob/living/simple_animal/construct/New()
..()
name = text("[initial(name)] ([rand(1, 1000)])")
real_name = name
for(var/spell in construct_spells)
spell_list += new spell(src)
/mob/living/simple_animal/construct/death()
new /obj/item/weapon/ectoplasm (src.loc)
..(null,"collapses in a shattered heap.")
ghostize()
del src
/mob/living/simple_animal/construct/attack_generic(var/mob/user)
if(istype(user, /mob/living/simple_animal/construct/builder))
if(health < maxHealth)
adjustBruteLoss(-5)
user.visible_message("<b>\The [user]</b> mends some of \the [src]'s wounds.")
else
user << "<span class='notice'>\The [src] is undamaged.</span>"
return
return ..()
/mob/living/simple_animal/construct/examine(mob/user)
..(user)
var/msg = ""
if (src.health < src.maxHealth)
msg += "<span class='warning'>"
if (src.health >= src.maxHealth/2)
msg += "It looks slightly dented.\n"
else
msg += "<B>It looks severely dented!</B>\n"
msg += "</span>"
msg += "*---------*</span>"
user << msg
return
/mob/living/simple_animal/construct/Bump(atom/movable/AM as mob|obj, yes)
if ((!( yes ) || now_pushing))
return
now_pushing = 1
if(ismob(AM))
var/mob/tmob = AM
if(!(tmob.status_flags & CANPUSH))
now_pushing = 0
return
tmob.LAssailant = src
now_pushing = 0
..()
if (!istype(AM, /atom/movable))
return
if (!( now_pushing ))
now_pushing = 1
if (!( AM.anchored ))
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window))
var/obj/structure/window/W = AM
if(W.is_full_window())
for(var/obj/structure/window/win in get_step(AM,t))
now_pushing = 0
return
step(AM, t)
now_pushing = null
/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with [O]. ")
/////////////////Juggernaut///////////////
/mob/living/simple_animal/construct/armoured
name = "Juggernaut"
real_name = "Juggernaut"
desc = "A possessed suit of armour driven by the will of the restless dead"
icon = 'icons/mob/mob.dmi'
icon_state = "behemoth"
icon_living = "behemoth"
maxHealth = 250
health = 250
response_harm = "harmlessly punches"
harm_intent_damage = 0
melee_damage_lower = 30
melee_damage_upper = 30
attacktext = "smashed their armoured gauntlet into"
mob_size = 20
speed = 3
wall_smash = 1
attack_sound = 'sound/weapons/punch3.ogg'
status_flags = 0
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
if(O.force >= 11)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
else
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [O] bounces harmlessly off of [src]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with [O]. ")
/mob/living/simple_animal/construct/armoured/Life()
weakened = 0
..()
/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
var/reflectchance = 80 - round(P.damage/3)
if(prob(reflectchance))
adjustBruteLoss(P.damage * 0.5)
visible_message("<span class='danger'>\The [P] was reflected by \the [src]'s shell!</span>", \
"<span class='userdanger'>\The [P] was reflected by \the [src]'s shell!</span>")
// Find a turf near or on the original location to bounce to
if(P.starting)
var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
var/turf/curloc = get_turf(src)
// redirect the projectile
P.redirect(new_x, new_y, curloc, src)
return -1 // complete projectile permutation
return (..(P))
////////////////////////Wraith/////////////////////////////////////////////
/mob/living/simple_animal/construct/wraith
name = "Wraith"
real_name = "Wraith"
desc = "A wicked bladed shell contraption piloted by a bound spirit"
icon = 'icons/mob/mob.dmi'
icon_state = "floating"
icon_living = "floating"
maxHealth = 75
health = 75
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashed"
speed = -1
see_in_dark = 7
attack_sound = 'sound/weapons/bladeslice.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
/////////////////////////////Artificer/////////////////////////
/mob/living/simple_animal/construct/builder
name = "Artificer"
real_name = "Artificer"
desc = "A bulbous construct dedicated to building and maintaining The Cult of Nar-Sie's armies"
icon = 'icons/mob/mob.dmi'
icon_state = "artificer"
icon_living = "artificer"
maxHealth = 50
health = 50
response_harm = "viciously beats"
harm_intent_damage = 5
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "rammed"
speed = 0
wall_smash = 1
attack_sound = 'sound/weapons/punch2.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,)
/////////////////////////////Behemoth/////////////////////////
/mob/living/simple_animal/construct/behemoth
name = "Behemoth"
real_name = "Behemoth"
desc = "The pinnacle of occult technology, Behemoths are the ultimate weapon in the Cult of Nar-Sie's arsenal."
icon = 'icons/mob/mob.dmi'
icon_state = "behemoth"
icon_living = "behemoth"
maxHealth = 750
health = 750
speak_emote = list("rumbles")
response_harm = "harmlessly punches"
harm_intent_damage = 0
melee_damage_lower = 50
melee_damage_upper = 50
attacktext = "brutally crushed"
speed = 5
wall_smash = 1
attack_sound = 'sound/weapons/punch4.ogg'
mob_size = 20
var/energy = 0
var/max_energy = 1000
/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
if(O.force >= 11)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
else
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [O] bounces harmlessly off of [src]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with [O]. ")
////////////////Powers//////////////////
/*
/client/proc/summon_cultist()
set category = "Behemoth"
set name = "Summon Cultist (300)"
set desc = "Teleport a cultist to your location"
if (istype(usr,/mob/living/simple_animal/constructbehemoth))
if(usr.energy<300)
usr << "\red You do not have enough power stored!"
return
if(usr.stat)
return
usr.energy -= 300
var/list/mob/living/cultists = new
for(var/datum/mind/H in ticker.mode.cult)
if (istype(H.current,/mob/living))
cultists+=H.current
var/mob/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - usr)
if(!cultist)
return
if (cultist == usr) //just to be sure.
return
cultist.loc = usr.loc
usr.visible_message("/red [cultist] appears in a flash of red light as [usr] glows with power")*/
/mob/living/simple_animal/construct
name = "Construct"
real_name = "Construct"
desc = ""
speak_emote = list("hisses")
emote_hear = list("wails","screeches")
response_help = "thinks better of touching"
response_disarm = "flails at"
response_harm = "punches"
icon_dead = "shade_dead"
speed = -1
a_intent = "harm"
stop_automated_movement = 1
status_flags = CANPUSH
universal_speak = 1
attack_sound = 'sound/weapons/punch1.ogg'
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
faction = "cult"
var/list/construct_spells = list()
/mob/living/simple_animal/construct/New()
..()
name = text("[initial(name)] ([rand(1, 1000)])")
real_name = name
for(var/spell in construct_spells)
spell_list += new spell(src)
/mob/living/simple_animal/construct/death()
new /obj/item/weapon/ectoplasm (src.loc)
..(null,"collapses in a shattered heap.")
ghostize()
del src
/mob/living/simple_animal/construct/attack_generic(var/mob/user)
if(istype(user, /mob/living/simple_animal/construct/builder))
if(health < maxHealth)
adjustBruteLoss(-5)
user.visible_message("<b>\The [user]</b> mends some of \the [src]'s wounds.")
else
user << "<span class='notice'>\The [src] is undamaged.</span>"
return
return ..()
/mob/living/simple_animal/construct/examine(mob/user)
..(user)
var/msg = ""
if (src.health < src.maxHealth)
msg += "<span class='warning'>"
if (src.health >= src.maxHealth/2)
msg += "It looks slightly dented.\n"
else
msg += "<B>It looks severely dented!</B>\n"
msg += "</span>"
msg += "*---------*</span>"
user << msg
return
/mob/living/simple_animal/construct/Bump(atom/movable/AM as mob|obj, yes)
if ((!( yes ) || now_pushing))
return
now_pushing = 1
if(ismob(AM))
var/mob/tmob = AM
if(!(tmob.status_flags & CANPUSH))
now_pushing = 0
return
tmob.LAssailant = src
now_pushing = 0
..()
if (!istype(AM, /atom/movable))
return
if (!( now_pushing ))
now_pushing = 1
if (!( AM.anchored ))
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window))
var/obj/structure/window/W = AM
if(W.is_full_window())
for(var/obj/structure/window/win in get_step(AM,t))
now_pushing = 0
return
step(AM, t)
now_pushing = null
/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with [O]. ")
/////////////////Juggernaut///////////////
/mob/living/simple_animal/construct/armoured
name = "Juggernaut"
real_name = "Juggernaut"
desc = "A possessed suit of armour driven by the will of the restless dead"
icon = 'icons/mob/mob.dmi'
icon_state = "behemoth"
icon_living = "behemoth"
maxHealth = 250
health = 250
response_harm = "harmlessly punches"
harm_intent_damage = 0
melee_damage_lower = 30
melee_damage_upper = 30
attacktext = "smashed their armoured gauntlet into"
mob_size = 20
speed = 3
wall_smash = 1
attack_sound = 'sound/weapons/punch3.ogg'
status_flags = 0
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
if(O.force >= 11)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
else
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [O] bounces harmlessly off of [src]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with [O]. ")
/mob/living/simple_animal/construct/armoured/Life()
weakened = 0
..()
/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
var/reflectchance = 80 - round(P.damage/3)
if(prob(reflectchance))
adjustBruteLoss(P.damage * 0.5)
visible_message("<span class='danger'>\The [P] was reflected by \the [src]'s shell!</span>", \
"<span class='userdanger'>\The [P] was reflected by \the [src]'s shell!</span>")
// Find a turf near or on the original location to bounce to
if(P.starting)
var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
var/turf/curloc = get_turf(src)
// redirect the projectile
P.redirect(new_x, new_y, curloc, src)
return -1 // complete projectile permutation
return (..(P))
////////////////////////Wraith/////////////////////////////////////////////
/mob/living/simple_animal/construct/wraith
name = "Wraith"
real_name = "Wraith"
desc = "A wicked bladed shell contraption piloted by a bound spirit"
icon = 'icons/mob/mob.dmi'
icon_state = "floating"
icon_living = "floating"
maxHealth = 75
health = 75
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashed"
speed = -1
see_in_dark = 7
attack_sound = 'sound/weapons/bladeslice.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
/////////////////////////////Artificer/////////////////////////
/mob/living/simple_animal/construct/builder
name = "Artificer"
real_name = "Artificer"
desc = "A bulbous construct dedicated to building and maintaining The Cult of Nar-Sie's armies"
icon = 'icons/mob/mob.dmi'
icon_state = "artificer"
icon_living = "artificer"
maxHealth = 50
health = 50
response_harm = "viciously beats"
harm_intent_damage = 5
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "rammed"
speed = 0
wall_smash = 1
attack_sound = 'sound/weapons/punch2.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,)
/////////////////////////////Behemoth/////////////////////////
/mob/living/simple_animal/construct/behemoth
name = "Behemoth"
real_name = "Behemoth"
desc = "The pinnacle of occult technology, Behemoths are the ultimate weapon in the Cult of Nar-Sie's arsenal."
icon = 'icons/mob/mob.dmi'
icon_state = "behemoth"
icon_living = "behemoth"
maxHealth = 750
health = 750
speak_emote = list("rumbles")
response_harm = "harmlessly punches"
harm_intent_damage = 0
melee_damage_lower = 50
melee_damage_upper = 50
attacktext = "brutally crushed"
speed = 5
wall_smash = 1
attack_sound = 'sound/weapons/punch4.ogg'
mob_size = 20
var/energy = 0
var/max_energy = 1000
/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
if(O.force >= 11)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
else
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [O] bounces harmlessly off of [src]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with [O]. ")
////////////////Powers//////////////////
/*
/client/proc/summon_cultist()
set category = "Behemoth"
set name = "Summon Cultist (300)"
set desc = "Teleport a cultist to your location"
if (istype(usr,/mob/living/simple_animal/constructbehemoth))
if(usr.energy<300)
usr << "\red You do not have enough power stored!"
return
if(usr.stat)
return
usr.energy -= 300
var/list/mob/living/cultists = new
for(var/datum/mind/H in ticker.mode.cult)
if (istype(H.current,/mob/living))
cultists+=H.current
var/mob/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - usr)
if(!cultist)
return
if (cultist == usr) //just to be sure.
return
cultist.loc = usr.loc
usr.visible_message("/red [cultist] appears in a flash of red light as [usr] glows with power")*/

View File

@@ -0,0 +1,207 @@
/obj/item/device/soulstone
name = "Soul Stone Shard"
icon = 'icons/obj/wizard.dmi'
icon_state = "soulstone"
item_state = "electronic"
desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefacts power."
w_class = 1.0
slot_flags = SLOT_BELT
origin_tech = "bluespace=4;materials=4"
var/imprinted = "empty"
//////////////////////////////Capturing////////////////////////////////////////////////////////
attack(mob/living/carbon/human/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
return ..()
if(istype(M, /mob/living/carbon/human/dummy))
return..()
if(M.has_brain_worms()) //Borer stuff - RR
user << "<span class='warning'>This being is corrupted by an alien intelligence and cannot be soul trapped.</span>"
return..()
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their soul captured with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to capture the soul of [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
transfer_soul("VICTIM", M, user)
return
/*attack(mob/living/simple_animal/shade/M as mob, mob/user as mob)//APPARENTLY THEY NEED THEIR OWN SPECIAL SNOWFLAKE CODE IN THE LIVING ANIMAL DEFINES
if(!istype(M, /mob/living/simple_animal/shade))//If target is not a shade
return ..()
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
transfer_soul("SHADE", M, user)
return*/
///////////////////Options for using captured souls///////////////////////////////////////
attack_self(mob/user)
if (!in_range(src, user))
return
user.set_machine(src)
var/dat = "<TT><B>Soul Stone</B><BR>"
for(var/mob/living/simple_animal/shade/A in src)
dat += "Captured Soul: [A.name]<br>"
dat += {"<A href='byond://?src=\ref[src];choice=Summon'>Summon Shade</A>"}
dat += "<br>"
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
user << browse(dat, "window=aicard")
onclose(user, "aicard")
return
Topic(href, href_list)
var/mob/U = usr
if (!in_range(src, U)||U.machine!=src)
U << browse(null, "window=aicard")
U.unset_machine()
return
add_fingerprint(U)
U.set_machine(src)
switch(href_list["choice"])//Now we switch based on choice.
if ("Close")
U << browse(null, "window=aicard")
U.unset_machine()
return
if ("Summon")
for(var/mob/living/simple_animal/shade/A in src)
A.status_flags &= ~GODMODE
A.canmove = 1
A << "<b>You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs.</b>"
A.loc = U.loc
A.cancel_camera()
src.icon_state = "soulstone"
attack_self(U)
///////////////////////////Transferring to constructs/////////////////////////////////////////////////////
/obj/structure/constructshell
name = "empty shell"
icon = 'icons/obj/wizard.dmi'
icon_state = "construct"
desc = "A wicked machine used by those skilled in magical arts. It is inactive"
/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/device/soulstone))
O.transfer_soul("CONSTRUCT",src,user)
////////////////////////////Proc for moving soul in and out off stone//////////////////////////////////////
/obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob).
switch(choice)
if("VICTIM")
var/mob/living/carbon/human/T = target
var/obj/item/device/soulstone/C = src
if(C.imprinted != "empty")
U << "\red <b>Capture failed!</b>: \black The soul stone has already been imprinted with [C.imprinted]'s mind!"
else
if ((T.health + T.halloss) > config.health_threshold_crit)
U << "\red <b>Capture failed!</b>: \black Kill or maim the victim first!"
else
if(T.client == null)
U << "\red <b>Capture failed!</b>: \black The soul has already fled it's mortal frame."
else
if(C.contents.len)
U << "\red <b>Capture failed!</b>: \black The soul stone is full! Use or free an existing soul to make room."
else
for(var/obj/item/W in T)
T.drop_from_inventory(W)
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
T.invisibility = 101
var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc )
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = T
flick("dust-h", animation)
del(animation)
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc )
S.loc = C //put shade in stone
S.status_flags |= GODMODE //So they won't die inside the stone somehow
S.canmove = 0//Can't move out of the soul stone
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
S.icon = T.icon
S.icon_state = T.icon_state
S.overlays = T.overlays
S.color = rgb(254,0,0)
S.alpha = 127
if (T.client)
T.client.mob = S
S.cancel_camera()
C.icon_state = "soulstone2"
C.name = "Soul Stone: [S.real_name]"
S << "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs."
U << "\blue <b>Capture successful!</b>: \black [T.real_name]'s soul has been ripped from their body and stored within the soul stone."
U << "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls."
C.imprinted = "[S.name]"
del T
if("SHADE")
var/mob/living/simple_animal/shade/T = target
var/obj/item/device/soulstone/C = src
if (T.stat == DEAD)
U << "\red <b>Capture failed!</b>: \black The shade has already been banished!"
else
if(C.contents.len)
U << "\red <b>Capture failed!</b>: \black The soul stone is full! Use or free an existing soul to make room."
else
if(T.name != C.imprinted)
U << "\red <b>Capture failed!</b>: \black The soul stone has already been imprinted with [C.imprinted]'s mind!"
else
T.loc = C //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
C.icon_state = "soulstone2"
T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form"
U << "\blue <b>Capture successful!</b>: \black [T.name]'s has been recaptured and stored within the soul stone."
if("CONSTRUCT")
var/obj/structure/constructshell/T = target
var/obj/item/device/soulstone/C = src
var/mob/living/simple_animal/shade/A = locate() in C
if(A)
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
switch(construct_class)
if("Juggernaut")
var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
del(T)
Z << "<B>You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike.</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
del(C)
if("Wraith")
var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
del(T)
Z << "<B>You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
del(C)
if("Artificer")
var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
del(T)
Z << "<B>You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
del(C)
else
U << "\red <b>Creation failed!</b>: \black The soul stone is empty! Go kill someone!"
return

View File

@@ -398,7 +398,7 @@ var/list/slot_equipment_priority = list( \
if ((stat != 2 || !( ticker )))
usr << "<span class='notice'><B>You must be dead to use this!</B></span>"
return
if (ticker.mode.name == "meteor" || ticker.mode.name == "epidemic") //BS12 EDIT
if (ticker.mode.deny_respawn) //BS12 EDIT
usr << "<span class='notice'>Respawn is disabled for this roundtype.</span>"
return
else

View File

@@ -358,8 +358,6 @@
ticker.mode.latespawn(character)
//ticker.mode.latespawn(character)
if(character.mind.assigned_role != "Cyborg")
data_core.manifest_inject(character)
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn

View File

@@ -170,16 +170,12 @@
src.update()
/obj/machinery/power/apc/Del()
if(malfai && operating)
if (ticker.mode.config_tag == "malfunction")
if (src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas))
ticker.mode:apcs--
if(operating && malf && src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas))
malf.hacked_apcs -= src
area.power_light = 0
area.power_equip = 0
area.power_environ = 0
area.power_change()
if(occupier)
malfvacate(1)
del(wires)
if(cell)
del(cell) // qdel
@@ -740,7 +736,7 @@
/obj/machinery/power/apc/proc/get_malf_status(mob/user)
if (ticker && ticker.mode && (user.mind in ticker.mode.malf_ai) && istype(user, /mob/living/silicon/ai))
if (malf && (user.mind in malf.current_antagonists) && istype(user, /mob/living/silicon/ai))
if (src.malfai == (user:parent ? user:parent : user))
if (src.occupier == user)
return 3 // 3 = User is shunted in this APC
@@ -947,9 +943,6 @@
malfai.malfhack = null
malfai.malfhacking = 0
locked = 1
if (ticker.mode.config_tag == "malfunction")
if (src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas))
ticker.mode:apcs++
if(usr:parent)
src.malfai = usr:parent
else
@@ -957,14 +950,6 @@
malfai << "Hack complete. The APC is now under your exclusive control."
update_icon()
else if (href_list["occupyapc"])
if(get_malf_status(usr))
malfoccupy(usr)
else if (href_list["deoccupyapc"])
if(get_malf_status(usr))
malfvacate()
else if (href_list["toggleaccess"])
if(istype(usr, /mob/living/silicon))
if(emagged || (stat & (BROKEN|MAINT)))
@@ -977,73 +962,9 @@
/obj/machinery/power/apc/proc/toggle_breaker()
operating = !operating
if(malfai)
if (ticker.mode.config_tag == "malfunction")
if (src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas))
operating ? ticker.mode:apcs++ : ticker.mode:apcs--
src.update()
update_icon()
/obj/machinery/power/apc/proc/malfoccupy(var/mob/living/silicon/ai/malf)
return
if(!istype(malf))
return
if(istype(malf.loc, /obj/machinery/power/apc)) // Already in an APC
malf << "<span class='warning'>You must evacuate your current apc first.</span>"
return
/*if(!malf.can_shunt)
malf << "<span class='warning'>You cannot shunt.</span>"
return*/
if(isNotStationLevel(src.z))
return
src.occupier = new /mob/living/silicon/ai(src,malf.laws,null,1)
src.occupier.adjustOxyLoss(malf.getOxyLoss())
if(!findtext(src.occupier.name,"APC Copy"))
src.occupier.name = "[malf.name] APC Copy"
if(malf.parent)
src.occupier.parent = malf.parent
else
src.occupier.parent = malf
malf.mind.transfer_to(src.occupier)
src.occupier.eyeobj.name = "[src.occupier.name] (AI Eye)"
if(malf.parent)
del(malf) // qdel
// src.occupier.verbs += /mob/living/silicon/ai/proc/corereturn
src.occupier.verbs += /datum/game_mode/malfunction/proc/takeover
src.occupier.cancel_camera()
if (seclevel2num(get_security_level()) == SEC_LEVEL_DELTA)
for(var/obj/item/weapon/pinpointer/point in world)
point.the_disk = src //the pinpointer will detect the shunted AI
/obj/machinery/power/apc/proc/malfvacate(var/forced)
if(!src.occupier)
return
if(src.occupier.parent && src.occupier.parent.stat != 2)
src.occupier.mind.transfer_to(src.occupier.parent)
src.occupier.parent.adjustOxyLoss(src.occupier.getOxyLoss())
src.occupier.parent.cancel_camera()
del(src.occupier) // qdel
if (seclevel2num(get_security_level()) == SEC_LEVEL_DELTA)
for(var/obj/item/weapon/pinpointer/point in world)
for(var/datum/mind/AI_mind in ticker.mode.malf_ai)
var/mob/living/silicon/ai/A = AI_mind.current // the current mob the mind owns
if(A.stat != DEAD)
point.the_disk = A //The pinpointer tracks the AI back into its core.
else
src.occupier << "<span class='danger'>Primary core damaged, unable to return core processes.</span>"
if(forced)
src.occupier.loc = src.loc
src.occupier.death()
src.occupier.gib()
for(var/obj/item/weapon/pinpointer/point in world)
point.the_disk = null //the pinpointer will go back to pointing at the nuke disc.
/obj/machinery/power/apc/proc/ion_act()
//intended to be exactly the same as an AI malf attack
if(!src.malfhack && src.z in config.station_levels)
@@ -1312,10 +1233,6 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on)
terminal = null
/obj/machinery/power/apc/proc/set_broken()
if(malfai && operating)
if (ticker.mode.config_tag == "malfunction")
if (src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas))
ticker.mode:apcs--
// Aesthetically much better!
src.visible_message("<span class='notice'>[src]'s screen flickers with warnings briefly!</span>")
spawn(rand(2,5))
@@ -1324,8 +1241,6 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on)
operating = 0
update_icon()
update()
if(occupier)
malfvacate(1)
// overload all the lights in this APC area

View File

@@ -511,15 +511,16 @@ var/global/list/uneatable = list(
/obj/machinery/singularity/narsie/proc/pickcultist() //Narsie rewards his cultists with being devoured first, then picks a ghost to follow. --NEO
var/list/cultists = list()
for(var/datum/mind/cult_nh_mind in ticker.mode.cult)
if(!cult_nh_mind.current)
continue
if(cult_nh_mind.current.stat)
continue
var/turf/pos = get_turf(cult_nh_mind.current)
if(pos.z != src.z)
continue
cultists += cult_nh_mind.current
if(cult && cult.current_antagonists.len)
for(var/datum/mind/cult_nh_mind in cult.current_antagonists)
if(!cult_nh_mind.current)
continue
if(cult_nh_mind.current.stat)
continue
var/turf/pos = get_turf(cult_nh_mind.current)
if(pos.z != src.z)
continue
cultists += cult_nh_mind.current
if(cultists.len)
acquire(pick(cultists))
return

View File

@@ -1,6 +1,7 @@
//Vox pinning weapon.
/obj/item/weapon/gun/launcher/spikethrower
name = "vox spike thrower"
name = "spike thrower"
desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
var/last_regen = 0

View File

@@ -95,7 +95,7 @@
/obj/item/weapon/gun/energy/mindflayer
name = "mind flayer"
desc = "A prototype weapon recovered from the ruins of Research-Station Epsilon."
desc = "A custom-built weapon of some kind."
icon_state = "xray"
projectile_type = /obj/item/projectile/beam/mindflayer
fire_sound = 'sound/weapons/Laser.ogg'

View File

@@ -287,11 +287,8 @@ datum
on_mob_life(var/mob/living/M as mob)
if(ishuman(M))
if((M.mind in ticker.mode.cult) && prob(10))
M << "\blue A cooling sensation from inside you brings you an untold calmness."
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.
if(M.mind && cult.is_antagonist(M.mind) && prob(10))
cult.remove_antagonist(M.mind)
holder.remove_reagent(src.id, 10 * REAGENTS_METABOLISM) //high metabolism to prevent extended uncult rolls.
return

View File

@@ -1,7 +1,7 @@
/obj/machinery/computer/shuttle_control/multi/vox
name = "skipjack control console"
req_access = list(access_syndicate)
shuttle_tag = "Vox Skipjack"
shuttle_tag = "Skipjack"
/obj/machinery/computer/shuttle_control/multi/syndicate
name = "mercenary shuttle control console"

View File

@@ -1,4 +1,4 @@
//This is a holder for things like the Vox and Nuke shuttle.
//This is a holder for things like the Skipjack and Nuke shuttle.
/datum/shuttle/multi_shuttle
var/cloaked = 1

View File

@@ -0,0 +1,82 @@
/obj/effect/proc_holder/spell/targeted/area_teleport
name = "Area teleport"
desc = "This spell teleports you to a type of area of your selection."
var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list
var/invocation_area = 1 //if the invocation appends the selected area
/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1)
var/thearea = before_cast(targets)
if(!thearea || !cast_check(1))
revert_cast()
return
invocation(thearea)
spawn(0)
if(charge_type == "recharge" && recharge)
start_recharge()
cast(targets,thearea)
after_cast(targets)
/obj/effect/proc_holder/spell/targeted/area_teleport/before_cast(list/targets)
var/A = null
if(!randomise_selection)
A = input("Area to teleport to", "Teleport", A) in teleportlocs
else
A = pick(teleportlocs)
var/area/thearea = teleportlocs[A]
return thearea
/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea)
for(var/mob/living/target in targets)
var/list/L = list()
for(var/turf/T in get_area_turfs(thearea.type))
if(!T.density)
var/clear = 1
for(var/obj/O in T)
if(O.density)
clear = 0
break
if(clear)
L+=T
if(!L.len)
usr <<"The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry."
return
if(target && target.buckled)
target.buckled.unbuckle_mob()
var/list/tempL = L
var/attempt = null
var/success = 0
while(tempL.len)
attempt = pick(tempL)
success = target.Move(attempt)
if(!success)
tempL.Remove(attempt)
else
break
if(!success)
target.loc = pick(L)
return
/obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null)
if(!invocation_area || !chosenarea)
..()
else
switch(invocation_type)
if("shout")
usr.say("[invocation] [uppertext(chosenarea.name)]")
if(usr.gender==MALE)
playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
else
playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
if("whisper")
usr.whisper("[invocation] [uppertext(chosenarea.name)]")
return

View File

@@ -0,0 +1,87 @@
/obj/effect/proc_holder/spell/aoe_turf/conjure
name = "Conjure"
desc = "This spell conjures objs of the specified types in range."
var/list/summon_type = list() //determines what exactly will be summoned
//should be text, like list("/obj/machinery/bot/ed209")
var/summon_lifespan = 0 // 0=permanent, any other time in deciseconds
var/summon_amt = 1 //amount of objects summoned
var/summon_ignore_density = 0 //if set to 1, adds dense tiles to possible spawn places
var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point
var/list/newVars = list() //vars of the summoned objects will be replaced with those where they meet
//should have format of list("emagged" = 1,"name" = "Wizard's Justicebot"), for example
var/delay = 1//Go Go Gadget Inheritance
/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets)
for(var/turf/T in targets)
if(T.density && !summon_ignore_density)
targets -= T
playsound(src.loc, 'sound/items/welder.ogg', 50, 1)
if(do_after(usr,delay))
for(var/i=0,i<summon_amt,i++)
if(!targets.len)
break
var/summoned_object_type = pick(summon_type)
var/spawn_place = pick(targets)
if(summon_ignore_prev_spawn_points)
targets -= spawn_place
if(ispath(summoned_object_type,/turf))
var/turf/O = spawn_place
var/turf/N = summoned_object_type
O.ChangeTurf(N)
else
var/atom/summoned_object = new summoned_object_type(spawn_place)
for(var/varName in newVars)
if(varName in summoned_object.vars)
summoned_object.vars[varName] = newVars[varName]
if(summon_lifespan)
spawn(summon_lifespan)
if(summoned_object)
del(summoned_object)
else
switch(charge_type)
if("recharge")
charge_counter = charge_max - 5//So you don't lose charge for a failed spell(Also prevents most over-fill)
if("charges")
charge_counter++//Ditto, just for different spell types
return
/obj/effect/proc_holder/spell/aoe_turf/conjure/summonEdSwarm //test purposes
name = "Dispense Wizard Justice"
desc = "This spell dispenses wizard justice."
summon_type = list(/obj/item/weapon/secbot_assembly/ed209_assembly)
summon_amt = 10
range = 3
newVars = list("emagged" = 1,"name" = "Wizard's Justicebot")
//This was previously left in the old wizard code, not being included.
//Wasn't sure if I should transfer it here, or to code/datums/spells.dm
//But I decided because it is a conjuration related object it would fit better here
//Feel free to change this, I don't know.
/obj/effect/forcefield
desc = "A space wizard's magic wall."
name = "FORCEWALL"
icon = 'icons/effects/effects.dmi'
icon_state = "m_shield"
anchored = 1.0
opacity = 0
density = 1
unacidable = 1
bullet_act(var/obj/item/projectile/Proj, var/def_zone)
var/turf/T = get_turf(src.loc)
if(T)
for(var/mob/M in T)
Proj.on_hit(M,M.bullet_act(Proj, def_zone))
return

View File

@@ -0,0 +1,86 @@
/obj/effect/proc_holder/spell/dumbfire
var/projectile_type = ""
var/activate_on_collision = 1
var/proj_icon = 'icons/obj/projectiles.dmi'
var/proj_icon_state = "spell"
var/proj_name = "a spell projectile"
var/proj_trail = 0 //if it leaves a trail
var/proj_trail_lifespan = 0 //deciseconds
var/proj_trail_icon = 'icons/obj/wizard.dmi'
var/proj_trail_icon_state = "trail"
var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this
var/proj_insubstantial = 0 //if it can pass through dense objects or not
var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target)
var/proj_lifespan = 100 //in deciseconds * proj_step_delay
var/proj_step_delay = 1 //lower = faster
/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr)
var/turf/T = get_turf(usr)
for(var/i = 1; i < range; i++)
var/turf/new_turf = get_step(T, usr.dir)
if(new_turf.density)
break
T = new_turf
perform(list(T))
/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr)
for(var/turf/target in targets)
spawn(0)
var/obj/effect/proc_holder/spell/targeted/projectile
if(istext(proj_type))
var/projectile_type = text2path(proj_type)
projectile = new projectile_type(user)
if(istype(proj_type,/obj/effect/proc_holder/spell))
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
projectile:linked_spells += proj_type
projectile.icon = proj_icon
projectile.icon_state = proj_icon_state
projectile.set_dir(get_dir(projectile, target))
projectile.name = proj_name
var/current_loc = usr.loc
projectile.loc = current_loc
for(var/i = 0,i < proj_lifespan,i++)
if(!projectile)
break
if(proj_insubstantial)
projectile.loc = get_step(projectile, projectile.dir)
else
step(projectile, projectile.dir)
if(projectile.loc == current_loc || i == proj_lifespan)
projectile.cast(current_loc)
break
var/mob/living/L = locate(/mob/living) in range(projectile, proj_trigger_range) - usr
if(L)
projectile.cast(L.loc)
break
if(proj_trail && projectile)
spawn(0)
if(projectile)
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
trail.icon = proj_trail_icon
trail.icon_state = proj_trail_icon_state
trail.density = 0
spawn(proj_trail_lifespan)
del(trail)
current_loc = projectile.loc
sleep(proj_step_delay)
if(projectile)
del(projectile)

View File

@@ -0,0 +1,13 @@
/obj/effect/proc_holder/spell/targeted/emplosion
name = "Emplosion"
desc = "This spell emplodes an area."
var/emp_heavy = 2
var/emp_light = 3
/obj/effect/proc_holder/spell/targeted/emplosion/cast(list/targets)
for(var/mob/living/target in targets)
empulse(target.loc, emp_heavy, emp_light)
return

View File

@@ -0,0 +1,106 @@
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt
name = "Ethereal Jaunt"
desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
school = "transmutation"
charge_max = 300
clothes_req = 1
invocation = "none"
invocation_type = "none"
range = -1
include_user = 1
centcomm_cancast = 0 //Prevent people from getting to centcomm
var phaseshift = 0
var/jaunt_duration = 50 //in deciseconds
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets) //magnets, so mostly hardcoded
for(var/mob/living/target in targets)
spawn(0)
if(target.buckled)
var/obj/structure/bed/buckled_to = target.buckled.
buckled_to.unbuckle_mob()
var/mobloc = get_turf(target.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
if(phaseshift == 1)
animation.dir = target.dir
flick("phase_shift",animation)
target.loc = holder
target.client.eye = holder
sleep(jaunt_duration)
mobloc = get_turf(target.loc)
animation.loc = mobloc
target.canmove = 0
sleep(20)
animation.dir = target.dir
flick("phase_shift2",animation)
sleep(5)
if(!target.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(target.Move(T))
break
target.canmove = 1
target.client.eye = target
del(animation)
del(holder)
else
flick("liquify",animation)
target.loc = holder
target.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(target.loc)
animation.loc = mobloc
steam.location = mobloc
steam.start()
target.canmove = 0
sleep(20)
flick("reappear",animation)
sleep(5)
if(!target.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(target.Move(T))
break
target.canmove = 1
target.client.eye = target
del(animation)
del(holder)
/obj/effect/dummy/spell_jaunt
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
var/canmove = 1
density = 0
anchored = 1
/obj/effect/dummy/spell_jaunt/relaymove(var/mob/user, direction)
if (!src.canmove) return
var/turf/newLoc = get_step(src,direction)
if(!(newLoc.flags & NOJAUNT))
loc = newLoc
else
user << "<span class='warning'>Some strange aura is blocking the way!</span>"
src.canmove = 0
spawn(2) src.canmove = 1
/obj/effect/dummy/spell_jaunt/ex_act(blah)
return
/obj/effect/dummy/spell_jaunt/bullet_act(blah)
return

View File

@@ -0,0 +1,15 @@
/obj/effect/proc_holder/spell/targeted/explosion
name = "Explosion"
desc = "This spell explodes an area."
var/ex_severe = 1
var/ex_heavy = 2
var/ex_light = 3
var/ex_flash = 4
/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets)
for(var/mob/living/target in targets)
explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash)
return

View File

@@ -0,0 +1,31 @@
/obj/effect/proc_holder/spell/targeted/genetic
name = "Genetic"
desc = "This spell inflicts a set of mutations and disabilities upon the target."
var/disabilities = 0 //bits
var/list/mutations = list() //mutation strings
var/duration = 100 //deciseconds
/*
Disabilities
1st bit - ?
2nd bit - ?
3rd bit - ?
4th bit - ?
5th bit - ?
6th bit - ?
*/
/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets)
for(var/mob/living/target in targets)
for(var/x in mutations)
target.mutations.Add(x)
target.disabilities |= disabilities
target.update_mutations() //update target's mutation overlays
spawn(duration)
for(var/x in mutations)
target.mutations.Remove(x)
target.disabilities &= ~disabilities
target.update_mutations()
return

View File

@@ -0,0 +1,50 @@
/obj/effect/proc_holder/spell/targeted/horsemask
name = "Curse of the Horseman"
desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes."
school = "transmutation"
charge_type = "recharge"
charge_max = 150
charge_counter = 0
clothes_req = 0
stat_allowed = 0
invocation = "KN'A FTAGHU, PUCK 'BTHNK!"
invocation_type = "shout"
range = 7
selection_type = "range"
var/list/compatible_mobs = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
/obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr)
if(!targets.len)
user << "<span class='notice'>No target found in range.</span>"
return
var/mob/living/carbon/target = targets[1]
if(!(target.type in compatible_mobs))
user << "<span class='notice'>It'd be stupid to curse [target] with a horse's head!</span>"
return
if(!(target in oview(range)))//If they are not in overview after selection.
user << "<span class='notice'>They are too far away!</span>"
return
var/obj/item/clothing/mask/horsehead/magic/magichead = new /obj/item/clothing/mask/horsehead/magic
target.visible_message( "<span class='danger'>[target]'s face lights up in fire, and after the event a horse's head takes its place!</span>", \
"<span class='danger'>Your face burns up, and shortly after the fire you realise you have the face of a horse!</span>")
target.equip_to_slot(magichead, slot_wear_mask)
flick("e_flash", target.flash)
//item used by the horsehead spell
/obj/item/clothing/mask/horsehead/magic
//flags_inv = null //so you can still see their face... no. How can you recognize someone when their face is completely different?
voicechange = 1 //NEEEEIIGHH
dropped(mob/user as mob)
canremove = 1
..()
equipped(var/mob/user, var/slot)
if (slot == slot_wear_mask)
canremove = 0 //curses!
..()

View File

@@ -0,0 +1,59 @@
/obj/effect/proc_holder/spell/targeted/inflict_handler
name = "Inflict Handler"
desc = "This spell blinds and/or destroys/damages/heals and/or weakens/stuns the target."
var/amt_weakened = 0
var/amt_paralysis = 0
var/amt_stunned = 0
//set to negatives for healing
var/amt_dam_fire = 0
var/amt_dam_brute = 0
var/amt_dam_oxy = 0
var/amt_dam_tox = 0
var/amt_eye_blind = 0
var/amt_eye_blurry = 0
var/destroys = "none" //can be "none", "gib" or "disintegrate"
/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets)
for(var/mob/living/target in targets)
switch(destroys)
if("gib")
target.gib()
if("gib_brain")
if(ishuman(target) || ismonkey(target))
var/mob/living/carbon/C = target
if(!C.has_brain()) // Their brain is already taken out
var/obj/item/organ/brain/B = new(C.loc)
B.transfer_identity(C)
target.gib()
if("disintegrate")
target.dust()
if(!target)
continue
//damage
if(amt_dam_brute > 0)
if(amt_dam_fire >= 0)
target.take_overall_damage(amt_dam_brute,amt_dam_fire)
else if (amt_dam_fire < 0)
target.take_overall_damage(amt_dam_brute,0)
target.heal_overall_damage(0,amt_dam_fire)
else if(amt_dam_brute < 0)
if(amt_dam_fire > 0)
target.take_overall_damage(0,amt_dam_fire)
target.heal_overall_damage(amt_dam_brute,0)
else if (amt_dam_fire <= 0)
target.heal_overall_damage(amt_dam_brute,amt_dam_fire)
target.adjustToxLoss(amt_dam_tox)
target.oxyloss += amt_dam_oxy
//disabling
target.Weaken(amt_weakened)
target.Paralyse(amt_paralysis)
target.Stun(amt_stunned)
target.eye_blind += amt_eye_blind
target.eye_blurry += amt_eye_blurry

View File

@@ -0,0 +1,20 @@
/obj/effect/proc_holder/spell/aoe_turf/knock
name = "Knock"
desc = "This spell opens nearby doors and does not require wizard garb."
school = "transmutation"
charge_max = 100
clothes_req = 0
invocation = "AULIE OXIN FIERA"
invocation_type = "whisper"
range = 3
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets)
for(var/turf/T in targets)
for(var/obj/machinery/door/door in T.contents)
spawn(1)
if(istype(door,/obj/machinery/door/airlock))
var/obj/machinery/door/airlock/A = door
A.unlock(1) //forced because it's magic!
door.open()
return

View File

@@ -0,0 +1,114 @@
/obj/effect/proc_holder/spell/targeted/mind_transfer
name = "Mind Transfer"
desc = "This spell allows the user to switch bodies with a target."
school = "transmutation"
charge_max = 600
clothes_req = 0
invocation = "GIN'YU CAPAN"
invocation_type = "whisper"
range = 1
var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell
var/list/compatible_mobs = list(/mob/living/carbon/human,/mob/living/carbon/monkey) //which types of mobs are affected by the spell. NOTE: change at your own risk
var/base_spell_loss_chance = 20 //base probability of the wizard losing a spell in the process
var/spell_loss_chance_modifier = 7 //amount of probability of losing a spell added per spell (mind_transfer included)
var/spell_loss_amount = 1 //the maximum amount of spells possible to lose during a single transfer
var/msg_wait = 500 //how long in deciseconds it waits before telling that body doesn't feel right or mind swap robbed of a spell
var/paralysis_amount_caster = 20 //how much the caster is paralysed for after the spell
var/paralysis_amount_victim = 20 //how much the victim is paralysed for after the spell
/*
Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do.
Make sure spells that are removed from spell_list are actually removed and deleted when mind transfering.
Also, you never added distance checking after target is selected. I've went ahead and did that.
*/
/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets,mob/user = usr)
if(!targets.len)
user << "No mind found."
return
if(targets.len > 1)
user << "Too many minds! You're not a hive damnit!"//Whaa...aat?
return
var/mob/living/target = targets[1]
if(!(target in oview(range)))//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it.
user << "They are too far away!"
return
if(!(target.type in compatible_mobs))
user << "Their mind isn't compatible with yours."
return
if(target.stat == DEAD)
user << "You didn't study necromancy back at the Space Wizard Federation academy."
return
if(!target.key || !target.mind)
user << "They appear to be catatonic. Not even magic can affect their vacant mind."
return
if(target.mind.special_role in protected_roles)
user << "Their mind is resisting your spell."
return
var/mob/living/victim = target//The target of the spell whos body will be transferred to.
var/mob/caster = user//The wizard/whomever doing the body transferring.
//SPELL LOSS BEGIN
//NOTE: The caster must ALWAYS keep mind transfer, even when other spells are lost.
var/obj/effect/proc_holder/spell/targeted/mind_transfer/m_transfer = locate() in user.spell_list//Find mind transfer directly.
var/list/checked_spells = user.spell_list
checked_spells -= m_transfer //Remove Mind Transfer from the list.
if(caster.spell_list.len)//If they have any spells left over after mind transfer is taken out. If they don't, we don't need this.
for(var/i=spell_loss_amount,(i>0&&checked_spells.len),i--)//While spell loss amount is greater than zero and checked_spells has spells in it, run this proc.
for(var/j=checked_spells.len,(j>0&&checked_spells.len),j--)//While the spell list to check is greater than zero and has spells in it, run this proc.
if(prob(base_spell_loss_chance))
checked_spells -= pick(checked_spells)//Pick a random spell to remove.
spawn(msg_wait)
victim << "The mind transfer has robbed you of a spell."
break//Spell lost. Break loop, going back to the previous for() statement.
else//Or keep checking, adding spell chance modifier to increase chance of losing a spell.
base_spell_loss_chance += spell_loss_chance_modifier
checked_spells += m_transfer//Add back Mind Transfer.
user.spell_list = checked_spells//Set user spell list to whatever the new list is.
//SPELL LOSS END
//MIND TRANSFER BEGIN
if(caster.mind.special_verbs.len)//If the caster had any special verbs, remove them from the mob verb list.
for(var/V in caster.mind.special_verbs)//Since the caster is using an object spell system, this is mostly moot.
caster.verbs -= V//But a safety nontheless.
if(victim.mind.special_verbs.len)//Now remove all of the victim's verbs.
for(var/V in victim.mind.special_verbs)
victim.verbs -= V
var/mob/dead/observer/ghost = victim.ghostize(0)
ghost.spell_list = victim.spell_list//If they have spells, transfer them. Now we basically have a backup mob.
caster.mind.transfer_to(victim)
victim.spell_list = caster.spell_list//Now they are inside the victim's body.
if(victim.mind.special_verbs.len)//To add all the special verbs for the original caster.
for(var/V in caster.mind.special_verbs)//Not too important but could come into play.
caster.verbs += V
ghost.mind.transfer_to(caster)
caster.key = ghost.key //have to transfer the key since the mind was not active
caster.spell_list = ghost.spell_list
if(caster.mind.special_verbs.len)//If they had any special verbs, we add them here.
for(var/V in caster.mind.special_verbs)
caster.verbs += V
//MIND TRANSFER END
//Here we paralyze both mobs and knock them out for a time.
caster.Paralyse(paralysis_amount_caster)
victim.Paralyse(paralysis_amount_victim)
//After a certain amount of time the victim gets a message about being in a different body.
spawn(msg_wait)
caster << "\red You feel woozy and lightheaded. <b>Your body doesn't seem like your own.</b>"

View File

@@ -0,0 +1,83 @@
/obj/effect/proc_holder/spell/targeted/projectile
name = "Projectile"
desc = "This spell summons projectiles which try to hit the targets."
var/proj_icon = 'icons/obj/projectiles.dmi'
var/proj_icon_state = "spell"
var/proj_name = "a spell projectile"
var/proj_trail = 0 //if it leaves a trail
var/proj_trail_lifespan = 0 //deciseconds
var/proj_trail_icon = 'icons/obj/wizard.dmi'
var/proj_trail_icon_state = "trail"
var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this
var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle
var/proj_homing = 1 //if it follows the target
var/proj_insubstantial = 0 //if it can pass through dense objects or not
var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target)
var/proj_lifespan = 15 //in deciseconds * proj_step_delay
var/proj_step_delay = 1 //lower = faster
/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr)
for(var/mob/living/target in targets)
spawn(0)
var/obj/effect/proc_holder/spell/targeted/projectile
if(istext(proj_type))
var/projectile_type = text2path(proj_type)
projectile = new projectile_type(user)
if(istype(proj_type,/obj/effect/proc_holder/spell))
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
projectile:linked_spells += proj_type
projectile.icon = proj_icon
projectile.icon_state = proj_icon_state
projectile.set_dir(get_dir(target,projectile))
projectile.name = proj_name
var/current_loc = usr.loc
projectile.loc = current_loc
for(var/i = 0,i < proj_lifespan,i++)
if(!projectile)
break
if(proj_homing)
if(proj_insubstantial)
projectile.set_dir(get_dir(projectile,target))
projectile.loc = get_step_to(projectile,target)
else
step_to(projectile,target)
else
if(proj_insubstantial)
projectile.loc = get_step(projectile,dir)
else
step(projectile,dir)
if(!proj_lingering && projectile.loc == current_loc) //if it didn't move since last time
del(projectile)
break
if(proj_trail && projectile)
spawn(0)
if(projectile)
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
trail.icon = proj_trail_icon
trail.icon_state = proj_trail_icon_state
trail.density = 0
spawn(proj_trail_lifespan)
del(trail)
if(projectile.loc in range(target.loc,proj_trigger_range))
projectile.perform(list(target))
break
current_loc = projectile.loc
sleep(proj_step_delay)
if(projectile)
del(projectile)

View File

@@ -0,0 +1,302 @@
/client/proc/give_spell(mob/T as mob in mob_list) // -- Urist
set category = "Fun"
set name = "Give Spell"
set desc = "Gives a spell to a mob."
var/list/spell_names = list()
for(var/v in spells)
// "/obj/effect/proc_holder/spell/" 30 symbols ~Intercross21
spell_names.Add(copytext("[v]", 31, 0))
var/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_names
if(!S) return
var/path = text2path("/obj/effect/proc_holder/spell/[S]")
T.spell_list += new path
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1)
/obj/effect/proc_holder
var/panel = "Debug"//What panel the proc holder needs to go on.
var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin verb for now
/obj/effect/proc_holder/spell
name = "Spell"
desc = "A wizard spell"
density = 0
opacity = 0
var/school = "evocation" //not relevant at now, but may be important later if there are changes to how spells work. the ones I used for now will probably be changed... maybe spell presets? lacking flexibility but with some other benefit?
var/charge_type = "recharge" //can be recharge or charges, see charge_max and charge_counter descriptions; can also be based on the holder's vars now, use "holder_var" for that
var/charge_max = 100 //recharge time in deciseconds if charge_type = "recharge" or starting charges if charge_type = "charges"
var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = "recharge" or -- each cast if charge_type = "charges"
var/holder_var_type = "bruteloss" //only used if charge_type equals to "holder_var"
var/holder_var_amount = 20 //same. The amount adjusted with the mob's var when the spell is used
var/clothes_req = 1 //see if it requires clothes
var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells
var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell
var/invocation_type = "none" //can be none, whisper and shout
var/range = 7 //the range of the spell; outer radius for aoe spells
var/message = "" //whatever it says to the guy affected by it
var/selection_type = "view" //can be "range" or "view"
var/overlay = 0
var/overlay_icon = 'icons/obj/wizard.dmi'
var/overlay_icon_state = "spell"
var/overlay_lifespan = 0
var/sparks_spread = 0
var/sparks_amt = 0 //cropped at 10
var/smoke_spread = 0 //1 - harmless, 2 - harmful
var/smoke_amt = 0 //cropped at 10
var/critfailchance = 0
var/centcomm_cancast = 1 //Whether or not the spell should be allowed on z2
/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
if(!(src in usr.spell_list))
usr << "\red You shouldn't have this spell! Something's wrong."
return 0
if(usr.z == 2 && !centcomm_cancast) //Certain spells are not allowed on the centcomm zlevel
return 0
if(!skipcharge)
switch(charge_type)
if("recharge")
if(charge_counter < charge_max)
usr << "[name] is still recharging."
return 0
if("charges")
if(!charge_counter)
usr << "[name] has no charges left."
return 0
if(usr.stat && !stat_allowed)
usr << "Not when you're incapacitated."
return 0
if(ishuman(usr) || ismonkey(usr))
if(istype(usr.wear_mask, /obj/item/clothing/mask/muzzle))
usr << "Mmmf mrrfff!"
return 0
if(clothes_req) //clothes check
if(!istype(usr, /mob/living/carbon/human))
usr << "You aren't a human, Why are you trying to cast a human spell, silly non-human? Casting human spells is for humans."
return 0
if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(user:wear_suit, /obj/item/clothing/suit/space/void/wizard))
usr << "I don't feel strong enough without my robe."
return 0
if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal))
usr << "I don't feel strong enough without my sandals."
return 0
if(!istype(usr:head, /obj/item/clothing/head/wizard) && !istype(user:head, /obj/item/clothing/head/helmet/space/void/wizard))
usr << "I don't feel strong enough without my hat."
return 0
if(!skipcharge)
switch(charge_type)
if("recharge")
charge_counter = 0 //doesn't start recharging until the targets selecting ends
if("charges")
charge_counter-- //returns the charge if the targets selecting fails
if("holdervar")
adjust_var(user, holder_var_type, holder_var_amount)
return 1
/obj/effect/proc_holder/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount
switch(invocation_type)
if("shout")
if(prob(50))//Auto-mute? Fuck that noise
usr.say(invocation)
else
usr.say(replacetext(invocation," ","`"))
if(usr.gender==MALE)
playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
else
playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
if("whisper")
if(prob(50))
usr.whisper(invocation)
else
usr.whisper(replacetext(invocation," ","`"))
/obj/effect/proc_holder/spell/New()
..()
charge_counter = charge_max
/obj/effect/proc_holder/spell/Click()
if(cast_check())
choose_targets()
return 1
/obj/effect/proc_holder/spell/proc/choose_targets(mob/user = usr) //depends on subtype - /targeted or /aoe_turf
return
/obj/effect/proc_holder/spell/proc/start_recharge()
while(charge_counter < charge_max)
sleep(1)
charge_counter++
/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1) //if recharge is started is important for the trigger spells
before_cast(targets)
invocation()
spawn(0)
if(charge_type == "recharge" && recharge)
start_recharge()
if(prob(critfailchance))
critfail(targets)
else
cast(targets)
after_cast(targets)
/obj/effect/proc_holder/spell/proc/before_cast(list/targets)
if(overlay)
for(var/atom/target in targets)
var/location
if(istype(target,/mob/living))
location = target.loc
else if(istype(target,/turf))
location = target
var/obj/effect/overlay/spell = new /obj/effect/overlay(location)
spell.icon = overlay_icon
spell.icon_state = overlay_icon_state
spell.anchored = 1
spell.density = 0
spawn(overlay_lifespan)
del(spell)
/obj/effect/proc_holder/spell/proc/after_cast(list/targets)
for(var/atom/target in targets)
var/location
if(istype(target,/mob/living))
location = target.loc
else if(istype(target,/turf))
location = target
if(istype(target,/mob/living) && message)
target << text("[message]")
if(sparks_spread)
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
sparks.set_up(sparks_amt, 0, location) //no idea what the 0 is
sparks.start()
if(smoke_spread)
if(smoke_spread == 1)
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is
smoke.start()
else if(smoke_spread == 2)
var/datum/effect/effect/system/smoke_spread/bad/smoke = new /datum/effect/effect/system/smoke_spread/bad()
smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is
smoke.start()
/obj/effect/proc_holder/spell/proc/cast(list/targets)
return
/obj/effect/proc_holder/spell/proc/critfail(list/targets)
return
/obj/effect/proc_holder/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge
switch(charge_type)
if("recharge")
charge_counter = charge_max
if("charges")
charge_counter++
if("holdervar")
adjust_var(user, holder_var_type, -holder_var_amount)
return
/obj/effect/proc_holder/spell/proc/adjust_var(mob/living/target = usr, type, amount) //handles the adjustment of the var when the spell is used. has some hardcoded types
switch(type)
if("bruteloss")
target.adjustBruteLoss(amount)
if("fireloss")
target.adjustFireLoss(amount)
if("toxloss")
target.adjustToxLoss(amount)
if("oxyloss")
target.adjustOxyLoss(amount)
if("stunned")
target.AdjustStunned(amount)
if("weakened")
target.AdjustWeakened(amount)
if("paralysis")
target.AdjustParalysis(amount)
else
target.vars[type] += amount //I bear no responsibility for the runtimes that'll happen if you try to adjust non-numeric or even non-existant vars
return
/obj/effect/proc_holder/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob
var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range
var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast
var/include_user = 0 //if it includes usr in the target list
/obj/effect/proc_holder/spell/aoe_turf //affects all turfs in view or range (depends)
var/inner_radius = -1 //for all your ring spell needs
/obj/effect/proc_holder/spell/targeted/choose_targets(mob/user = usr)
var/list/targets = list()
switch(max_targets)
if(0) //unlimited
for(var/mob/living/target in view_or_range(range, user, selection_type))
targets += target
if(1) //single target can be picked
if(range < 0)
targets += user
else
var/possible_targets = list()
for(var/mob/living/M in view_or_range(range, user, selection_type))
if(!include_user && user == M)
continue
possible_targets += M
targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets
else
var/list/possible_targets = list()
for(var/mob/living/target in view_or_range(range, user, selection_type))
possible_targets += target
for(var/i=1,i<=max_targets,i++)
if(!possible_targets.len)
break
if(target_ignore_prev)
var/target = pick(possible_targets)
possible_targets -= target
targets += target
else
targets += pick(possible_targets)
if(!include_user && (user in targets))
targets -= user
if(!targets.len) //doesn't waste the spell
revert_cast(user)
return
perform(targets)
return
/obj/effect/proc_holder/spell/aoe_turf/choose_targets(mob/user = usr)
var/list/targets = list()
for(var/turf/target in view_or_range(range,user,selection_type))
if(!(target in view_or_range(inner_radius,user,selection_type)))
targets += target
if(!targets.len) //doesn't waste the spell
revert_cast()
return
perform(targets)
return

View File

@@ -0,0 +1,211 @@
// This is a bloody terrible place to put the spellbook, but it doesn't belong in the
// roundmode code and the wizard's staff is in weapons.dm for some fucking reason. ~Z
/obj/item/weapon/spellbook
name = "spell book"
desc = "The legendary book of spells of the wizard."
icon = 'icons/obj/library.dmi'
icon_state ="book"
throw_speed = 1
throw_range = 5
w_class = 2.0
var/uses = 5
var/temp = null
var/max_uses = 5
var/op = 1
/obj/item/weapon/spellbook/attack_self(mob/user as mob)
user.set_machine(src)
var/dat
if(temp)
dat = "[temp]<BR><BR><A href='byond://?src=\ref[src];temp=1'>Clear</A>"
else
dat = "<B>The Book of Spells:</B><BR>"
dat += "Spells left to memorize: [uses]<BR>"
dat += "<HR>"
dat += "<B>Memorize which spell:</B><BR>"
dat += "<I>The number after the spell name is the cooldown time.</I><BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=magicmissile'>Magic Missile</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=fireball'>Fireball</A> (10)<BR>"
//dat += "<A href='byond://?src=\ref[src];spell_choice=disintegrate'>Disintegrate</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=disabletech'>Disable Technology</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=smoke'>Smoke</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=blind'>Blind</A> (30)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=mindswap'>Mind Transfer</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=forcewall'>Forcewall</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=blink'>Blink</A> (2)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=teleport'>Teleport</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=mutate'>Mutate</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=etherealjaunt'>Ethereal Jaunt</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=knock'>Knock</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=horseman'>Curse of the Horseman</A> (15)<BR>"
// if(op)
// dat += "<A href='byond://?src=\ref[src];spell_choice=summonguns'>Summon Guns</A> (One time use, global spell)<BR>"
dat += "<HR>"
dat += "<B>Artefacts:</B><BR>"
dat += "Powerful items imbued with eldritch magics. Summoning one will count towards your maximum number of spells.<BR>"
dat += "It is recommended that only experienced wizards attempt to wield such artefacts.<BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=staffchange'>Staff of Change</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=mentalfocus'>Mental Focus</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=soulstone'>Six Soul Stone Shards and the spell Artificer</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=armor'>Mastercrafted Armor Set</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=staffanimation'>Staff of Animation</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=scrying'>Scrying Orb</A><BR>"
dat += "<HR>"
if(op)
dat += "<A href='byond://?src=\ref[src];spell_choice=rememorize'>Re-memorize Spells</A><BR>"
user << browse(dat, "window=radio")
onclose(user, "radio")
return
/obj/item/weapon/spellbook/Topic(href, href_list)
..()
var/mob/living/carbon/human/H = usr
if(H.stat || H.restrained())
return
if(!istype(H, /mob/living/carbon/human))
return 1
if(loc == H || (in_range(src, H) && istype(loc, /turf)))
H.set_machine(src)
if(href_list["spell_choice"])
if(href_list["spell_choice"] == "rememorize")
var/area/wizard_station/A = locate()
if(usr in A.contents)
uses = max_uses
H.spellremove(usr)
temp = "All spells have been removed. You may now memorize a new set of spells."
feedback_add_details("wizard_spell_learned","UM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
else
temp = "You may only re-memorize spells whilst located inside the wizard sanctuary."
else if(uses >= 1 && max_uses >=1)
uses--
/*
*/
var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", summonguns = "Summon Guns", staffchange = "Staff of Change", mentalfocus = "Mental Focus", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation")
var/already_knows = 0
for(var/obj/effect/proc_holder/spell/aspell in H.spell_list)
if(available_spells[href_list["spell_choice"]] == aspell.name)
already_knows = 1
temp = "You already know that spell."
uses++
break
/*
*/
if(!already_knows)
switch(href_list["spell_choice"])
if("magicmissile")
feedback_add_details("wizard_spell_learned","MM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(H)
temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage."
if("fireball")
feedback_add_details("wizard_spell_learned","FB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/dumbfire/fireball(H)
temp = "This spell fires a fireball in the direction you're facing and does not require wizard garb. Be careful not to fire it at people that are standing next to you."
if("disintegrate")
feedback_add_details("wizard_spell_learned","DG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/inflict_handler/disintegrate(H)
temp = "This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown."
if("disabletech")
feedback_add_details("wizard_spell_learned","DT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech(H)
temp = "This spell disables all weapons, cameras and most other technology in range."
if("smoke")
feedback_add_details("wizard_spell_learned","SM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/smoke(H)
temp = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
if("blind")
feedback_add_details("wizard_spell_learned","BD") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/trigger/blind(H)
temp = "This spell temporarly blinds a single person and does not require wizard garb."
if("mindswap")
feedback_add_details("wizard_spell_learned","MT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/mind_transfer(H)
temp = "This spell allows the user to switch bodies with a target. Careful to not lose your memory in the process."
if("forcewall")
feedback_add_details("wizard_spell_learned","FW") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall(H)
temp = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb."
if("blink")
feedback_add_details("wizard_spell_learned","BL") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(H)
temp = "This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience."
if("teleport")
feedback_add_details("wizard_spell_learned","TP") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(H)
temp = "This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable."
if("mutate")
feedback_add_details("wizard_spell_learned","MU") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/genetic/mutate(H)
temp = "This spell causes you to turn into a hulk and gain telekinesis for a short while."
if("etherealjaunt")
feedback_add_details("wizard_spell_learned","EJ") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(H)
temp = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
if("knock")
feedback_add_details("wizard_spell_learned","KN") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/knock(H)
temp = "This spell opens nearby doors and does not require wizard garb."
if("horseman")
feedback_add_details("wizard_spell_learned","HH") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/horsemask(H)
temp = "This spell will curse a person to wear an unremovable horse mask (it has glue on the inside) and speak like a horse. It does not require a wizard garb. Do note the curse will disintegrate the target's current mask if they are wearing one."
if("summonguns")
feedback_add_details("wizard_spell_learned","SG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
rightandwrong()
max_uses--
temp = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill eachother. Just be careful not to get hit in the crossfire!"
if("staffchange")
feedback_add_details("wizard_spell_learned","ST") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/gun/energy/staff(get_turf(H))
temp = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
max_uses--
if("mentalfocus")
feedback_add_details("wizard_spell_learned","MF") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/gun/energy/staff/focus(get_turf(H))
temp = "An artefact that channels the will of the user into destructive bolts of force."
max_uses--
if("soulstone")
feedback_add_details("wizard_spell_learned","SS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/storage/belt/soulstone/full(get_turf(H))
H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(H)
temp = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot."
max_uses--
if("armor")
feedback_add_details("wizard_spell_learned","HS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/clothing/shoes/sandal(get_turf(H)) //In case they've lost them.
new /obj/item/clothing/gloves/purple(get_turf(H))//To complete the outfit
new /obj/item/clothing/suit/space/void/wizard(get_turf(H))
new /obj/item/clothing/head/helmet/space/void/wizard(get_turf(H))
temp = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
max_uses--
if("staffanimation")
feedback_add_details("wizard_spell_learned","SA") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/gun/energy/staff/animate(get_turf(H))
temp = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
max_uses--
if("scrying")
feedback_add_details("wizard_spell_learned","SO") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/scrying(get_turf(H))
if (!(XRAY in H.mutations))
H.mutations.Add(XRAY)
H.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
H.see_in_dark = 8
H.see_invisible = SEE_INVISIBLE_LEVEL_TWO
H << "<span class='info'>The walls suddenly disappear.</span>"
temp = "You have purchased a scrying orb, and gained x-ray vision."
max_uses--
else
if(href_list["temp"])
temp = null
attack_self(H)
return

View File

@@ -0,0 +1,28 @@
/obj/effect/proc_holder/spell/targeted/trigger
name = "Trigger"
desc = "This spell triggers another spell or a few."
var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly
var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks
/obj/effect/proc_holder/spell/targeted/trigger/New()
..()
for(var/spell in starting_spells)
var/spell_to_add = text2path(spell)
new spell_to_add(src) //should result in adding to contents, needs testing
/obj/effect/proc_holder/spell/targeted/trigger/Del()
for(var/spell in contents)
del(spell)
..()
/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets)
for(var/mob/living/target in targets)
for(var/obj/effect/proc_holder/spell/spell in contents)
spell.perform(list(target),0)
for(var/obj/effect/proc_holder/spell/spell in linked_spells)
spell.perform(list(target),0)
return

View File

@@ -0,0 +1,34 @@
/obj/effect/proc_holder/spell/targeted/turf_teleport
name = "Turf Teleport"
desc = "This spell teleports the target to the turf in range."
var/inner_tele_radius = 1
var/outer_tele_radius = 2
var/include_space = 0 //whether it includes space tiles in possible teleport locations
var/include_dense = 0 //whether it includes dense tiles in possible teleport locations
/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets)
for(var/mob/living/target in targets)
var/list/turfs = new/list()
for(var/turf/T in range(target,outer_tele_radius))
if(T in range(target,inner_tele_radius)) continue
if(istype(T,/turf/space) && !include_space) continue
if(T.density && !include_dense) continue
if(T.x>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
turfs += T
if(!turfs.len)
var/list/turfs_to_pick_from = list()
for(var/turf/T in orange(target,outer_tele_radius))
if(!(T in orange(target,inner_tele_radius)))
turfs_to_pick_from += T
turfs += pick(/turf in turfs_to_pick_from)
var/turf/picked = pick(turfs)
if(!picked || !isturf(picked))
return
target.loc = picked

View File

@@ -0,0 +1,59 @@
// Veil render //
/obj/item/weapon/veilrender
name = "veil render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast city."
icon = 'icons/obj/wizard.dmi'
icon_state = "render"
item_state = "render"
force = 15
throwforce = 10
w_class = 3
var/charged = 1
/obj/effect/rend
name = "Tear in the fabric of reality"
desc = "You should run now"
icon = 'icons/obj/wizard.dmi'
icon_state = "rift"
density = 1
unacidable = 1
anchored = 1.0
/obj/effect/rend/New()
spawn(50)
new /obj/machinery/singularity/narsie/wizard(get_turf(src))
del(src)
return
return
/obj/item/weapon/veilrender/attack_self(mob/user as mob)
if(charged == 1)
new /obj/effect/rend(get_turf(usr))
charged = 0
visible_message("\red <B>[src] hums with power as [usr] deals a blow to reality itself!</B>")
else
user << "\red The unearthly energies that powered the blade are now dormant"
// Scrying orb //
/obj/item/weapon/scrying
name = "scrying orb"
desc = "An incandescent orb of otherworldly energy, staring into it gives you vision beyond mortal means."
icon = 'icons/obj/projectiles.dmi'
icon_state = "bluespace"
throw_speed = 3
throw_range = 7
throwforce = 10
damtype = BURN
force = 10
hitsound = 'sound/items/welder2.ogg'
/obj/item/weapon/scrying/attack_self(mob/user as mob)
user << "<span class='info'>You can see... everything!</span>"
visible_message("<span class='danger'>[usr] stares into [src], their eyes glazing over.</span>")
announce_ghost_joinleave(user.ghostize(1), 1, "You feel that they used a powerful artifact to [pick("invade","disturb","disrupt","infest","taint","spoil","blight")] this place with their presence.")
return

View File

@@ -0,0 +1,327 @@
/obj/effect/proc_holder/spell/targeted/projectile/magic_missile
name = "Magic Missile"
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
school = "evocation"
charge_max = 150
clothes_req = 1
invocation = "FORTI GY AMA"
invocation_type = "shout"
range = 7
max_targets = 0
proj_icon_state = "magicm"
proj_name = "a magic missile"
proj_lingering = 1
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile"
proj_lifespan = 20
proj_step_delay = 5
proj_trail = 1
proj_trail_lifespan = 5
proj_trail_icon_state = "magicmd"
/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile
amt_weakened = 5
amt_dam_fire = 10
/obj/effect/proc_holder/spell/targeted/genetic/mutate
name = "Mutate"
desc = "This spell causes you to turn into a hulk and gain laser vision for a short while."
school = "transmutation"
charge_max = 400
clothes_req = 1
invocation = "BIRUZ BENNAR"
invocation_type = "shout"
message = "\blue You feel strong! You feel a pressure building behind your eyes!"
range = -1
include_user = 1
mutations = list(LASER, HULK)
duration = 300
/obj/effect/proc_holder/spell/targeted/inflict_handler/disintegrate
name = "Disintegrate"
desc = "This spell instantly kills somebody adjacent to you with the vilest of magick."
school = "evocation"
charge_max = 600
clothes_req = 1
invocation = "EI NATH"
invocation_type = "shout"
range = 1
destroys = "gib_brain"
sparks_spread = 1
sparks_amt = 4
/obj/effect/proc_holder/spell/targeted/smoke
name = "Smoke"
desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
school = "conjuration"
charge_max = 120
clothes_req = 0
invocation = "none"
invocation_type = "none"
range = -1
include_user = 1
smoke_spread = 2
smoke_amt = 10
/obj/effect/proc_holder/spell/targeted/emplosion/disable_tech
name = "Disable Tech"
desc = "This spell disables all weapons, cameras and most other technology in range."
charge_max = 400
clothes_req = 1
invocation = "NEC CANTIO"
invocation_type = "shout"
range = -1
include_user = 1
emp_heavy = 6
emp_light = 10
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink
name = "Blink"
desc = "This spell randomly teleports you a short distance."
school = "abjuration"
charge_max = 20
clothes_req = 1
invocation = "none"
invocation_type = "none"
range = -1
include_user = 1
smoke_spread = 1
smoke_amt = 10
inner_tele_radius = 0
outer_tele_radius = 6
centcomm_cancast = 0 //prevent people from getting to centcomm
/obj/effect/proc_holder/spell/targeted/area_teleport/teleport
name = "Teleport"
desc = "This spell teleports you to a type of area of your selection."
school = "abjuration"
charge_max = 600
clothes_req = 1
invocation = "SCYAR NILA"
invocation_type = "shout"
range = -1
include_user = 1
smoke_spread = 1
smoke_amt = 5
/obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall
name = "Forcewall"
desc = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb."
school = "transmutation"
charge_max = 100
clothes_req = 0
invocation = "TARCOL MINTI ZHERI"
invocation_type = "whisper"
range = 0
summon_type = list("/obj/effect/forcefield")
summon_lifespan = 300
/obj/effect/proc_holder/spell/aoe_turf/conjure/carp
name = "Summon Carp"
desc = "This spell conjures a simple carp."
school = "conjuration"
charge_max = 1200
clothes_req = 1
invocation = "NOUK FHUNMM SACP RISSKA"
invocation_type = "shout"
range = 1
summon_type = list(/mob/living/simple_animal/hostile/carp)
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct
name = "Artificer"
desc = "This spell conjures a construct which may be controlled by Shades"
school = "conjuration"
charge_max = 600
clothes_req = 0
invocation = "none"
invocation_type = "none"
range = 0
summon_type = list(/obj/structure/constructshell)
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature
name = "Summon Creature Swarm"
desc = "This spell tears the fabric of reality, allowing horrific daemons to spill forth"
school = "conjuration"
charge_max = 1200
clothes_req = 0
invocation = "IA IA"
invocation_type = "shout"
summon_amt = 10
range = 3
summon_type = list(/mob/living/simple_animal/hostile/creature)
/obj/effect/proc_holder/spell/targeted/trigger/blind
name = "Blind"
desc = "This spell temporarily blinds a single person and does not require wizard garb."
school = "transmutation"
charge_max = 300
clothes_req = 0
invocation = "STI KALY"
invocation_type = "whisper"
message = "\blue Your eyes cry out in pain!"
starting_spells = list("/obj/effect/proc_holder/spell/targeted/inflict_handler/blind","/obj/effect/proc_holder/spell/targeted/genetic/blind")
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
amt_eye_blind = 10
amt_eye_blurry = 20
/obj/effect/proc_holder/spell/targeted/genetic/blind
disabilities = 1
duration = 300
/obj/effect/proc_holder/spell/dumbfire/fireball
name = "Fireball"
desc = "This spell fires a fireball at a target and does not require wizard garb."
school = "evocation"
charge_max = 100
clothes_req = 0
invocation = "ONI SOMA"
invocation_type = "shout"
range = 20
proj_icon_state = "fireball"
proj_name = "a fireball"
proj_type = "/obj/effect/proc_holder/spell/turf/fireball"
proj_lifespan = 200
proj_step_delay = 1
/obj/effect/proc_holder/spell/turf/fireball/cast(var/turf/T)
explosion(T, -1, 1, 2, 3)
/obj/effect/proc_holder/spell/targeted/inflict_handler/fireball
amt_dam_brute = 20
amt_dam_fire = 25
/obj/effect/proc_holder/spell/targeted/explosion/fireball
ex_severe = -1
ex_heavy = -1
ex_light = 2
ex_flash = 5
//////////////////////////////Construct Spells/////////////////////////
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser
charge_max = 1800
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor
name = "Floor Construction"
desc = "This spell constructs a cult floor"
school = "conjuration"
charge_max = 20
clothes_req = 0
invocation = "none"
invocation_type = "none"
range = 0
summon_type = list(/turf/simulated/floor/engine/cult)
centcomm_cancast = 0 //Stop crashing the server by spawning turfs on transit tiles
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall
name = "Leser Construction"
desc = "This spell constructs a cult wall"
school = "conjuration"
charge_max = 100
clothes_req = 0
invocation = "none"
invocation_type = "none"
range = 0
summon_type = list(/turf/simulated/wall/cult)
centcomm_cancast = 0 //Stop crashing the server by spawning turfs on transit tiles
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall/reinforced
name = "Greater Construction"
desc = "This spell constructs a reinforced metal wall"
school = "conjuration"
charge_max = 300
clothes_req = 0
invocation = "none"
invocation_type = "none"
range = 0
centcomm_cancast = 0 //Stop crashing the server by spawning turfs on transit tiles
delay = 50
summon_type = list(/turf/simulated/wall/r_wall)
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone
name = "Summon Soulstone"
desc = "This spell reaches into Nar-Sie's realm, summoning one of the legendary fragments across time and space"
school = "conjuration"
charge_max = 3000
clothes_req = 0
invocation = "none"
invocation_type = "none"
range = 0
summon_type = list(/obj/item/device/soulstone)
/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall
name = "Shield"
desc = "This spell creates a temporary forcefield to shield yourself and allies from incoming fire"
school = "transmutation"
charge_max = 300
clothes_req = 0
invocation = "none"
invocation_type = "none"
range = 0
summon_type = list(/obj/effect/forcefield)
summon_lifespan = 50
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift
name = "Phase Shift"
desc = "This spell allows you to pass through walls"
school = "transmutation"
charge_max = 200
clothes_req = 0
invocation = "none"
invocation_type = "none"
range = -1
include_user = 1
phaseshift = 1
jaunt_duration = 50 //in deciseconds
centcomm_cancast = 0 //Stop people from getting to centcomm