mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-01-05 23:12:26 +00:00
Merge remote-tracking branch 'upstream/dev' into PCAILaws
This commit is contained in:
@@ -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>"
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=traitor;jobban4=\ref[M]'>[replacetext("Traitor", " ", " ")]</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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=changeling;jobban4=\ref[M]'>[replacetext("Changeling", " ", " ")]</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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=operative;jobban4=\ref[M]'>[replacetext("Mercenary", " ", " ")]</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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=revolutionary;jobban4=\ref[M]'>[replacetext("Revolutionary", " ", " ")]</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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=cultist;jobban4=\ref[M]'>[replacetext("Cultist", " ", " ")]</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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=wizard;jobban4=\ref[M]'>[replacetext("Wizard", " ", " ")]</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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=malf AI;jobban4=\ref[M]'>[replacetext("Malf AI", " ", " ")]</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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=alien candidate;jobban4=\ref[M]'>[replacetext("Alien", " ", " ")]</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", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=infested monkey;jobban4=\ref[M]'>[replacetext("Infested Monkey", " ", " ")]</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]", " ", " ")]</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[antag.bantype];jobban4=\ref[M]'>[replacetext("[antag.role_text]", " ", " ")]</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"]]")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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.")
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
13
code/modules/events/random_antagonist.dm
Normal file
13
code/modules/events/random_antagonist.dm
Normal 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()
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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 .
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
..()
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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")*/
|
||||
207
code/modules/mob/living/simple_animal/constructs/soulstone.dm
Normal file
207
code/modules/mob/living/simple_animal/constructs/soulstone.dm
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
82
code/modules/spells/area_teleport.dm
Normal file
82
code/modules/spells/area_teleport.dm
Normal 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
|
||||
87
code/modules/spells/conjure.dm
Normal file
87
code/modules/spells/conjure.dm
Normal 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
|
||||
86
code/modules/spells/dumbfire.dm
Normal file
86
code/modules/spells/dumbfire.dm
Normal 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)
|
||||
13
code/modules/spells/emplosion.dm
Normal file
13
code/modules/spells/emplosion.dm
Normal 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
|
||||
106
code/modules/spells/ethereal_jaunt.dm
Normal file
106
code/modules/spells/ethereal_jaunt.dm
Normal 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
|
||||
15
code/modules/spells/explosion.dm
Normal file
15
code/modules/spells/explosion.dm
Normal 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
|
||||
31
code/modules/spells/genetic.dm
Normal file
31
code/modules/spells/genetic.dm
Normal 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
|
||||
50
code/modules/spells/horsemask.dm
Normal file
50
code/modules/spells/horsemask.dm
Normal 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!
|
||||
..()
|
||||
59
code/modules/spells/inflict_handler.dm
Normal file
59
code/modules/spells/inflict_handler.dm
Normal 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
|
||||
20
code/modules/spells/knock.dm
Normal file
20
code/modules/spells/knock.dm
Normal 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
|
||||
114
code/modules/spells/mind_transfer.dm
Normal file
114
code/modules/spells/mind_transfer.dm
Normal 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>"
|
||||
83
code/modules/spells/projectile.dm
Normal file
83
code/modules/spells/projectile.dm
Normal 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)
|
||||
302
code/modules/spells/spell.dm
Normal file
302
code/modules/spells/spell.dm
Normal 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
|
||||
211
code/modules/spells/spellbook.dm
Normal file
211
code/modules/spells/spellbook.dm
Normal 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
|
||||
28
code/modules/spells/trigger.dm
Normal file
28
code/modules/spells/trigger.dm
Normal 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
|
||||
34
code/modules/spells/turf_teleport.dm
Normal file
34
code/modules/spells/turf_teleport.dm
Normal 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
|
||||
59
code/modules/spells/wizard_artifacts.dm
Normal file
59
code/modules/spells/wizard_artifacts.dm
Normal 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
|
||||
327
code/modules/spells/wizard_spells.dm
Normal file
327
code/modules/spells/wizard_spells.dm
Normal 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
|
||||
Reference in New Issue
Block a user