mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-22 12:46:40 +01:00
Merge remote-tracking branch 'Meghan-Rossi/master' into job_description_alt
This commit is contained in:
@@ -300,7 +300,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
|
||||
output += "<option value=''>--</option>"
|
||||
for(var/j in get_all_jobs())
|
||||
output += "<option value='[j]'>[j]</option>"
|
||||
for(var/j in nonhuman_positions)
|
||||
for(var/j in SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))
|
||||
output += "<option value='[j]'>[j]</option>"
|
||||
var/list/bantypes = list("traitor","changeling","operative","revolutionary","cultist","wizard") //For legacy bans.
|
||||
for(var/antag_type in all_antag_types) // Grab other bans.
|
||||
|
||||
@@ -105,7 +105,8 @@ var/list/admin_verbs_admin = list(
|
||||
/datum/admins/proc/paralyze_mob,
|
||||
/client/proc/fixatmos,
|
||||
/datum/admins/proc/sendFax,
|
||||
/client/proc/despawn_player
|
||||
/client/proc/despawn_player,
|
||||
/datum/admins/proc/view_feedback
|
||||
)
|
||||
|
||||
var/list/admin_verbs_ban = list(
|
||||
@@ -228,7 +229,8 @@ var/list/admin_verbs_debug = list(
|
||||
/datum/admins/proc/change_weather,
|
||||
/datum/admins/proc/change_time,
|
||||
/client/proc/admin_give_modifier,
|
||||
/client/proc/simple_DPS
|
||||
/client/proc/simple_DPS,
|
||||
/datum/admins/proc/view_feedback
|
||||
)
|
||||
|
||||
var/list/admin_verbs_paranoid_debug = list(
|
||||
|
||||
+24
-24
@@ -394,8 +394,8 @@
|
||||
//Regular jobs
|
||||
//Command (Blue)
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr align='center' bgcolor='ccccff'><th colspan='[length(command_positions)]'><a href='?src=\ref[src];jobban3=commanddept;jobban4=\ref[M]'>Command Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in command_positions)
|
||||
jobs += "<tr align='center' bgcolor='ccccff'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))]'><a href='?src=\ref[src];jobban3=commanddept;jobban4=\ref[M]'>Command Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
@@ -415,8 +415,8 @@
|
||||
//Security (Red)
|
||||
counter = 0
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr bgcolor='ffddf0'><th colspan='[length(security_positions)]'><a href='?src=\ref[src];jobban3=securitydept;jobban4=\ref[M]'>Security Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in security_positions)
|
||||
jobs += "<tr bgcolor='ffddf0'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_SECURITY))]'><a href='?src=\ref[src];jobban3=securitydept;jobban4=\ref[M]'>Security Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_SECURITY))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
@@ -436,8 +436,8 @@
|
||||
//Engineering (Yellow)
|
||||
counter = 0
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr bgcolor='fff5cc'><th colspan='[length(engineering_positions)]'><a href='?src=\ref[src];jobban3=engineeringdept;jobban4=\ref[M]'>Engineering Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in engineering_positions)
|
||||
jobs += "<tr bgcolor='fff5cc'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_ENGINEERING))]'><a href='?src=\ref[src];jobban3=engineeringdept;jobban4=\ref[M]'>Engineering Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_ENGINEERING))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
@@ -457,8 +457,8 @@
|
||||
//Cargo (Yellow)
|
||||
counter = 0
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr bgcolor='fff5cc'><th colspan='[length(cargo_positions)]'><a href='?src=\ref[src];jobban3=cargodept;jobban4=\ref[M]'>Cargo Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in cargo_positions)
|
||||
jobs += "<tr bgcolor='fff5cc'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_CARGO))]'><a href='?src=\ref[src];jobban3=cargodept;jobban4=\ref[M]'>Cargo Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_CARGO))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
@@ -478,8 +478,8 @@
|
||||
//Medical (White)
|
||||
counter = 0
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr bgcolor='ffeef0'><th colspan='[length(medical_positions)]'><a href='?src=\ref[src];jobban3=medicaldept;jobban4=\ref[M]'>Medical Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in medical_positions)
|
||||
jobs += "<tr bgcolor='ffeef0'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_MEDICAL))]'><a href='?src=\ref[src];jobban3=medicaldept;jobban4=\ref[M]'>Medical Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_MEDICAL))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
@@ -499,8 +499,8 @@
|
||||
//Science (Purple)
|
||||
counter = 0
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr bgcolor='e79fff'><th colspan='[length(science_positions)]'><a href='?src=\ref[src];jobban3=sciencedept;jobban4=\ref[M]'>Science Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in science_positions)
|
||||
jobs += "<tr bgcolor='e79fff'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_RESEARCH))]'><a href='?src=\ref[src];jobban3=sciencedept;jobban4=\ref[M]'>Science Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_RESEARCH))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
@@ -520,8 +520,8 @@
|
||||
//Civilian (Grey)
|
||||
counter = 0
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr bgcolor='dddddd'><th colspan='[length(civilian_positions)]'><a href='?src=\ref[src];jobban3=civiliandept;jobban4=\ref[M]'>Civilian Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in civilian_positions)
|
||||
jobs += "<tr bgcolor='dddddd'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_CIVILIAN))]'><a href='?src=\ref[src];jobban3=civiliandept;jobban4=\ref[M]'>Civilian Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_CIVILIAN))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
@@ -547,8 +547,8 @@
|
||||
//Non-Human (Green)
|
||||
counter = 0
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(nonhuman_positions)+1]'><a href='?src=\ref[src];jobban3=nonhumandept;jobban4=\ref[M]'>Non-human Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in nonhuman_positions)
|
||||
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))+1]'><a href='?src=\ref[src];jobban3=nonhumandept;jobban4=\ref[M]'>Non-human Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
@@ -635,50 +635,50 @@
|
||||
var/list/joblist = list()
|
||||
switch(href_list["jobban3"])
|
||||
if("commanddept")
|
||||
for(var/jobPos in command_positions)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("securitydept")
|
||||
for(var/jobPos in security_positions)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_SECURITY))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("engineeringdept")
|
||||
for(var/jobPos in engineering_positions)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_ENGINEERING))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("cargodept")
|
||||
for(var/jobPos in cargo_positions)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_CARGO))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("medicaldept")
|
||||
for(var/jobPos in medical_positions)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_MEDICAL))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("sciencedept")
|
||||
for(var/jobPos in science_positions)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_RESEARCH))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("civiliandept")
|
||||
for(var/jobPos in civilian_positions)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_CIVILIAN))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("nonhumandept")
|
||||
joblist += "pAI"
|
||||
for(var/jobPos in nonhuman_positions)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
#define BUILDMODE_BASIC 1
|
||||
#define BUILDMODE_ADVANCED 2
|
||||
#define BUILDMODE_EDIT 3
|
||||
#define BUILDMODE_THROW 4
|
||||
#define BUILDMODE_ROOM 5
|
||||
#define BUILDMODE_LADDER 6
|
||||
#define BUILDMODE_CONTENTS 7
|
||||
#define BUILDMODE_LIGHTS 8
|
||||
#define BUILDMODE_AI 9
|
||||
|
||||
#define LAST_BUILDMODE 9
|
||||
|
||||
/proc/togglebuildmode(mob/M as mob in player_list)
|
||||
set name = "Toggle Build Mode"
|
||||
set category = "Special Verbs"
|
||||
@@ -6,6 +18,7 @@
|
||||
log_admin("[key_name(usr)] has left build mode.")
|
||||
M.client.buildmode = 0
|
||||
M.client.show_popup_menus = 1
|
||||
M.plane_holder.set_vis(VIS_BUILDMODE, FALSE)
|
||||
for(var/obj/effect/bmode/buildholder/H)
|
||||
if(H.cl == M.client)
|
||||
qdel(H)
|
||||
@@ -13,6 +26,7 @@
|
||||
log_admin("[key_name(usr)] has entered build mode.")
|
||||
M.client.buildmode = 1
|
||||
M.client.show_popup_menus = 0
|
||||
M.plane_holder.set_vis(VIS_BUILDMODE, TRUE)
|
||||
|
||||
var/obj/effect/bmode/buildholder/H = new/obj/effect/bmode/buildholder()
|
||||
var/obj/effect/bmode/builddir/A = new/obj/effect/bmode/builddir(H)
|
||||
@@ -72,7 +86,8 @@
|
||||
screen_loc = "NORTH,WEST+1"
|
||||
Click()
|
||||
switch(master.cl.buildmode)
|
||||
if(1) // Basic Build
|
||||
|
||||
if(BUILDMODE_BASIC)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button = Construct / Upgrade</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button = Deconstruct / Delete / Downgrade</span>")
|
||||
@@ -82,7 +97,8 @@
|
||||
to_chat(usr, "<span class='notice'>Use the button in the upper left corner to</span>")
|
||||
to_chat(usr, "<span class='notice'>change the direction of built objects.</span>")
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
if(2) // Adv. Build
|
||||
|
||||
if(BUILDMODE_ADVANCED)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on buildmode button = Set object type</span>")
|
||||
to_chat(usr, "<span class='notice'>Middle Mouse Button on buildmode button= On/Off object type saying</span>")
|
||||
@@ -94,44 +110,56 @@
|
||||
to_chat(usr, "<span class='notice'>Use the button in the upper left corner to</span>")
|
||||
to_chat(usr, "<span class='notice'>change the direction of built objects.</span>")
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
if(3) // Edit
|
||||
|
||||
if(BUILDMODE_EDIT)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on buildmode button = Select var(type) & value</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button on turf/obj/mob = Set var(type) & value</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on turf/obj/mob = Reset var's value</span>")
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
if(4) // Throw
|
||||
|
||||
if(BUILDMODE_THROW)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on turf/obj/mob = Throw</span>")
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
if(5) // Room Build
|
||||
|
||||
if(BUILDMODE_ROOM)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button on turf = Select as point A</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on turf = Select as point B</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on buildmode button = Change floor/wall type</span>")
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
if(6) // Make Ladders
|
||||
|
||||
if(BUILDMODE_LADDER)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button on turf = Set as upper ladder loc</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on turf = Set as lower ladder loc</span>")
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
if(7) // Move Into Contents
|
||||
|
||||
if(BUILDMODE_CONTENTS)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on turf/obj/mob = Move into selection</span>")
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
if(8) // Make Lights
|
||||
|
||||
if(BUILDMODE_LIGHTS)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button on turf/obj/mob = Make it glow</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on turf/obj/mob = Reset glowing</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on buildmode button = Change glow properties</span>")
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
if(9) // Control mobs with ai_holders.
|
||||
|
||||
if(BUILDMODE_AI)
|
||||
to_chat(usr, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button drag box = Select only mobs in box</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button drag box + shift = Select additional mobs in area</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button on non-mob = Deselect all mobs</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button on AI mob = Select/Deselect mob</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button + alt on AI mob = Toggle hostility on mob</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button + ctrl on AI mob = Reset target/following/movement</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button + shift on AI mob = Toggle AI (also resets)</span>")
|
||||
to_chat(usr, "<span class='notice'>Left Mouse Button + ctrl on AI mob = Copy mob faction</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button + ctrl on any mob = Paste mob faction copied with Left Mouse Button + shift</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on enemy mob = Command selected mobs to attack mob</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button on allied mob = Command selected mobs to follow mob</span>")
|
||||
to_chat(usr, "<span class='notice'>Right Mouse Button + shift on any mob = Command selected mobs to follow mob regardless of faction</span>")
|
||||
@@ -159,6 +187,7 @@
|
||||
var/obj/effect/bmode/buildquit/buildquit = null
|
||||
var/atom/movable/throw_atom = null
|
||||
var/list/selected_mobs = list()
|
||||
var/copied_faction = null
|
||||
|
||||
/obj/effect/bmode/buildholder/Destroy()
|
||||
qdel(builddir)
|
||||
@@ -184,7 +213,6 @@
|
||||
selected_mobs -= unit
|
||||
C.images -= unit.selected_image
|
||||
|
||||
|
||||
/obj/effect/bmode/buildmode
|
||||
icon_state = "buildmode1"
|
||||
screen_loc = "NORTH,WEST+2"
|
||||
@@ -207,48 +235,25 @@
|
||||
|
||||
if(pa.Find("middle"))
|
||||
switch(master.cl.buildmode)
|
||||
if(2)
|
||||
if(BUILDMODE_ADVANCED)
|
||||
objsay=!objsay
|
||||
|
||||
|
||||
if(pa.Find("left"))
|
||||
switch(master.cl.buildmode)
|
||||
if(1)
|
||||
master.cl.buildmode = 2
|
||||
src.icon_state = "buildmode2"
|
||||
if(2)
|
||||
master.cl.buildmode = 3
|
||||
src.icon_state = "buildmode3"
|
||||
if(3)
|
||||
master.cl.buildmode = 4
|
||||
src.icon_state = "buildmode4"
|
||||
if(4)
|
||||
master.cl.buildmode = 5
|
||||
src.icon_state = "buildmode5"
|
||||
if(5)
|
||||
master.cl.buildmode = 6
|
||||
src.icon_state = "buildmode6"
|
||||
if(6)
|
||||
master.cl.buildmode = 7
|
||||
src.icon_state = "buildmode7"
|
||||
if(7)
|
||||
master.cl.buildmode = 8
|
||||
src.icon_state = "buildmode8"
|
||||
if(8)
|
||||
master.cl.buildmode = 9
|
||||
src.icon_state = "buildmode9"
|
||||
if(9)
|
||||
master.cl.buildmode = 1
|
||||
src.icon_state = "buildmode1"
|
||||
if(master.cl.buildmode == LAST_BUILDMODE)
|
||||
master.cl.buildmode = 1
|
||||
else
|
||||
master.cl.buildmode++
|
||||
src.icon_state = "buildmode[master.cl.buildmode]"
|
||||
|
||||
else if(pa.Find("right"))
|
||||
switch(master.cl.buildmode)
|
||||
if(1) // Basic Build
|
||||
if(BUILDMODE_BASIC)
|
||||
|
||||
return 1
|
||||
if(2) // Adv. Build
|
||||
if(BUILDMODE_ADVANCED)
|
||||
objholder = get_path_from_partial_text(/obj/structure/closet)
|
||||
|
||||
if(3) // Edit
|
||||
if(BUILDMODE_EDIT)
|
||||
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
|
||||
|
||||
master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name")
|
||||
@@ -267,14 +272,16 @@
|
||||
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world
|
||||
if("turf-reference")
|
||||
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world
|
||||
if(5) // Room build
|
||||
|
||||
if(BUILDMODE_ROOM)
|
||||
var/choice = alert("Would you like to change the floor or wall holders?","Room Builder", "Floor", "Wall")
|
||||
switch(choice)
|
||||
if("Floor")
|
||||
floor_holder = get_path_from_partial_text(/turf/simulated/floor/plating)
|
||||
if("Wall")
|
||||
wall_holder = get_path_from_partial_text(/turf/simulated/wall)
|
||||
if(8) // Lights
|
||||
|
||||
if(BUILDMODE_LIGHTS)
|
||||
var/choice = alert("Change the new light range, power, or color?", "Light Maker", "Range", "Power", "Color")
|
||||
switch(choice)
|
||||
if("Range")
|
||||
@@ -301,7 +308,7 @@
|
||||
var/list/pa = params2list(params)
|
||||
|
||||
switch(buildmode)
|
||||
if(1) // Basic Build
|
||||
if(BUILDMODE_BASIC)
|
||||
if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") )
|
||||
if(istype(object,/turf/space))
|
||||
var/turf/T = object
|
||||
@@ -350,7 +357,8 @@
|
||||
if(NORTHWEST)
|
||||
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
|
||||
WIN.set_dir(NORTHWEST)
|
||||
if(2) // Adv. Build
|
||||
|
||||
if(BUILDMODE_ADVANCED)
|
||||
if(pa.Find("left") && !pa.Find("ctrl"))
|
||||
if(ispath(holder.buildmode.objholder,/turf))
|
||||
var/turf/T = get_turf(object)
|
||||
@@ -369,8 +377,7 @@
|
||||
if(holder.buildmode.objsay)
|
||||
to_chat(usr, "[object.type]")
|
||||
|
||||
|
||||
if(3) // Edit
|
||||
if(BUILDMODE_EDIT)
|
||||
if(pa.Find("left")) //I cant believe this shit actually compiles.
|
||||
if(object.vars.Find(holder.buildmode.varholder))
|
||||
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
|
||||
@@ -384,7 +391,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='danger'>[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'</span>")
|
||||
|
||||
if(4) // Throw
|
||||
if(BUILDMODE_THROW)
|
||||
if(pa.Find("left"))
|
||||
if(istype(object, /atom/movable))
|
||||
holder.throw_atom = object
|
||||
@@ -392,7 +399,8 @@
|
||||
if(holder.throw_atom)
|
||||
holder.throw_atom.throw_at(object, 10, 1)
|
||||
log_admin("[key_name(usr)] threw [holder.throw_atom] at [object]")
|
||||
if(5) // Room build
|
||||
|
||||
if(BUILDMODE_ROOM)
|
||||
if(pa.Find("left"))
|
||||
holder.buildmode.coordA = get_turf(object)
|
||||
to_chat(user, "<span class='notice'>Defined [object] ([object.type]) as point A.</span>")
|
||||
@@ -411,7 +419,8 @@
|
||||
)
|
||||
holder.buildmode.coordA = null
|
||||
holder.buildmode.coordB = null
|
||||
if(6) // Ladders
|
||||
|
||||
if(BUILDMODE_LADDER)
|
||||
if(pa.Find("left"))
|
||||
holder.buildmode.coordA = get_turf(object)
|
||||
to_chat(user, "<span class='notice'>Defined [object] ([object.type]) as upper ladder location.</span>")
|
||||
@@ -430,7 +439,8 @@
|
||||
B.update_icon()
|
||||
holder.buildmode.coordA = null
|
||||
holder.buildmode.coordB = null
|
||||
if(7) // Move into contents
|
||||
|
||||
if(BUILDMODE_CONTENTS)
|
||||
if(pa.Find("left"))
|
||||
if(istype(object, /atom))
|
||||
holder.throw_atom = object
|
||||
@@ -438,23 +448,32 @@
|
||||
if(holder.throw_atom && istype(object, /atom/movable))
|
||||
object.forceMove(holder.throw_atom)
|
||||
log_admin("[key_name(usr)] moved [object] into [holder.throw_atom].")
|
||||
if(8) // Lights
|
||||
|
||||
if(BUILDMODE_LIGHTS)
|
||||
if(pa.Find("left"))
|
||||
if(object)
|
||||
object.set_light(holder.buildmode.new_light_range, holder.buildmode.new_light_intensity, holder.buildmode.new_light_color)
|
||||
if(pa.Find("right"))
|
||||
if(object)
|
||||
object.set_light(0, 0, "#FFFFFF")
|
||||
if(9) // AI control
|
||||
|
||||
if(BUILDMODE_AI)
|
||||
if(pa.Find("left"))
|
||||
if(isliving(object))
|
||||
var/mob/living/L = object
|
||||
// Reset processes.
|
||||
if(pa.Find("ctrl"))
|
||||
if(!isnull(L.get_AI_stance())) // Null means there's no AI datum or it has one but is player controlled w/o autopilot on.
|
||||
|
||||
// Pause/unpause AI
|
||||
if(pa.Find("shift"))
|
||||
var/stance = L.get_AI_stance()
|
||||
if(!isnull(stance)) // Null means there's no AI datum or it has one but is player controlled w/o autopilot on.
|
||||
var/datum/ai_holder/AI = L.ai_holder
|
||||
AI.forget_everything()
|
||||
to_chat(user, span("notice", "\The [L]'s AI has forgotten its target/movement destination/leader."))
|
||||
if(stance == STANCE_SLEEP)
|
||||
AI.go_wake()
|
||||
to_chat(user, span("notice", "\The [L]'s AI has been enabled."))
|
||||
else
|
||||
AI.go_sleep()
|
||||
to_chat(user, span("notice", "\The [L]'s AI has been disabled."))
|
||||
return
|
||||
else
|
||||
to_chat(user, span("warning", "\The [L] is not AI controlled."))
|
||||
return
|
||||
@@ -469,6 +488,12 @@
|
||||
to_chat(user, span("warning", "\The [L] is not AI controlled."))
|
||||
return
|
||||
|
||||
// Copy faction
|
||||
if(pa.Find("ctrl"))
|
||||
holder.copied_faction = L.faction
|
||||
to_chat(user, span("notice", "Copied faction '[holder.copied_faction]'."))
|
||||
return
|
||||
|
||||
// Select/Deselect
|
||||
if(!isnull(L.get_AI_stance()))
|
||||
if(L in holder.selected_mobs)
|
||||
@@ -477,10 +502,27 @@
|
||||
else
|
||||
holder.select_AI_mob(user.client, L)
|
||||
to_chat(user, span("notice", "Selected \the [L]."))
|
||||
return
|
||||
else
|
||||
to_chat(user, span("warning", "\The [L] is not AI controlled."))
|
||||
return
|
||||
else //Not living
|
||||
for(var/mob/living/unit in holder.selected_mobs)
|
||||
holder.deselect_AI_mob(user.client, unit)
|
||||
|
||||
|
||||
if(pa.Find("right"))
|
||||
// Paste faction
|
||||
if(pa.Find("ctrl") && isliving(object))
|
||||
if(!holder.copied_faction)
|
||||
to_chat(user, span("warning", "LMB+Shift a mob to copy their faction before pasting."))
|
||||
return
|
||||
else
|
||||
var/mob/living/L = object
|
||||
L.faction = holder.copied_faction
|
||||
to_chat(user, span("notice", "Pasted faction '[holder.copied_faction]'."))
|
||||
return
|
||||
|
||||
if(istype(object, /atom)) // Force attack.
|
||||
var/atom/A = object
|
||||
|
||||
@@ -491,6 +533,9 @@
|
||||
AI.give_target(A)
|
||||
i++
|
||||
to_chat(user, span("notice", "Commanded [i] mob\s to attack \the [A]."))
|
||||
var/image/orderimage = image(buildmode_hud,A,"ai_targetorder")
|
||||
orderimage.plane = PLANE_BUILDMODE
|
||||
flick_overlay(orderimage, list(user.client), 8, TRUE)
|
||||
return
|
||||
|
||||
if(isliving(object)) // Follow or attack.
|
||||
@@ -515,16 +560,67 @@
|
||||
if(j)
|
||||
message += "[j] mob\s to follow \the [L]."
|
||||
to_chat(user, span("notice", message))
|
||||
var/image/orderimage = image(buildmode_hud,L,"ai_targetorder")
|
||||
orderimage.plane = PLANE_BUILDMODE
|
||||
flick_overlay(orderimage, list(user.client), 8, TRUE)
|
||||
return
|
||||
|
||||
if(isturf(object)) // Move or reposition.
|
||||
var/turf/T = object
|
||||
var/i = 0
|
||||
var/forced = 0
|
||||
var/told = 0
|
||||
for(var/mob/living/unit in holder.selected_mobs)
|
||||
var/datum/ai_holder/AI = unit.ai_holder
|
||||
AI.give_destination(T, 1, pa.Find("shift")) // If shift is held, the mobs will not stop moving to attack a visible enemy.
|
||||
i++
|
||||
to_chat(user, span("notice", "Commanded [i] mob\s to move to \the [T]."))
|
||||
if(unit.get_AI_stance() == STANCE_SLEEP)
|
||||
unit.forceMove(T)
|
||||
forced++
|
||||
else
|
||||
AI.give_destination(T, 1, pa.Find("shift")) // If shift is held, the mobs will not stop moving to attack a visible enemy.
|
||||
told++
|
||||
to_chat(user, span("notice", "Commanded [told] mob\s to move to \the [T], and manually placed [forced] of them."))
|
||||
var/image/orderimage = image(buildmode_hud,T,"ai_turforder")
|
||||
orderimage.plane = PLANE_BUILDMODE
|
||||
flick_overlay(orderimage, list(user.client), 8, TRUE)
|
||||
return
|
||||
|
||||
/proc/build_drag(var/client/user, buildmode, var/atom/fromatom, var/atom/toatom, var/atom/fromloc, var/atom/toloc, var/fromcontrol, var/tocontrol, params)
|
||||
var/obj/effect/bmode/buildholder/holder = null
|
||||
for(var/obj/effect/bmode/buildholder/H)
|
||||
if(H.cl == user)
|
||||
holder = H
|
||||
break
|
||||
if(!holder) return
|
||||
var/list/pa = params2list(params)
|
||||
|
||||
switch(buildmode)
|
||||
if(BUILDMODE_AI)
|
||||
|
||||
//Holding shift prevents the deselection of existing
|
||||
if(!pa.Find("shift"))
|
||||
for(var/mob/living/unit in holder.selected_mobs)
|
||||
holder.deselect_AI_mob(user, unit)
|
||||
|
||||
var/turf/c1 = get_turf(fromatom)
|
||||
var/turf/c2 = get_turf(toatom)
|
||||
if(!c1 || !c2)
|
||||
return //Dragged outside window or something
|
||||
|
||||
var/low_x = min(c1.x,c2.x)
|
||||
var/low_y = min(c1.y,c2.y)
|
||||
var/hi_x = max(c1.x,c2.x)
|
||||
var/hi_y = max(c1.y,c2.y)
|
||||
var/z = c1.z //Eh
|
||||
|
||||
var/i = 0
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(L.z != z || L.client)
|
||||
continue
|
||||
if(L.x >= low_x && L.x <= hi_x && L.y >= low_y && L.y <= hi_y)
|
||||
holder.select_AI_mob(user, L)
|
||||
i++
|
||||
|
||||
to_chat(user, span("notice", "Band-selected [i] mobs."))
|
||||
return
|
||||
|
||||
/obj/effect/bmode/buildmode/proc/get_path_from_partial_text(default_path)
|
||||
var/desired_path = input("Enter full or partial typepath.","Typepath","[default_path]")
|
||||
@@ -596,4 +692,15 @@
|
||||
if(isturf(floor_type))
|
||||
T.ChangeTurf(floor_type)
|
||||
else
|
||||
new floor_type(T)
|
||||
new floor_type(T)
|
||||
|
||||
#undef BUILDMODE_BASIC
|
||||
#undef BUILDMODE_ADVANCED
|
||||
#undef BUILDMODE_EDIT
|
||||
#undef BUILDMODE_THROW
|
||||
#undef BUILDMODE_ROOM
|
||||
#undef BUILDMODE_LADDER
|
||||
#undef BUILDMODE_CONTENTS
|
||||
#undef BUILDMODE_LIGHTS
|
||||
#undef BUILDMODE_AI
|
||||
#undef LAST_BUILDMODE
|
||||
@@ -638,13 +638,14 @@
|
||||
return
|
||||
|
||||
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in SSplanets.planets
|
||||
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
|
||||
if(new_weather)
|
||||
planet.weather_holder.change_weather(new_weather)
|
||||
planet.weather_holder.rebuild_forecast()
|
||||
var/log = "[key_name(src)] changed [planet.name]'s weather to [new_weather]."
|
||||
message_admins(log)
|
||||
log_admin(log)
|
||||
if(istype(planet))
|
||||
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
|
||||
if(new_weather)
|
||||
planet.weather_holder.change_weather(new_weather)
|
||||
planet.weather_holder.rebuild_forecast()
|
||||
var/log = "[key_name(src)] changed [planet.name]'s weather to [new_weather]."
|
||||
message_admins(log)
|
||||
log_admin(log)
|
||||
|
||||
/datum/admins/proc/change_time()
|
||||
set category = "Debug"
|
||||
@@ -655,20 +656,20 @@
|
||||
return
|
||||
|
||||
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in SSplanets.planets
|
||||
if(istype(planet))
|
||||
var/datum/time/current_time_datum = planet.current_time
|
||||
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
|
||||
if(!isnull(new_hour))
|
||||
var/new_minute = input(usr, "What minute do you want to change to?", "Change Time", text2num(current_time_datum.show_time("mm")) ) as null|num
|
||||
if(!isnull(new_minute))
|
||||
var/type_needed = current_time_datum.type
|
||||
var/datum/time/new_time = new type_needed()
|
||||
new_time = new_time.add_hours(new_hour)
|
||||
new_time = new_time.add_minutes(new_minute)
|
||||
planet.current_time = new_time
|
||||
spawn(1)
|
||||
planet.update_sun()
|
||||
|
||||
var/datum/time/current_time_datum = planet.current_time
|
||||
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
|
||||
if(!isnull(new_hour))
|
||||
var/new_minute = input(usr, "What minute do you want to change to?", "Change Time", text2num(current_time_datum.show_time("mm")) ) as null|num
|
||||
if(!isnull(new_minute))
|
||||
var/type_needed = current_time_datum.type
|
||||
var/datum/time/new_time = new type_needed()
|
||||
new_time = new_time.add_hours(new_hour)
|
||||
new_time = new_time.add_minutes(new_minute)
|
||||
planet.current_time = new_time
|
||||
spawn(1)
|
||||
planet.update_sun()
|
||||
|
||||
var/log = "[key_name(src)] changed [planet.name]'s time to [planet.current_time.show_time("hh:mm")]."
|
||||
message_admins(log)
|
||||
log_admin(log)
|
||||
var/log = "[key_name(src)] changed [planet.name]'s time to [planet.current_time.show_time("hh:mm")]."
|
||||
message_admins(log)
|
||||
log_admin(log)
|
||||
@@ -1,6 +1,6 @@
|
||||
/client/proc/admin_lightning_strike()
|
||||
set name = "Lightning Strike"
|
||||
set desc = "Causes lightning to strike on your tile. This will hurt things on or nearby it severely."
|
||||
set desc = "Causes lightning to strike on your tile. This can be made to hurt things on or nearby it severely."
|
||||
set category = "Fun"
|
||||
|
||||
if(!check_rights(R_FUN))
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
// Do a lightning flash for the whole planet, if the turf belongs to a planet.
|
||||
var/datum/planet/P = null
|
||||
P = SSplanets.z_to_planet[T.z]
|
||||
P = LAZYACCESS(SSplanets.z_to_planet, T.z)
|
||||
if(P)
|
||||
var/datum/weather_holder/holder = P.weather_holder
|
||||
flick("lightning_flash", holder.special_visuals)
|
||||
@@ -64,7 +64,7 @@
|
||||
// Otherwise only those on the current z-level will hear it.
|
||||
var/sound = get_sfx("thunder")
|
||||
for(var/mob/M in player_list)
|
||||
if((P && M.z in P.expected_z_levels) || M.z == T.z)
|
||||
if( (P && (M.z in P.expected_z_levels)) || M.z == T.z)
|
||||
if(M.is_preference_enabled(/datum/client_preference/weather_sounds))
|
||||
M.playsound_local(get_turf(M), soundin = sound, vol = 70, vary = FALSE, is_global = TRUE)
|
||||
|
||||
|
||||
@@ -149,3 +149,40 @@
|
||||
// Simple mobs that retaliate and support others in their faction who get attacked.
|
||||
/datum/ai_holder/simple_mob/retaliate/cooperative
|
||||
cooperative = TRUE
|
||||
|
||||
// With all the bells and whistles
|
||||
/datum/ai_holder/simple_mob/humanoid
|
||||
intelligence_level = AI_SMART //Purportedly
|
||||
retaliate = TRUE //If attacked, attack back
|
||||
threaten = TRUE //Verbal threats
|
||||
firing_lanes = TRUE //Avoid shooting allies
|
||||
conserve_ammo = TRUE //Don't shoot when it can't hit target
|
||||
can_breakthrough = TRUE //Can break through doors
|
||||
violent_breakthrough = FALSE //Won't try to break through walls (humans can, but usually don't)
|
||||
speak_chance = 2 //Babble chance
|
||||
cooperative = TRUE //Assist each other
|
||||
wander = TRUE //Wander around
|
||||
returns_home = TRUE //But not too far
|
||||
use_astar = TRUE //Path smartly
|
||||
home_low_priority = TRUE //Following/helping is more important
|
||||
|
||||
// The hostile subtype is implied to be trained combatants who use ""tactics""
|
||||
/datum/ai_holder/simple_mob/humanoid/hostile
|
||||
var/run_if_this_close = 4 // If anything gets within this range, it'll try to move away.
|
||||
hostile = TRUE //Attack!
|
||||
|
||||
// Juke
|
||||
/datum/ai_holder/simple_mob/humanoid/hostile/post_melee_attack(atom/A)
|
||||
holder.IMove(get_step(holder, pick(alldirs)))
|
||||
holder.face_atom(A)
|
||||
|
||||
/datum/ai_holder/simple_mob/humanoid/hostile/post_ranged_attack(atom/A)
|
||||
//Pick a random turf to step into
|
||||
var/turf/T = get_step(holder, pick(alldirs))
|
||||
if(check_trajectory(A, T)) // Can we even hit them from there?
|
||||
holder.IMove(T)
|
||||
holder.face_atom(A)
|
||||
|
||||
if(get_dist(holder, A) < run_if_this_close)
|
||||
holder.IMove(get_step_away(holder, A))
|
||||
holder.face_atom(A)
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
if(rabid)
|
||||
return
|
||||
var/justified = my_slime.is_justified_to_discipline() // This will also consider the AI-side of that proc.
|
||||
lost_target() // Stop attacking.
|
||||
remove_target() // Stop attacking.
|
||||
|
||||
if(justified)
|
||||
obedience++
|
||||
@@ -137,7 +137,7 @@
|
||||
|
||||
// Called when using a pacification agent (or it's Kendrick being initalized).
|
||||
/datum/ai_holder/simple_mob/xenobio_slime/proc/pacify()
|
||||
lost_target() // So it stops trying to kill them.
|
||||
remove_target() // So it stops trying to kill them.
|
||||
rabid = FALSE
|
||||
hostile = FALSE
|
||||
retaliate = FALSE
|
||||
@@ -167,7 +167,7 @@
|
||||
return 1 // Melee (eat) the target if dead/dying, don't shoot it.
|
||||
return ..()
|
||||
|
||||
/datum/ai_holder/simple_mob/xenobio_slime/can_attack(atom/movable/AM)
|
||||
/datum/ai_holder/simple_mob/xenobio_slime/can_attack(atom/movable/AM, var/vision_required = TRUE)
|
||||
. = ..()
|
||||
if(.) // Do some additional checks because we have Special Code(tm).
|
||||
if(ishuman(AM))
|
||||
@@ -247,7 +247,7 @@
|
||||
else
|
||||
delayed_say("Fine...", speaker)
|
||||
adjust_discipline(1, TRUE) // This must come before losing the target or it will be unjustified.
|
||||
lost_target()
|
||||
remove_target()
|
||||
|
||||
|
||||
if(leader) // We're being asked to stop following someone.
|
||||
|
||||
@@ -46,8 +46,25 @@
|
||||
home_turf = null
|
||||
return ..()
|
||||
|
||||
/datum/ai_holder/proc/update_stance_hud()
|
||||
var/image/stanceimage = holder.grab_hud(LIFE_HUD)
|
||||
stanceimage.icon_state = "ais_[stance]"
|
||||
holder.apply_hud(LIFE_HUD, stanceimage)
|
||||
|
||||
/datum/ai_holder/proc/update_paused_hud()
|
||||
var/image/sleepingimage = holder.grab_hud(STATUS_HUD)
|
||||
var/asleep = 0
|
||||
if(busy)
|
||||
asleep = 2
|
||||
else if (stance == STANCE_SLEEP)
|
||||
asleep = 1
|
||||
sleepingimage.icon_state = "ai_[asleep]"
|
||||
holder.apply_hud(STATUS_HUD, sleepingimage)
|
||||
|
||||
// Now for the actual AI stuff.
|
||||
/datum/ai_holder/proc/set_busy(var/value = 0)
|
||||
busy = value
|
||||
update_paused_hud()
|
||||
|
||||
// Makes this ai holder not get processed.
|
||||
// Called automatically when the host mob is killed.
|
||||
@@ -58,6 +75,7 @@
|
||||
forget_everything() // If we ever wake up, its really unlikely that our current memory will be of use.
|
||||
set_stance(STANCE_SLEEP)
|
||||
SSai.processing -= src
|
||||
update_paused_hud()
|
||||
|
||||
// Reverses the above proc.
|
||||
// Revived mobs will wake their AI if they have one.
|
||||
@@ -68,6 +86,7 @@
|
||||
return
|
||||
set_stance(STANCE_IDLE)
|
||||
SSai.processing += src
|
||||
update_paused_hud()
|
||||
|
||||
/datum/ai_holder/proc/should_wake()
|
||||
if(holder.client && !autopilot)
|
||||
@@ -80,9 +99,7 @@
|
||||
/datum/ai_holder/proc/forget_everything()
|
||||
// Some of these might be redundant, but hopefully this prevents future bugs if that changes.
|
||||
lose_follow()
|
||||
lose_target()
|
||||
lose_target_position()
|
||||
give_up_movement()
|
||||
remove_target()
|
||||
|
||||
// 'Tactical' processes such as moving a step, meleeing an enemy, firing a projectile, and other fairly cheap actions that need to happen quickly.
|
||||
/datum/ai_holder/proc/handle_tactics()
|
||||
@@ -103,39 +120,13 @@
|
||||
|
||||
/datum/ai_holder/proc/handle_special_strategical()
|
||||
|
||||
/*
|
||||
//AI Actions
|
||||
if(!ai_inactive)
|
||||
//Stanceyness
|
||||
handle_stance()
|
||||
|
||||
//Movement
|
||||
if(!stop_automated_movement && wander && !anchored) //Allowed to move?
|
||||
handle_wander_movement()
|
||||
|
||||
//Speaking
|
||||
if(speak_chance && stance == STANCE_IDLE) // Allowed to chatter?
|
||||
handle_idle_speaking()
|
||||
|
||||
//Resisting out buckles
|
||||
if(stance != STANCE_IDLE && incapacitated(INCAPACITATION_BUCKLED_PARTIALLY))
|
||||
handle_resist()
|
||||
|
||||
//Resisting out of closets
|
||||
if(istype(loc,/obj/structure/closet))
|
||||
var/obj/structure/closet/C = loc
|
||||
if(C.welded)
|
||||
resist()
|
||||
else
|
||||
C.open()
|
||||
*/
|
||||
|
||||
// For setting the stance WITHOUT processing it
|
||||
/datum/ai_holder/proc/set_stance(var/new_stance)
|
||||
ai_log("set_stance() : Setting stance from [stance] to [new_stance].", AI_LOG_INFO)
|
||||
stance = new_stance
|
||||
if(stance_coloring) // For debugging or really weird mobs.
|
||||
stance_color()
|
||||
update_stance_hud()
|
||||
|
||||
// This is called every half a second.
|
||||
/datum/ai_holder/proc/handle_stance_tactical()
|
||||
@@ -207,7 +198,8 @@
|
||||
|
||||
if(STANCE_REPOSITION) // This is the same as above but doesn't stop if an enemy is visible since its an 'in-combat' move order.
|
||||
ai_log("handle_stance_tactical() : STANCE_REPOSITION, going to walk_to_destination().", AI_LOG_TRACE)
|
||||
walk_to_destination()
|
||||
if(!target && !find_target())
|
||||
walk_to_destination()
|
||||
|
||||
if(STANCE_FOLLOW)
|
||||
ai_log("handle_stance_tactical() : STANCE_FOLLOW, going to walk_to_leader().", AI_LOG_TRACE)
|
||||
@@ -232,13 +224,23 @@
|
||||
/datum/ai_holder/proc/handle_stance_strategical()
|
||||
ai_log("++++++++++ Slow Process Beginning ++++++++++", AI_LOG_TRACE)
|
||||
ai_log("handle_stance_strategical() : Called.", AI_LOG_TRACE)
|
||||
|
||||
//We got left around for some reason. Goodbye cruel world.
|
||||
if(!holder)
|
||||
qdel(src)
|
||||
|
||||
ai_log("handle_stance_strategical() : LTT=[lose_target_time]", AI_LOG_TRACE)
|
||||
if(lose_target_time && (lose_target_time + lose_target_timeout < world.time)) // We were tracking an enemy but they are gone.
|
||||
ai_log("handle_stance_strategical() : Giving up a chase.", AI_LOG_DEBUG)
|
||||
remove_target()
|
||||
|
||||
if(stance in STANCES_COMBAT)
|
||||
request_help() // Call our allies.
|
||||
|
||||
switch(stance)
|
||||
if(STANCE_IDLE)
|
||||
|
||||
if(speak_chance) // In the long loop since otherwise it wont shut up.
|
||||
handle_idle_speaking()
|
||||
|
||||
if(hostile)
|
||||
ai_log("handle_stance_strategical() : STANCE_IDLE, going to find_target().", AI_LOG_TRACE)
|
||||
find_target()
|
||||
@@ -246,6 +248,7 @@
|
||||
if(target)
|
||||
ai_log("handle_stance_strategical() : STANCE_APPROACH, going to calculate_path([target]).", AI_LOG_TRACE)
|
||||
calculate_path(target)
|
||||
walk_to_target()
|
||||
if(STANCE_MOVE)
|
||||
if(hostile && find_target()) // This will switch its stance.
|
||||
ai_log("handle_stance_strategical() : STANCE_MOVE, found target and was inturrupted.", AI_LOG_TRACE)
|
||||
@@ -255,6 +258,7 @@
|
||||
else if(leader)
|
||||
ai_log("handle_stance_strategical() : STANCE_FOLLOW, going to calculate_path([leader]).", AI_LOG_TRACE)
|
||||
calculate_path(leader)
|
||||
walk_to_leader()
|
||||
|
||||
ai_log("handle_stance_strategical() : Exiting.", AI_LOG_TRACE)
|
||||
ai_log("++++++++++ Slow Process Ending ++++++++++", AI_LOG_TRACE)
|
||||
@@ -263,7 +267,7 @@
|
||||
// Helper proc to turn AI 'busy' mode on or off without having to check if there is an AI, to simplify writing code.
|
||||
/mob/living/proc/set_AI_busy(value)
|
||||
if(ai_holder)
|
||||
ai_holder.busy = value
|
||||
ai_holder.set_busy(value)
|
||||
|
||||
/mob/living/proc/is_AI_busy()
|
||||
if(!ai_holder)
|
||||
|
||||
@@ -9,47 +9,23 @@
|
||||
var/violent_breakthrough = TRUE // If false, the AI is not allowed to destroy things like windows or other structures in the way. Requires above var to be true.
|
||||
|
||||
var/stand_ground = FALSE // If true, the AI won't try to get closer to an enemy if out of range.
|
||||
|
||||
|
||||
|
||||
// This does the actual attacking.
|
||||
/datum/ai_holder/proc/engage_target()
|
||||
ai_log("engage_target() : Entering.", AI_LOG_DEBUG)
|
||||
|
||||
// Can we still see them?
|
||||
// if(!target || !can_attack(target) || (!(target in list_targets())) )
|
||||
if(!target || !can_attack(target))
|
||||
ai_log("engage_target() : Lost sight of target.", AI_LOG_TRACE)
|
||||
lose_target() // We lost them.
|
||||
|
||||
if(!find_target()) // If we can't get a new one, then wait for a bit and then time out.
|
||||
set_stance(STANCE_IDLE)
|
||||
lost_target()
|
||||
ai_log("engage_target() : No more targets. Exiting.", AI_LOG_DEBUG)
|
||||
if(lose_target()) // We lost them (returns TRUE if we found something else to do)
|
||||
ai_log("engage_target() : Pursuing other options (last seen, or a new target).", AI_LOG_TRACE)
|
||||
return
|
||||
// if(lose_target_time + lose_target_timeout < world.time)
|
||||
// ai_log("engage_target() : Unseen enemy timed out.", AI_LOG_TRACE)
|
||||
// set_stance(STANCE_IDLE) // It must've been the wind.
|
||||
// lost_target()
|
||||
// ai_log("engage_target() : Exiting.", AI_LOG_DEBUG)
|
||||
// return
|
||||
|
||||
// // But maybe we do one last ditch effort.
|
||||
// if(!target_last_seen_turf || intelligence_level < AI_SMART)
|
||||
// ai_log("engage_target() : No last known position or is too dumb to fight unseen enemies.", AI_LOG_TRACE)
|
||||
// set_stance(STANCE_IDLE)
|
||||
// else
|
||||
// ai_log("engage_target() : Fighting unseen enemy.", AI_LOG_TRACE)
|
||||
// engage_unseen_enemy()
|
||||
else
|
||||
ai_log("engage_target() : Got new target ([target]).", AI_LOG_TRACE)
|
||||
|
||||
var/distance = get_dist(holder, target)
|
||||
ai_log("engage_target() : Distance to target ([target]) is [distance].", AI_LOG_TRACE)
|
||||
holder.face_atom(target)
|
||||
last_conflict_time = world.time
|
||||
|
||||
request_help() // Call our allies.
|
||||
|
||||
// Do a 'special' attack, if one is allowed.
|
||||
// if(prob(special_attack_prob) && (distance >= special_attack_min_range) && (distance <= special_attack_max_range))
|
||||
if(holder.ICheckSpecialAttack(target))
|
||||
@@ -198,12 +174,8 @@
|
||||
// Make sure we can still chase/attack them.
|
||||
if(!target || !can_attack(target))
|
||||
ai_log("walk_to_target() : Lost target.", AI_LOG_INFO)
|
||||
if(!find_target())
|
||||
lost_target()
|
||||
ai_log("walk_to_target() : Exiting.", AI_LOG_DEBUG)
|
||||
return
|
||||
else
|
||||
ai_log("walk_to_target() : Found new target ([target]).", AI_LOG_INFO)
|
||||
lose_target()
|
||||
return
|
||||
|
||||
// Find out where we're going.
|
||||
var/get_to = closest_distance(target)
|
||||
@@ -220,7 +192,6 @@
|
||||
ai_log("walk_to_target() : Exiting.", AI_LOG_DEBUG)
|
||||
return
|
||||
|
||||
|
||||
// Otherwise keep walking.
|
||||
if(!stand_ground)
|
||||
walk_path(target, get_to)
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
|
||||
// Used when a target is out of sight or invisible.
|
||||
/datum/ai_holder/proc/engage_unseen_enemy()
|
||||
ai_log("engage_unseen_enemy() : Entering.", AI_LOG_TRACE)
|
||||
// Lets do some last things before giving up.
|
||||
if(!ranged)
|
||||
if(get_dist(holder, target_last_seen_turf > 1)) // We last saw them over there.
|
||||
if(conserve_ammo || !holder.ICheckRangedAttack(target_last_seen_turf))
|
||||
if(get_dist(holder, target_last_seen_turf) > 1) // We last saw them over there.
|
||||
// Go to where you last saw the enemy.
|
||||
give_destination(target_last_seen_turf, 1, TRUE) // This will set it to STANCE_REPOSITION.
|
||||
else // We last saw them next to us, so do a blind attack on that tile.
|
||||
give_destination(target_last_seen_turf, 1, TRUE) // Sets stance as well
|
||||
else if(lose_target_time == world.time) // We last saw them next to us, so do a blind attack on that tile.
|
||||
melee_on_tile(target_last_seen_turf)
|
||||
|
||||
else if(!conserve_ammo)
|
||||
else
|
||||
find_target()
|
||||
else
|
||||
shoot_near_turf(target_last_seen_turf)
|
||||
|
||||
// This shoots semi-randomly near a specific turf.
|
||||
/datum/ai_holder/proc/shoot_near_turf(turf/targeted_turf)
|
||||
if(!ranged)
|
||||
return // Can't shoot.
|
||||
if(get_dist(holder, targeted_turf) > max_range(targeted_turf))
|
||||
return // Too far to shoot.
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
// Attempts to attack something on a specific tile.
|
||||
// TODO: Put on mob/living?
|
||||
/datum/ai_holder/proc/melee_on_tile(turf/T)
|
||||
ai_log("melee_on_tile() : Entering.", AI_LOG_TRACE)
|
||||
var/mob/living/L = locate() in T
|
||||
if(!L)
|
||||
T.visible_message("\The [holder] attacks nothing around \the [T].")
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/datum/ai_holder/proc/should_threaten()
|
||||
if(!threaten)
|
||||
return FALSE // We don't negotiate.
|
||||
if(target in attackers)
|
||||
if(check_attacker(target))
|
||||
return FALSE // They (or someone like them) attacked us before, escalate immediately.
|
||||
if(!will_threaten(target))
|
||||
return FALSE // Pointless to threaten an animal, a mindless drone, or an object.
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
ai_log("request_help() : Exiting.", AI_LOG_DEBUG)
|
||||
|
||||
// What allies receive when someone else is calling for help.
|
||||
// What allies receive when someone else is calling for help.1
|
||||
/datum/ai_holder/proc/help_requested(mob/living/friend)
|
||||
ai_log("help_requested() : Entering.", AI_LOG_DEBUG)
|
||||
if(stance == STANCE_SLEEP)
|
||||
@@ -92,24 +92,26 @@
|
||||
if(!holder.IIsAlly(friend)) // Extra sanity.
|
||||
ai_log("help_requested() : Help requested by [friend] but we hate them.", AI_LOG_INFO)
|
||||
return
|
||||
if(friend.ai_holder && friend.ai_holder.target && !can_attack(friend.ai_holder.target))
|
||||
ai_log("help_requested() : Help requested by [friend] but we don't want to fight their target.", AI_LOG_INFO)
|
||||
return
|
||||
if(get_dist(holder, friend) <= follow_distance)
|
||||
ai_log("help_requested() : Help requested by [friend] but we're already here.", AI_LOG_INFO)
|
||||
return
|
||||
if(get_dist(holder, friend) <= vision_range) // Within our sight.
|
||||
ai_log("help_requested() : Help requested by [friend], and within target sharing range.", AI_LOG_INFO)
|
||||
if(friend.ai_holder) // AI calling for help.
|
||||
if(friend.ai_holder.target && can_attack(friend.ai_holder.target)) // Friend wants us to attack their target.
|
||||
last_conflict_time = world.time // So we attack immediately and not threaten.
|
||||
give_target(friend.ai_holder.target) // This will set us to the appropiate stance.
|
||||
ai_log("help_requested() : Given target [target] by [friend]. Exiting", AI_LOG_DEBUG)
|
||||
return
|
||||
var/their_target = friend?.ai_holder?.target
|
||||
if(their_target) // They have a target and aren't just shouting for no reason
|
||||
if(!can_attack(their_target, vision_required = FALSE))
|
||||
ai_log("help_requested() : Help requested by [friend] but we don't want to fight their target.", AI_LOG_INFO)
|
||||
return
|
||||
if(get_dist(holder, friend) <= follow_distance)
|
||||
ai_log("help_requested() : Help requested by [friend] but we're already here.", AI_LOG_INFO)
|
||||
return
|
||||
if(get_dist(holder, friend) <= vision_range) // Within our sight.
|
||||
ai_log("help_requested() : Help requested by [friend], and within target sharing range.", AI_LOG_INFO)
|
||||
last_conflict_time = world.time // So we attack immediately and not threaten.
|
||||
give_target(their_target, urgent = TRUE) // This will set us to the appropiate stance.
|
||||
ai_log("help_requested() : Given target [target] by [friend]. Exiting", AI_LOG_DEBUG)
|
||||
return
|
||||
|
||||
// Otherwise they're outside our sight, lack a target, or aren't AI controlled, but within call range.
|
||||
// So assuming we're AI controlled, we'll go to them and see whats wrong.
|
||||
ai_log("help_requested() : Help requested by [friend], going to go to friend.", AI_LOG_INFO)
|
||||
if(their_target)
|
||||
add_attacker(their_target) // We won't wait and 'warn' them while they're stabbing our ally
|
||||
set_follow(friend, 10 SECONDS)
|
||||
ai_log("help_requested() : Exiting.", AI_LOG_DEBUG)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
// Step 1, find out what we can see.
|
||||
/datum/ai_holder/proc/list_targets()
|
||||
. = hearers(vision_range, holder) - holder // Remove ourselves to prevent suicidal decisions. ~ SRC is the ai_holder.
|
||||
. -= dview_mob // Not the dview mob either, nerd.
|
||||
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha))
|
||||
|
||||
@@ -35,6 +36,7 @@
|
||||
|
||||
// Step 2, filter down possible targets to things we actually care about.
|
||||
/datum/ai_holder/proc/find_target(var/list/possible_targets, var/has_targets_list = FALSE)
|
||||
ai_log("find_target() : Entered.", AI_LOG_TRACE)
|
||||
if(!hostile) // So retaliating mobs only attack the thing that hit it.
|
||||
return null
|
||||
. = list()
|
||||
@@ -70,13 +72,17 @@
|
||||
return chosen_target
|
||||
|
||||
// Step 4, give us our selected target.
|
||||
/datum/ai_holder/proc/give_target(new_target)
|
||||
/datum/ai_holder/proc/give_target(new_target, urgent = FALSE)
|
||||
ai_log("give_target() : Given '[new_target]', urgent=[urgent].", AI_LOG_TRACE)
|
||||
target = new_target
|
||||
|
||||
if(target != null)
|
||||
if(should_threaten())
|
||||
lose_target_time = 0
|
||||
track_target_position()
|
||||
if(should_threaten() && !urgent)
|
||||
set_stance(STANCE_ALERT)
|
||||
else
|
||||
set_stance(STANCE_APPROACH)
|
||||
set_stance(STANCE_FIGHT)
|
||||
last_target_time = world.time
|
||||
return TRUE
|
||||
|
||||
@@ -109,8 +115,8 @@
|
||||
sorted_targets += A
|
||||
return sorted_targets
|
||||
|
||||
/datum/ai_holder/proc/can_attack(atom/movable/the_target)
|
||||
if(!can_see_target(the_target))
|
||||
/datum/ai_holder/proc/can_attack(atom/movable/the_target, var/vision_required = TRUE)
|
||||
if(!can_see_target(the_target) && vision_required)
|
||||
return FALSE
|
||||
|
||||
if(istype(the_target, /mob/zshadow))
|
||||
@@ -157,21 +163,38 @@
|
||||
/datum/ai_holder/proc/found(atom/movable/the_target)
|
||||
return FALSE
|
||||
|
||||
//We can't see the target, go look or attack where they were last seen.
|
||||
// 'Soft' loss of target. They may still exist, we still have some info about them maybe.
|
||||
/datum/ai_holder/proc/lose_target()
|
||||
ai_log("lose_target() : Entering.", AI_LOG_TRACE)
|
||||
if(target)
|
||||
ai_log("lose_target() : Had a target, setting to null and LTT.", AI_LOG_DEBUG)
|
||||
target = null
|
||||
lose_target_time = world.time
|
||||
|
||||
give_up_movement()
|
||||
|
||||
if(target_last_seen_turf && intelligence_level >= AI_SMART)
|
||||
ai_log("lose_target() : Going into 'engage unseen enemy' mode.", AI_LOG_INFO)
|
||||
engage_unseen_enemy()
|
||||
return TRUE //We're still working on it
|
||||
else
|
||||
ai_log("lose_target() : Can't chase target, so giving up.", AI_LOG_INFO)
|
||||
remove_target()
|
||||
return find_target() //Returns if we found anything else to do
|
||||
|
||||
//Target is no longer valid (?)
|
||||
/datum/ai_holder/proc/lost_target()
|
||||
set_stance(STANCE_IDLE)
|
||||
return FALSE //Nothing new to do
|
||||
|
||||
// 'Hard' loss of target. Clean things up and return to idle.
|
||||
/datum/ai_holder/proc/remove_target()
|
||||
ai_log("remove_target() : Entering.", AI_LOG_TRACE)
|
||||
if(target)
|
||||
target = null
|
||||
|
||||
lose_target_time = 0
|
||||
give_up_movement()
|
||||
lose_target_position()
|
||||
lose_target()
|
||||
|
||||
set_stance(STANCE_IDLE)
|
||||
|
||||
// Check if target is visible to us.
|
||||
/datum/ai_holder/proc/can_see_target(atom/movable/the_target, view_range = vision_range)
|
||||
ai_log("can_see_target() : Entering.", AI_LOG_TRACE)
|
||||
@@ -235,7 +258,7 @@
|
||||
ai_log("react_to_attack() : Was attacked by [attacker], but we already have a target.", AI_LOG_TRACE)
|
||||
on_attacked(attacker) // So we attack immediately and not threaten.
|
||||
return FALSE
|
||||
else if(attacker in attackers && world.time > last_target_time + 3 SECONDS) // Otherwise, let 'er rip
|
||||
else if(check_attacker(attacker) && world.time > last_target_time + 3 SECONDS) // Otherwise, let 'er rip
|
||||
ai_log("react_to_attack() : Was attacked by [attacker]. Can retaliate, waited 3 seconds.", AI_LOG_INFO)
|
||||
on_attacked(attacker) // So we attack immediately and not threaten.
|
||||
return give_target(attacker) // Also handles setting the appropiate stance.
|
||||
@@ -246,16 +269,25 @@
|
||||
|
||||
ai_log("react_to_attack() : Was attacked by [attacker].", AI_LOG_INFO)
|
||||
on_attacked(attacker) // So we attack immediately and not threaten.
|
||||
return give_target(attacker) // Also handles setting the appropiate stance.
|
||||
return give_target(attacker, urgent = TRUE) // Also handles setting the appropiate stance.
|
||||
|
||||
// Sets a few vars so mobs that threaten will react faster to an attacker or someone who attacked them before.
|
||||
/datum/ai_holder/proc/on_attacked(atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!(L.name in attackers))
|
||||
attackers |= L.name
|
||||
last_conflict_time = world.time
|
||||
last_conflict_time = world.time
|
||||
add_attacker(AM)
|
||||
|
||||
// Checks to see if an atom attacked us lately
|
||||
/datum/ai_holder/proc/check_attacker(var/atom/movable/A)
|
||||
return (A in attackers)
|
||||
|
||||
// We were attacked by this thing recently
|
||||
/datum/ai_holder/proc/add_attacker(var/atom/movable/A)
|
||||
attackers |= A.name
|
||||
|
||||
// Forgive this attacker
|
||||
/datum/ai_holder/proc/remove_attacker(var/atom/movable/A)
|
||||
attackers -= A.name
|
||||
|
||||
// Causes targeting to prefer targeting the taunter if possible.
|
||||
// This generally occurs if more than one option is within striking distance, including the taunter.
|
||||
// Otherwise the default filter will prefer the closest target.
|
||||
|
||||
@@ -320,6 +320,14 @@
|
||||
if(inactivity > duration) return inactivity
|
||||
return 0
|
||||
|
||||
//Called when the client performs a drag-and-drop operation.
|
||||
/client/MouseDrop(start_object,end_object,start_location,end_location,start_control,end_control,params)
|
||||
if(buildmode && start_control == "mapwindow.map" && start_control == end_control)
|
||||
build_drag(src,buildmode,start_object,end_object,start_location,end_location,start_control,end_control,params)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
|
||||
// Byond seemingly calls stat, each tick.
|
||||
// Calling things each tick can get expensive real quick.
|
||||
// So we slow this down a little.
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
pref.backbag = 1 //Same as above
|
||||
character.backbag = pref.backbag
|
||||
|
||||
if(pref.pdachoice > 4 || pref.pdachoice < 1)
|
||||
if(pref.pdachoice > 5 || pref.pdachoice < 1)
|
||||
pref.pdachoice = 1
|
||||
character.pdachoice = pref.pdachoice
|
||||
|
||||
|
||||
@@ -110,11 +110,11 @@ var/list/_client_preferences_by_type
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/air_pump_noise
|
||||
description ="Air Pump Ambient Noise"
|
||||
key = "SOUND_AIRPUMP"
|
||||
enabled_description = "Audible"
|
||||
disabled_description = "Silent"
|
||||
/datum/client_preference/air_pump_noise
|
||||
description ="Air Pump Ambient Noise"
|
||||
key = "SOUND_AIRPUMP"
|
||||
enabled_description = "Audible"
|
||||
disabled_description = "Silent"
|
||||
|
||||
/datum/client_preference/mob_tooltips
|
||||
description ="Mob tooltips"
|
||||
@@ -128,6 +128,12 @@ var/list/_client_preferences_by_type
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/precision_placement
|
||||
description ="Precision Placement"
|
||||
key = "PRECISE_PLACEMENT"
|
||||
enabled_description = "Active"
|
||||
disabled_description = "Inactive"
|
||||
|
||||
/datum/client_preference/hotkeys_default
|
||||
description ="Hotkeys Default"
|
||||
key = "HUD_HOTKEYS"
|
||||
|
||||
@@ -257,12 +257,12 @@ var/list/gear_datums = list()
|
||||
|
||||
/datum/gear/proc/spawn_item(var/location, var/metadata)
|
||||
var/datum/gear_data/gd = new(path, location)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
if(gear_tweaks.len)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_gear_data(metadata["[gt]"], gd)
|
||||
var/item = new gd.path(gd.location)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
if(gear_tweaks.len)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_item(item, metadata["[gt]"])
|
||||
var/mob/M = location
|
||||
if(istype(M) && exploitable) //Update exploitable info records for the mob without creating a duplicate object at their feet.
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
|
||||
/datum/gear/uniform/dept/undercoat/mining
|
||||
display_name = "mining undercoat (Teshari)"
|
||||
path = /obj/item/clothing/accessory/poncho/roles/cloak/mining
|
||||
path = /obj/item/clothing/under/seromi/undercoat/jobs/mining
|
||||
allowed_roles = list("Quartermaster","Shaft Miner")
|
||||
|
||||
/datum/gear/uniform/dept/undercoat/security
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
if((pref.job_civilian_low & ASSISTANT) && job.type != /datum/job/assistant)
|
||||
. += "<font color=grey>[rank]</font></a></td><td></td></tr>"
|
||||
continue
|
||||
if((rank in command_positions) || (rank == "AI"))//Bold head jobs
|
||||
if((rank in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND) ) || (rank == "AI"))//Bold head jobs
|
||||
. += "<b>[rank]</b></a>"
|
||||
else
|
||||
. += "[rank]</a>"
|
||||
|
||||
@@ -89,6 +89,21 @@
|
||||
|
||||
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_precision_placement()
|
||||
set name = "Enable/Disable Precision Placement"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles precise placement of objects on tables."
|
||||
|
||||
var/pref_path = /datum/client_preference/precision_placement
|
||||
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] place items where your cursor is on the table.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TPIP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_typing()
|
||||
set name = "Show/Hide Typing Indicator"
|
||||
set category = "Preferences"
|
||||
@@ -209,20 +224,20 @@
|
||||
|
||||
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_air_pump_hum()
|
||||
set name = "Toggle Air Pump Noise"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles Air Pumps humming"
|
||||
/client/verb/toggle_air_pump_hum()
|
||||
set name = "Toggle Air Pump Noise"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles Air Pumps humming"
|
||||
|
||||
var/pref_path = /datum/client_preference/air_pump_noise
|
||||
var/pref_path = /datum/client_preference/air_pump_noise
|
||||
|
||||
toggle_preference(pref_path)
|
||||
toggle_preference(pref_path)
|
||||
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear air pumps hum, start, and stop.")
|
||||
to_chat(src, "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear air pumps hum, start, and stop.")
|
||||
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
SScharacter_setup.queue_preferences_save(prefs)
|
||||
|
||||
feedback_add_details("admin_verb","TAirPumpNoise")
|
||||
feedback_add_details("admin_verb","TAirPumpNoise")
|
||||
|
||||
/client/verb/toggle_safe_firing()
|
||||
set name = "Toggle Gun Firing Intent Requirement"
|
||||
|
||||
@@ -214,6 +214,18 @@
|
||||
var/mob/M = src.loc
|
||||
M.update_inv_back()
|
||||
|
||||
/obj/item/weapon/storage/backpack/chameleon/full
|
||||
starts_with = list(
|
||||
/obj/item/clothing/under/chameleon,
|
||||
/obj/item/clothing/head/chameleon,
|
||||
/obj/item/clothing/suit/chameleon,
|
||||
/obj/item/clothing/shoes/chameleon,
|
||||
/obj/item/clothing/gloves/chameleon,
|
||||
/obj/item/clothing/mask/chameleon,
|
||||
/obj/item/clothing/glasses/chameleon,
|
||||
/obj/item/clothing/accessory/chameleon
|
||||
)
|
||||
|
||||
//********************
|
||||
//**Chameleon Gloves**
|
||||
//********************
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
/obj/item/clothing/head/helmet/space/verb/toggle_camera()
|
||||
set name = "Toggle Helmet Camera"
|
||||
set desc = "Turn your helmet's camera on or off."
|
||||
set category = "Object"
|
||||
set category = "Hardsuit"
|
||||
set src in usr
|
||||
if(usr.stat || usr.restrained() || usr.incapacitated())
|
||||
return
|
||||
|
||||
@@ -205,15 +205,15 @@
|
||||
/obj/item/clothing/accessory/armor/armguards/laserproof
|
||||
name = "ablative arm guards"
|
||||
desc = "These arm guards will protect your arms from energy weapons."
|
||||
icon_state = "armguards_laser"
|
||||
icon_state = "armguards_ablative"
|
||||
item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat")
|
||||
siemens_coefficient = 0.4 //This is worse than the other ablative pieces, to avoid this from becoming the poor warden's insulated gloves.
|
||||
siemens_coefficient = 0.1 //These don't cover the hands, so the siemens doesn't need to be worse than normal ablative.
|
||||
armor = list(melee = 10, bullet = 10, laser = 80, energy = 50, bomb = 0, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/accessory/armor/armguards/bulletproof
|
||||
name = "bullet resistant arm guards"
|
||||
desc = "These arm guards will protect your arms from ballistic weapons."
|
||||
icon_state = "armguards_bullet"
|
||||
icon_state = "armguards_ballistic"
|
||||
item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat")
|
||||
siemens_coefficient = 0.7
|
||||
armor = list(melee = 10, bullet = 80, laser = 10, energy = 50, bomb = 0, bio = 0, rad = 0)
|
||||
@@ -264,7 +264,7 @@
|
||||
/obj/item/clothing/accessory/armor/legguards/laserproof
|
||||
name = "ablative leg guards"
|
||||
desc = "These will protect your legs from energy weapons."
|
||||
icon_state = "legguards_laser"
|
||||
icon_state = "legguards_ablative"
|
||||
item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots")
|
||||
siemens_coefficient = 0.1
|
||||
armor = list(melee = 10, bullet = 10, laser = 80, energy = 50, bomb = 0, bio = 0, rad = 0)
|
||||
@@ -272,7 +272,7 @@
|
||||
/obj/item/clothing/accessory/armor/legguards/bulletproof
|
||||
name = "bullet resistant leg guards"
|
||||
desc = "These will protect your legs from ballistic weapons."
|
||||
icon_state = "legguards_bullet"
|
||||
icon_state = "legguards_ballistic"
|
||||
item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots")
|
||||
siemens_coefficient = 0.7
|
||||
armor = list(melee = 10, bullet = 80, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0)
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
slot = ACCESSORY_SLOT_TORSO //Legacy/balance purposes
|
||||
concealed_holster = 1
|
||||
var/obj/item/holstered = null
|
||||
var/holster_in = 'sound/items/holsterin.ogg'
|
||||
var/holster_out = 'sound/items/holsterout.ogg'
|
||||
|
||||
/obj/item/clothing/accessory/holster/proc/holster(var/obj/item/I, var/mob/living/user)
|
||||
if(holstered && istype(user))
|
||||
@@ -15,6 +17,9 @@
|
||||
to_chat(user, "<span class='warning'>[I] won't fit in [src]!</span>")
|
||||
return
|
||||
|
||||
if(holster_in)
|
||||
playsound(get_turf(src), holster_in, 50)
|
||||
|
||||
if(istype(user))
|
||||
user.stop_aiming(no_message=1)
|
||||
holstered = I
|
||||
@@ -36,7 +41,9 @@
|
||||
if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj))
|
||||
to_chat(user, "<span class='warning'>You need an empty hand to draw \the [holstered]!</span>")
|
||||
else
|
||||
var/sound_vol = 25
|
||||
if(user.a_intent == I_HURT)
|
||||
sound_vol = 50
|
||||
usr.visible_message(
|
||||
"<span class='danger'>[user] draws \the [holstered], ready to shoot!</span>",
|
||||
"<span class='warning'>You draw \the [holstered], ready to shoot!</span>"
|
||||
@@ -46,6 +53,10 @@
|
||||
"<span class='notice'>[user] draws \the [holstered], pointing it at the ground.</span>",
|
||||
"<span class='notice'>You draw \the [holstered], pointing it at the ground.</span>"
|
||||
)
|
||||
|
||||
if(holster_out)
|
||||
playsound(get_turf(src), holster_out, sound_vol)
|
||||
|
||||
user.put_in_hands(holstered)
|
||||
holstered.add_fingerprint(user)
|
||||
w_class = initial(w_class)
|
||||
|
||||
@@ -206,16 +206,16 @@ var/list/event_last_fired = list()
|
||||
else if(istype(R.module, /obj/item/weapon/robot_module/robot/research))
|
||||
active_with_role["Scientist"]++
|
||||
|
||||
if(M.mind.assigned_role in engineering_positions)
|
||||
if(M.mind.assigned_role in SSjob.get_job_titles_in_department(DEPARTMENT_ENGINEERING))
|
||||
active_with_role["Engineer"]++
|
||||
|
||||
if(M.mind.assigned_role in medical_positions)
|
||||
if(M.mind.assigned_role in SSjob.get_job_titles_in_department(DEPARTMENT_MEDICAL))
|
||||
active_with_role["Medical"]++
|
||||
|
||||
if(M.mind.assigned_role in security_positions)
|
||||
if(M.mind.assigned_role in SSjob.get_job_titles_in_department(DEPARTMENT_SECURITY))
|
||||
active_with_role["Security"]++
|
||||
|
||||
if(M.mind.assigned_role in science_positions)
|
||||
if(M.mind.assigned_role in SSjob.get_job_titles_in_department(DEPARTMENT_RESEARCH))
|
||||
active_with_role["Scientist"]++
|
||||
|
||||
if(M.mind.assigned_role == "AI")
|
||||
|
||||
@@ -647,6 +647,10 @@ Drinks Data
|
||||
glass_icon_state = "appleade"
|
||||
glass_center_of_mass = list("x"=16, "y"=8)
|
||||
|
||||
/datum/reagent/drink/mintapplesparkle
|
||||
glass_icon_state = "mintapplesparkle"
|
||||
glass_center_of_mass = list("x"=16, "y"=8)
|
||||
|
||||
/datum/reagent/drink/soda/pineappleade
|
||||
glass_icon_state = "pineappleade"
|
||||
glass_center_of_mass = list("x"=16, "y"=8)
|
||||
|
||||
@@ -510,6 +510,25 @@
|
||||
src.name = "Frosted Jelly Donut"
|
||||
reagents.add_reagent("sprinkles", 2)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/poisonberry
|
||||
name = "Jelly Donut"
|
||||
desc = "You jelly?"
|
||||
icon_state = "jdonut1"
|
||||
filling_color = "#ED1169"
|
||||
center_of_mass = list("x"=16, "y"=11)
|
||||
nutriment_amt = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/poisonberry/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("sprinkles", 1)
|
||||
reagents.add_reagent("poisonberryjuice", 5)
|
||||
bitesize = 5
|
||||
if(prob(30))
|
||||
src.icon_state = "jdonut2"
|
||||
src.overlay_state = "box-donut2"
|
||||
src.name = "Frosted Jelly Donut"
|
||||
reagents.add_reagent("sprinkles", 2)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly
|
||||
name = "Jelly Donut"
|
||||
desc = "You jelly?"
|
||||
@@ -1105,9 +1124,16 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("berryjuice", 5)
|
||||
bitesize = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/berry/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("berryjuice", 5)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/poison/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("poisonberryjuice", 5)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/waffles
|
||||
name = "waffles"
|
||||
desc = "Mmm, waffles"
|
||||
@@ -1629,7 +1655,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/slimesoup
|
||||
name = "slime soup"
|
||||
desc = "If no water is available, you may substitute tears."
|
||||
icon_state = "slimesoup" //nonexistant?
|
||||
icon_state = "rorosoup" //nonexistant? - 3/1/2020 FIXED. roro's live on.
|
||||
filling_color = "#C4DBA0"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/slimesoup/Initialize()
|
||||
@@ -3888,13 +3914,21 @@
|
||||
filling_color = "#E0CF9B"
|
||||
center_of_mass = list("x"=17, "y"=4)
|
||||
nutriment_amt = 6
|
||||
nutriment_desc = list("sweetness" = 2, "muffin" = 2, "berries" = 2)
|
||||
nutriment_desc = list("sweetness" = 2, "muffin" = 2)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/berrymuffin/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("nutriment", 6)
|
||||
bitesize = 2
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/berrymuffin/berry/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("berryjuice", 3)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/berrymuffin/poison/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("poisonberryjuice", 3)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ghostmuffin
|
||||
name = "booberry muffin"
|
||||
desc = "My stomach is a graveyard! No living being can quench my bloodthirst!"
|
||||
@@ -3909,6 +3943,16 @@
|
||||
reagents.add_reagent("nutriment", 6)
|
||||
bitesize = 2
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/berry/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("berryjuice", 3)
|
||||
bitesize = 2
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/poison/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("poisonberryjuice", 3)
|
||||
bitesize = 2
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/eggroll
|
||||
name = "egg roll"
|
||||
desc = "Free with orders over 10 thalers."
|
||||
|
||||
@@ -274,6 +274,6 @@
|
||||
qdel(W)
|
||||
stage++
|
||||
desc = desclist2[stage]
|
||||
icon_state = "chaoscake_stage-[stage]"
|
||||
icon_state = "chaoscake_unfinished-[stage]"
|
||||
else
|
||||
to_chat(user, "Hmm, doesnt seem like this layer is supposed to be added there?")
|
||||
|
||||
@@ -55,6 +55,13 @@ I said no!
|
||||
)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/donut/jelly
|
||||
|
||||
/datum/recipe/microwave/jellydonut/poisonberry
|
||||
reagents = list("poisonberryjuice" = 5, "sugar" = 5)
|
||||
items = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/dough
|
||||
)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/donut/poisonberry
|
||||
|
||||
/datum/recipe/microwave/jellydonut/slime
|
||||
reagents = list("slimejelly" = 5, "sugar" = 5)
|
||||
items = list(
|
||||
@@ -308,7 +315,14 @@ I said no!
|
||||
items = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough,
|
||||
)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/berryclafoutis
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/berry
|
||||
|
||||
/datum/recipe/microwave/poisonberryclafoutis
|
||||
fruit = list("poisonberries" = 1)
|
||||
items = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough,
|
||||
)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/poison
|
||||
|
||||
/datum/recipe/microwave/wingfangchu
|
||||
reagents = list("soysauce" = 5)
|
||||
@@ -639,7 +653,7 @@ I said no!
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/toastedsandwich
|
||||
|
||||
/datum/recipe/microwave/peanutbutterjellysandwich
|
||||
reagents = list("berryjuice" = 5, "peanutbutter" = 5)
|
||||
reagents = list("cherryjelly" = 5, "peanutbutter" = 5)
|
||||
items = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/slice/bread
|
||||
@@ -1106,7 +1120,15 @@ I said no!
|
||||
/obj/item/weapon/reagent_containers/food/snacks/dough
|
||||
)
|
||||
fruit = list("berries" = 1)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/berrymuffin
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/berrymuffin/berry
|
||||
|
||||
/datum/recipe/microwave/poisonberrymuffin
|
||||
reagents = list("milk" = 5, "sugar" = 5)
|
||||
items = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/dough
|
||||
)
|
||||
fruit = list("poisonberries" = 1)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/berrymuffin/poison
|
||||
|
||||
/datum/recipe/microwave/ghostmuffin
|
||||
reagents = list("milk" = 5, "sugar" = 5)
|
||||
@@ -1115,7 +1137,16 @@ I said no!
|
||||
/obj/item/weapon/ectoplasm
|
||||
)
|
||||
fruit = list("berries" = 1)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/ghostmuffin
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/berry
|
||||
|
||||
/datum/recipe/microwave/poisonghostmuffin
|
||||
reagents = list("milk" = 5, "sugar" = 5)
|
||||
items = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/dough,
|
||||
/obj/item/weapon/ectoplasm
|
||||
)
|
||||
fruit = list("poisonberries" = 1)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/poison
|
||||
|
||||
/datum/recipe/microwave/eggroll
|
||||
reagents = list("soysauce" = 10)
|
||||
@@ -1201,7 +1232,7 @@ I said no!
|
||||
|
||||
/datum/recipe/microwave/piginblanket
|
||||
items = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/doughslice,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sausage
|
||||
)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/piginblanket
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/atmos_leak
|
||||
name = "atmospherics leak"
|
||||
departments = list(ROLE_ENGINEERING, ROLE_SYNTHETIC)
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_SYNTHETIC)
|
||||
var/area/target_area // Chosen target area
|
||||
var/area/target_turf // Chosen target turf in target_area
|
||||
var/gas_type // Chosen gas to release
|
||||
@@ -74,4 +74,4 @@
|
||||
playsound(target_turf, 'sound/effects/smoke.ogg', 50, 1)
|
||||
|
||||
/datum/gm_action/atmos_leak/get_weight()
|
||||
return 15 + (metric.count_people_in_department(ROLE_ENGINEERING) * 10 + metric.count_people_in_department(ROLE_SYNTHETIC) * 30) // Synthetics are counted in higher value because they can wirelessly connect to alarms.
|
||||
return 15 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 10 + metric.count_people_in_department(DEPARTMENT_SYNTHETIC) * 30) // Synthetics are counted in higher value because they can wirelessly connect to alarms.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/blob
|
||||
name = "blob infestation"
|
||||
departments = list(ROLE_ENGINEERING, ROLE_SECURITY, ROLE_MEDICAL)
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_SECURITY, DEPARTMENT_MEDICAL)
|
||||
chaotic = 25
|
||||
|
||||
var/list/area/excluded = list(
|
||||
@@ -62,9 +62,9 @@
|
||||
command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
|
||||
|
||||
/datum/gm_action/blob/get_weight()
|
||||
var/engineers = metric.count_people_in_department(ROLE_ENGINEERING)
|
||||
var/security = metric.count_people_in_department(ROLE_SECURITY)
|
||||
var/medical = metric.count_people_in_department(ROLE_MEDICAL)
|
||||
var/engineers = metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
var/security = metric.count_people_in_department(DEPARTMENT_SECURITY)
|
||||
var/medical = metric.count_people_in_department(DEPARTMENT_MEDICAL)
|
||||
|
||||
var/assigned_staff = engineers + security
|
||||
if(engineers || security) // Medical only counts if one of the other two exists, and even then they count as half.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/gm_action/brand_intelligence
|
||||
name = "rampant vending machines"
|
||||
length = 30 MINUTES
|
||||
departments = list(ROLE_ENGINEERING, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_EVERYONE)
|
||||
|
||||
var/list/obj/machinery/vending/vendingMachines = list()
|
||||
var/list/obj/machinery/vending/infectedVendingMachines = list()
|
||||
@@ -66,4 +66,4 @@
|
||||
infectedMachine.shoot_inventory = 0
|
||||
|
||||
/datum/gm_action/brand_intelligence/get_weight()
|
||||
return 60 + (metric.count_people_in_department(ROLE_ENGINEERING) * 20)
|
||||
return 60 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 20)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/gm_action/camera_damage
|
||||
name = "random camera damage"
|
||||
reusable = TRUE
|
||||
departments = list(ROLE_SYNTHETIC, ROLE_ENGINEERING)
|
||||
departments = list(DEPARTMENT_SYNTHETIC, DEPARTMENT_ENGINEERING)
|
||||
|
||||
/datum/gm_action/camera_damage/start()
|
||||
var/obj/machinery/camera/C = acquire_random_camera()
|
||||
@@ -49,4 +49,4 @@
|
||||
return T && C.can_use() && istype(C.loc, /turf) && (T.z in using_map.player_levels)
|
||||
|
||||
/datum/gm_action/camera_damage/get_weight()
|
||||
return 40 + (metric.count_people_in_department(ROLE_ENGINEERING) * 20) + (metric.count_people_in_department(ROLE_SYNTHETIC) * 40)
|
||||
return 40 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 20) + (metric.count_people_in_department(DEPARTMENT_SYNTHETIC) * 40)
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
/datum/gm_action/canister_leak
|
||||
name = "Canister Leak"
|
||||
departments = list(ROLE_ENGINEERING)
|
||||
departments = list(DEPARTMENT_ENGINEERING)
|
||||
chaotic = 20
|
||||
|
||||
/datum/gm_action/canister_leak/get_weight()
|
||||
return metric.count_people_in_department(ROLE_ENGINEERING) * 30
|
||||
return metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 30
|
||||
|
||||
/datum/gm_action/canister_leak/start()
|
||||
..()
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
//carp_migration
|
||||
/datum/gm_action/carp_migration
|
||||
name = "carp migration"
|
||||
departments = list(ROLE_SECURITY, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_EVERYONE)
|
||||
chaotic = 50
|
||||
var/list/spawned_carp = list()
|
||||
var/carp_amount = 0
|
||||
length = 20 MINUTES
|
||||
|
||||
/datum/gm_action/carp_migration/get_weight()
|
||||
return 50 + (metric.count_people_in_department(ROLE_SECURITY) * 10) + (metric.count_all_space_mobs() * 20)
|
||||
return 50 + (metric.count_people_in_department(DEPARTMENT_SECURITY) * 10) + (metric.count_all_space_mobs() * 20)
|
||||
|
||||
/datum/gm_action/carp_migration/announce()
|
||||
var/announcement = "Unknown biological entities have been detected near [station_name()], please stand-by."
|
||||
@@ -17,12 +17,12 @@
|
||||
/datum/gm_action/carp_migration/set_up()
|
||||
// Higher filled roles means more groups of fish.
|
||||
var/station_strength = 0
|
||||
station_strength += (metric.count_people_in_department(ROLE_SECURITY) * 3)
|
||||
station_strength += (metric.count_people_in_department(ROLE_ENGINEERING) * 2)
|
||||
station_strength += metric.count_people_in_department(ROLE_MEDICAL)
|
||||
station_strength += (metric.count_people_in_department(DEPARTMENT_SECURITY) * 3)
|
||||
station_strength += (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 2)
|
||||
station_strength += metric.count_people_in_department(DEPARTMENT_MEDICAL)
|
||||
|
||||
// Less active emergency response departments tones the event down.
|
||||
var/activeness = ((metric.assess_department(ROLE_SECURITY) + metric.assess_department(ROLE_ENGINEERING) + metric.assess_department(ROLE_MEDICAL)) / 3)
|
||||
var/activeness = ((metric.assess_department(DEPARTMENT_SECURITY) + metric.assess_department(DEPARTMENT_ENGINEERING) + metric.assess_department(DEPARTMENT_MEDICAL)) / 3)
|
||||
activeness = max(activeness, 20)
|
||||
|
||||
carp_amount = CEILING(station_strength * (activeness / 100) + 1, 1)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/datum/gm_action/comms_blackout
|
||||
name = "communications blackout"
|
||||
departments = list(ROLE_ENGINEERING, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_EVERYONE)
|
||||
chaotic = 35
|
||||
|
||||
/datum/gm_action/comms_blackout/get_weight()
|
||||
return 50 + (metric.count_people_in_department(ROLE_ENGINEERING) * 40)
|
||||
return 50 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 40)
|
||||
|
||||
/datum/gm_action/comms_blackout/announce()
|
||||
if(prob(33))
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/datum/gm_action/security_drill
|
||||
name = "security drills"
|
||||
departments = list(ROLE_SECURITY, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_EVERYONE)
|
||||
|
||||
/datum/gm_action/security_drill/announce()
|
||||
spawn(rand(1 MINUTE, 2 MINUTES))
|
||||
command_announcement.Announce("[pick("A NanoTrasen security director", "A Vir-Gov correspondant", "Local Sif authoritiy")] has advised the enactment of [pick("a rampant wildlife", "a fire", "a hostile boarding", "a nonstandard", "a bomb", "an emergent intelligence")] drill with the personnel onboard \the [station_name()].", "Security Advisement")
|
||||
|
||||
/datum/gm_action/security_drill/get_weight()
|
||||
return max(-20, 10 + gm.staleness - (gm.danger * 2)) + (metric.count_people_in_department(ROLE_SECURITY) * 5) + (metric.count_people_in_department(ROLE_EVERYONE) * 1.5)
|
||||
return max(-20, 10 + gm.staleness - (gm.danger * 2)) + (metric.count_people_in_department(DEPARTMENT_SECURITY) * 5) + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 1.5)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/dust
|
||||
name = "dust"
|
||||
departments = list(ROLE_ENGINEERING)
|
||||
departments = list(DEPARTMENT_ENGINEERING)
|
||||
chaotic = 10
|
||||
reusable = TRUE
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
command_announcement.Announce("Debris resulting from activity on another nearby asteroid is approaching your colony.", "Dust Alert")
|
||||
|
||||
/datum/gm_action/dust/get_weight()
|
||||
var/engineers = metric.count_people_in_department(ROLE_ENGINEERING)
|
||||
var/engineers = metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
var/weight = 30 + (engineers * 25)
|
||||
return weight
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/electrical_storm
|
||||
name = "electrical storm"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
reusable = TRUE
|
||||
var/lightsoutAmount = 1
|
||||
var/lightsoutRange = 25
|
||||
@@ -30,4 +30,4 @@
|
||||
apc.overload_lighting()
|
||||
|
||||
/datum/gm_action/electrical_storm/get_weight()
|
||||
return 30 + (metric.count_people_in_department(ROLE_ENGINEERING) * 15) + (metric.count_people_in_department(ROLE_EVERYONE) * 5)
|
||||
return 30 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 15) + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 5)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/electrified_door
|
||||
name = "airlock short-circuit"
|
||||
departments = list(ROLE_ENGINEERING, ROLE_MEDICAL)
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_MEDICAL)
|
||||
chaotic = 10
|
||||
var/obj/machinery/door/airlock/chosen_door
|
||||
var/area/target_area
|
||||
@@ -72,4 +72,4 @@
|
||||
chosen_door.update_icon()
|
||||
|
||||
/datum/gm_action/electrified_door/get_weight()
|
||||
return 10 + (metric.count_people_in_department(ROLE_ENGINEERING) * 5 + metric.count_people_in_department(ROLE_MEDICAL) * 10)
|
||||
return 10 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 5 + metric.count_people_in_department(DEPARTMENT_MEDICAL) * 10)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/gravity
|
||||
name = "gravity failure"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
length = 600
|
||||
var/list/zLevels
|
||||
|
||||
@@ -33,4 +33,4 @@
|
||||
command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.", "Gravity Restored")
|
||||
|
||||
/datum/gm_action/gravity/get_weight()
|
||||
return 30 + (metric.count_people_in_department(ROLE_EVERYONE) * 20)
|
||||
return 30 + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 20)
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
/datum/gm_action/grid_check
|
||||
name = "grid check"
|
||||
departments = list(ROLE_ENGINEERING, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_EVERYONE)
|
||||
chaotic = 20
|
||||
|
||||
/datum/gm_action/grid_check/get_weight()
|
||||
return 50 + (metric.count_people_in_department(ROLE_ENGINEERING) * 30)
|
||||
return 50 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 30)
|
||||
|
||||
/datum/gm_action/grid_check/start()
|
||||
..()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/datum/gm_action/infestation
|
||||
name = "animal infestation"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
var/location
|
||||
var/locstring
|
||||
var/vermin
|
||||
@@ -100,7 +100,7 @@
|
||||
command_announcement.Announce("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Vermin infestation")
|
||||
|
||||
/datum/gm_action/infestation/get_weight()
|
||||
return 5 + (metric.count_people_in_department(ROLE_EVERYONE) * 20)
|
||||
return 5 + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 20)
|
||||
|
||||
#undef LOC_KITCHEN
|
||||
#undef LOC_ATMOS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/ionstorm
|
||||
name = "ion storm"
|
||||
departments = list(ROLE_SYNTHETIC)
|
||||
departments = list(DEPARTMENT_SYNTHETIC)
|
||||
var/botEmagChance = 0.5
|
||||
var/list/players = list()
|
||||
var/active = FALSE
|
||||
@@ -45,6 +45,6 @@
|
||||
ion_storm_announcement()
|
||||
|
||||
/datum/gm_action/ionstorm/get_weight()
|
||||
var/bots = metric.count_people_in_department(ROLE_SYNTHETIC)
|
||||
var/bots = metric.count_people_in_department(DEPARTMENT_SYNTHETIC)
|
||||
var/weight = 5 + (bots * 20)
|
||||
return weight
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/gm_action/manifest_malfunction
|
||||
name = "manifest malfunction"
|
||||
enabled = TRUE
|
||||
departments = list(ROLE_SECURITY, ROLE_SYNTHETIC, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_SYNTHETIC, DEPARTMENT_EVERYONE)
|
||||
chaotic = 3
|
||||
reusable = FALSE
|
||||
length = 0
|
||||
@@ -21,10 +21,10 @@
|
||||
/datum/gm_action/manifest_malfunction/get_weight()
|
||||
. = -10
|
||||
|
||||
var/security = metric.count_people_in_department(ROLE_SECURITY)
|
||||
var/security = metric.count_people_in_department(DEPARTMENT_SECURITY)
|
||||
|
||||
if(security && data_core)
|
||||
. += (metric.count_people_in_department(ROLE_EVERYONE) * 5) - (metric.count_people_in_department(ROLE_SYNTHETIC) * 5)
|
||||
. += (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 5) - (metric.count_people_in_department(DEPARTMENT_SYNTHETIC) * 5)
|
||||
|
||||
return .
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/datum/gm_action/meteor_defense
|
||||
name = "meteor defense"
|
||||
departments = list(ROLE_ENGINEERING, ROLE_CARGO)
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_CARGO)
|
||||
chaotic = 50
|
||||
var/direction = null
|
||||
var/dir_text = null
|
||||
@@ -11,9 +11,9 @@
|
||||
var/meteor_types
|
||||
|
||||
/datum/gm_action/meteor_defense/get_weight()
|
||||
var/engineers = metric.count_people_in_department(ROLE_ENGINEERING)
|
||||
var/cargo = metric.count_people_in_department(ROLE_CARGO)
|
||||
var/bots = metric.count_people_in_department(ROLE_SYNTHETIC)
|
||||
var/engineers = metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
var/cargo = metric.count_people_in_department(DEPARTMENT_CARGO)
|
||||
var/bots = metric.count_people_in_department(DEPARTMENT_SYNTHETIC)
|
||||
var/weight = (max(engineers - 1, 0) * 20) // If only one engineer exists, no meteors for now.
|
||||
|
||||
if(engineers >= 2)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/datum/gm_action/money_hacker
|
||||
name = "bank account hacker"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
reusable = TRUE
|
||||
var/datum/money_account/affected_account
|
||||
var/active
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/money_lotto
|
||||
name = "lottery win"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
var/winner_name = "John Smith"
|
||||
var/winner_sum = 0
|
||||
var/deposit_success = 0
|
||||
@@ -36,4 +36,4 @@
|
||||
news_network.SubmitArticle(body, author, channel, null, 1)
|
||||
|
||||
/datum/gm_action/money_lotto/get_weight()
|
||||
return 25 * metric.count_people_in_department(ROLE_EVERYONE)
|
||||
return 25 * metric.count_people_in_department(DEPARTMENT_EVERYONE)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/pda_spam
|
||||
name = "PDA spam"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
reusable = TRUE
|
||||
var/last_spam_time = 0
|
||||
var/obj/machinery/message_server/useMS
|
||||
@@ -126,4 +126,4 @@
|
||||
to_chat(L, "\icon[P] <b>Message from [sender] (Unknown / spam?), </b>\"[message]\" (Unable to Reply)")
|
||||
|
||||
/datum/gm_action/pda_spam/get_weight()
|
||||
return 25 * metric.count_people_in_department(ROLE_EVERYONE)
|
||||
return 25 * metric.count_people_in_department(DEPARTMENT_EVERYONE)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/gm_action/planet_weather_shift
|
||||
name = "sudden weather shift"
|
||||
enabled = TRUE
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
reusable = TRUE
|
||||
var/datum/planet/target_planet
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/prison_break
|
||||
name = "prison break"
|
||||
departments = list(ROLE_SECURITY, ROLE_SYNTHETIC)
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_SYNTHETIC)
|
||||
|
||||
var/start_time = 0
|
||||
var/active = FALSE // Are we doing stuff?
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/datum/gm_action/prison_break/get_weight()
|
||||
var/afflicted_staff = 0
|
||||
var/assigned_staff = metric.count_people_in_department(ROLE_ENGINEERING)
|
||||
var/assigned_staff = metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
for(var/department in departments)
|
||||
afflicted_staff += round(metric.count_people_in_department(department) / 2)
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
|
||||
/datum/gm_action/prison_break/virology
|
||||
name = "virology breakout"
|
||||
departments = list(ROLE_MEDICAL, ROLE_SYNTHETIC)
|
||||
departments = list(DEPARTMENT_MEDICAL, DEPARTMENT_SYNTHETIC)
|
||||
eventDept = "Medical"
|
||||
areaName = list("Virology")
|
||||
areaType = list(/area/medical/virology, /area/medical/virologyaccess)
|
||||
|
||||
/datum/gm_action/prison_break/xenobiology
|
||||
name = "xenobiology breakout"
|
||||
departments = list(ROLE_RESEARCH, ROLE_SYNTHETIC)
|
||||
departments = list(DEPARTMENT_RESEARCH, DEPARTMENT_SYNTHETIC)
|
||||
eventDept = "Science"
|
||||
areaName = list("Xenobiology")
|
||||
areaType = list(/area/rnd/xenobiology)
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
/datum/gm_action/prison_break/station
|
||||
name = "station-wide breakout"
|
||||
departments = list(ROLE_SECURITY, ROLE_MEDICAL, ROLE_RESEARCH, ROLE_SYNTHETIC)
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_MEDICAL, DEPARTMENT_RESEARCH, DEPARTMENT_SYNTHETIC)
|
||||
eventDept = "Station"
|
||||
areaName = list("Brig","Virology","Xenobiology")
|
||||
areaType = list(/area/security/prison, /area/security/brig, /area/medical/virology, /area/medical/virologyaccess, /area/rnd/xenobiology)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/radiation_storm
|
||||
name = "radiation storm"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
reusable = TRUE
|
||||
|
||||
var/enterBelt = 30
|
||||
@@ -64,4 +64,4 @@
|
||||
revoke_maint_all_access()
|
||||
|
||||
/datum/gm_action/radiation_storm/get_weight()
|
||||
return 20 + (metric.count_people_in_department(ROLE_MEDICAL) * 10) + (metric.count_all_space_mobs() * 40) + (metric.count_people_in_department(ROLE_EVERYONE) * 20)
|
||||
return 20 + (metric.count_people_in_department(DEPARTMENT_MEDICAL) * 10) + (metric.count_all_space_mobs() * 40) + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 20)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// The random spawn proc on the antag datum will handle announcing the spawn and whatnot.
|
||||
/datum/gm_action/random_antag
|
||||
name = "random antagonist"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
chaotic = 30
|
||||
reusable = TRUE
|
||||
|
||||
@@ -19,5 +19,5 @@
|
||||
/datum/gm_action/random_antag/get_weight()
|
||||
. = ..()
|
||||
if(gm)
|
||||
var/weight = max(0, (metric.count_people_in_department(ROLE_SECURITY) * 20) + (metric.count_people_in_department(ROLE_EVERYONE) * 5) + gm.staleness)
|
||||
var/weight = max(0, (metric.count_people_in_department(DEPARTMENT_SECURITY) * 20) + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 5) + gm.staleness)
|
||||
return weight
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/rogue_drone
|
||||
name = "rogue drones"
|
||||
departments = list(ROLE_SECURITY)
|
||||
departments = list(DEPARTMENT_SECURITY)
|
||||
chaotic = 60
|
||||
length = 20 MINUTES
|
||||
var/list/drones_list = list()
|
||||
@@ -60,4 +60,4 @@
|
||||
command_announcement.Announce("We're disappointed at the loss of the drones, but the survivors have been recovered.", "Rogue drone alert")
|
||||
|
||||
/datum/gm_action/rogue_drone/get_weight()
|
||||
return 20 + (metric.count_people_in_department(ROLE_SECURITY) * 10) + (metric.count_all_space_mobs() * 30)
|
||||
return 20 + (metric.count_people_in_department(DEPARTMENT_SECURITY) * 10) + (metric.count_all_space_mobs() * 30)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/security_screening
|
||||
name = "security screening"
|
||||
departments = list(ROLE_SECURITY, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_EVERYONE)
|
||||
|
||||
var/list/species_weights = list(
|
||||
SPECIES_SKRELL = 9,
|
||||
@@ -46,4 +46,4 @@
|
||||
command_announcement.Announce("[pick("A nearby Navy vessel", "A Solar official", "A Vir-Gov official", "A NanoTrasen board director")] has requested the screening of [pick("every other", "every", "suspicious", "willing")] [pickweight(end_weights)] personnel onboard \the [station_name()].", "Security Advisement")
|
||||
|
||||
/datum/gm_action/security_screening/get_weight()
|
||||
return max(-20, 10 + round(gm.staleness * 1.5) - (gm.danger * 2)) + (metric.count_people_in_department(ROLE_SECURITY) * 10) + (metric.count_people_in_department(ROLE_EVERYONE) * 1.5)
|
||||
return max(-20, 10 + round(gm.staleness * 1.5) - (gm.danger * 2)) + (metric.count_people_in_department(DEPARTMENT_SECURITY) * 10) + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 1.5)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/datum/gm_action/shipping_error
|
||||
name = "shipping error"
|
||||
departments = list(ROLE_CARGO)
|
||||
departments = list(DEPARTMENT_CARGO)
|
||||
reusable = TRUE
|
||||
|
||||
/datum/gm_action/shipping_error/get_weight()
|
||||
var/cargo = metric.count_people_in_department(ROLE_CARGO)
|
||||
var/cargo = metric.count_people_in_department(DEPARTMENT_CARGO)
|
||||
var/weight = (cargo * 40)
|
||||
return weight
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
radiate()
|
||||
|
||||
/datum/gm_action/solar_storm/get_weight()
|
||||
return 20 + (metric.count_people_in_department(ROLE_ENGINEERING) * 10) + (metric.count_all_space_mobs() * 30)
|
||||
return 20 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 10) + (metric.count_all_space_mobs() * 30)
|
||||
|
||||
/datum/gm_action/solar_storm/proc/radiate()
|
||||
// Note: Too complicated to be worth trying to use the radiation system for this. Its only in space anyway, so we make an exception in this case.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/spacevine
|
||||
name = "space-vine infestation"
|
||||
departments = list(ROLE_ENGINEERING)
|
||||
departments = list(DEPARTMENT_ENGINEERING)
|
||||
chaotic = 2
|
||||
|
||||
/datum/gm_action/spacevine/start()
|
||||
@@ -11,4 +11,4 @@
|
||||
level_seven_announcement()
|
||||
|
||||
/datum/gm_action/spacevine/get_weight()
|
||||
return 20 + (metric.count_people_in_department(ROLE_ENGINEERING) * 20) + (metric.count_people_in_department(ROLE_EVERYONE) * 10)
|
||||
return 20 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 20) + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 10)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/spider_infestation
|
||||
name = "spider infestation"
|
||||
departments = list(ROLE_SECURITY, ROLE_MEDICAL, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_MEDICAL, DEPARTMENT_EVERYONE)
|
||||
chaotic = 30
|
||||
|
||||
severity = 1
|
||||
@@ -10,9 +10,9 @@
|
||||
var/spawntype = /obj/effect/spider/spiderling
|
||||
|
||||
/datum/gm_action/spider_infestation/set_up()
|
||||
severity = pickweight(EVENT_LEVEL_MUNDANE = max(1,(12 - (3 * metric.count_people_in_department(ROLE_SECURITY)))),
|
||||
EVENT_LEVEL_MODERATE = (7 + (2 * metric.count_people_in_department(ROLE_SECURITY))),
|
||||
EVENT_LEVEL_MAJOR = (1 + (2 * metric.count_people_in_department(ROLE_SECURITY)))
|
||||
severity = pickweight(EVENT_LEVEL_MUNDANE = max(1,(12 - (3 * metric.count_people_in_department(DEPARTMENT_SECURITY)))),
|
||||
EVENT_LEVEL_MODERATE = (7 + (2 * metric.count_people_in_department(DEPARTMENT_SECURITY))),
|
||||
EVENT_LEVEL_MAJOR = (1 + (2 * metric.count_people_in_department(DEPARTMENT_SECURITY)))
|
||||
)
|
||||
|
||||
switch(severity)
|
||||
@@ -47,9 +47,9 @@
|
||||
spawncount--
|
||||
|
||||
/datum/gm_action/spider_infestation/get_weight()
|
||||
var/security = metric.count_people_in_department(ROLE_SECURITY)
|
||||
var/medical = metric.count_people_in_department(ROLE_MEDICAL)
|
||||
var/engineering = metric.count_people_in_department(ROLE_ENGINEERING)
|
||||
var/security = metric.count_people_in_department(DEPARTMENT_SECURITY)
|
||||
var/medical = metric.count_people_in_department(DEPARTMENT_MEDICAL)
|
||||
var/engineering = metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
|
||||
var/assigned_staff = security + round(medical / 2) + round(engineering / 2)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/spontaneous_appendicitis
|
||||
name = "appendicitis"
|
||||
departments = list(ROLE_MEDICAL, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_MEDICAL, DEPARTMENT_EVERYONE)
|
||||
chaotic = 1
|
||||
|
||||
/datum/gm_action/spontaneous_appendicitis/start()
|
||||
@@ -10,4 +10,4 @@
|
||||
break
|
||||
|
||||
/datum/gm_action/spontaneous_appendicitis/get_weight()
|
||||
return max(0, -5 + (metric.count_people_in_department(ROLE_MEDICAL) * 10))
|
||||
return max(0, -5 + (metric.count_people_in_department(DEPARTMENT_MEDICAL) * 10))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/station_fund_raise
|
||||
name = "local funding drive"
|
||||
departments = list(ROLE_SECURITY, ROLE_CARGO, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_CARGO, DEPARTMENT_EVERYONE)
|
||||
|
||||
/datum/gm_action/station_fund_raise/announce()
|
||||
spawn(rand(1 MINUTE, 2 MINUTES))
|
||||
@@ -11,4 +11,4 @@
|
||||
if(station_account.money <= 80000)
|
||||
weight_modifier = 1
|
||||
|
||||
return (max(-20, 10 + gm.staleness) + ((metric.count_people_in_department(ROLE_SECURITY) + (metric.count_people_in_department(ROLE_CARGO))) * 5) + (metric.count_people_in_department(ROLE_EVERYONE) * 3)) * weight_modifier
|
||||
return (max(-20, 10 + gm.staleness) + ((metric.count_people_in_department(DEPARTMENT_SECURITY) + (metric.count_people_in_department(DEPARTMENT_CARGO))) * 5) + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 3)) * weight_modifier
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/stowaway
|
||||
name = "stowaway pod"
|
||||
departments = list(ROLE_EVERYONE, ROLE_SECURITY)
|
||||
departments = list(DEPARTMENT_EVERYONE, DEPARTMENT_SECURITY)
|
||||
chaotic = 10
|
||||
observers_used = TRUE
|
||||
var/area/target_area // Chosen target area
|
||||
@@ -72,7 +72,7 @@
|
||||
say_dead_object("A <span class='notice'>[HP.occupant_type]</span> pod is now available in \the [target_area].", HP)
|
||||
|
||||
/datum/gm_action/stowaway/get_weight()
|
||||
return -20 + (metric.count_people_in_department(ROLE_SECURITY) * 15 + metric.count_people_in_department(ROLE_SYNTHETIC) * 5 + metric.count_people_in_department(ROLE_EVERYONE) * 1)
|
||||
return -20 + (metric.count_people_in_department(DEPARTMENT_SECURITY) * 15 + metric.count_people_in_department(DEPARTMENT_SYNTHETIC) * 5 + metric.count_people_in_department(DEPARTMENT_EVERYONE) * 1)
|
||||
|
||||
/datum/gm_action/stowaway/announce()
|
||||
spawn(rand(15 MINUTES, 30 MINUTES))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/gm_action/nanotrasen_budget_allocation
|
||||
name = "supply point to cargo budget"
|
||||
enabled = TRUE
|
||||
departments = list(ROLE_CARGO)
|
||||
departments = list(DEPARTMENT_CARGO)
|
||||
chaotic = 0
|
||||
reusable = TRUE
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/datum/gm_action/nanotrasen_budget_allocation/get_weight()
|
||||
. = round(SC.points / 15)
|
||||
|
||||
var/cargo = metric.count_people_in_department(ROLE_CARGO)
|
||||
var/personnel = metric.count_people_in_department(ROLE_EVERYONE)
|
||||
var/cargo = metric.count_people_in_department(DEPARTMENT_CARGO)
|
||||
var/personnel = metric.count_people_in_department(DEPARTMENT_EVERYONE)
|
||||
if(cargo)
|
||||
. = round(SC.points / (10 + personnel)) + cargo * 10
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/datum/gm_action/request
|
||||
name = "general request"
|
||||
departments = list(ROLE_CARGO)
|
||||
departments = list(DEPARTMENT_CARGO)
|
||||
|
||||
/datum/gm_action/request/announce()
|
||||
spawn(rand(1 MINUTE, 2 MINUTES))
|
||||
command_announcement.Announce("[pick("A nearby vessel", "A Solar contractor", "A Skrellian contractor", "A NanoTrasen board director")] has requested the delivery of [pick("one","two","three","several")] [pick("medical","engineering","research","civilian")] supply packages. The [station_name()] has been tasked with completing this request.", "Supply Request")
|
||||
|
||||
/datum/gm_action/request/get_weight()
|
||||
return max(15, 15 + round(gm.staleness / 2) - gm.danger) + (metric.count_people_in_department(ROLE_CARGO) * 10)
|
||||
return max(15, 15 + round(gm.staleness / 2) - gm.danger) + (metric.count_people_in_department(DEPARTMENT_CARGO) * 10)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/datum/gm_action/surprise_carp_attack
|
||||
name = "surprise carp attack"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
reusable = TRUE
|
||||
chaotic = 10
|
||||
var/mob/living/victim = null
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
/datum/gm_action/surprise_meteors
|
||||
name = "surprise meteors"
|
||||
departments = list(ROLE_ENGINEERING)
|
||||
departments = list(DEPARTMENT_ENGINEERING)
|
||||
chaotic = 25
|
||||
|
||||
/datum/gm_action/surprise_meteors/get_weight()
|
||||
var/engineers = metric.count_people_in_department(ROLE_ENGINEERING)
|
||||
var/engineers = metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
var/weight = (max(engineers - 1, 0) * 25) // If only one engineer exists, no meteors for now.
|
||||
return weight
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/swarm_boarder
|
||||
name = "swarmer shell"
|
||||
departments = list(ROLE_EVERYONE, ROLE_SECURITY, ROLE_ENGINEERING)
|
||||
departments = list(DEPARTMENT_EVERYONE, DEPARTMENT_SECURITY, DEPARTMENT_ENGINEERING)
|
||||
chaotic = 60
|
||||
observers_used = TRUE
|
||||
var/area/target_area // Chosen target area
|
||||
@@ -67,7 +67,7 @@
|
||||
new swarmertype(target_turf)
|
||||
|
||||
/datum/gm_action/swarm_boarder/get_weight()
|
||||
return max(0, -60 + (metric.count_people_in_department(ROLE_SECURITY) * 10 + metric.count_people_in_department(ROLE_SYNTHETIC) * 5))
|
||||
return max(0, -60 + (metric.count_people_in_department(DEPARTMENT_SECURITY) * 10 + metric.count_people_in_department(DEPARTMENT_SYNTHETIC) * 5))
|
||||
|
||||
/datum/gm_action/swarm_boarder/announce()
|
||||
spawn(rand(5 MINUTES, 15 MINUTES))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/datum/gm_action/viral_infection
|
||||
name = "viral infection"
|
||||
departments = list(ROLE_MEDICAL)
|
||||
departments = list(DEPARTMENT_MEDICAL)
|
||||
chaotic = 5
|
||||
var/list/viruses = list()
|
||||
severity = 1
|
||||
@@ -80,4 +80,4 @@
|
||||
message_admins("Virus event affecting [english_list(used_candidates_links)] started; Viruses: [english_list(used_viruses_links)]")
|
||||
|
||||
/datum/gm_action/viral_infection/get_weight()
|
||||
return (metric.count_people_in_department(ROLE_MEDICAL) * 20)
|
||||
return (metric.count_people_in_department(DEPARTMENT_MEDICAL) * 20)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/viral_outbreak
|
||||
name = "viral outbreak"
|
||||
departments = list(ROLE_MEDICAL, ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_MEDICAL, DEPARTMENT_EVERYONE)
|
||||
chaotic = 30
|
||||
severity = 1
|
||||
var/list/candidates = list()
|
||||
@@ -29,9 +29,9 @@
|
||||
severity--
|
||||
|
||||
/datum/gm_action/viral_outbreak/get_weight()
|
||||
var/medical = metric.count_people_in_department(ROLE_MEDICAL)
|
||||
var/security = metric.count_people_in_department(ROLE_SECURITY)
|
||||
var/everyone = metric.count_people_in_department(ROLE_EVERYONE)
|
||||
var/medical = metric.count_people_in_department(DEPARTMENT_MEDICAL)
|
||||
var/security = metric.count_people_in_department(DEPARTMENT_SECURITY)
|
||||
var/everyone = metric.count_people_in_department(DEPARTMENT_EVERYONE)
|
||||
|
||||
var/assigned_staff = medical + round(security / 2)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/wallrot
|
||||
name = "wall rot"
|
||||
departments = list(ROLE_ENGINEERING)
|
||||
departments = list(DEPARTMENT_ENGINEERING)
|
||||
reusable = TRUE
|
||||
var/turf/simulated/wall/center
|
||||
severity = 1
|
||||
@@ -40,4 +40,4 @@
|
||||
break
|
||||
|
||||
/datum/gm_action/wallrot/get_weight()
|
||||
return 60 + (metric.count_people_in_department(ROLE_ENGINEERING) * 35)
|
||||
return 60 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 35)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
/datum/gm_action/waste_disposal
|
||||
name = "waste disposal"
|
||||
departments = list(ROLE_CARGO)
|
||||
departments = list(DEPARTMENT_CARGO)
|
||||
chaotic = 0
|
||||
|
||||
/datum/gm_action/waste_disposal/get_weight()
|
||||
return metric.count_people_in_department(ROLE_CARGO) * 50
|
||||
return metric.count_people_in_department(DEPARTMENT_CARGO) * 50
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/gm_action/window_break
|
||||
name = "window breach"
|
||||
departments = list(ROLE_ENGINEERING)
|
||||
departments = list(DEPARTMENT_ENGINEERING)
|
||||
chaotic = 5
|
||||
var/obj/structure/window/chosen_window
|
||||
var/list/obj/structure/window/collateral_windows
|
||||
@@ -75,4 +75,4 @@
|
||||
command_announcement.Announce("Structural integrity of windows at [chosen_location.loc.name] is failing. Immediate repair or replacement is advised.", "Structural Alert")
|
||||
|
||||
/datum/gm_action/window_break/get_weight()
|
||||
return 20 * metric.count_people_in_department(ROLE_ENGINEERING)
|
||||
return 20 * metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "space-time anomalies"
|
||||
chaotic = 70
|
||||
length = 12 MINUTES
|
||||
departments = list(ROLE_EVERYONE)
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
severity = 1
|
||||
|
||||
/datum/gm_action/wormholes/set_up() // 1 out of 5 will be full-duration wormholes, meaning up to a minute long.
|
||||
@@ -17,7 +17,7 @@
|
||||
wormhole_event(length / 2, (severity / 3))
|
||||
|
||||
/datum/gm_action/wormholes/get_weight()
|
||||
return 10 + max(0, -30 + (metric.count_people_in_department(ROLE_EVERYONE) * 5) + (metric.count_people_in_department(ROLE_ENGINEERING) + 10) + (metric.count_people_in_department(ROLE_MEDICAL) * 20))
|
||||
return 10 + max(0, -30 + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 5) + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) + 10) + (metric.count_people_in_department(DEPARTMENT_MEDICAL) * 20))
|
||||
|
||||
/datum/gm_action/wormholes/end()
|
||||
command_announcement.Announce("There are no more space-time anomalies detected on the station.", "Anomaly Alert")
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
for(var/datum/gm_action/action in available_actions)
|
||||
if(!action.enabled)
|
||||
continue
|
||||
if(ROLE_EVERYONE in action.departments)
|
||||
if(DEPARTMENT_EVERYONE in action.departments)
|
||||
best_actions.Add(action)
|
||||
log_debug("[action.name] is being considered because it involves everyone.")
|
||||
|
||||
|
||||
@@ -104,3 +104,11 @@ GLOBAL_LIST_INIT(plant_item_products, list(
|
||||
/obj/item/weapon/spacecash/c1 = 3,
|
||||
/obj/item/weapon/spacecash/c10 = 1
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(forbidden_plant_growth_sprites, list(
|
||||
"gnomes"
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(forbidden_plant_product_sprites, list(
|
||||
"gnomes"
|
||||
))
|
||||
@@ -98,7 +98,7 @@
|
||||
return
|
||||
|
||||
var/datum/reagents/R = new/datum/reagents(100)
|
||||
if(chems.len)
|
||||
if(chems && chems.len)
|
||||
for(var/rid in chems)
|
||||
var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/3))
|
||||
R.add_reagent(rid,injecting)
|
||||
@@ -192,7 +192,7 @@
|
||||
if(!flesh_colour) flesh_colour = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(flesh_colour) splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
|
||||
if(chems)
|
||||
if(chems && chems.len)
|
||||
for(var/mob/living/M in T.contents)
|
||||
if(!M.reagents)
|
||||
continue
|
||||
@@ -408,8 +408,8 @@
|
||||
seed_noun = pick("spores","nodes","cuttings","seeds")
|
||||
|
||||
set_trait(TRAIT_POTENCY,rand(5,30),200,0)
|
||||
set_trait(TRAIT_PRODUCT_ICON,pick(plant_controller.plant_product_sprites))
|
||||
set_trait(TRAIT_PLANT_ICON,pick(plant_controller.plant_sprites))
|
||||
set_trait(TRAIT_PRODUCT_ICON,pick(plant_controller.accessible_product_sprites))
|
||||
set_trait(TRAIT_PLANT_ICON,pick(plant_controller.accessible_plant_sprites))
|
||||
set_trait(TRAIT_PLANT_COLOUR,"#[get_random_colour(0,75,190)]")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#[get_random_colour(0,75,190)]")
|
||||
update_growth_stages()
|
||||
@@ -454,6 +454,7 @@
|
||||
|
||||
var/list/banned_chems = list(
|
||||
"adminordrazine",
|
||||
"magicdust",
|
||||
"nutriment"
|
||||
)
|
||||
|
||||
|
||||
@@ -25,16 +25,18 @@ var/global/datum/controller/plants/plant_controller // Set in New().
|
||||
|
||||
var/plants_per_tick = PLANTS_PER_TICK
|
||||
var/plant_tick_time = PLANT_TICK_TIME
|
||||
var/list/product_descs = list() // Stores generated fruit descs.
|
||||
var/list/plant_queue = list() // All queued plants.
|
||||
var/list/seeds = list() // All seed data stored here.
|
||||
var/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness.
|
||||
var/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds.
|
||||
var/list/plant_sprites = list() // List of all harvested product sprites.
|
||||
var/list/plant_product_sprites = list() // List of all growth sprites plus number of growth stages.
|
||||
var/processing = 0 // Off/on.
|
||||
var/list/gene_masked_list = list() // Stored gene masked list, rather than recreating it when needed.
|
||||
var/list/plant_gene_datums = list() // Stored datum versions of the gene masked list.
|
||||
var/list/product_descs = list() // Stores generated fruit descs.
|
||||
var/list/plant_queue = list() // All queued plants.
|
||||
var/list/seeds = list() // All seed data stored here.
|
||||
var/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness.
|
||||
var/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds.
|
||||
var/list/plant_sprites = list() // List of all growth sprites plus number of growth stages.
|
||||
var/list/accessible_plant_sprites = list() // List of all plant sprites allowed to appear in random generation.
|
||||
var/list/plant_product_sprites = list() // List of all harvested product sprites.
|
||||
var/list/accessible_product_sprites = list() // List of all product sprites allowed to appear in random generation.
|
||||
var/processing = 0 // Off/on.
|
||||
var/list/gene_masked_list = list() // Stored gene masked list, rather than recreating it when needed.
|
||||
var/list/plant_gene_datums = list() // Stored datum versions of the gene masked list.
|
||||
|
||||
/datum/controller/plants/New()
|
||||
if(plant_controller && plant_controller != src)
|
||||
@@ -66,11 +68,16 @@ var/global/datum/controller/plants/plant_controller // Set in New().
|
||||
|
||||
if(!(plant_sprites[base]) || (plant_sprites[base]<ikey))
|
||||
plant_sprites[base] = ikey
|
||||
if(!(base in GLOB.forbidden_plant_growth_sprites))
|
||||
accessible_plant_sprites[base] = ikey
|
||||
|
||||
for(var/icostate in icon_states('icons/obj/hydroponics_products.dmi'))
|
||||
var/split = findtext(icostate,"-")
|
||||
var/base = copytext(icostate,1,split)
|
||||
if(split)
|
||||
plant_product_sprites |= copytext(icostate,1,split)
|
||||
plant_product_sprites |= base
|
||||
if(!(base in GLOB.forbidden_plant_product_sprites))
|
||||
accessible_product_sprites |= base
|
||||
|
||||
// Populate the global seed datum list.
|
||||
for(var/type in typesof(/datum/seed)-/datum/seed)
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
/datum/seed/berry/poison
|
||||
name = "poisonberries"
|
||||
seed_name = "poison berry"
|
||||
kitchen_tag = "poisonberries"
|
||||
display_name = "poison berry bush"
|
||||
mutants = list("deathberries")
|
||||
chems = list("nutriment" = list(1), "toxin" = list(3,5), "poisonberryjuice" = list(10,5))
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
new/datum/stack_recipe("blue comfy chair", /obj/structure/bed/chair/comfy/blue, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("purple comfy chair", /obj/structure/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("yellow comfy chair", /obj/structure/bed/chair/comfy/yellow, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("orange comfy chair", /obj/structure/bed/chair/comfy/orange, 2, one_per_turf = 1, on_floor = 1), \
|
||||
))
|
||||
recipes += new/datum/stack_recipe("table frame", /obj/structure/table, 1, time = 10, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("bench frame", /obj/structure/table/bench, 1, time = 10, one_per_turf = 1, on_floor = 1)
|
||||
|
||||
@@ -1112,6 +1112,28 @@ var/list/name_to_material
|
||||
protectiveness = 1 // 4%
|
||||
conductive = 0
|
||||
|
||||
/material/cloth_yellow
|
||||
name = "yellow"
|
||||
display_name = "yellow"
|
||||
use_name = "yellow cloth"
|
||||
icon_colour = "#EEF573"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
protectiveness = 1 // 4%
|
||||
conductive = 0
|
||||
|
||||
/material/cloth_orange
|
||||
name = "orange"
|
||||
display_name = "orange"
|
||||
use_name = "orange cloth"
|
||||
icon_colour = "#E3BF49"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
protectiveness = 1 // 4%
|
||||
conductive = 0
|
||||
|
||||
/material/toy_foam
|
||||
name = "foam"
|
||||
display_name = "foam"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This proc tries to find the department of an arbitrary mob.
|
||||
/datum/metric/proc/guess_department(var/mob/M)
|
||||
var/list/found_roles = list()
|
||||
. = ROLE_UNKNOWN
|
||||
. = DEPARTMENT_UNKNOWN
|
||||
|
||||
// Records are usually the most reliable way to get what job someone is.
|
||||
var/datum/data/record/R = find_general_record("name", M.real_name)
|
||||
@@ -10,7 +10,7 @@
|
||||
var/recorded_rank = R.fields["real_rank"]
|
||||
found_roles = role_name_to_department(recorded_rank)
|
||||
. = found_roles[1]
|
||||
if(. != ROLE_UNKNOWN) // We found the correct department, so we can stop now.
|
||||
if(. != DEPARTMENT_UNKNOWN) // We found the correct department, so we can stop now.
|
||||
return
|
||||
|
||||
// They have a custom title, aren't crew, or someone deleted their record, so we need a fallback method.
|
||||
@@ -18,16 +18,16 @@
|
||||
if(M.mind)
|
||||
found_roles = role_name_to_department(M.mind.assigned_role)
|
||||
. = found_roles[1]
|
||||
if(. != ROLE_UNKNOWN)
|
||||
if(. != DEPARTMENT_UNKNOWN)
|
||||
return
|
||||
|
||||
// At this point, they don't have a mind, or for some reason assigned_role didn't work.
|
||||
found_roles = role_name_to_department(M.job)
|
||||
. = found_roles[1]
|
||||
if(. != ROLE_UNKNOWN)
|
||||
if(. != DEPARTMENT_UNKNOWN)
|
||||
return
|
||||
|
||||
return ROLE_UNKNOWN // Welp.
|
||||
return DEPARTMENT_UNKNOWN // Welp.
|
||||
|
||||
// Feed this proc the name of a job, and it will try to figure out what department they are apart of.
|
||||
// Note that this returns a list, as some jobs are in more than one department, like Command. The 'primary' department is the first
|
||||
@@ -35,32 +35,32 @@
|
||||
/datum/metric/proc/role_name_to_department(var/role_name)
|
||||
var/list/result = list()
|
||||
|
||||
if(role_name in security_positions)
|
||||
result += ROLE_SECURITY
|
||||
if(SSjob.is_job_in_department(role_name, DEPARTMENT_SECURITY))
|
||||
result += DEPARTMENT_SECURITY
|
||||
|
||||
if(role_name in engineering_positions)
|
||||
result += ROLE_ENGINEERING
|
||||
if(SSjob.is_job_in_department(role_name, DEPARTMENT_ENGINEERING))
|
||||
result += DEPARTMENT_ENGINEERING
|
||||
|
||||
if(role_name in medical_positions)
|
||||
result += ROLE_MEDICAL
|
||||
if(SSjob.is_job_in_department(role_name, DEPARTMENT_MEDICAL))
|
||||
result += DEPARTMENT_MEDICAL
|
||||
|
||||
if(role_name in science_positions)
|
||||
result += ROLE_RESEARCH
|
||||
if(SSjob.is_job_in_department(role_name, DEPARTMENT_RESEARCH))
|
||||
result += DEPARTMENT_RESEARCH
|
||||
|
||||
if(role_name in cargo_positions)
|
||||
result += ROLE_CARGO
|
||||
if(SSjob.is_job_in_department(role_name, DEPARTMENT_CARGO))
|
||||
result += DEPARTMENT_CARGO
|
||||
|
||||
if(role_name in civilian_positions)
|
||||
result += ROLE_CIVILIAN
|
||||
if(SSjob.is_job_in_department(role_name, DEPARTMENT_CIVILIAN))
|
||||
result += DEPARTMENT_CIVILIAN
|
||||
|
||||
if(role_name in nonhuman_positions)
|
||||
result += ROLE_SYNTHETIC
|
||||
if(SSjob.is_job_in_department(role_name, DEPARTMENT_SYNTHETIC))
|
||||
result += DEPARTMENT_SYNTHETIC
|
||||
|
||||
if(role_name in command_positions) // We do Command last, since we consider command to only be a primary department for hop/admin.
|
||||
result += ROLE_COMMAND
|
||||
if(SSjob.is_job_in_department(role_name, DEPARTMENT_COMMAND)) // We do Command last, since we consider command to only be a primary department for hop/admin.
|
||||
result += DEPARTMENT_COMMAND
|
||||
|
||||
if(!result.len) // No department was found.
|
||||
result += ROLE_UNKNOWN
|
||||
result += DEPARTMENT_UNKNOWN
|
||||
return result
|
||||
|
||||
/datum/metric/proc/count_people_in_department(var/department)
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
/datum/metric
|
||||
var/list/departments = list(
|
||||
ROLE_COMMAND,
|
||||
ROLE_SECURITY,
|
||||
ROLE_ENGINEERING,
|
||||
ROLE_MEDICAL,
|
||||
ROLE_RESEARCH,
|
||||
ROLE_CARGO,
|
||||
ROLE_CIVILIAN,
|
||||
ROLE_SYNTHETIC
|
||||
DEPARTMENT_COMMAND,
|
||||
DEPARTMENT_SECURITY,
|
||||
DEPARTMENT_ENGINEERING,
|
||||
DEPARTMENT_MEDICAL,
|
||||
DEPARTMENT_RESEARCH,
|
||||
DEPARTMENT_CARGO,
|
||||
DEPARTMENT_CIVILIAN,
|
||||
DEPARTMENT_SYNTHETIC
|
||||
)
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
m_type = 1
|
||||
|
||||
//Machine-only emotes
|
||||
if("ping", "beep", "buzz", "yes", "ye", "no", "rcough", "rsneeze")
|
||||
if("ping", "beep", "buzz", "yes", "ye", "dwoop", "no", "rcough", "rsneeze")
|
||||
|
||||
if(!isSynthetic())
|
||||
to_chat(src, "<span class='warning'>You are not a synthetic.</span>")
|
||||
@@ -55,6 +55,9 @@
|
||||
else if(act == "yes" || act == "ye")
|
||||
display_msg = "emits an affirmative blip"
|
||||
use_sound = 'sound/machines/synth_yes.ogg'
|
||||
else if(act == "dwoop")
|
||||
display_msg = "chirps happily"
|
||||
use_sound = 'sound/machines/dwoop.ogg'
|
||||
else if(act == "no")
|
||||
display_msg = "emits a negative blip"
|
||||
use_sound = 'sound/machines/synth_no.ogg'
|
||||
@@ -88,6 +91,15 @@
|
||||
message = "squishes."
|
||||
m_type = 1
|
||||
|
||||
//Skrell-only emotes
|
||||
if("warble")
|
||||
if(species.name != SPECIES_SKRELL)
|
||||
to_chat(src, "<span class='warning'>You are not a Skrell!</span>")
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/effects/warble.ogg', 50, 0) // Copyright CC BY 3.0 alienistcog (freesound.org) for the sound.
|
||||
message = "warbles."
|
||||
m_type = 2
|
||||
|
||||
if ("blink")
|
||||
message = "blinks."
|
||||
@@ -727,7 +739,7 @@
|
||||
to_chat(src, "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, deathgasp, drool, eyebrow, fastsway/qwag, \
|
||||
frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, \
|
||||
raise, salute, scream, sneeze, shake, shiver, shrug, sigh, signal-#1-10, slap-(none)/mob, smile, sneeze, sniff, snore, stare-(none)/mob, stopsway/swag, sway/wag, swish, tremble, twitch, \
|
||||
twitch_v, vomit, whimper, wink, yawn. Synthetics: beep, buzz, yes, no, rcough, rsneeze, ping")
|
||||
twitch_v, vomit, whimper, wink, yawn. Prometheans: squish Synthetics: beep, buzz, dwoop, yes, no, rcough, rsneeze, ping. Skrell: warble")
|
||||
|
||||
else
|
||||
to_chat(src, "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>")
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
|
||||
H.do_attack_animation(src)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='warning'>[M] has grabbed [src] passively!</span>")
|
||||
visible_message("<span class='warning'>[M] has grabbed [src][(M.zone_sel.selecting == "l_hand" || M.zone_sel.selecting == "r_hand")? " by their hands!":" passively!"]</span>")
|
||||
return TRUE
|
||||
|
||||
if(I_HURT)
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
var/list/all_underwear = list()
|
||||
var/list/all_underwear_metadata = list()
|
||||
var/list/hide_underwear = list()
|
||||
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.
|
||||
var/pdachoice = 1 //Which PDA type the player has chosen. Default, Slim, Old, or Rugged.
|
||||
var/backbag = 2 //Which backpack type the player has chosen.
|
||||
var/pdachoice = 1 //Which PDA type the player has chosen.
|
||||
|
||||
// General information
|
||||
var/home_system = ""
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
for(var/obj/item/rig_module/stealth_field/cloaker in suit.installed_modules)
|
||||
if(cloaker.active)
|
||||
cloaker.deactivate()
|
||||
for(var/obj/item/weapon/deadringer/dr in src)
|
||||
dr.uncloak()
|
||||
|
||||
/mob/living/carbon/human/is_cloaked()
|
||||
if(mind && mind.changeling && mind.changeling.cloaked) // Ling camo.
|
||||
@@ -72,6 +74,9 @@
|
||||
for(var/obj/item/rig_module/stealth_field/cloaker in suit.installed_modules)
|
||||
if(cloaker.active)
|
||||
return TRUE
|
||||
for(var/obj/item/weapon/deadringer/dr in src)
|
||||
if(dr.timer > 20)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_ear_protection()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
dsma.blend_mode = BLEND_ADD
|
||||
dsoverlay.appearance = dsma
|
||||
|
||||
selected_image = image(icon = 'icons/mob/screen1.dmi', loc = src, icon_state = "centermarker")
|
||||
selected_image = image(icon = buildmode_hud, loc = src, icon_state = "ai_sel")
|
||||
|
||||
/mob/living/Destroy()
|
||||
dsoverlay.loc = null //I'll take my coat with me
|
||||
|
||||
@@ -202,6 +202,23 @@
|
||||
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
if("dwoop")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "chirps happily at [param]"
|
||||
else
|
||||
message = "chirps happily."
|
||||
playsound(src.loc, 'sound/machines/dwoop.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
|
||||
if("no")
|
||||
var/M = null
|
||||
if(param)
|
||||
@@ -238,7 +255,7 @@
|
||||
to_chat(src, "You are not security.")
|
||||
|
||||
if ("help")
|
||||
to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitch_s, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look, beep, ping, \nbuzz, law, halt, yes, no")
|
||||
to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitch_s, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look, beep, ping, \nbuzz, law, halt, yes, dwoop, no")
|
||||
else
|
||||
to_chat(src, "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>")
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
mob_swap_flags = ~HEAVY
|
||||
mob_push_flags = ~HEAVY
|
||||
|
||||
has_huds = TRUE // We do show AI status huds for buildmode players
|
||||
|
||||
var/tt_desc = null //Tooltip description
|
||||
|
||||
//Settings for played mobs
|
||||
@@ -295,4 +297,9 @@
|
||||
return mob_class & MOB_CLASS_HUMANOID|MOB_CLASS_ANIMAL|MOB_CLASS_SLIME // Update this if needed.
|
||||
|
||||
/mob/living/simple_mob/get_nametag_desc(mob/user)
|
||||
return "<i>[tt_desc]</i>"
|
||||
return "<i>[tt_desc]</i>"
|
||||
|
||||
/mob/living/simple_mob/make_hud_overlays()
|
||||
hud_list[STATUS_HUD] = gen_hud_image(buildmode_hud, src, "ai_0", plane = PLANE_BUILDMODE)
|
||||
hud_list[LIFE_HUD] = gen_hud_image(buildmode_hud, src, "ais_1", plane = PLANE_BUILDMODE)
|
||||
add_overlay(hud_list)
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
|
||||
return ..(targets)
|
||||
|
||||
/datum/ai_holder/simple_mob/melee/nurse_spider/can_attack(atom/movable/the_target)
|
||||
/datum/ai_holder/simple_mob/melee/nurse_spider/can_attack(atom/movable/the_target, var/vision_required = TRUE)
|
||||
. = ..()
|
||||
if(!.) // Parent returned FALSE.
|
||||
if(istype(the_target, /obj))
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
plane_masters[VIS_MESONS] = new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings.
|
||||
|
||||
plane_masters[VIS_BUILDMODE] = new /obj/screen/plane_master{plane = PLANE_BUILDMODE} //Things that only show up while in build mode
|
||||
|
||||
// Real tangible stuff planes
|
||||
plane_masters[VIS_TURFS] = new /obj/screen/plane_master/main{plane = TURF_PLANE}
|
||||
plane_masters[VIS_OBJS] = new /obj/screen/plane_master/main{plane = OBJ_PLANE}
|
||||
|
||||
@@ -66,9 +66,11 @@
|
||||
else
|
||||
output += "<p><a href='byond://?src=\ref[src];shownews=1'>Show News</A></p>"
|
||||
|
||||
if(SSsqlite.can_submit_feedback(client))
|
||||
output += "<p>[href(src, list("give_feedback" = 1), "Give Feedback")]</p>"
|
||||
output += "</div>"
|
||||
|
||||
panel = new(src, "Welcome","Welcome", 210, 280, src)
|
||||
panel = new(src, "Welcome","Welcome", 210, 300, src)
|
||||
panel.set_window_options("can_close=0")
|
||||
panel.set_content(output)
|
||||
panel.open()
|
||||
@@ -89,8 +91,10 @@
|
||||
stat("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]")
|
||||
totalPlayers = 0
|
||||
totalPlayersReady = 0
|
||||
var/datum/job/refJob = null
|
||||
for(var/mob/new_player/player in player_list)
|
||||
stat("[player.key]", (player.ready)?("(Playing)"):(null))
|
||||
refJob = player.client.prefs.get_highest_job()
|
||||
stat("[player.key]", (player.ready)?("(Playing as: [(refJob)?(refJob.title):("Unknown")])"):(null))
|
||||
totalPlayers++
|
||||
if(player.ready)totalPlayersReady++
|
||||
|
||||
@@ -162,7 +166,7 @@
|
||||
ViewManifest()
|
||||
|
||||
if(href_list["SelectedJob"])
|
||||
|
||||
|
||||
//Prevents people rejoining as same character.
|
||||
for (var/mob/living/carbon/human/C in mob_list)
|
||||
var/char_name = client.prefs.real_name
|
||||
@@ -296,6 +300,15 @@
|
||||
show_hidden_jobs = !show_hidden_jobs
|
||||
LateChoices()
|
||||
|
||||
if(href_list["give_feedback"])
|
||||
if(!SSsqlite.can_submit_feedback(my_client))
|
||||
return
|
||||
|
||||
if(client.feedback_form)
|
||||
client.feedback_form.display() // In case they closed the form early.
|
||||
else
|
||||
client.feedback_form = new(client)
|
||||
|
||||
/mob/new_player/proc/handle_server_news()
|
||||
if(!client)
|
||||
return
|
||||
@@ -315,6 +328,7 @@
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
|
||||
/mob/new_player/proc/IsJobAvailable(rank)
|
||||
var/datum/job/job = job_master.GetJob(rank)
|
||||
if(!job) return 0
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
backbag = rand(1,5)
|
||||
pdachoice = rand(1,4)
|
||||
pdachoice = rand(1,5)
|
||||
age = rand(current_species.min_age, current_species.max_age)
|
||||
b_type = RANDOM_BLOOD_TYPE
|
||||
if(H)
|
||||
@@ -266,3 +266,24 @@
|
||||
preview_icon.Blend(stamp, ICON_OVERLAY, 49, 1)
|
||||
|
||||
preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser.
|
||||
|
||||
/datum/preferences/proc/get_highest_job()
|
||||
var/datum/job/highJob
|
||||
// Determine what job is marked as 'High' priority, and dress them up as such.
|
||||
if(job_civilian_low & ASSISTANT)
|
||||
highJob = job_master.GetJob("Assistant")
|
||||
else
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
var/job_flag
|
||||
switch(job.department_flag)
|
||||
if(CIVILIAN)
|
||||
job_flag = job_civilian_high
|
||||
if(MEDSCI)
|
||||
job_flag = job_medsci_high
|
||||
if(ENGSEC)
|
||||
job_flag = job_engsec_high
|
||||
if(job.flag == job_flag)
|
||||
highJob = job
|
||||
break
|
||||
|
||||
return highJob
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/modular_computer/get_cell()
|
||||
if(battery_module)
|
||||
return battery_module.battery
|
||||
else
|
||||
..()
|
||||
|
||||
// Tries to use power from APC, if present.
|
||||
/obj/item/modular_computer/proc/apc_power(var/power_usage = 0)
|
||||
apc_powered = TRUE
|
||||
|
||||
@@ -44,14 +44,16 @@
|
||||
data["id_owner"] = id_card && id_card.registered_name ? id_card.registered_name : "-----"
|
||||
data["id_name"] = id_card ? id_card.name : "-----"
|
||||
|
||||
data["command_jobs"] = format_jobs(command_positions)
|
||||
data["engineering_jobs"] = format_jobs(engineering_positions)
|
||||
data["medical_jobs"] = format_jobs(medical_positions)
|
||||
data["science_jobs"] = format_jobs(science_positions)
|
||||
data["security_jobs"] = format_jobs(security_positions)
|
||||
data["cargo_jobs"] = format_jobs(cargo_positions)
|
||||
data["civilian_jobs"] = format_jobs(civilian_positions)
|
||||
data["centcom_jobs"] = format_jobs(get_all_centcom_jobs())
|
||||
var/list/departments = list()
|
||||
for(var/D in SSjob.get_all_department_datums())
|
||||
var/datum/department/dept = D
|
||||
if(!dept.assignable) // No AI ID cards for you.
|
||||
continue
|
||||
if(dept.centcom_only && !is_centcom)
|
||||
continue
|
||||
departments[++departments.len] = list("department_name" = dept.name, "jobs" = format_jobs(SSjob.get_job_titles_in_department(dept.name)) )
|
||||
|
||||
data["departments"] = departments
|
||||
|
||||
data["all_centcom_access"] = is_centcom ? get_accesses(1) : null
|
||||
data["regions"] = get_accesses()
|
||||
|
||||
@@ -76,4 +76,7 @@
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery_module/proc/charge_to_full()
|
||||
if(battery)
|
||||
battery.charge = battery.maxcharge
|
||||
battery.charge = battery.maxcharge
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery_module/get_cell()
|
||||
return battery
|
||||
@@ -24,6 +24,9 @@
|
||||
var/colour = "black" //what colour the ink is!
|
||||
pressure_resistance = 2
|
||||
|
||||
/obj/item/weapon/pen/attack_self(var/mob/user)
|
||||
to_chat(user, "<span class='notice'>Click.</span>")
|
||||
playsound(loc, 'sound/items/penclick.ogg', 50, 1)
|
||||
|
||||
/obj/item/weapon/pen/blue
|
||||
desc = "It's a normal blue ink pen."
|
||||
|
||||
@@ -168,6 +168,8 @@
|
||||
C.electrocute_act(500, src, def_zone = BP_TORSO)
|
||||
|
||||
/proc/tesla_zap(atom/source, zap_range = 3, power, explosive = FALSE, stun_mobs = TRUE)
|
||||
if(!source) // Some mobs and maybe some objects delete themselves when they die.
|
||||
return
|
||||
. = source.dir
|
||||
if(power < 1000)
|
||||
return
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
removable_components = TRUE
|
||||
|
||||
initial_cell_type = /obj/item/weapon/cell/high
|
||||
initial_cell_type = /obj/item/weapon/cell/device/weapon
|
||||
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor
|
||||
|
||||
fire_delay = 8
|
||||
@@ -127,7 +127,7 @@
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
slowdown = 0
|
||||
slowdown_held = 0
|
||||
slowdown_held = 0.3
|
||||
slowdown_worn = 0
|
||||
|
||||
power_cost = 400
|
||||
@@ -150,14 +150,16 @@
|
||||
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
|
||||
initial_cell_type = /obj/item/weapon/cell/high
|
||||
slowdown_held = 0
|
||||
|
||||
initial_cell_type = /obj/item/weapon/cell/device/weapon
|
||||
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor
|
||||
|
||||
slot_flags = SLOT_BELT|SLOT_HOLSTER
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="lethal", power_cost = 2000, projectile_type = /obj/item/projectile/bullet/magnetic/heated, burst=1, fire_delay=8, move_delay=null, one_handed_penalty=0),
|
||||
list(mode_name="stun", power_cost = 1500, projectile_type = /obj/item/projectile/energy/electrode/stunshot, burst=1, fire_delay=5, move_delay=null, one_handed_penalty=0),
|
||||
list(mode_name="lethal", power_cost = 500, projectile_type = /obj/item/projectile/bullet/magnetic/heated, burst=1, fire_delay=10, move_delay=null, one_handed_penalty=0),
|
||||
list(mode_name="stun", power_cost = 350, projectile_type = /obj/item/projectile/energy/electrode/stunshot, burst=1, fire_delay=7, move_delay=null, one_handed_penalty=0),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/magnetic/railgun/heater/pistol/hos
|
||||
@@ -168,8 +170,8 @@
|
||||
description_antag = "This weapon starts with a DNA locking chip attached. Using an EMAG on the weapon will disarm it, and allow you to use the chip as your own."
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="lethal", power_cost = 1500, projectile_type = /obj/item/projectile/bullet/magnetic/heated, burst=1, fire_delay=8, move_delay=null, one_handed_penalty=0),
|
||||
list(mode_name="stun", power_cost = 1200, projectile_type = /obj/item/projectile/energy/electrode/stunshot, burst=1, fire_delay=5, move_delay=null, one_handed_penalty=0),
|
||||
list(mode_name="lethal", power_cost = 400, projectile_type = /obj/item/projectile/bullet/magnetic/heated, burst=1, fire_delay=8, move_delay=null, one_handed_penalty=0),
|
||||
list(mode_name="stun", power_cost = 300, projectile_type = /obj/item/projectile/energy/electrode/stunshot, burst=1, fire_delay=5, move_delay=null, one_handed_penalty=0),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/magnetic/railgun/flechette/sif
|
||||
@@ -184,9 +186,9 @@
|
||||
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
slowdown = 0.3
|
||||
slowdown_held = 0.3
|
||||
|
||||
power_cost = 200
|
||||
power_cost = 300
|
||||
projectile_type = /obj/item/projectile/bullet/magnetic/flechette/hunting
|
||||
empty_sound = 'sound/weapons/smg_empty_alarm.ogg'
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user