mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 16:18:01 +01:00
Merge branch 'master' of https://github.com/tgstation/-tg-station into posfixes
Conflicts: code/modules/mob/dead/observer/observer.dm
This commit is contained in:
@@ -578,10 +578,8 @@ var/global/floorIsLava = 0
|
||||
set category = "Server"
|
||||
set desc="Start the round RIGHT NOW"
|
||||
set name="Start Now"
|
||||
if(!ticker)
|
||||
alert("Unable to start the game as it is not set up.")
|
||||
return
|
||||
if(ticker.current_state == GAME_STATE_PREGAME)
|
||||
ticker.can_fire = 1
|
||||
ticker.current_state = GAME_STATE_SETTING_UP
|
||||
log_admin("[usr.key] has started the game.")
|
||||
message_admins("<font color='blue'>[usr.key] has started the game.</font>")
|
||||
@@ -636,10 +634,10 @@ var/global/floorIsLava = 0
|
||||
set category = "Server"
|
||||
set desc="Delay the game start"
|
||||
set name="Delay"
|
||||
if (!ticker || ticker.current_state != GAME_STATE_PREGAME)
|
||||
return alert("Too late... The game has already started!", null, null, null, null, null)
|
||||
going = !( going )
|
||||
if (!( going ))
|
||||
if(ticker.current_state > GAME_STATE_PREGAME)
|
||||
return alert("Too late... The game has already started!")
|
||||
ticker.can_fire = !ticker.can_fire
|
||||
if(!ticker.can_fire)
|
||||
world << "<b>The game start has been delayed.</b>"
|
||||
log_admin("[key_name(usr)] delayed the game.")
|
||||
else
|
||||
@@ -810,8 +808,8 @@ var/global/floorIsLava = 0
|
||||
alert(usr, "You cannot manage jobs before the round starts!")
|
||||
return
|
||||
|
||||
if(job_master)
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
if(SSjob)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
count++
|
||||
var/J_title = html_encode(job.title)
|
||||
var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions))
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
F << "<small>[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z])</small> || [src] [message]<br>"
|
||||
|
||||
//ADMINVERBS
|
||||
/client/proc/investigate_show( subject in list("hrefs","notes","ntsl","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter") )
|
||||
/client/proc/investigate_show( subject in list("hrefs","notes","ntsl","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos") )
|
||||
set name = "Investigate"
|
||||
set category = "Admin"
|
||||
if(!holder) return
|
||||
switch(subject)
|
||||
if("singulo", "ntsl", "wires", "telesci", "gravity", "records", "cargo", "supermatter") //general one-round-only stuff
|
||||
if("singulo", "ntsl", "wires", "telesci", "gravity", "records", "cargo", "supermatter", "atmos") //general one-round-only stuff
|
||||
var/F = investigate_subject2file(subject)
|
||||
if(!F)
|
||||
src << "<font color='red'>Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.</font>"
|
||||
|
||||
@@ -18,7 +18,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums
|
||||
adds = init_adds
|
||||
subs = init_subs
|
||||
|
||||
/datum/admin_rank/proc/process_keyword(word, previous_rights=0)
|
||||
/proc/admin_keyword_to_flag(word, previous_rights=0)
|
||||
var/flag = 0
|
||||
switch(ckey(word))
|
||||
if("buildmode","build") flag = R_BUILDMODE
|
||||
@@ -36,22 +36,41 @@ var/list/admin_ranks = list() //list of all admin_rank datums
|
||||
if("sound","sounds") flag = R_SOUNDS
|
||||
if("spawn","create") flag = R_SPAWN
|
||||
if("@","prev") flag = previous_rights
|
||||
else
|
||||
//isn't a keyword so maybe it's a verbpath?
|
||||
var/path = text2path(copytext(word,2,findtext(word," ",2,0)))
|
||||
if(path)
|
||||
switch(text2ascii(word,1))
|
||||
if(43)
|
||||
if(!subs.Remove(path))
|
||||
adds += path //+
|
||||
if(45)
|
||||
if(!adds.Remove(path))
|
||||
subs += path //-
|
||||
return
|
||||
switch(text2ascii(word,1))
|
||||
if(43) rights |= flag //+
|
||||
if(45) rights &= ~flag //-
|
||||
return
|
||||
return flag
|
||||
|
||||
/proc/admin_keyword_to_path(word) //use this with verb keywords eg +/client/proc/blah
|
||||
return text2path(copytext(word,2,findtext(word," ",2,0)))
|
||||
|
||||
// Adds/removes rights to this admin_rank
|
||||
/datum/admin_rank/proc/process_keyword(word, previous_rights=0)
|
||||
var/flag = admin_keyword_to_flag(word, previous_rights)
|
||||
if(flag)
|
||||
switch(text2ascii(word,1))
|
||||
if(43) rights |= flag //+
|
||||
if(45) rights &= ~flag //-
|
||||
else
|
||||
//isn't a keyword so maybe it's a verbpath?
|
||||
var/path = admin_keyword_to_path(word)
|
||||
if(path)
|
||||
switch(text2ascii(word,1))
|
||||
if(43)
|
||||
if(!subs.Remove(path))
|
||||
adds += path //+
|
||||
if(45)
|
||||
if(!adds.Remove(path))
|
||||
subs += path //-
|
||||
|
||||
// Checks for (keyword-formatted) rights on this admin
|
||||
/datum/admins/proc/check_keyword(word)
|
||||
var/flag = admin_keyword_to_flag(word)
|
||||
if(flag)
|
||||
return ((rank.rights & flag) == flag) //true only if right has everything in flag
|
||||
else
|
||||
var/path = admin_keyword_to_path(word)
|
||||
for(var/i in owner.verbs) //this needs to be a foreach loop for some reason. in operator and verbs.Find() don't work
|
||||
if(i == path)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//load our rank - > rights associations
|
||||
/proc/load_admin_ranks()
|
||||
@@ -279,7 +298,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums
|
||||
var/keyword = input("Input permission keyword (one at a time):\ne.g. +BAN or -FUN or +/client/proc/someverb", "Permission toggle", null, null) as null|text
|
||||
if(!keyword) return
|
||||
|
||||
if(!check_if_greater_rights_than_holder(D))
|
||||
if(!check_keyword(keyword) || !check_if_greater_rights_than_holder(D))
|
||||
message_admins("[key_name_admin(usr)] attempted to give [adm_ckey] the keyword [keyword] without sufficient rights.")
|
||||
log_admin("[key_name(usr)] attempted to give [adm_ckey] the keyword [keyword] without sufficient rights.")
|
||||
return
|
||||
|
||||
@@ -106,7 +106,6 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/restart_controller,
|
||||
/client/proc/cmd_admin_list_open_jobs,
|
||||
/client/proc/Debug2,
|
||||
/client/proc/kill_air,
|
||||
/client/proc/cmd_debug_make_powernets,
|
||||
/client/proc/debug_controller,
|
||||
/client/proc/cmd_debug_mob_lists,
|
||||
@@ -178,7 +177,6 @@ var/list/admin_verbs_hideable = list(
|
||||
/client/proc/callproc,
|
||||
/client/proc/Debug2,
|
||||
/client/proc/reload_admins,
|
||||
/client/proc/kill_air,
|
||||
/client/proc/cmd_debug_make_powernets,
|
||||
/client/proc/debug_controller,
|
||||
/client/proc/startSinglo,
|
||||
@@ -243,7 +241,7 @@ var/list/admin_verbs_hideable = list(
|
||||
/client/proc/count_objects_all,
|
||||
/client/proc/cmd_assume_direct_control,
|
||||
/client/proc/startSinglo,
|
||||
/client/proc/ticklag,
|
||||
/client/proc/fps,
|
||||
/client/proc/cmd_admin_grantfullaccess,
|
||||
/client/proc/cmd_admin_areatest,
|
||||
/client/proc/readmin
|
||||
@@ -483,20 +481,6 @@ var/list/admin_verbs_hideable = list(
|
||||
togglebuildmode(src.mob)
|
||||
feedback_add_details("admin_verb","TBMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/kill_air()
|
||||
set category = "Debug"
|
||||
set name = "Kill Air"
|
||||
set desc = "Toggle Air Processing"
|
||||
if(kill_air)
|
||||
kill_air = 0
|
||||
usr << "<b>Enabled air processing.</b>"
|
||||
else
|
||||
kill_air = 1
|
||||
usr << "<b>Disabled air processing.</b>"
|
||||
feedback_add_details("admin_verb","KA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] used 'kill air'.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] used 'kill air'.</span>")
|
||||
|
||||
/client/proc/deadmin_self()
|
||||
set name = "De-admin self"
|
||||
set category = "Admin"
|
||||
|
||||
@@ -45,6 +45,8 @@ var/list/admin_datums = list()
|
||||
return 1 //they have no rights
|
||||
if(rank.rights == 65535)
|
||||
return 1 //we have all the rights
|
||||
if(src == other)
|
||||
return 1 //you always have more rights than yourself
|
||||
if(rank.rights != other.rank.rights)
|
||||
if( (rank.rights & other.rank.rights) == other.rank.rights )
|
||||
return 1 //we have all the rights they have and more
|
||||
|
||||
@@ -370,11 +370,11 @@
|
||||
dat += "Current Game Mode: <B>[ticker.mode.name]</B><BR>"
|
||||
dat += "Round Duration: <B>[round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B><BR>"
|
||||
dat += "<B>Emergency shuttle</B><BR>"
|
||||
if (!emergency_shuttle.online)
|
||||
if(SSshuttle.emergency.mode < SHUTTLE_CALL)
|
||||
dat += "<a href='?_src_=holder;call_shuttle=1'>Call Shuttle</a><br>"
|
||||
else
|
||||
var/timeleft = emergency_shuttle.timeleft()
|
||||
if(emergency_shuttle.location == 0)
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
if(SSshuttle.emergency.mode < SHUTTLE_DOCKED)
|
||||
dat += "ETA: <a href='?_src_=holder;edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
|
||||
dat += "<a href='?_src_=holder;call_shuttle=2'>Send Back</a><br>"
|
||||
else
|
||||
|
||||
+56
-56
@@ -69,7 +69,7 @@
|
||||
|
||||
|
||||
else if(href_list["forceevent"])
|
||||
var/datum/round_event_control/E = locate(href_list["forceevent"]) in events.control
|
||||
var/datum/round_event_control/E = locate(href_list["forceevent"]) in SSevent.control
|
||||
if(E)
|
||||
var/datum/round_event/event = E.runEvent()
|
||||
if(event.announceWhen>0)
|
||||
@@ -182,34 +182,36 @@
|
||||
|
||||
switch(href_list["call_shuttle"])
|
||||
if("1")
|
||||
if ((!( ticker ) || emergency_shuttle.location))
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
|
||||
return
|
||||
emergency_shuttle.incall()
|
||||
SSshuttle.emergency.request()
|
||||
log_admin("[key_name(usr)] called the Emergency Shuttle")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>")
|
||||
|
||||
if("2")
|
||||
if ((!( ticker ) || emergency_shuttle.location || emergency_shuttle.direction == 0))
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
|
||||
return
|
||||
switch(emergency_shuttle.direction)
|
||||
if(-1)
|
||||
emergency_shuttle.incall()
|
||||
log_admin("[key_name(usr)] called the Emergency Shuttle")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>")
|
||||
if(1)
|
||||
emergency_shuttle.recall()
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
SSshuttle.emergency.cancel()
|
||||
log_admin("[key_name(usr)] sent the Emergency Shuttle back")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] sent the Emergency Shuttle back</span>")
|
||||
else
|
||||
SSshuttle.emergency.cancel()
|
||||
log_admin("[key_name(usr)] called the Emergency Shuttle")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>")
|
||||
|
||||
|
||||
href_list["secretsadmin"] = "check_antagonist"
|
||||
|
||||
else if(href_list["edit_shuttle_time"])
|
||||
if(!check_rights(R_SERVER)) return
|
||||
|
||||
emergency_shuttle.settimeleft( input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", emergency_shuttle.timeleft() ) as num )
|
||||
log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]")
|
||||
minor_announce("The emergency shuttle will reach its destination in [round(emergency_shuttle.timeleft()/60)] minutes.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]</span>")
|
||||
var/timer = input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", SSshuttle.emergency.timeLeft() ) as num
|
||||
SSshuttle.emergency.setTimer(timer*10)
|
||||
log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds")
|
||||
minor_announce("The emergency shuttle will reach its destination in [round(SSshuttle.emergency.timeLeft(600))] minutes.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds</span>")
|
||||
href_list["secretsadmin"] = "check_antagonist"
|
||||
|
||||
else if(href_list["delay_round_end"])
|
||||
@@ -384,9 +386,6 @@
|
||||
if(!M.ckey) //sanity
|
||||
usr << "This mob has no ckey"
|
||||
return
|
||||
if(!job_master)
|
||||
usr << "Job Master has not been setup!"
|
||||
return
|
||||
|
||||
var/dat = ""
|
||||
var/header = "<head><title>Job-Ban Panel: [M.name]</title></head>"
|
||||
@@ -405,7 +404,7 @@
|
||||
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)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -426,7 +425,7 @@
|
||||
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)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -447,7 +446,7 @@
|
||||
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)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -468,7 +467,7 @@
|
||||
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)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -489,7 +488,7 @@
|
||||
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)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -510,7 +509,7 @@
|
||||
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)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -531,7 +530,7 @@
|
||||
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(nonhuman_positions)]'><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)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.GetJob(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -636,7 +635,7 @@
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
if(!job_master)
|
||||
if(!SSjob)
|
||||
usr << "Job Master has not been setup!"
|
||||
return
|
||||
|
||||
@@ -646,43 +645,43 @@
|
||||
if("commanddept")
|
||||
for(var/jobPos in command_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("securitydept")
|
||||
for(var/jobPos in security_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("engineeringdept")
|
||||
for(var/jobPos in engineering_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("medicaldept")
|
||||
for(var/jobPos in medical_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("sciencedept")
|
||||
for(var/jobPos in science_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("civiliandept")
|
||||
for(var/jobPos in civilian_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("nonhumandept")
|
||||
for(var/jobPos in nonhuman_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
else
|
||||
@@ -1330,7 +1329,7 @@
|
||||
|
||||
var/Add = href_list["addjobslot"]
|
||||
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job.title == Add)
|
||||
job.total_positions += 1
|
||||
break
|
||||
@@ -1342,7 +1341,7 @@
|
||||
|
||||
var/Remove = href_list["removejobslot"]
|
||||
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job.title == Remove && job.total_positions - job.current_positions > 0)
|
||||
job.total_positions -= 1
|
||||
break
|
||||
@@ -1892,21 +1891,21 @@
|
||||
|
||||
rightandwrong(1, usr, survivor_probability)
|
||||
if("events")
|
||||
if(events && !events.wizardmode)
|
||||
if(!SSevent.wizardmode)
|
||||
if(alert("Do you want to toggle summon events on?",,"Yes","No") == "Yes")
|
||||
summonevents()
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","SE")
|
||||
|
||||
else if(events && events.wizardmode)
|
||||
else
|
||||
switch(alert("What would you like to do?",,"Intensify Summon Events","Turn Off Summon Events","Nothing"))
|
||||
if("Intensify Summon Events")
|
||||
summonevents()
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","SE")
|
||||
if("Turn Off Summon Events")
|
||||
events.toggleWizardmode()
|
||||
events.resetFrequency()
|
||||
SSevent.toggleWizardmode()
|
||||
SSevent.resetFrequency()
|
||||
if("dorf")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","DF")
|
||||
@@ -1939,7 +1938,7 @@
|
||||
var/choice = input("Are you sure you want to cure all disease?") in list("Yes", "Cancel")
|
||||
if(choice == "Yes")
|
||||
message_admins("[key_name_admin(usr)] has cured all diseases.")
|
||||
for(var/datum/disease/D in active_diseases)
|
||||
for(var/datum/disease/D in SSdisease.processing)
|
||||
D.cure(D)
|
||||
if("list_bombers")
|
||||
var/dat = "<B>Bombing List<HR>"
|
||||
@@ -1958,27 +1957,28 @@
|
||||
usr << browse(dat, "window=lawchanges;size=800x500")
|
||||
if("check_antagonist")
|
||||
check_antagonists()
|
||||
|
||||
if("moveminingshuttle")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","ShM")
|
||||
var/datum/shuttle_manager/s = shuttles["mining"]
|
||||
if(istype(s)) s.move_shuttle(0)
|
||||
message_admins("[key_name_admin(usr)] moved mining shuttle")
|
||||
log_admin("[key_name(usr)] moved the mining shuttle")
|
||||
if(!SSshuttle.toggleShuttle("mining","mining_home","mining_away"))
|
||||
message_admins("[key_name_admin(usr)] moved mining shuttle")
|
||||
log_admin("[key_name(usr)] moved the mining shuttle")
|
||||
|
||||
if("movelaborshuttle")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","ShL")
|
||||
var/datum/shuttle_manager/s = shuttles["laborcamp"]
|
||||
if(istype(s)) s.move_shuttle(0)
|
||||
message_admins("[key_name_admin(usr)] moved labor shuttle")
|
||||
log_admin("[key_name(usr)] moved the labor shuttle")
|
||||
if(!SSshuttle.toggleShuttle("laborcamp","laborcamp_home","laborcamp_away"))
|
||||
message_admins("[key_name_admin(usr)] moved labor shuttle")
|
||||
log_admin("[key_name(usr)] moved the labor shuttle")
|
||||
|
||||
if("moveferry")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","ShF")
|
||||
var/datum/shuttle_manager/s = shuttles["ferry"]
|
||||
if(istype(s)) s.move_shuttle(0)
|
||||
message_admins("[key_name_admin(usr)] moved the centcom ferry")
|
||||
log_admin("[key_name(usr)] moved the centcom ferry")
|
||||
if(!SSshuttle.toggleShuttle("ferry","ferry_home","ferry_away"))
|
||||
message_admins("[key_name_admin(usr)] moved the centcom ferry")
|
||||
log_admin("[key_name(usr)] moved the centcom ferry")
|
||||
|
||||
if("kick_all_from_lobby")
|
||||
if(ticker && ticker.current_state == GAME_STATE_PLAYING)
|
||||
var/afkonly = text2num(href_list["afkonly"])
|
||||
@@ -2046,11 +2046,11 @@
|
||||
usr << browse(dat, "window=admin_log")
|
||||
if("list_job_debug")
|
||||
var/dat = "<B>Job Debug info.</B><HR>"
|
||||
if(job_master)
|
||||
for(var/line in job_master.job_debug)
|
||||
if(SSjob)
|
||||
for(var/line in SSjob.job_debug)
|
||||
dat += "[line]<BR>"
|
||||
dat+= "*******<BR><BR>"
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(!job) continue
|
||||
dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions] <BR>"
|
||||
usr << browse(dat, "window=jobdebug;size=600x500")
|
||||
@@ -2080,7 +2080,7 @@
|
||||
M.req_one_access = list(access_brig,access_engine)
|
||||
message_admins("[key_name_admin(usr)] made all maint doors engineering and brig access-only.")
|
||||
if("infinite_sec")
|
||||
var/datum/job/J = job_master.GetJob("Security Officer")
|
||||
var/datum/job/J = SSjob.GetJob("Security Officer")
|
||||
if(!J) return
|
||||
J.total_positions = -1
|
||||
J.spawn_positions = -1
|
||||
|
||||
@@ -419,7 +419,7 @@ var/global/list/g_fancy_list_of_types = null
|
||||
/client/proc/cmd_debug_make_powernets()
|
||||
set category = "Debug"
|
||||
set name = "Make Powernets"
|
||||
makepowernets()
|
||||
SSpower.makepowernets()
|
||||
log_admin("[key_name(src)] has remade the powernet. makepowernets() called.")
|
||||
message_admins("[key_name_admin(src)] has remade the powernets. makepowernets() called.", 0)
|
||||
feedback_add_details("admin_verb","MPWN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -611,9 +611,10 @@ var/global/list/g_fancy_list_of_types = null
|
||||
var/datum/job/jobdatum
|
||||
if (dresscode == "as job...")
|
||||
var/jobname = input("Select job", "Robust quick dress shop") as null|anything in get_all_jobs()
|
||||
jobdatum = job_master.GetJob(jobname)
|
||||
if(isnull(jobname))
|
||||
return
|
||||
jobdatum = SSjob.GetJob(jobname)
|
||||
|
||||
|
||||
feedback_add_details("admin_verb","SEQ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
for (var/obj/item/I in M)
|
||||
@@ -1048,8 +1049,8 @@ var/global/list/g_fancy_list_of_types = null
|
||||
|
||||
var/dat = "<B>List of things that failed to GC this round</B><BR><BR>"
|
||||
|
||||
for(var/path in garbage.logging)
|
||||
dat += "[path] - [garbage.logging[path]] times<BR>"
|
||||
for(var/path in SSgarbage.logging)
|
||||
dat += "[path] - [SSgarbage.logging[path]] times<BR>"
|
||||
|
||||
usr << browse(dat, "window=dellog")
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//replaces the old Ticklag verb, fps is easier to understand
|
||||
/client/proc/fps()
|
||||
set category = "Debug"
|
||||
set name = "Set fps"
|
||||
set desc = "Sets game speed in frames-per-second. Can potentially break the game"
|
||||
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
var/fps = round(input("Sets game frames-per-second. Can potentially break the game","FPS", config.fps) as num|null)
|
||||
|
||||
if(fps <= 0)
|
||||
src << "<span class='danger'>Error: ticklag(): Invalid world.ticklag value. No changes made.</span>"
|
||||
return
|
||||
if(fps > config.fps)
|
||||
if(alert(src, "You are setting fps to a high value:\n\t[fps] frames-per-second\n\tconfig.fps = [config.fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
|
||||
return
|
||||
|
||||
switch(alert("Enable Tick Compensation?","Tick Comp is currently: [config.Tickcomp]","Enable","Disable"))
|
||||
if("Enable") config.Tickcomp = 1
|
||||
else config.Tickcomp = 0
|
||||
|
||||
var/msg = "[key_name(src)] has modified world.fps to [fps] and config.Tickcomp to [config.Tickcomp]"
|
||||
log_admin(msg, 0)
|
||||
message_admins(msg, 0)
|
||||
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
world.fps = fps
|
||||
@@ -132,15 +132,13 @@ var/intercom_range_display_status = 0
|
||||
src.verbs += /client/proc/count_objects_all
|
||||
src.verbs += /client/proc/cmd_assume_direct_control //-errorage
|
||||
src.verbs += /client/proc/startSinglo
|
||||
src.verbs += /client/proc/ticklag //allows you to set the ticklag.
|
||||
src.verbs += /client/proc/fps //allows you to set the ticklag.
|
||||
src.verbs += /client/proc/cmd_admin_grantfullaccess
|
||||
src.verbs += /client/proc/cmd_admin_areatest
|
||||
src.verbs += /client/proc/cmd_admin_rejuvenate
|
||||
src.verbs += /datum/admins/proc/show_traitor_panel
|
||||
src.verbs += /client/proc/print_jobban_old
|
||||
src.verbs += /client/proc/print_jobban_old_filter
|
||||
src.verbs += /client/proc/kill_pipe_processing
|
||||
src.verbs += /client/proc/kill_air_processing
|
||||
src.verbs += /client/proc/disable_communication
|
||||
src.verbs += /client/proc/print_pointers
|
||||
src.verbs += /client/proc/count_movable_instances
|
||||
@@ -234,25 +232,6 @@ var/intercom_range_display_status = 0
|
||||
world << "There are [count] objects of type [type_path] in the game world"
|
||||
feedback_add_details("admin_verb","mOBJ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/kill_pipe_processing()
|
||||
set category = "Mapping"
|
||||
set name = "Kill pipe processing"
|
||||
|
||||
pipe_processing_killed = !pipe_processing_killed
|
||||
if(pipe_processing_killed)
|
||||
message_admins("[src.ckey] used 'kill pipe processing', stopping all pipe processing.")
|
||||
else
|
||||
message_admins("[src.ckey] used 'kill pipe processing', restoring all pipe processing.")
|
||||
|
||||
/client/proc/kill_air_processing()
|
||||
set category = "Mapping"
|
||||
set name = "Kill air processing"
|
||||
|
||||
air_processing_killed = !air_processing_killed
|
||||
if(air_processing_killed)
|
||||
message_admins("[src.ckey] used 'kill air processing', stopping all air processing.")
|
||||
else
|
||||
message_admins("[src.ckey] used 'kill air processing', restoring all air processing.")
|
||||
|
||||
//This proc is intended to detect lag problems relating to communication procs
|
||||
var/global/say_disabled = 0
|
||||
|
||||
@@ -13,7 +13,7 @@ var/sound/admin_sound
|
||||
log_admin("[key_name(src)] played sound [S]")
|
||||
message_admins("[key_name_admin(src)] played sound [S]")
|
||||
|
||||
if(events.holiday == "April Fool's Day")
|
||||
if(SSevent.holiday == "April Fool's Day")
|
||||
admin_sound.frequency = pick(0.5, 0.7, 0.8, 0.85, 0.9, 0.95, 1.1, 1.2, 1.4, 1.6, 2.0, 2.5)
|
||||
src << "You feel the Honkmother messing with your song..."
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
//Now for special roles and equipment.
|
||||
switch(new_character.mind.special_role)
|
||||
if("traitor")
|
||||
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)
|
||||
SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)
|
||||
ticker.mode.equip_traitor(new_character)
|
||||
if("Wizard")
|
||||
new_character.loc = pick(wizardstart)
|
||||
@@ -354,7 +354,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(new_character.mind.special_role=="traitor")
|
||||
ticker.mode.add_law_zero(new_character)
|
||||
else
|
||||
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
|
||||
SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
|
||||
|
||||
//Announces the character on all the systems, based on the record.
|
||||
if(!issilicon(new_character))//If they are not a cyborg/AI.
|
||||
@@ -671,7 +671,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Admin"
|
||||
set name = "Call Shuttle"
|
||||
|
||||
if ((!( ticker ) || emergency_shuttle.location))
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
|
||||
return
|
||||
|
||||
if (!holder)
|
||||
@@ -684,11 +684,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || ticker.mode.name == "confliction")
|
||||
var/choice = input("The shuttle will just return if you call it. Call anyway?") in list("Confirm", "Cancel")
|
||||
if(choice == "Confirm")
|
||||
emergency_shuttle.fake_recall = rand(300,500)
|
||||
SSshuttle.emergencyFakeRecall = rand(0.5,0.9)
|
||||
else
|
||||
return
|
||||
|
||||
emergency_shuttle.incall()
|
||||
SSshuttle.emergency.request()
|
||||
feedback_add_details("admin_verb","CSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] admin-called the emergency shuttle.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] admin-called the emergency shuttle.</span>")
|
||||
@@ -700,10 +700,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(!check_rights(0)) return
|
||||
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return
|
||||
|
||||
if(!ticker || emergency_shuttle.location || emergency_shuttle.direction == 0)
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
|
||||
return
|
||||
|
||||
emergency_shuttle.recall()
|
||||
SSshuttle.emergency.cancel()
|
||||
feedback_add_details("admin_verb","CCSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] admin-recalled the emergency shuttle.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] admin-recalled the emergency shuttle.</span>")
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
//Merged Doohl's and the existing ticklag as they both had good elements about them ~Carn
|
||||
|
||||
/client/proc/ticklag()
|
||||
set category = "Debug"
|
||||
set name = "Set Ticklag"
|
||||
set desc = "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9"
|
||||
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null
|
||||
//I've used ticks of 2 before to help with serious singulo lags
|
||||
if(newtick && newtick <= 2 && newtick > 0)
|
||||
log_admin("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
|
||||
message_admins("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
|
||||
world.tick_lag = newtick
|
||||
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
switch(alert("Enable Tick Compensation?","Tick Comp is currently: [config.Tickcomp]","Yes","No"))
|
||||
if("Yes") config.Tickcomp = 1
|
||||
else config.Tickcomp = 0
|
||||
else
|
||||
src << "<span class='danger'>Error: ticklag(): Invalid world.ticklag value. No changes made.</span>"
|
||||
|
||||
|
||||
@@ -6,17 +6,15 @@
|
||||
usr << "This option is currently only usable during pregame. This may change at a later date."
|
||||
return
|
||||
|
||||
if(job_master && ticker)
|
||||
var/datum/job/job = job_master.GetJob("AI")
|
||||
if(!job)
|
||||
usr << "Unable to locate the AI job"
|
||||
return
|
||||
if(ticker.triai)
|
||||
ticker.triai = 0
|
||||
usr << "Only one AI will be spawned at round start."
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has toggled off triple AIs at round start.</span>")
|
||||
else
|
||||
ticker.triai = 1
|
||||
usr << "There will be an AI Triumvirate at round start."
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has toggled on triple AIs at round start.</span>")
|
||||
return
|
||||
var/datum/job/job = SSjob.GetJob("AI")
|
||||
if(!job)
|
||||
usr << "Unable to locate the AI job"
|
||||
return
|
||||
if(ticker.triai)
|
||||
ticker.triai = 0
|
||||
usr << "Only one AI will be spawned at round start."
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has toggled off triple AIs at round start.</span>")
|
||||
else
|
||||
ticker.triai = 1
|
||||
usr << "There will be an AI Triumvirate at round start."
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has toggled on triple AIs at round start.</span>")
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
|
||||
|
||||
/obj/item/device/assembly/process()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
/obj/item/device/assembly/infra/toggle_secure()
|
||||
secured = !secured
|
||||
if(secured)
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
else
|
||||
on = 0
|
||||
if(first) qdel(first)
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
/obj/item/device/assembly/prox_sensor/toggle_secure()
|
||||
secured = !secured
|
||||
if(secured)
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
else
|
||||
scanning = 0
|
||||
timing = 0
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
/obj/item/device/assembly/timer/toggle_secure()
|
||||
secured = !secured
|
||||
if(secured)
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
else
|
||||
timing = 0
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ datum/preferences
|
||||
popup.open(0)
|
||||
|
||||
proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620)
|
||||
if(!job_master) return
|
||||
if(!SSjob) return
|
||||
|
||||
//limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice.
|
||||
//splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE to make it look nice.
|
||||
@@ -300,7 +300,7 @@ datum/preferences
|
||||
//The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows.
|
||||
var/datum/job/lastJob
|
||||
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
|
||||
index += 1
|
||||
if((index >= limit) || (job.title in splitJobs))
|
||||
@@ -453,9 +453,9 @@ datum/preferences
|
||||
return 0
|
||||
|
||||
proc/UpdateJobPreference(mob/user, role, desiredLvl)
|
||||
if(!job_master)
|
||||
if(!SSjob)
|
||||
return
|
||||
var/datum/job/job = job_master.GetJob(role)
|
||||
var/datum/job/job = SSjob.GetJob(role)
|
||||
|
||||
if(!job)
|
||||
user << browse(null, "window=mob_occupation")
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
/obj/item/clothing/head/cakehat/process()
|
||||
if(!onfire)
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
return
|
||||
|
||||
var/turf/location = src.loc
|
||||
@@ -74,7 +74,7 @@
|
||||
src.force = 3
|
||||
src.damtype = "fire"
|
||||
src.icon_state = "cake1"
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
else
|
||||
src.force = null
|
||||
src.damtype = "brute"
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
gas_transfer_coefficient = 0.90
|
||||
permeability_coefficient = 0.50
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
allowed = list(/obj/item/weapon/kitchenknife,/obj/item/weapon/butch)
|
||||
allowed = list(/obj/item/weapon/kitchenknife)
|
||||
action_button_name = "Toggle Jacket Sleeves"
|
||||
togglename = "sleeves"
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
item_state = "apronchef"
|
||||
blood_overlay_type = "armor"
|
||||
body_parts_covered = CHEST|GROIN
|
||||
allowed = list(/obj/item/weapon/kitchenknife,/obj/item/weapon/butch)
|
||||
allowed = list(/obj/item/weapon/kitchenknife)
|
||||
|
||||
//Detective
|
||||
/obj/item/clothing/suit/det_suit
|
||||
|
||||
@@ -110,11 +110,11 @@
|
||||
//which should be the only place it's referenced.
|
||||
//Called when start(), announce() and end() has all been called.
|
||||
/datum/round_event/proc/kill()
|
||||
events.running -= src
|
||||
SSevent.running -= src
|
||||
|
||||
|
||||
//Sets up the event then adds the event to the the list of running events
|
||||
/datum/round_event/New()
|
||||
setup()
|
||||
events.running += src
|
||||
SSevent.running += src
|
||||
return ..()
|
||||
@@ -1,282 +0,0 @@
|
||||
var/datum/controller/event/events
|
||||
|
||||
/datum/controller/event
|
||||
var/list/control = list() //list of all datum/round_event_control. Used for selecting events based on weight and occurrences.
|
||||
var/list/running = list() //list of all existing /datum/round_event
|
||||
|
||||
var/scheduled = 0 //The next world.time that a naturally occuring random event can be selected.
|
||||
var/frequency_lower = 3000 //5 minutes lower bound.
|
||||
var/frequency_upper = 9000 //15 minutes upper bound. Basically an event will happen every 15 to 30 minutes.
|
||||
|
||||
var/holiday //This will be a string of the name of any realworld holiday which occurs today (GMT time)
|
||||
var/wizardmode = 0 //If the summon events spell is in effect this is true
|
||||
|
||||
//Initial controller setup.
|
||||
/datum/controller/event/New()
|
||||
//There can be only one events manager. Out with the old and in with the new.
|
||||
if(events != src)
|
||||
if(istype(events))
|
||||
del(events)
|
||||
events = src
|
||||
|
||||
for(var/type in typesof(/datum/round_event_control))
|
||||
var/datum/round_event_control/E = new type()
|
||||
if(!E.typepath)
|
||||
continue //don't want this one! leave it for the garbage collector
|
||||
if(E.wizardevent && !wizardmode)
|
||||
E.weight = 0
|
||||
control += E //add it to the list of all events (controls)
|
||||
reschedule()
|
||||
getHoliday()
|
||||
|
||||
//This is called by the MC every MC-tick (*neatfreak*).
|
||||
/datum/controller/event/proc/process()
|
||||
checkEvent()
|
||||
var/i = 1
|
||||
while(i<=running.len)
|
||||
var/datum/round_event/Event = running[i]
|
||||
if(Event)
|
||||
Event.process()
|
||||
i++
|
||||
continue
|
||||
running.Cut(i,i+1)
|
||||
|
||||
//checks if we should select a random event yet, and reschedules if necessary
|
||||
/datum/controller/event/proc/checkEvent()
|
||||
if(scheduled <= world.time)
|
||||
spawnEvent()
|
||||
reschedule()
|
||||
|
||||
//decides which world.time we should select another random event at.
|
||||
/datum/controller/event/proc/reschedule()
|
||||
scheduled = world.time + rand(frequency_lower, max(frequency_lower,frequency_upper))
|
||||
|
||||
//selects a random event based on whether it can occur and it's 'weight'(probability)
|
||||
/datum/controller/event/proc/spawnEvent()
|
||||
if(!config.allow_random_events)
|
||||
return
|
||||
|
||||
var/sum_of_weights = 0
|
||||
for(var/datum/round_event_control/E in control)
|
||||
if(E.occurrences >= E.max_occurrences) continue
|
||||
if(E.earliest_start >= world.time) continue
|
||||
if(E.holidayID)
|
||||
if(E.holidayID != holiday) continue
|
||||
if(E.weight < 0) //for round-start events etc.
|
||||
if(E.runEvent() == PROCESS_KILL)
|
||||
E.max_occurrences = 0
|
||||
continue
|
||||
return
|
||||
sum_of_weights += E.weight
|
||||
|
||||
sum_of_weights = rand(0,sum_of_weights) //reusing this variable. It now represents the 'weight' we want to select
|
||||
|
||||
for(var/datum/round_event_control/E in control)
|
||||
if(E.occurrences >= E.max_occurrences) continue
|
||||
if(E.earliest_start >= world.time) continue
|
||||
if(E.holidayID)
|
||||
if(E.holidayID != holiday) continue
|
||||
sum_of_weights -= E.weight
|
||||
|
||||
if(sum_of_weights <= 0) //we've hit our goal
|
||||
if(E.runEvent() == PROCESS_KILL)//we couldn't run this event for some reason, set its max_occurrences to 0
|
||||
E.max_occurrences = 0
|
||||
continue
|
||||
return
|
||||
|
||||
|
||||
/datum/round_event/proc/findEventArea() //Here's a nice proc to use to find an area for your event to land in!
|
||||
var/list/safe_areas = list(
|
||||
/area/turret_protected/ai,
|
||||
/area/turret_protected/ai_upload,
|
||||
/area/engine,
|
||||
/area/solar,
|
||||
/area/holodeck,
|
||||
/area/shuttle/arrival,
|
||||
/area/shuttle/escape/station,
|
||||
/area/shuttle/escape_pod1/station,
|
||||
/area/shuttle/escape_pod2/station,
|
||||
/area/shuttle/escape_pod3/station,
|
||||
/area/shuttle/escape_pod4/station,
|
||||
/area/shuttle/mining/station,
|
||||
/area/shuttle/transport1/station,
|
||||
/area/shuttle/specops/station)
|
||||
|
||||
//These are needed because /area/engine has to be removed from the list, but we still want these areas to get fucked up.
|
||||
var/list/danger_areas = list(
|
||||
/area/engine/break_room,
|
||||
/area/engine/chiefs_office)
|
||||
|
||||
//Need to locate() as it's just a list of paths.
|
||||
return locate(pick((the_station_areas - safe_areas) + danger_areas))
|
||||
|
||||
|
||||
|
||||
//allows a client to trigger an event
|
||||
//aka Badmin Central
|
||||
/client/proc/forceEvent()
|
||||
set name = "Trigger Event"
|
||||
set category = "Fun"
|
||||
|
||||
if(!holder ||!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
holder.forceEvent()
|
||||
|
||||
/datum/admins/proc/forceEvent()
|
||||
var/dat = ""
|
||||
var/normal = ""
|
||||
var/magic = ""
|
||||
var/holiday = ""
|
||||
for(var/datum/round_event_control/E in events.control)
|
||||
dat = "<BR><A href='?src=\ref[src];forceevent=\ref[E]'>[E]</A>"
|
||||
if(E.holidayID)
|
||||
holiday += dat
|
||||
else if(E.wizardevent)
|
||||
magic += dat
|
||||
else
|
||||
normal += dat
|
||||
|
||||
dat = normal + "<BR>" + magic + "<BR>" + holiday
|
||||
|
||||
var/datum/browser/popup = new(usr, "forceevent", "Force Random Event", 300, 750)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
|
||||
/*
|
||||
//////////////
|
||||
// HOLIDAYS //
|
||||
//////////////
|
||||
//Uncommenting ALLOW_HOLIDAYS in config.txt will enable holidays
|
||||
|
||||
//It's easy to add stuff. Just modify getHoliday to set holiday to something using the switch for DD(#day) MM(#month) YY(#year).
|
||||
//You can then check if it's a special day in any code in the game by doing if(events.holiday == "MyHolidayID")
|
||||
|
||||
//You can also make holiday random events easily thanks to Pete/Gia's system.
|
||||
//simply make a random event normally, then assign it a holidayID string which matches the one you gave it in getHolday.
|
||||
//Anything with a holidayID, which does not match the holiday string, will never occur.
|
||||
|
||||
//Please, Don't spam stuff up with stupid stuff (key example being april-fools Pooh/ERP/etc),
|
||||
//And don't forget: CHECK YOUR CODE!!!! We don't want any zero-day bugs which happen only on holidays and never get found/fixed!
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
~Carn */
|
||||
|
||||
//sets up the holiday string in the events manager.
|
||||
/datum/controller/event/proc/getHoliday()
|
||||
if(!config.allow_holidays) return // Holiday stuff was not enabled in the config!
|
||||
holiday = null
|
||||
|
||||
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
|
||||
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
|
||||
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
|
||||
|
||||
//Main switch. If any of these are too dumb/inappropriate, or you have better ones, feel free to change whatever
|
||||
switch(MM)
|
||||
if(1) //Jan
|
||||
switch(DD)
|
||||
if(1) holiday = "New Year"
|
||||
|
||||
if(2) //Feb
|
||||
switch(DD)
|
||||
if(2) holiday = "Groundhog Day"
|
||||
if(14) holiday = "Valentine's Day"
|
||||
if(17) holiday = "Random Acts of Kindness Day"
|
||||
|
||||
if(3) //Mar
|
||||
switch(DD)
|
||||
if(14) holiday = "Pi Day"
|
||||
if(17) holiday = "St. Patrick's Day"
|
||||
if(27)
|
||||
if(YY == 16)
|
||||
holiday = "Easter"
|
||||
if(31)
|
||||
if(YY == 13)
|
||||
holiday = "Easter"
|
||||
|
||||
if(4) //Apr
|
||||
switch(DD)
|
||||
if(1)
|
||||
holiday = "April Fool's Day"
|
||||
if(YY == 18 && prob(50)) holiday = "Easter"
|
||||
if(5)
|
||||
if(YY == 15) holiday = "Easter"
|
||||
if(16)
|
||||
if(YY == 17) holiday = "Easter"
|
||||
if(20)
|
||||
holiday = "Four-Twenty"
|
||||
if(YY == 14 && prob(50)) holiday = "Easter"
|
||||
if(22) holiday = "Earth Day"
|
||||
|
||||
if(5) //May
|
||||
switch(DD)
|
||||
if(1) holiday = "Labour Day"
|
||||
if(4) holiday = "FireFighter's Day"
|
||||
if(12) holiday = "Owl and Pussycat Day" //what a dumb day of observence...but we -do- have costumes already :3
|
||||
|
||||
if(6) //Jun
|
||||
|
||||
if(7) //Jul
|
||||
switch(DD)
|
||||
if(1) holiday = "Doctor's Day"
|
||||
if(2) holiday = "UFO Day"
|
||||
if(8) holiday = "Writer's Day"
|
||||
if(30) holiday = "Friendship Day"
|
||||
|
||||
if(8) //Aug
|
||||
switch(DD)
|
||||
if(5) holiday = "Beer Day"
|
||||
|
||||
if(9) //Sep
|
||||
switch(DD)
|
||||
if(19) holiday = "Talk-Like-a-Pirate Day"
|
||||
if(28) holiday = "Stupid-Questions Day"
|
||||
|
||||
if(10) //Oct
|
||||
switch(DD)
|
||||
if(4) holiday = "Animal's Day"
|
||||
if(7) holiday = "Smiling Day"
|
||||
if(16) holiday = "Boss' Day"
|
||||
if(31) holiday = "Halloween"
|
||||
|
||||
if(11) //Nov
|
||||
switch(DD)
|
||||
if(1) holiday = "Vegan Day"
|
||||
if(13) holiday = "Kindness Day"
|
||||
if(19) holiday = "Flowers Day"
|
||||
if(21) holiday = "Saying-'Hello' Day"
|
||||
|
||||
if(12) //Dec
|
||||
switch(DD)
|
||||
if(10) holiday = "Human-Rights Day"
|
||||
if(14) holiday = "Monkey Day"
|
||||
if(21) holiday = "Mayan Doomsday Anniversary"
|
||||
if(22) holiday = "Orgasming Day" //lol. These all actually exist
|
||||
if(24) holiday = "Xmas"
|
||||
if(25) holiday = "Xmas"
|
||||
if(26) holiday = "Boxing Day"
|
||||
if(31) holiday = "New Year"
|
||||
|
||||
if(!holiday)
|
||||
//Friday the 13th
|
||||
if(DD == 13)
|
||||
if(time2text(world.timeofday, "DDD") == "Fri")
|
||||
holiday = "Friday the 13th"
|
||||
|
||||
world.update_status()
|
||||
|
||||
/datum/controller/event/proc/toggleWizardmode()
|
||||
wizardmode = !wizardmode
|
||||
for(var/datum/round_event_control/E in control)
|
||||
E.weight = initial(E.weight)
|
||||
if((E.wizardevent && !wizardmode) || (!E.wizardevent && wizardmode))
|
||||
E.weight = 0
|
||||
message_admins("Summon Events has been [wizardmode ? "enabled, events will occur every [events.frequency_lower / 600] to [events.frequency_upper / 600] minutes" : "disabled"]!")
|
||||
log_game("Summon Events was [wizardmode ? "enabled" : "disabled"]!")
|
||||
|
||||
/datum/controller/event/proc/resetFrequency()
|
||||
frequency_lower = initial(frequency_lower)
|
||||
frequency_upper = initial(frequency_upper)
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
/datum/round_event/falsealarm/announce()
|
||||
var/list/events_list = list()
|
||||
for(var/datum/round_event_control/E in events.control)
|
||||
for(var/datum/round_event_control/E in SSevent.control)
|
||||
if(!E.holidayID) //No holiday cheer allowed during non-holidays. Not even fake holiday cheer.
|
||||
events_list += E //No holiday cheer allowed during non-holidays. Not even fake holiday cheer.
|
||||
var/datum/round_event_control/event_control = pick(events_list)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
dispatch_type = pick(HIJACK_SYNDIE, RUSKY_PARTY, SPIDER_GIFT, DEPARTMENT_RESUPPLY)
|
||||
|
||||
/datum/round_event/shuttle_loan/announce()
|
||||
supply_shuttle.shuttle_loan = src
|
||||
SSshuttle.shuttle_loan = src
|
||||
switch(dispatch_type)
|
||||
if(HIJACK_SYNDIE)
|
||||
priority_announce("The syndicate are trying to infiltrate your station. If you let them hijack your shuttle, you'll save us a headache.","Centcom Counter Intelligence")
|
||||
@@ -38,49 +38,49 @@
|
||||
priority_announce(thanks_msg, "Cargo shuttle commandeered by Centcom.")
|
||||
|
||||
dispatched = 1
|
||||
supply_shuttle.points += bonus_points
|
||||
SSshuttle.points += bonus_points
|
||||
endWhen = activeFor + 1
|
||||
supply_shuttle.eta_timeofday = (world.timeofday + 3000) % 2160000
|
||||
supply_shuttle.moving = 1
|
||||
|
||||
SSshuttle.supply.sell()
|
||||
SSshuttle.supply.enterTransit()
|
||||
SSshuttle.supply.mode = SHUTTLE_RECALL
|
||||
SSshuttle.supply.setTimer(3000)
|
||||
|
||||
switch(dispatch_type)
|
||||
if(HIJACK_SYNDIE)
|
||||
supply_shuttle.centcom_message += "<font color=blue>Syndicate hijack team incoming.</font>"
|
||||
SSshuttle.centcom_message += "<font color=blue>Syndicate hijack team incoming.</font>"
|
||||
if(RUSKY_PARTY)
|
||||
supply_shuttle.centcom_message += "<font color=blue>Partying Russians incoming.</font>"
|
||||
SSshuttle.centcom_message += "<font color=blue>Partying Russians incoming.</font>"
|
||||
if(SPIDER_GIFT)
|
||||
supply_shuttle.centcom_message += "<font color=blue>Spider Clan gift incoming.</font>"
|
||||
SSshuttle.centcom_message += "<font color=blue>Spider Clan gift incoming.</font>"
|
||||
if(DEPARTMENT_RESUPPLY)
|
||||
supply_shuttle.centcom_message += "<font color=blue>Department resupply incoming.</font>"
|
||||
SSshuttle.centcom_message += "<font color=blue>Department resupply incoming.</font>"
|
||||
|
||||
/datum/round_event/shuttle_loan/tick()
|
||||
if(dispatched)
|
||||
if(supply_shuttle.moving)
|
||||
if(SSshuttle.supply.mode != SHUTTLE_IDLE)
|
||||
endWhen = activeFor
|
||||
else
|
||||
endWhen = activeFor + 1
|
||||
|
||||
//whomever coded this didn't even bother to follow the supply ordering code as an example.
|
||||
//So I had to waste time rewriting it. Thanks for that >:[
|
||||
/datum/round_event/shuttle_loan/end()
|
||||
if(supply_shuttle.shuttle_loan && supply_shuttle.shuttle_loan.dispatched)
|
||||
if(SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched)
|
||||
//make sure the shuttle was dispatched in time
|
||||
supply_shuttle.shuttle_loan = null
|
||||
SSshuttle.shuttle_loan = null
|
||||
|
||||
//spawn some stuff as reward
|
||||
var/area/shuttle_at = locate(SUPPLY_DOCK_AREATYPE)
|
||||
var/list/empty_shuttle_turfs = list()
|
||||
for(var/turf/simulated/shuttle/T in shuttle_at)
|
||||
if(T.density)
|
||||
continue
|
||||
empty_shuttle_turfs.Add(T)
|
||||
for(var/turf/simulated/shuttle/T in SSshuttle.supply.areaInstance)
|
||||
if(T.density || T.contents.len) continue
|
||||
empty_shuttle_turfs += T
|
||||
if(!empty_shuttle_turfs.len)
|
||||
return
|
||||
|
||||
var/list/shuttle_spawns = list()
|
||||
switch(dispatch_type)
|
||||
if(HIJACK_SYNDIE)
|
||||
var/datum/supply_order/O = new /datum/supply_order()
|
||||
O.ordernum = supply_shuttle.ordernum
|
||||
O.object = new /datum/supply_packs/emergency/specialops()
|
||||
O.orderedby = "Syndicate"
|
||||
supply_shuttle.shoppinglist += O
|
||||
SSshuttle.generateSupplyOrder(/datum/supply_packs/emergency/specialops, "Syndicate")
|
||||
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate)
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate)
|
||||
@@ -89,21 +89,8 @@
|
||||
if(prob(50))
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate)
|
||||
|
||||
var/turf/T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/blood(T)
|
||||
T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/blood(T)
|
||||
T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/blood(T)
|
||||
T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/oil(T)
|
||||
|
||||
if(RUSKY_PARTY)
|
||||
var/datum/supply_order/O = new /datum/supply_order()
|
||||
O.ordernum = supply_shuttle.ordernum
|
||||
O.object = new /datum/supply_packs/organic/party()
|
||||
O.orderedby = "Russian Confederation"
|
||||
supply_shuttle.shoppinglist += O
|
||||
SSshuttle.generateSupplyOrder(/datum/supply_packs/organic/party, "Russian Confederation")
|
||||
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian/ranged) //drops a mateba
|
||||
@@ -113,25 +100,8 @@
|
||||
if(prob(50))
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear)
|
||||
|
||||
var/turf/T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/vomit(T)
|
||||
T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/vomit(T)
|
||||
T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/vomit(T)
|
||||
T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/vomit(T)
|
||||
T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/ash(T)
|
||||
T = pick(empty_shuttle_turfs)
|
||||
new /obj/effect/decal/cleanable/ash(T)
|
||||
|
||||
if(SPIDER_GIFT)
|
||||
var/datum/supply_order/O = new /datum/supply_order()
|
||||
O.ordernum = supply_shuttle.ordernum
|
||||
O.object = new /datum/supply_packs/emergency/specialops()
|
||||
O.orderedby = "Spider Clan"
|
||||
supply_shuttle.shoppinglist += O
|
||||
SSshuttle.generateSupplyOrder(/datum/supply_packs/emergency/specialops, "Spider Clan")
|
||||
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider)
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider)
|
||||
@@ -158,27 +128,20 @@
|
||||
new /obj/effect/spider/stickyweb(T)
|
||||
|
||||
if(DEPARTMENT_RESUPPLY)
|
||||
var/list/crate_types = list()
|
||||
var/list/crate_types = list(
|
||||
/datum/supply_packs/emergency/evac,
|
||||
/datum/supply_packs/security/supplies,
|
||||
/datum/supply_packs/organic/food,
|
||||
/datum/supply_packs/emergency/weedcontrol,
|
||||
/datum/supply_packs/engineering/tools,
|
||||
/datum/supply_packs/engineering/engiequipment,
|
||||
/datum/supply_packs/science/robotics,
|
||||
/datum/supply_packs/science/plasma,
|
||||
/datum/supply_packs/medical/supplies
|
||||
)
|
||||
|
||||
crate_types.Add(/datum/supply_packs/emergency/evac)
|
||||
crate_types.Add(/datum/supply_packs/security/supplies)
|
||||
crate_types.Add(/datum/supply_packs/organic/food)
|
||||
crate_types.Add(/datum/supply_packs/emergency/weedcontrol)
|
||||
crate_types.Add(/datum/supply_packs/engineering/tools)
|
||||
crate_types.Add(/datum/supply_packs/engineering/engiequipment)
|
||||
crate_types.Add(/datum/supply_packs/science/robotics)
|
||||
crate_types.Add(/datum/supply_packs/science/plasma)
|
||||
crate_types.Add(/datum/supply_packs/medical/supplies)
|
||||
|
||||
while(crate_types.len > 0)
|
||||
var/datum/supply_order/O = new /datum/supply_order()
|
||||
O.ordernum = supply_shuttle.ordernum
|
||||
O.orderedby = "Centcom"
|
||||
supply_shuttle.shoppinglist += O
|
||||
|
||||
var/spawn_type = crate_types[crate_types.len]
|
||||
O.object = new spawn_type()
|
||||
crate_types.Cut(crate_types.len, crate_types.len + 1)
|
||||
for(var/spawn_type in crate_types)
|
||||
SSshuttle.generateSupplyOrder(spawn_type, "Centcom")
|
||||
|
||||
for(var/i=0,i<3,i++)
|
||||
var/turf/T = pick(empty_shuttle_turfs)
|
||||
@@ -186,20 +149,15 @@
|
||||
new spawn_type(T)
|
||||
|
||||
var/false_positive = 0
|
||||
while(shuttle_spawns.len > 0 && empty_shuttle_turfs.len > 0)
|
||||
var/turf/T = pick(empty_shuttle_turfs)
|
||||
while(shuttle_spawns.len && empty_shuttle_turfs.len)
|
||||
var/turf/T = pick_n_take(empty_shuttle_turfs)
|
||||
if(T.contents.len && false_positive < 5)
|
||||
false_positive++
|
||||
continue
|
||||
|
||||
var/spawn_type = shuttle_spawns[1]
|
||||
shuttle_spawns.Cut(1, 2)
|
||||
empty_shuttle_turfs.Remove(T)
|
||||
var/spawn_type = pick_n_take(shuttle_spawns)
|
||||
new spawn_type(T)
|
||||
|
||||
supply_shuttle.buy()
|
||||
//supply_shuttle.send()
|
||||
//supply_shuttle.moving = 0
|
||||
|
||||
#undef HIJACK_SYNDIE
|
||||
#undef RUSKY_PARTY
|
||||
|
||||
@@ -354,13 +354,13 @@
|
||||
qdel(src)
|
||||
|
||||
spawn_spacevine_piece(src.loc, , muts)
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
init_subtypes(/datum/spacevine_mutation/, mutations_list)
|
||||
if(mttv != null)
|
||||
mutativness = mttv
|
||||
|
||||
/obj/effect/spacevine_controller/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/effect/spacevine_controller/proc/spawn_spacevine_piece(var/turf/location, obj/effect/spacevine/parent, list/muts)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
if(!(user in color_altered_mobs))
|
||||
color_altered_mobs += user
|
||||
user.color = "#00FF00"
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/greentext/dropped(mob/living/user as mob)
|
||||
@@ -48,7 +48,7 @@
|
||||
user.color = "#FF0000" //ya blew it
|
||||
last_holder = null
|
||||
new_holder = null
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/greentext/process()
|
||||
|
||||
@@ -135,7 +135,6 @@
|
||||
var/inaccurate = 0
|
||||
if( \
|
||||
istype(W, /obj/item/weapon/kitchenknife) || \
|
||||
istype(W, /obj/item/weapon/butch) || \
|
||||
istype(W, /obj/item/weapon/scalpel) || \
|
||||
istype(W, /obj/item/weapon/kitchen/utensil/knife) \
|
||||
)
|
||||
|
||||
@@ -539,7 +539,7 @@
|
||||
..()
|
||||
if( istype(src.loc, /mob) )
|
||||
held_mob = src.loc
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chilli/process()
|
||||
if(held_mob && src.loc == held_mob)
|
||||
|
||||
@@ -793,16 +793,29 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
/obj/item/seeds/replicapod/harvest(mob/user = usr) //now that one is fun -- Urist
|
||||
var/obj/machinery/hydroponics/parent = loc
|
||||
var/make_podman = 0
|
||||
if(ckey && config.revival_pod_plants)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.ckey == ckey && M.stat == 2 && !M.suiciding)
|
||||
var/ckey_holder = null
|
||||
if(config.revival_pod_plants)
|
||||
if(ckey)
|
||||
for(var/mob/M in player_list)
|
||||
if(istype(M, /mob/dead/observer))
|
||||
var/mob/dead/observer/O = M
|
||||
if(O.can_reenter_corpse)
|
||||
if(O.ckey == ckey && O.can_reenter_corpse)
|
||||
make_podman = 1
|
||||
break
|
||||
else
|
||||
if(M.ckey == ckey && M.stat == 2 && !M.suiciding)
|
||||
make_podman = 1
|
||||
break
|
||||
else //If the player has ghosted from his corpse before blood was drawn, his ckey is no longer attached to the mob, so we need to match up the cloned player through the mind key
|
||||
for(var/mob/M in player_list)
|
||||
if(ckey(M.mind.key) == ckey(mind.key) && M.ckey && M.client && M.stat == 2 && !M.suiciding)
|
||||
if(istype(M, /mob/dead/observer))
|
||||
var/mob/dead/observer/O = M
|
||||
if(!O.can_reenter_corpse)
|
||||
break
|
||||
make_podman = 1
|
||||
ckey_holder = M.ckey
|
||||
break
|
||||
make_podman = 1
|
||||
break
|
||||
|
||||
if(make_podman) //all conditions met!
|
||||
var/mob/living/carbon/human/podman = new /mob/living/carbon/human(parent.loc)
|
||||
@@ -811,7 +824,10 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
else
|
||||
podman.real_name = "Pod Person [rand(0,999)]"
|
||||
mind.transfer_to(podman)
|
||||
podman.ckey = ckey
|
||||
if(ckey)
|
||||
podman.ckey = ckey
|
||||
else
|
||||
podman.ckey = ckey_holder
|
||||
podman.gender = blood_gender
|
||||
podman.faction |= factions
|
||||
hardset_dna(podman,null,null,podman.real_name,blood_type,/datum/species/plant/pod,"#59CE00")//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
|
||||
|
||||
@@ -81,10 +81,11 @@
|
||||
var/blood_gender = null
|
||||
var/blood_type = null
|
||||
var/factions = null
|
||||
var/contains_sample = 0
|
||||
|
||||
/obj/item/seeds/replicapod/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/reagent_containers/syringe))
|
||||
if(ckey == null)
|
||||
if(!contains_sample)
|
||||
for(var/datum/reagent/blood/bloodSample in W.reagents.reagent_list)
|
||||
if(bloodSample.data["mind"] && bloodSample.data["cloneable"] == 1)
|
||||
mind = bloodSample.data["mind"]
|
||||
@@ -95,6 +96,7 @@
|
||||
factions = bloodSample.data["factions"]
|
||||
W.reagents.clear_reagents()
|
||||
user << "You inject the contents of the syringe into the seeds."
|
||||
contains_sample = 1
|
||||
else
|
||||
user << "The seeds reject the sample!"
|
||||
else
|
||||
|
||||
@@ -4,20 +4,26 @@
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "shuttle"
|
||||
circuit = /obj/item/weapon/circuitboard/labor_shuttle
|
||||
id = "laborcamp"
|
||||
shuttleId = "laborcamp"
|
||||
possible_destinations = "laborcamp_home;laborcamp_away"
|
||||
req_access = list(access_brig)
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle/labor/one_way
|
||||
name = "prisoner shuttle console"
|
||||
desc = "A one-way shuttle console, used to summon the shuttle to the labor camp."
|
||||
possible_destinations = "laborcamp_away"
|
||||
circuit = /obj/item/weapon/circuitboard/labor_shuttle/one_way
|
||||
req_access = list( )
|
||||
|
||||
/obj/machinery/computer/shuttle/labor/one_way/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
var/datum/shuttle_manager/s = shuttles["laborcamp"]
|
||||
if(s.location == /area/shuttle/laborcamp/outpost)
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle("laborcamp")
|
||||
if(!M)
|
||||
usr << "<span class='notice'>Cannot locate shuttle.</span>"
|
||||
return 0
|
||||
var/obj/docking_port/stationary/S = M.get_docked()
|
||||
if(S && S.name == "laborcamp_away")
|
||||
usr << "<span class='notice'>Shuttle is already at the outpost.</span>"
|
||||
return 0
|
||||
..()
|
||||
@@ -92,29 +92,32 @@
|
||||
else usr << "<span class='warning'>Invalid ID.</span>"
|
||||
if(check_auth()) //Sanity check against hef spoofs
|
||||
if(href_list["choice"] == "station")
|
||||
var/datum/shuttle_manager/s = shuttles["laborcamp"]
|
||||
if(s.location == /area/shuttle/laborcamp/outpost)
|
||||
if(alone_in_area(get_area(loc), usr))
|
||||
if (s.move_shuttle(0)) // No delay, to stop people from getting on while it is departing.
|
||||
if(!alone_in_area(get_area(src), usr))
|
||||
usr << "<span class='warning'>Prisoners are only allowed to be released while alone.</span>"
|
||||
else
|
||||
switch(SSshuttle.moveShuttle("laborcamp","laborcamp_home"))
|
||||
if(1)
|
||||
usr << "<span class='notice'>Shuttle not found</span>"
|
||||
if(2)
|
||||
usr << "<span class='notice'>Shuttle already at station</span>"
|
||||
if(3)
|
||||
usr << "<span class='notice'>No permission to dock could be granted.</span>"
|
||||
else
|
||||
Radio.set_frequency(SEC_FREQ)
|
||||
Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", SEC_FREQ)
|
||||
usr << "<span class='notice'>Shuttle recieved message and will be sent shortly.</span>"
|
||||
else
|
||||
usr << "<span class='notice'>Shuttle is already moving.</span>"
|
||||
else
|
||||
usr << "<span class='warning'>Prisoners are only allowed to be released while alone.</span>"
|
||||
else
|
||||
usr << "<span class='notice'>Shuttle is already on-station.</span>"
|
||||
|
||||
if(href_list["choice"] == "release")
|
||||
var/datum/shuttle_manager/s = shuttles["laborcamp"]
|
||||
if(s.location == /area/shuttle/laborcamp/outpost)
|
||||
usr << "<span class='warning'>Prisoners can only be released while docked with the station.</span>"
|
||||
return
|
||||
if(alone_in_area(get_area(loc), usr))
|
||||
if(release_door.density)
|
||||
release_door.open()
|
||||
var/obj/docking_port/stationary/S = SSshuttle.getDock("laborcamp_home")
|
||||
if(S && S.get_docked())
|
||||
if(release_door && release_door.density)
|
||||
release_door.open()
|
||||
else
|
||||
usr << "<span class='warning'>Prisoners can only be released while docked with the station.</span>"
|
||||
else
|
||||
usr << "<span class='warning'>Prisoners are only allowed to be released while alone.</span>"
|
||||
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
desc = "Used to call and send the mining shuttle."
|
||||
req_access = list(access_mining)
|
||||
circuit = /obj/item/weapon/circuitboard/mining_shuttle
|
||||
id = "mining"
|
||||
shuttleId = "mining"
|
||||
possible_destinations = "mining_home;mining_away"
|
||||
|
||||
/******************************Lantern*******************************/
|
||||
|
||||
|
||||
@@ -475,6 +475,7 @@
|
||||
icon_state = "asteroid"
|
||||
icon_plating = "asteroid"
|
||||
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
|
||||
ignoredirt = 1
|
||||
|
||||
/turf/simulated/floor/plating/asteroid/airless
|
||||
oxygen = 0.01
|
||||
|
||||
@@ -126,11 +126,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
//world << "DEBUG: malf mode ticker test"
|
||||
if(malf.malf_mode_declared && (malf.apcs > 0))
|
||||
stat(null, "Time left: [max(malf.AI_win_timeleft/malf.apcs, 0)]")
|
||||
if(emergency_shuttle)
|
||||
if(emergency_shuttle.online && emergency_shuttle.location < 2)
|
||||
var/timeleft = emergency_shuttle.timeleft()
|
||||
if (timeleft)
|
||||
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
var/ETA
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
ETA = "ETA"
|
||||
if(SHUTTLE_DOCKED)
|
||||
ETA = "ETD"
|
||||
if(ETA)
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
stat(null, "[ETA]-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
|
||||
/mob/dead/observer/verb/reenter_corpse()
|
||||
set category = "Ghost"
|
||||
@@ -310,3 +314,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
dat += data_core.get_manifest()
|
||||
|
||||
src << browse(dat, "window=manifest;size=387x420;can_close=1")
|
||||
|
||||
/mob/dead/observer/Topic(href, href_list)
|
||||
if(href_list["follow"])
|
||||
var/atom/movable/target = locate(href_list["follow"])
|
||||
if((usr == src) && istype(target) && (target != src)) //for safety against href exploits
|
||||
ManualFollow(target)
|
||||
|
||||
|
||||
@@ -17,4 +17,5 @@
|
||||
. = src.say_dead(message)
|
||||
|
||||
/mob/dead/observer/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq)
|
||||
src << message
|
||||
src << "<a href=?src=\ref[src];follow=\ref[speaker]>(F)</a> [message]"
|
||||
|
||||
|
||||
@@ -0,0 +1,663 @@
|
||||
#define INTERACTING 2
|
||||
#define TRAVEL 4
|
||||
#define FIGHTING 8
|
||||
|
||||
//TRAITS
|
||||
|
||||
#define TRAIT_ROBUST 2
|
||||
#define TRAIT_UNROBUST 4
|
||||
#define TRAIT_SMART 8
|
||||
#define TRAIT_DUMB 16
|
||||
#define TRAIT_MEAN 32
|
||||
#define TRAIT_FRIENDLY 64
|
||||
#define TRAIT_THIEVING 128
|
||||
|
||||
//defines
|
||||
#define MAX_RANGE_FIND 32
|
||||
#define MIN_RANGE_FIND 16
|
||||
#define FUZZY_CHANCE_HIGH 85
|
||||
#define FUZZY_CHANCE_LOW 50
|
||||
#define CHANCE_TALK 15
|
||||
|
||||
/*
|
||||
NPC VAR EXPLANATIONS (for modules and other things)
|
||||
|
||||
doing = their current action, INTERACTING, TRAVEL or FIGHTING
|
||||
interest = how interested the NPC is in the situation, if they are idle, this drops
|
||||
timeout = this is internal
|
||||
TARGET = their current target
|
||||
LAST_TARGET = their last target
|
||||
nearby = a list of nearby mobs
|
||||
best_force = the highest force object, used for checking when to swap items
|
||||
retal = this is internal
|
||||
retal_target = this is internal
|
||||
update_hands = this is a bool (1/0) to determine if the NPC should update what is in his hands
|
||||
|
||||
MYID = their ID card
|
||||
MYPDA = their PDA
|
||||
main_hand = what is in their "main" hand (chosen from left > right)
|
||||
TRAITS = the traits assigned to this npc
|
||||
mymjob = the job assigned to the npc
|
||||
|
||||
robustness = the chance for the npc to hit something
|
||||
smartness = the inverse chance for an npc to do stupid things
|
||||
attitude = the chance for an npc to do rude or mean things
|
||||
slyness = the chance for an npc to do naughty things ie thieving
|
||||
|
||||
functions = the list of procs that the npc will use for modules
|
||||
|
||||
graytide = shitmin var to make them go psycho
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/interactive
|
||||
name = "interactive station member"
|
||||
var/doing = 0
|
||||
var/interest = 100
|
||||
var/timeout = 0
|
||||
var/inactivity_period = 0
|
||||
var/TARGET = null
|
||||
var/LAST_TARGET = null
|
||||
var/list/nearby = list()
|
||||
var/best_force = 0
|
||||
var/retal = 0
|
||||
var/mob/retal_target = null
|
||||
var/update_hands = 0
|
||||
//Job and mind data
|
||||
var/obj/item/weapon/card/id/MYID
|
||||
var/obj/item/device/pda/MYPDA
|
||||
var/obj/item/main_hand
|
||||
var/obj/item/other_hand
|
||||
var/TRAITS = 0
|
||||
var/datum/job/myjob
|
||||
//trait vars
|
||||
var/robustness = 50
|
||||
var/smartness = 50
|
||||
var/attitude = 50
|
||||
var/slyness = 50
|
||||
var/graytide = 0
|
||||
var/chattyness = CHANCE_TALK
|
||||
//modules
|
||||
var/list/functions = list("nearbyscan","combat","doorscan","shitcurity","chatter")
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/random()
|
||||
//this is here because this has no client/prefs/brain whatever.
|
||||
underwear = random_underwear(gender)
|
||||
skin_tone = random_skin_tone()
|
||||
hair_style = random_hair_style(gender)
|
||||
facial_hair_style = random_facial_hair_style(gender)
|
||||
hair_color = random_short_color()
|
||||
facial_hair_color = hair_color
|
||||
eye_color = random_eye_color()
|
||||
age = rand(AGE_MIN,AGE_MAX)
|
||||
ready_dna(src,random_blood_type())
|
||||
//job handling
|
||||
var/list/jobs = SSjob.occupations
|
||||
for(var/datum/job/J in jobs)
|
||||
if(J.title == "Cyborg" || J.title == "AI" || J.title == "Chaplain" || J.title == "Mime")
|
||||
jobs -= J
|
||||
myjob = pick(jobs)
|
||||
if(!graytide)
|
||||
myjob.equip(src)
|
||||
myjob.apply_fingerprints(src)
|
||||
src.job = myjob
|
||||
|
||||
/mob/living/carbon/human/interactive/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone)
|
||||
..()
|
||||
retal = 1
|
||||
retal_target = user
|
||||
|
||||
/mob/living/carbon/human/interactive/New()
|
||||
..()
|
||||
gender = pick(MALE,FEMALE)
|
||||
if(gender == MALE)
|
||||
name = "[pick(first_names_male)] [pick(last_names)]"
|
||||
real_name = name
|
||||
else
|
||||
name = "[pick(first_names_female)] [pick(last_names)]"
|
||||
real_name = name
|
||||
random()
|
||||
MYID = new(src)
|
||||
MYID.name = "[src.real_name]'s ID Card ([myjob.title])"
|
||||
MYID.assignment = "[myjob.title]"
|
||||
MYID.registered_name = src.real_name
|
||||
MYID.access = myjob.access
|
||||
src.equip_to_slot_or_del(MYID, slot_wear_id)
|
||||
MYPDA = new(src)
|
||||
MYPDA.owner = src.real_name
|
||||
MYPDA.ownjob = "Crew"
|
||||
MYPDA.name = "PDA-[src.real_name] ([myjob.title])"
|
||||
src.equip_to_slot_or_del(MYPDA, slot_belt)
|
||||
zone_sel = new /obj/screen/zone_sel()
|
||||
zone_sel.selecting = "chest"
|
||||
if(prob(10)) //my x is augmented
|
||||
//arms
|
||||
if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH)))
|
||||
var/obj/item/organ/limb/r_arm/R = locate(/obj/item/organ/limb/r_arm) in organs
|
||||
del(R)
|
||||
organs += new /obj/item/organ/limb/robot/r_arm
|
||||
else
|
||||
var/obj/item/organ/limb/l_arm/L = locate(/obj/item/organ/limb/l_arm) in organs
|
||||
del(L)
|
||||
organs += new /obj/item/organ/limb/robot/l_arm
|
||||
//legs
|
||||
if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH)))
|
||||
var/obj/item/organ/limb/r_leg/R = locate(/obj/item/organ/limb/r_leg) in organs
|
||||
del(R)
|
||||
organs += new /obj/item/organ/limb/robot/r_leg
|
||||
else
|
||||
var/obj/item/organ/limb/l_leg/L = locate(/obj/item/organ/limb/l_leg) in organs
|
||||
del(L)
|
||||
organs += new /obj/item/organ/limb/robot/l_leg
|
||||
//chest and head
|
||||
if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH)))
|
||||
var/obj/item/organ/limb/chest/R = locate(/obj/item/organ/limb/chest) in organs
|
||||
del(R)
|
||||
organs += new /obj/item/organ/limb/robot/chest
|
||||
else
|
||||
var/obj/item/organ/limb/head/L = locate(/obj/item/organ/limb/head) in organs
|
||||
del(L)
|
||||
organs += new /obj/item/organ/limb/robot/head
|
||||
for(var/obj/item/organ/limb/LIMB in organs)
|
||||
LIMB.owner = src
|
||||
update_icons()
|
||||
update_damage_overlays(0)
|
||||
update_augments()
|
||||
|
||||
hand = 0
|
||||
|
||||
if(TRAITS & TRAIT_ROBUST)
|
||||
robustness = 75
|
||||
else if(TRAITS & TRAIT_UNROBUST)
|
||||
robustness = 25
|
||||
|
||||
//modifiers are prob chances, lower = smarter
|
||||
if(TRAITS & TRAIT_SMART)
|
||||
smartness = 25
|
||||
else if(TRAITS & TRAIT_DUMB)
|
||||
mutations |= CLUMSY
|
||||
smartness = 75
|
||||
|
||||
if(TRAITS & TRAIT_MEAN)
|
||||
attitude = 75
|
||||
else if(TRAITS & TRAIT_FRIENDLY)
|
||||
attitude = 1
|
||||
|
||||
if(TRAITS & TRAIT_THIEVING)
|
||||
slyness = 75
|
||||
|
||||
|
||||
/mob/living/carbon/human/interactive/attack_hand(mob/living/carbon/human/M as mob)
|
||||
..()
|
||||
if (health > 0)
|
||||
if(M.a_intent == "help")
|
||||
chatter()
|
||||
if(M.a_intent == "harm")
|
||||
retal = 1
|
||||
retal_target = M
|
||||
|
||||
//THESE EXIST FOR DEBUGGING OF THE DOING/INTEREST SYSTEM EASILY
|
||||
/mob/living/carbon/human/interactive/proc/doing2string(var/doin)
|
||||
var/toReturn = ""
|
||||
if(!doin)
|
||||
toReturn = "not doing anything"
|
||||
if(doin & INTERACTING)
|
||||
toReturn += "interacting with something, "
|
||||
if(doin & FIGHTING)
|
||||
toReturn += "engaging in combat, "
|
||||
if(doin & TRAVEL)
|
||||
toReturn += "and going somewhere"
|
||||
return toReturn
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/interest2string(var/inter)
|
||||
var/toReturn = "Flatlined"
|
||||
if(inter >= 0 && inter <= 25)
|
||||
toReturn = "Very Bored"
|
||||
if(inter >= 26 && inter <= 50)
|
||||
toReturn = "Bored"
|
||||
if(inter >= 51 && inter <= 75)
|
||||
toReturn = "Content"
|
||||
if(inter >= 76)
|
||||
toReturn = "Excited"
|
||||
return toReturn
|
||||
//END DEBUG
|
||||
/mob/living/carbon/human/interactive/proc/isnotfunc()
|
||||
if(!canmove)
|
||||
return 1
|
||||
if(health <= 0)
|
||||
return 1
|
||||
if(restrained())
|
||||
return 1
|
||||
if(paralysis)
|
||||
return 1
|
||||
if(stunned)
|
||||
return 1
|
||||
if(stat)
|
||||
return 1
|
||||
if(inactivity_period > 0)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/enforce_hands()
|
||||
if(hand)
|
||||
if(!l_hand)
|
||||
main_hand = null
|
||||
if(r_hand)
|
||||
swap_hands()
|
||||
else
|
||||
if(!r_hand)
|
||||
main_hand = null
|
||||
if(l_hand)
|
||||
swap_hands()
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/swap_hands()
|
||||
hand = !hand
|
||||
var/obj/item/T = other_hand
|
||||
main_hand = other_hand
|
||||
other_hand = T
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/take_to_slot(var/obj/item/G)
|
||||
var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_l_hand,"right hand" = slot_r_hand)
|
||||
G.loc = src
|
||||
if(G.force && G.force > best_force)
|
||||
best_force = G.force
|
||||
equip_in_one_of_slots(G, slots)
|
||||
update_hands = 1
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/insert_into_backpack()
|
||||
var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_l_hand,"right hand" = slot_r_hand)
|
||||
var/obj/item/I = get_item_by_slot(pick(slots))
|
||||
var/obj/item/weapon/storage/BP = get_item_by_slot(slot_back)
|
||||
if(back && BP && I)
|
||||
if(BP.can_be_inserted(I,0))
|
||||
BP.handle_item_insertion(I,0)
|
||||
else
|
||||
unEquip(I,TRUE)
|
||||
update_hands = 1
|
||||
|
||||
/mob/living/carbon/human/interactive/Life()
|
||||
..()
|
||||
if(isnotfunc()) return
|
||||
if(a_intent != "disarm")
|
||||
a_intent = "disarm"
|
||||
//---------------------------
|
||||
//---- interest flow control
|
||||
if(interest < 0 || inactivity_period < 0)
|
||||
if(interest < 0)
|
||||
interest = 0
|
||||
if(inactivity_period < 0)
|
||||
inactivity_period = 0
|
||||
if(interest > 100)
|
||||
interest = 100
|
||||
//---------------------------
|
||||
nearby = list()
|
||||
//VIEW FUNCTIONS
|
||||
|
||||
if(!l_hand || !r_hand)
|
||||
update_hands = 1
|
||||
|
||||
if(update_hands)
|
||||
if(l_hand || r_hand)
|
||||
if(l_hand)
|
||||
hand = 1
|
||||
main_hand = l_hand
|
||||
if(r_hand)
|
||||
other_hand = r_hand
|
||||
else if(r_hand)
|
||||
hand = 0
|
||||
main_hand = r_hand
|
||||
if(l_hand) //this technically shouldnt occur, but its a redundancy
|
||||
other_hand = l_hand
|
||||
update_icons()
|
||||
update_hands = 0
|
||||
|
||||
if(grabbed_by.len > 0)
|
||||
for(var/obj/item/weapon/grab/G in grabbed_by)
|
||||
if(Adjacent(G))
|
||||
a_intent = "disarm"
|
||||
G.assailant.attack_hand(src)
|
||||
inactivity_period = 10
|
||||
|
||||
//proc functions
|
||||
for(var/Proc in functions)
|
||||
if(!isnotfunc())
|
||||
spawn(1)
|
||||
call(src,Proc)(src)
|
||||
|
||||
//target interaction stays hardcoded
|
||||
|
||||
if((TARGET && (TARGET in view(1))) || timeout >= 2)
|
||||
if((TARGET in view(1,src)))//this is a bit redundant but it saves two if blocks
|
||||
doing |= INTERACTING
|
||||
//--------DOORS
|
||||
if(istype(TARGET, /obj/machinery/door))
|
||||
var/obj/machinery/door/D = TARGET
|
||||
if(D.check_access(MYID) && !istype(D,/obj/machinery/door/poddoor))
|
||||
D.open()
|
||||
sleep(15)
|
||||
var/turf/T = get_step(get_step(D.loc,dir),dir) //recursion yo
|
||||
tryWalk(T)
|
||||
//THIEVING SKILLS
|
||||
if(prob(slyness))
|
||||
//---------TOOLS
|
||||
if(istype(TARGET, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = TARGET
|
||||
if(W.force >= best_force || prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH)))
|
||||
if(!l_hand || !r_hand)
|
||||
take_to_slot(W)
|
||||
else
|
||||
insert_into_backpack()
|
||||
//---------FASHION
|
||||
if(istype(TARGET,/obj/item/clothing))
|
||||
if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH)))
|
||||
if(!l_hand || !r_hand)
|
||||
var/obj/item/clothing/C = TARGET
|
||||
take_to_slot(C)
|
||||
if(equip_to_appropriate_slot(C))
|
||||
C.update_icon()
|
||||
else
|
||||
var/obj/item/I = get_item_by_slot(C)
|
||||
unEquip(I)
|
||||
equip_to_appropriate_slot(C)
|
||||
update_hands = 1
|
||||
drop_item()
|
||||
if(MYPDA in src.loc || MYID in src.loc)
|
||||
if(MYPDA in src.loc)
|
||||
equip_to_appropriate_slot(MYPDA)
|
||||
if(MYID in src.loc)
|
||||
equip_to_appropriate_slot(MYID)
|
||||
update_icons()
|
||||
//THIEVING SKILLS END
|
||||
//-------------TOUCH ME
|
||||
if(istype(TARGET,/obj/structure))
|
||||
var/obj/structure/STR = TARGET
|
||||
if(main_hand)
|
||||
var/obj/item/weapon/W = main_hand
|
||||
STR.attackby(W, src)
|
||||
else
|
||||
STR.attack_hand(src)
|
||||
interest = interest + 25
|
||||
doing = doing & ~INTERACTING
|
||||
timeout = 0
|
||||
TARGET = null
|
||||
else
|
||||
tryWalk(TARGET)
|
||||
timeout++
|
||||
if(!doing)
|
||||
interest--
|
||||
else
|
||||
interest++
|
||||
if(inactivity_period > 0)
|
||||
inactivity_period--
|
||||
|
||||
//this is boring, lets move
|
||||
if(!doing && !isnotfunc() && !TARGET)
|
||||
doing |= TRAVEL
|
||||
if(nearby.len > 4)
|
||||
//i'm crowded, time to leave
|
||||
TARGET = pick(target_filter(orange(MAX_RANGE_FIND,src)))
|
||||
else if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH)))
|
||||
//chance to chase an item
|
||||
TARGET = locate(/obj/item) in orange(MIN_RANGE_FIND,src)
|
||||
else if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH)))
|
||||
//chance to leave
|
||||
TARGET = locate(/obj/machinery/door) in orange(MIN_RANGE_FIND,src) // this is a sort of fix for the current pathing.
|
||||
else
|
||||
//else, target whatever, or go to our department
|
||||
if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH)))
|
||||
TARGET = pick(target_filter(orange(MIN_RANGE_FIND,src)))
|
||||
else
|
||||
TARGET = pick(get_area_turfs(job2area(myjob)))
|
||||
tryWalk(TARGET)
|
||||
LAST_TARGET = TARGET
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/tryWalk(var/turf/TARGET)
|
||||
if(!isnotfunc())
|
||||
if(!walk2derpless(TARGET))
|
||||
timeout++
|
||||
else
|
||||
timeout++
|
||||
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/walk2derpless(var/target)
|
||||
set background = 1
|
||||
var/turf/T = get_turf(target)
|
||||
var/turf/D = get_step(src,dir)
|
||||
if(D)
|
||||
if(!D.density)
|
||||
walk_to(src,T,0,5)
|
||||
doing = doing & ~TRAVEL
|
||||
return 1
|
||||
else
|
||||
sidestep(D)
|
||||
doing = doing & ~TRAVEL
|
||||
return 0
|
||||
else
|
||||
doing = doing & ~TRAVEL
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/job2area(var/target)
|
||||
var/datum/job/T = target
|
||||
if(T.title == "Assistant")
|
||||
return /area/hallway/primary
|
||||
if(T.title == "Captain" || T.title == "Head of Personnel")
|
||||
return /area/bridge
|
||||
if(T.title == "Bartender" || T.title == "Chef")
|
||||
return /area/crew_quarters
|
||||
if(T.title == "Station Engineer" || T.title == "Chief Engineer" || T.title == "Atmospheric Technician")
|
||||
return /area/engine
|
||||
if(T.title == "Chief Medical Officer" || T.title == "Medical Doctor" || T.title == "Chemist" || T.title == "Virologist" || T.title == "Geneticist")
|
||||
return /area/medical
|
||||
if(T.title == "Research Director" || T.title == "Scientist" || T.title == "Roboticist")
|
||||
return /area/toxins
|
||||
if(T.title == "Head of Security" || T.title == "Warden" || T.title == "Security Officer" || T.title == "Detective")
|
||||
return /area/security
|
||||
else
|
||||
return pick(/area/hallway,/area/crew_quarters)
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/target_filter(var/target)
|
||||
var/list/L = target
|
||||
for(var/atom/A in target)
|
||||
if(istype(A,/area) || istype(A,/turf/unsimulated) || istype(A,/turf/space))
|
||||
L -= A
|
||||
return L
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/denied_filter(var/target)
|
||||
var/list/denied = list(/obj/structure/window,/obj/structure/table) //expand me
|
||||
for(var/a in denied)
|
||||
if(istype(target,a))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
///BUILT IN MODULES
|
||||
/mob/living/carbon/human/interactive/proc/chatter(obj)
|
||||
var/verbs_use = pick_list("npc_chatter.txt","verbs_use")
|
||||
var/verbs_touch = pick_list("npc_chatter.txt","verbs_touch")
|
||||
var/verbs_move = pick_list("npc_chatter.txt","verbs_move")
|
||||
var/nouns_insult = pick_list("npc_chatter.txt","nouns_insult")
|
||||
var/nouns_generic = pick_list("npc_chatter.txt","nouns_generic")
|
||||
var/nouns_objects = pick_list("npc_chatter.txt","nouns_objects")
|
||||
var/nouns_body = pick_list("npc_chatter.txt","nouns_body")
|
||||
var/adjective_insult = pick_list("npc_chatter.txt","adjective_insult")
|
||||
var/adjective_objects = pick_list("npc_chatter.txt","adjective_objects")
|
||||
var/adjective_generic = pick_list("npc_chatter.txt","adjective_generic")
|
||||
var/curse_words = pick_list("npc_chatter.txt","curse_words")
|
||||
|
||||
if(doing & INTERACTING)
|
||||
if(prob(chattyness))
|
||||
var/chat = pick("This [nouns_objects] is a little [adjective_objects].",
|
||||
"Well [verbs_use] my [nouns_body], this [nouns_insult] is pretty [adjective_insult].",
|
||||
"[capitalize(curse_words)], what am I meant to do with this [adjective_insult] [nouns_objects].")
|
||||
src.say(chat)
|
||||
if(doing & TRAVEL)
|
||||
if(prob(chattyness))
|
||||
var/chat = pick("Oh [curse_words], [verbs_move]!",
|
||||
"Time to get my [adjective_generic] [adjective_insult] [nouns_body] elsewhere.",
|
||||
"I wonder if there is anything to [verbs_use] and [verbs_touch] somewhere else..")
|
||||
src.say(chat)
|
||||
if(doing & FIGHTING)
|
||||
if(prob(chattyness))
|
||||
var/chat = pick("I'm going to [verbs_use] you, you [adjective_insult] [nouns_insult]!",
|
||||
"Rend and [verbs_touch], Rend and [verbs_use]!",
|
||||
"You [nouns_insult], I'm going to [verbs_use] you right in the [nouns_body]. JUST YOU WAIT!")
|
||||
src.say(chat)
|
||||
if(prob(chattyness/2))
|
||||
var/what = pick(1,2,3,4,5)
|
||||
switch(what)
|
||||
if(1)
|
||||
src.say("Well [curse_words], this is a [adjective_generic] situation.")
|
||||
if(2)
|
||||
src.say("Oh [curse_words], that [nouns_insult] was one hell of an [adjective_insult] [nouns_body].")
|
||||
if(3)
|
||||
src.say("I want to [verbs_use] that [nouns_insult] when I find them.")
|
||||
if(4)
|
||||
src.say("[pick("Innocent","Guilty","Traitorous","Honk")] until proven [adjective_generic]!")
|
||||
if(5)
|
||||
var/toSay = ""
|
||||
for(var/i = 0; i < 5; i++)
|
||||
curse_words = pick_list("npc_chatter.txt","curse_words")
|
||||
toSay += "[curse_words] "
|
||||
src.say("Hey [nouns_generic], why dont you go [toSay], you [nouns_insult]!")
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/shitcurity(obj)
|
||||
if(retal && TARGET)
|
||||
for(var/obj/item/I in src.contents)
|
||||
if(istype(I,/obj/item/weapon/restraints/handcuffs))
|
||||
take_to_slot(I)
|
||||
I.attack(TARGET,src)
|
||||
sleep(25)
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/sidestep(obj)
|
||||
var/shift = 0
|
||||
for(var/dir in cardinal)
|
||||
var/turf/T = get_step(src,dir)
|
||||
if(T)
|
||||
for(var/obj/A in T.contents)
|
||||
if(denied_filter(A))
|
||||
shift = 1
|
||||
if(T.density)
|
||||
shift = 1
|
||||
if(shift)
|
||||
if(src.dir == NORTH || SOUTH)
|
||||
var/towalk = pick(EAST,WEST)
|
||||
walk_to(src,get_step(src,towalk),0,5)
|
||||
else
|
||||
var/towalk = pick(NORTH,SOUTH)
|
||||
walk_to(src,get_step(src,towalk),0,5)
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/combat(obj)
|
||||
set background = 1
|
||||
enforce_hands()
|
||||
if(canmove)
|
||||
if(prob(attitude) && (graytide || (TRAITS & TRAIT_MEAN)) || retal)
|
||||
a_intent = "harm"
|
||||
zone_sel.selecting = pick("chest","r_leg","l_leg","r_arm","l_arm","head")
|
||||
doing |= FIGHTING
|
||||
if(retal)
|
||||
TARGET = retal_target
|
||||
else
|
||||
var/mob/living/M = locate(/mob/living) in oview(7,src)
|
||||
if(istype(M,/mob/living/carbon/human/interactive/greytide))
|
||||
return
|
||||
if(M != src)
|
||||
TARGET = M
|
||||
if(!M)
|
||||
doing = doing & ~FIGHTING
|
||||
|
||||
if((TARGET && (doing & FIGHTING)) || graytide) // this is a redundancy check
|
||||
var/mob/living/M = TARGET
|
||||
if(istype(M,/mob/living))
|
||||
if(M in range(FUZZY_CHANCE_LOW,src))
|
||||
if(M.health > 1)
|
||||
if(main_hand)
|
||||
if(main_hand.force != 0)
|
||||
if(istype(main_hand,/obj/item/weapon/gun/projectile))
|
||||
var/obj/item/weapon/gun/projectile/P = main_hand
|
||||
if(!P.chambered)
|
||||
P.chamber_round()
|
||||
P.update_icon()
|
||||
else if(P.get_ammo(1) == 0)
|
||||
P.attack_self(src)
|
||||
else
|
||||
P.afterattack(TARGET, src)
|
||||
else if(istype(main_hand,/obj/item/weapon/gun/energy))
|
||||
var/obj/item/weapon/gun/energy/P = main_hand
|
||||
if(!P.can_shoot())
|
||||
P.update_icon()
|
||||
drop_item()
|
||||
else
|
||||
P.afterattack(TARGET, src)
|
||||
else
|
||||
if(get_dist(src,TARGET) > 2)
|
||||
if(!walk2derpless(TARGET))
|
||||
timeout++
|
||||
else
|
||||
var/obj/item/weapon/W = main_hand
|
||||
if(prob(robustness))
|
||||
W.attack(TARGET,src)
|
||||
sleep(1)
|
||||
else
|
||||
if(get_dist(src,TARGET) > 2)
|
||||
tryWalk(TARGET)
|
||||
else
|
||||
if(Adjacent(TARGET))
|
||||
M.attack_hand(src)
|
||||
sleep(1)
|
||||
timeout++
|
||||
else if(timeout >= 10 || M.health <= 1 || !(M in range(14,src)))
|
||||
doing = doing & ~FIGHTING
|
||||
timeout = 0
|
||||
TARGET = null
|
||||
retal = 0
|
||||
retal_target = null
|
||||
else
|
||||
timeout++
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/doorscan(obj)
|
||||
for(var/dir in cardinal)
|
||||
var/turf/T = get_step(src,dir)
|
||||
if(T)
|
||||
for(var/obj/machinery/door/D in T.contents)
|
||||
if(D.check_access(MYID) && !istype(D,/obj/machinery/door/poddoor) && D.density)
|
||||
//layer 3.1 is "closed" for most doors, this is just a hacky !open check because i cannot find an open var
|
||||
spawn(1)
|
||||
D.open()
|
||||
sleep(5)
|
||||
walk2derpless(get_step(D,dir))
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/nearbyscan(obj)
|
||||
for(var/mob/living/M in view(4,src))
|
||||
if(M != src)
|
||||
nearby += M
|
||||
|
||||
//END OF MODULES
|
||||
/mob/living/carbon/human/interactive/angry
|
||||
New()
|
||||
TRAITS |= TRAIT_ROBUST
|
||||
TRAITS |= TRAIT_MEAN
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/interactive/friendly
|
||||
New()
|
||||
TRAITS |= TRAIT_FRIENDLY
|
||||
TRAITS |= TRAIT_UNROBUST
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/interactive/greytide
|
||||
New()
|
||||
TRAITS |= TRAIT_ROBUST
|
||||
TRAITS |= TRAIT_MEAN
|
||||
TRAITS |= TRAIT_THIEVING
|
||||
TRAITS |= TRAIT_DUMB
|
||||
graytide = 1
|
||||
..()
|
||||
|
||||
#undef INTERACTING
|
||||
#undef TRAVEL
|
||||
#undef FIGHTING
|
||||
#undef TRAIT_ROBUST
|
||||
#undef TRAIT_UNROBUST
|
||||
#undef TRAIT_SMART
|
||||
#undef TRAIT_DUMB
|
||||
#undef TRAIT_MEAN
|
||||
#undef TRAIT_FRIENDLY
|
||||
#undef TRAIT_THIEVING
|
||||
@@ -160,12 +160,15 @@
|
||||
if (client.statpanel == "Status")
|
||||
stat(null, "Plasma Stored: [getPlasma()]/[max_plasma]")
|
||||
|
||||
if(emergency_shuttle)
|
||||
if(emergency_shuttle.online && emergency_shuttle.location < 2)
|
||||
var/timeleft = emergency_shuttle.timeleft()
|
||||
if (timeleft)
|
||||
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
|
||||
var/ETA
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
ETA = "ETA"
|
||||
if(SHUTTLE_DOCKED)
|
||||
ETA = "ETD"
|
||||
if(ETA)
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
stat(null, "[ETA]-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
/mob/living/carbon/alien/Stun(amount)
|
||||
if(status_flags & CANSTUN)
|
||||
stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
//First, resolve location and get a breath
|
||||
|
||||
if(air_master.current_cycle%4==2)
|
||||
if(SSmob.times_fired%4==2)
|
||||
//Only try to take a breath every 4 seconds, unless suffocating
|
||||
spawn(0) breathe()
|
||||
|
||||
@@ -238,3 +238,4 @@
|
||||
reset_view(null)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
amount_grown++
|
||||
|
||||
//First, resolve location and get a breath
|
||||
if(air_master.current_cycle%4==2)
|
||||
if(SSair.times_fired%4==2)
|
||||
//Only try to take a breath every 4 seconds, unless suffocating
|
||||
spawn(0) breathe()
|
||||
else //Still give containing object the chance to interact
|
||||
@@ -215,3 +215,4 @@
|
||||
|
||||
/mob/living/carbon/alien/larva/proc/handle_random_events()
|
||||
return
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
stomach_contents.Remove(M)
|
||||
qdel(M)
|
||||
continue
|
||||
if(air_master.current_cycle%3==1)
|
||||
if(SSmob.times_fired%3==1)
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(5)
|
||||
nutrition += 10
|
||||
|
||||
@@ -14,10 +14,11 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
|
||||
if(istype(loc, /mob/living))
|
||||
affected_mob = loc
|
||||
affected_mob.status_flags |= XENO_HOST
|
||||
SSobj.processing.Add(src)
|
||||
if(istype(affected_mob,/mob/living/carbon))
|
||||
var/mob/living/carbon/H = affected_mob
|
||||
H.med_hud_set_status()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
spawn(0)
|
||||
AddInfectionImages(affected_mob)
|
||||
else
|
||||
@@ -37,10 +38,11 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
|
||||
if(!affected_mob) return
|
||||
if(loc != affected_mob)
|
||||
affected_mob.status_flags &= ~(XENO_HOST)
|
||||
SSobj.processing.Remove(src)
|
||||
if(istype(affected_mob,/mob/living/carbon))
|
||||
var/mob/living/carbon/H = affected_mob
|
||||
H.med_hud_set_status()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
spawn(0)
|
||||
RemoveInfectionImages(affected_mob)
|
||||
affected_mob = null
|
||||
|
||||
@@ -239,7 +239,9 @@
|
||||
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
|
||||
|
||||
if(getorgan(/obj/item/organ/brain))
|
||||
if(!key)
|
||||
if(istype(src,/mob/living/carbon/human/interactive))
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
|
||||
else if(!key)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.</span>\n"
|
||||
else if(!client)
|
||||
msg += "[t_He] [t_has] a vacant, braindead stare...\n"
|
||||
|
||||
@@ -53,20 +53,25 @@
|
||||
/mob/living/carbon/human/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
|
||||
var/datum/game_mode/malfunction/malf = ticker.mode
|
||||
if(malf.malf_mode_declared && (malf.apcs > 0))
|
||||
stat(null, "Time left: [max(malf.AI_win_timeleft/malf.apcs, 0)]")
|
||||
if(emergency_shuttle)
|
||||
if(emergency_shuttle.online && emergency_shuttle.location < 2)
|
||||
var/timeleft = emergency_shuttle.timeleft()
|
||||
if (timeleft)
|
||||
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
|
||||
if (client.statpanel == "Status")
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
|
||||
var/datum/game_mode/malfunction/malf = ticker.mode
|
||||
if(malf.malf_mode_declared && (malf.apcs > 0))
|
||||
stat(null, "Time left: [max(malf.AI_win_timeleft/malf.apcs, 0)]")
|
||||
|
||||
var/ETA
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
ETA = "ETA"
|
||||
if(SHUTTLE_DOCKED)
|
||||
ETA = "ETD"
|
||||
if(ETA)
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
stat(null, "[ETA]-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
|
||||
|
||||
if (internal)
|
||||
if (!internal.air_contents)
|
||||
qdel(internal)
|
||||
|
||||
@@ -62,9 +62,8 @@
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_life(src)
|
||||
|
||||
if(air_master.current_cycle%4==2 || failed_last_breath) //First, resolve location and get a breath
|
||||
if(SSmob.times_fired%4==2 || failed_last_breath) //First, resolve location and get a breath
|
||||
breathe() //Only try to take a breath every 4 ticks, unless suffocating
|
||||
|
||||
else //Still give containing object the chance to interact
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
@@ -679,7 +678,7 @@
|
||||
stomach_contents.Remove(M)
|
||||
qdel(M)
|
||||
continue
|
||||
if(air_master.current_cycle%3==1)
|
||||
if(SSmob.times_fired%3==1)
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(5)
|
||||
nutrition += 10
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define TINT_BLIND 3
|
||||
|
||||
#define HUMAN_MAX_OXYLOSS 3
|
||||
#define HUMAN_CRIT_MAX_OXYLOSS ( (last_tick_duration) /3)
|
||||
#define HUMAN_CRIT_MAX_OXYLOSS (SSmob.wait/3)
|
||||
|
||||
#define HEAT_DAMAGE_LEVEL_1 2
|
||||
#define HEAT_DAMAGE_LEVEL_2 3
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
if (stat != DEAD) //still breathing
|
||||
//First, resolve location and get a breath
|
||||
if(air_master.current_cycle%4==2)
|
||||
if(SSmob.times_fired%4==2)
|
||||
//Only try to take a breath every 4 seconds, unless suffocating
|
||||
breathe()
|
||||
else //Still give containing object the chance to interact
|
||||
@@ -392,7 +392,7 @@
|
||||
//Ears
|
||||
if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own
|
||||
ear_deaf = max(ear_deaf, 1)
|
||||
else
|
||||
else
|
||||
/* might be better to create a variable here, and instead of doing this nested for. */
|
||||
// deafness heals slowly over time, unless ear_damage is over 100
|
||||
if (ear_damage < 100)
|
||||
|
||||
@@ -664,30 +664,30 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "bottle19"
|
||||
|
||||
attack(mob/living/carbon/slime/M as mob, mob/user as mob)
|
||||
if(!istype(M, /mob/living/carbon/slime/))//If target is not a slime.
|
||||
user << "<span class='warning'> The potion only works on slimes!</span>"
|
||||
return ..()
|
||||
if(M.stat)
|
||||
user << "<span class='warning'> The slime is dead!</span>"
|
||||
return..()
|
||||
if(M.mind)
|
||||
user << "<span class='warning'> The slime resists!</span>"
|
||||
return ..()
|
||||
var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc)
|
||||
pet.icon_state = "[M.colour] adult slime"
|
||||
pet.icon_living = "[M.colour] adult slime"
|
||||
pet.icon_dead = "[M.colour] baby slime dead"
|
||||
pet.colour = "[M.colour]"
|
||||
user <<"You feed the slime the potion, removing it's powers and calming it."
|
||||
qdel(M)
|
||||
var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN)
|
||||
/obj/item/weapon/slimepotion2/attack(mob/living/carbon/slime/M as mob, mob/user as mob)
|
||||
if(!istype(M, /mob/living/carbon/slime/))//If target is not a slime.
|
||||
user << "<span class='warning'> The potion only works on slimes!</span>"
|
||||
return ..()
|
||||
if(M.stat)
|
||||
user << "<span class='warning'> The slime is dead!</span>"
|
||||
return..()
|
||||
if(M.mind)
|
||||
user << "<span class='warning'> The slime resists!</span>"
|
||||
return ..()
|
||||
var/mob/living/simple_animal/slime/adult/pet = new /mob/living/simple_animal/slime/adult(M.loc)
|
||||
pet.icon_state = "[M.colour] adult slime"
|
||||
pet.icon_living = "[M.colour] adult slime"
|
||||
pet.icon_dead = "[M.colour] baby slime dead"
|
||||
pet.colour = "[M.colour]"
|
||||
user <<"You feed the slime the potion, removing it's powers and calming it."
|
||||
qdel(M)
|
||||
var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN)
|
||||
|
||||
if (!newname)
|
||||
newname = "pet slime"
|
||||
pet.name = newname
|
||||
pet.real_name = newname
|
||||
qdel(src)
|
||||
if (!newname)
|
||||
newname = "pet slime"
|
||||
pet.name = newname
|
||||
pet.real_name = newname
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/weapon/slimesteroid
|
||||
@@ -805,7 +805,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
|
||||
|
||||
New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
/obj/effect/golemrune/process()
|
||||
var/mob/dead/observer/ghost
|
||||
@@ -917,11 +917,11 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Grow()
|
||||
grown = 1
|
||||
icon_state = "slime egg-grown"
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Hatch()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
var/turf/T = get_turf(src)
|
||||
src.visible_message("<span class='warning'> The [name] pulsates and quivers!</span>")
|
||||
spawn(rand(50,100))
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
/* I am informed this was added by Giacom to reduce mob-stacking in escape pods.
|
||||
It's sorta problematic atm due to the shuttle changes I am trying to do
|
||||
Sorry Giacom. Please don't be mad :(
|
||||
/mob/living/Life()
|
||||
..()
|
||||
var/area/cur_area = get_area(loc)
|
||||
if(cur_area)
|
||||
cur_area.mob_activate(src)
|
||||
var/area/A = get_area(loc)
|
||||
if(A && A.push_dir)
|
||||
push_mob_back(src, A.push_dir)
|
||||
*/
|
||||
|
||||
/mob/living/Destroy()
|
||||
// if(mind)
|
||||
|
||||
@@ -135,7 +135,7 @@ var/list/ai_list = list()
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
ai_list -= src
|
||||
shuttle_caller_list -= src
|
||||
emergency_shuttle.autoshuttlecall()
|
||||
SSshuttle.autoEvac()
|
||||
..()
|
||||
|
||||
|
||||
@@ -177,10 +177,15 @@ var/list/ai_list = list()
|
||||
..()
|
||||
statpanel("Status")
|
||||
if (client.statpanel == "Status")
|
||||
if(emergency_shuttle.online && emergency_shuttle.location < 2)
|
||||
var/timeleft = emergency_shuttle.timeleft()
|
||||
if (timeleft)
|
||||
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
var/ETA
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
ETA = "ETA"
|
||||
if(SHUTTLE_DOCKED)
|
||||
ETA = "ETD"
|
||||
if(ETA)
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
stat(null, "[ETA]-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
|
||||
if(ticker.mode.name == "AI malfunction")
|
||||
var/datum/game_mode/malfunction/malf = ticker.mode
|
||||
@@ -237,7 +242,7 @@ var/list/ai_list = list()
|
||||
onclose(src, "airoster")
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_call_shuttle()
|
||||
if(src.stat == 2)
|
||||
if(src.stat == DEAD)
|
||||
src << "You can't call the shuttle because you are dead!"
|
||||
return
|
||||
if(istype(usr,/mob/living/silicon/ai))
|
||||
@@ -248,11 +253,11 @@ var/list/ai_list = list()
|
||||
|
||||
var/reason = input(src, "What is the nature of your emergency? ([CALL_SHUTTLE_REASON_LENGTH] characters required.)", "Confirm Shuttle Call") as text
|
||||
|
||||
if(length(trim(reason)) > 0)
|
||||
call_shuttle_proc(src, reason)
|
||||
if(trim(reason))
|
||||
SSshuttle.requestEvac(src, reason)
|
||||
|
||||
// hack to display shuttle timer
|
||||
if(emergency_shuttle.online)
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_CALL)
|
||||
var/obj/machinery/computer/communications/C = locate() in machines
|
||||
if(C)
|
||||
C.post_status("shuttle")
|
||||
@@ -285,7 +290,7 @@ var/list/ai_list = list()
|
||||
if(AI.control_disabled)
|
||||
src << "Wireless control is disabled!"
|
||||
return
|
||||
cancel_call_proc(src)
|
||||
SSshuttle.cancelEvac(src)
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/check_eye(var/mob/user as mob)
|
||||
@@ -368,7 +373,7 @@ var/list/ai_list = list()
|
||||
return
|
||||
|
||||
if (href_list["callbot"]) //Command a bot to move to a selected location.
|
||||
Bot = locate(href_list["callbot"]) in aibots
|
||||
Bot = locate(href_list["callbot"]) in SSbot.processing
|
||||
if(!Bot || Bot.remote_disabled || src.control_disabled)
|
||||
return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off.
|
||||
waypoint_mode = 1
|
||||
@@ -376,7 +381,7 @@ var/list/ai_list = list()
|
||||
return
|
||||
|
||||
if (href_list["interface"]) //Remotely connect to a bot!
|
||||
Bot = locate(href_list["interface"]) in aibots
|
||||
Bot = locate(href_list["interface"]) in SSbot.processing
|
||||
if(!Bot || Bot.remote_disabled || src.control_disabled)
|
||||
return
|
||||
Bot.attack_ai(src)
|
||||
@@ -459,7 +464,7 @@ var/list/ai_list = list()
|
||||
d += "<A HREF=?src=\ref[src];botrefresh=\ref[Bot]>Query network status</A><br>"
|
||||
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='30%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
|
||||
|
||||
for (Bot in aibots)
|
||||
for (Bot in SSbot.processing)
|
||||
if(Bot.z == ai_Zlevel && !Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
|
||||
bot_area = get_area(Bot)
|
||||
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name]</td>"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
shuttle_caller_list -= src
|
||||
emergency_shuttle.autoshuttlecall()
|
||||
SSshuttle.autoEvac()
|
||||
|
||||
if(explosive)
|
||||
spawn(10)
|
||||
|
||||
@@ -80,10 +80,15 @@
|
||||
..()
|
||||
statpanel("Status")
|
||||
if (src.client.statpanel == "Status")
|
||||
if(emergency_shuttle.online && emergency_shuttle.location < 2)
|
||||
var/timeleft = emergency_shuttle.timeleft()
|
||||
if (timeleft)
|
||||
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
var/ETA
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
ETA = "ETA"
|
||||
if(SHUTTLE_DOCKED)
|
||||
ETA = "ETD"
|
||||
if(ETA)
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
stat(null, "[ETA]-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
if(src.silence_time)
|
||||
var/timeleft = round((silence_time - world.timeofday)/10 ,1)
|
||||
stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
|
||||
@@ -292,10 +292,16 @@
|
||||
..()
|
||||
statpanel("Status")
|
||||
if (client.statpanel == "Status")
|
||||
if(emergency_shuttle.online && emergency_shuttle.location < 2)
|
||||
var/timeleft = emergency_shuttle.timeleft()
|
||||
if (timeleft)
|
||||
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
var/ETA
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
ETA = "ETA"
|
||||
if(SHUTTLE_DOCKED)
|
||||
ETA = "ETD"
|
||||
if(ETA)
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
stat(null, "[ETA]-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
|
||||
|
||||
if(ticker.mode.name == "AI malfunction")
|
||||
var/datum/game_mode/malfunction/malf = ticker.mode
|
||||
@@ -846,6 +852,9 @@
|
||||
var/turf/tile = loc
|
||||
if(isturf(tile))
|
||||
tile.clean_blood()
|
||||
if (istype(tile, /turf/simulated/floor))
|
||||
var/turf/simulated/floor/F = tile
|
||||
F.dirt = 0
|
||||
for(var/A in tile)
|
||||
if(istype(A, /obj/effect))
|
||||
if(istype(A, /obj/effect/rune) || istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/overlay))
|
||||
|
||||
@@ -251,7 +251,7 @@ var/global/chicken_count = 0
|
||||
E.pixel_x = rand(-6,6)
|
||||
E.pixel_y = rand(-6,6)
|
||||
if(chicken_count < MAX_CHICKENS && prob(25))
|
||||
processing_objects.Add(E)
|
||||
SSobj.processing.Add(E)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/process()
|
||||
@@ -260,7 +260,7 @@ var/global/chicken_count = 0
|
||||
if(amount_grown >= 100)
|
||||
visible_message("[src] hatches with a quiet cracking sound.")
|
||||
new /mob/living/simple_animal/chick(get_turf(src))
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
qdel(src)
|
||||
else
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
|
||||
@@ -15,34 +15,21 @@
|
||||
ventcrawler = 2
|
||||
var/colour = "grey"
|
||||
|
||||
/mob/living/simple_animal/adultslime
|
||||
name = "pet slime"
|
||||
desc = "A lovable, domesticated slime."
|
||||
icon = 'icons/mob/slimes.dmi'
|
||||
/mob/living/simple_animal/slime/adult
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
icon_state = "grey adult slime"
|
||||
icon_living = "grey adult slime"
|
||||
icon_dead = "grey baby slime dead"
|
||||
response_help = "pets"
|
||||
response_disarm = "shoos"
|
||||
response_harm = "stomps on"
|
||||
emote_see = list("jiggles", "bounces in place")
|
||||
var/colour = "grey"
|
||||
|
||||
/mob/living/simple_animal/adultslime/New()
|
||||
/mob/living/simple_animal/slime/adult/New()
|
||||
..()
|
||||
overlays += "aslime-:33"
|
||||
|
||||
/mob/living/simple_animal/slime/adult/Die()
|
||||
var/mob/living/simple_animal/slime/S1 = new /mob/living/simple_animal/slime (src.loc)
|
||||
S1.icon_state = "[src.colour] baby slime"
|
||||
S1.icon_living = "[src.colour] baby slime"
|
||||
S1.icon_dead = "[src.colour] baby slime dead"
|
||||
S1.colour = "[src.colour]"
|
||||
var/mob/living/simple_animal/slime/S2 = new /mob/living/simple_animal/slime (src.loc)
|
||||
S2.icon_state = "[src.colour] baby slime"
|
||||
S2.icon_living = "[src.colour] baby slime"
|
||||
S2.icon_dead = "[src.colour] baby slime dead"
|
||||
S2.colour = "[src.colour]"
|
||||
for(var/i = 0, i<=1, i++)
|
||||
var/mob/living/simple_animal/slime/S1 = new /mob/living/simple_animal/slime (src.loc)
|
||||
S1.icon_state = "[colour] baby slime"
|
||||
S1.icon_living = "[colour] baby slime"
|
||||
S1.icon_dead = "[colour] baby slime dead"
|
||||
S1.colour = "[colour]"
|
||||
qdel(src)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
F
|
||||
|
||||
/mob/living/simple_animal/hostile/carp
|
||||
name = "space carp"
|
||||
desc = "A ferocious, fang-bearing creature that resembles a fish."
|
||||
|
||||
@@ -346,7 +346,7 @@
|
||||
user << "<span class='notice'> [src] is dead, medical items won't bring it back to life.</span>"
|
||||
return
|
||||
if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
|
||||
if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
|
||||
if(istype(O, /obj/item/weapon/kitchenknife))
|
||||
harvest()
|
||||
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/Logout()
|
||||
nanomanager.user_logout(src) // this is used to clean up (remove) this user's Nano UIs
|
||||
SSnano.user_logout(src) // this is used to clean up (remove) this user's Nano UIs
|
||||
player_list -= src
|
||||
log_access("Logout: [key_name(src)]")
|
||||
if(admin_datums[src.ckey])
|
||||
|
||||
+10
-21
@@ -43,7 +43,7 @@ var/next_mob_id = 0
|
||||
t+= "<span class='notice'>Plasma : [environment.toxins] \n</span>"
|
||||
t+= "<span class='notice'>Carbon Dioxide: [environment.carbon_dioxide] \n</span>"
|
||||
for(var/datum/gas/trace_gas in environment.trace_gases)
|
||||
usr << "<span class='notice'>[trace_gas.type]: [trace_gas.moles] \n</span>"
|
||||
t+= "<span class='notice'>[trace_gas.type]: [trace_gas.moles] \n</span>"
|
||||
|
||||
usr.show_message(t, 1)
|
||||
|
||||
@@ -669,29 +669,18 @@ var/list/slot_equipment_priority = list( \
|
||||
..()
|
||||
|
||||
if(client && client.holder)
|
||||
|
||||
if(statpanel("Status")) //not looking at that panel
|
||||
stat(null,"Location:\t([x], [y], [z])")
|
||||
stat(null,"CPU:\t[world.cpu]")
|
||||
stat(null,"Instances:\t[world.contents.len]")
|
||||
if(statpanel("MC"))
|
||||
stat("Location:","([x], [y], [z])")
|
||||
stat("CPU:","[world.cpu]")
|
||||
stat("Instances:","[world.contents.len]")
|
||||
|
||||
if(master_controller)
|
||||
stat(null,"MasterController-[last_tick_duration] ([master_controller.processing?"On":"Off"]-[controller_iteration])")
|
||||
stat(null,"Air-[master_controller.air_cost]\t#[global_activeturfs]")
|
||||
stat(null,"Turfs-[master_controller.air_turfs]\tGroups-[master_controller.air_groups]")
|
||||
stat(null,"SC-[master_controller.air_superconductivity]\tHP-[master_controller.air_highpressure]\tH-[master_controller.air_hotspots]")
|
||||
stat(null,"Sun-[master_controller.sun_cost]")
|
||||
stat(null,"Mob-[master_controller.mobs_cost]\t#[mob_list.len]")
|
||||
stat(null,"Dis-[master_controller.diseases_cost]\t#[active_diseases.len]")
|
||||
stat(null,"Mch-[master_controller.machines_cost]\t#[machines.len]")
|
||||
stat(null,"Bots-[master_controller.aibots_cost]\t#[aibots.len]")
|
||||
stat(null,"Obj-[master_controller.objects_cost]\t#[processing_objects.len]")
|
||||
stat(null,"Net-[master_controller.networks_cost]\tPnet-[master_controller.powernets_cost]")
|
||||
stat(null,"NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]")
|
||||
stat(null,"GC-[master_controller.gc_cost]\t#[garbage.destroyed.len]-#dels[garbage.dels]")
|
||||
stat(null,"Tick-[master_controller.ticker_cost]\tALL-[master_controller.total_cost]")
|
||||
stat("MasterController:","[round(master_controller.cost,0.001)]ds (Interval:[master_controller.processing_interval] | Iteration:[master_controller.iteration])")
|
||||
for(var/datum/subsystem/SS in master_controller.subsystems)
|
||||
if(SS.can_fire)
|
||||
SS.stat_entry()
|
||||
else
|
||||
stat(null,"MasterController-ERROR")
|
||||
stat("MasterController:","ERROR")
|
||||
|
||||
if(listed_turf && client)
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
/mob/new_player
|
||||
var/ready = 0
|
||||
var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
|
||||
var/totalPlayers = 0 //Player counts for the Lobby tab
|
||||
var/totalPlayersReady = 0
|
||||
|
||||
flags = NONE
|
||||
|
||||
@@ -67,28 +65,16 @@
|
||||
/mob/new_player/Stat()
|
||||
..()
|
||||
|
||||
statpanel("Lobby")
|
||||
if(client.statpanel == "Lobby" && ticker)
|
||||
if(ticker.hide_mode)
|
||||
stat("Game Mode:", "Secret")
|
||||
else
|
||||
stat("Game Mode:", "[master_mode]")
|
||||
|
||||
if((ticker.current_state == GAME_STATE_PREGAME) && going)
|
||||
stat("Time To Start:", ticker.pregame_timeleft)
|
||||
if((ticker.current_state == GAME_STATE_PREGAME) && !going)
|
||||
stat("Time To Start:", "DELAYED")
|
||||
if(statpanel("Lobby"))
|
||||
stat("Game Mode:", (ticker.hide_mode) ? "Secret" : "[master_mode]")
|
||||
|
||||
if(ticker.current_state == GAME_STATE_PREGAME)
|
||||
stat("Players:", "[totalPlayers]")
|
||||
if(src.client in admins)
|
||||
stat("Players Ready:", "[totalPlayersReady]")
|
||||
totalPlayers = 0
|
||||
totalPlayersReady = 0
|
||||
for(var/mob/new_player/player in player_list)
|
||||
stat("[player.key]", (player.ready && src.client in admins)?("(Playing)"):(null))
|
||||
totalPlayers++
|
||||
if(player.ready)totalPlayersReady++
|
||||
stat("Time To Start:", (ticker.can_fire) ? "[round(ticker.timeLeft / 10)]s" : "DELAYED")
|
||||
|
||||
stat("Players:", "[ticker.totalPlayers]")
|
||||
if(client.holder)
|
||||
stat("Players Ready:", "[ticker.totalPlayersReady]")
|
||||
|
||||
|
||||
/mob/new_player/Topic(href, href_list[])
|
||||
if(src != usr)
|
||||
@@ -252,7 +238,7 @@
|
||||
vote_on_poll(pollid, optionid, 1)
|
||||
|
||||
/mob/new_player/proc/IsJobAvailable(rank)
|
||||
var/datum/job/job = job_master.GetJob(rank)
|
||||
var/datum/job/job = SSjob.GetJob(rank)
|
||||
if(!job)
|
||||
return 0
|
||||
if((job.current_positions >= job.total_positions) && job.total_positions != -1)
|
||||
@@ -271,10 +257,10 @@
|
||||
src << alert("[rank] is not available. Please try another.")
|
||||
return 0
|
||||
|
||||
job_master.AssignRole(src, rank, 1)
|
||||
SSjob.AssignRole(src, rank, 1)
|
||||
|
||||
var/mob/living/carbon/human/character = create_character() //creates the human and transfers vars and mind
|
||||
job_master.EquipRank(character, rank, 1) //equips the human
|
||||
SSjob.EquipRank(character, rank, 1) //equips the human
|
||||
character.loc = pick(latejoin)
|
||||
character.lastarea = get_area(loc)
|
||||
|
||||
@@ -287,8 +273,13 @@
|
||||
|
||||
joined_player_list += character.ckey
|
||||
|
||||
if(config.allow_latejoin_antagonists && emergency_shuttle.timeleft() > 300) //Don't make them antags if the station is evacuating
|
||||
ticker.mode.make_antag_chance(character)
|
||||
if(config.allow_latejoin_antagonists)
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_RECALL, SHUTTLE_IDLE)
|
||||
ticker.mode.make_antag_chance(character)
|
||||
if(SHUTTLE_CALL)
|
||||
if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5)
|
||||
ticker.mode.make_antag_chance(character)
|
||||
qdel(src)
|
||||
|
||||
/mob/new_player/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank)
|
||||
@@ -310,21 +301,22 @@
|
||||
|
||||
var/dat = "<div class='notice'>Round Duration: [round(hours)]h [round(mins)]m</div>"
|
||||
|
||||
if(emergency_shuttle) //In case Nanotrasen decides reposess Centcom's shuttles.
|
||||
if(emergency_shuttle.direction == 2) //Shuttle is going to centcom, not recalled
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_ESCAPE)
|
||||
dat += "<div class='notice red'>The station has been evacuated.</div><br>"
|
||||
if(emergency_shuttle.direction == 1 && emergency_shuttle.timeleft() < 300) //Shuttle is past the point of no recall
|
||||
dat += "<div class='notice red'>The station is currently undergoing evacuation procedures.</div><br>"
|
||||
if(SHUTTLE_CALL)
|
||||
if(SSshuttle.emergency.timeLeft() < 0.5 * initial(SSshuttle.emergencyCallTime)) //Shuttle is past the point of no recall
|
||||
dat += "<div class='notice red'>The station is currently undergoing evacuation procedures.</div><br>"
|
||||
|
||||
var/available_job_count = 0
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job && IsJobAvailable(job.title))
|
||||
available_job_count++;
|
||||
|
||||
dat += "<div class='clearBoth'>Choose from the following open positions:</div><br>"
|
||||
dat += "<div class='jobs'><div class='jobsColumn'>"
|
||||
var/job_count = 0
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job && IsJobAvailable(job.title))
|
||||
job_count++;
|
||||
if (job_count > round(available_job_count / 2))
|
||||
|
||||
@@ -19,15 +19,17 @@
|
||||
canmove = 0
|
||||
stunned = 1
|
||||
icon = null
|
||||
overlays.Cut()
|
||||
invisibility = 101
|
||||
var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey( loc )
|
||||
O.invisibility = 101
|
||||
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( loc )
|
||||
var/atom/movable/overlay/animation = new( loc )
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
flick("h2monkey", animation)
|
||||
sleep(22)
|
||||
var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey( loc )
|
||||
qdel(animation)
|
||||
|
||||
// hash the original name?
|
||||
if (tr_flags & TR_HASHNAME)
|
||||
@@ -82,14 +84,8 @@
|
||||
updateappearance(O)
|
||||
. = O
|
||||
if ( !(tr_flags & TR_KEEPSRC) ) //flag should be used if monkeyize() is called inside another proc of src so that one does not crash
|
||||
var/mob/deleted = src
|
||||
src = O
|
||||
qdel(deleted)
|
||||
qdel(src)
|
||||
|
||||
spawn(22)
|
||||
//animation = null
|
||||
O.invisibility = 0
|
||||
qdel(animation)
|
||||
|
||||
////////////////////////// Humanize //////////////////////////////
|
||||
//Could probably be merged with monkeyize but other transformations got their own procs, too
|
||||
@@ -125,14 +121,18 @@
|
||||
canmove = 0
|
||||
stunned = 1
|
||||
icon = null
|
||||
overlays.Cut()
|
||||
invisibility = 101
|
||||
var/mob/living/carbon/human/O = new( loc )
|
||||
O.invisibility = 101
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( loc )
|
||||
var/atom/movable/overlay/animation = new( loc )
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
flick("monkey2h", animation)
|
||||
sleep(22)
|
||||
var/mob/living/carbon/human/O = new( loc )
|
||||
for(var/obj/item/C in O.loc)
|
||||
O.equip_to_appropriate_slot(C)
|
||||
qdel(animation)
|
||||
|
||||
O.gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
|
||||
O.dna = dna
|
||||
@@ -188,9 +188,6 @@
|
||||
if (tr_flags & TR_DEFAULTMSG)
|
||||
O << "<B>You are now a human.</B>"
|
||||
|
||||
for(var/obj/item/C in O.loc)
|
||||
O.equip_to_appropriate_slot(C)
|
||||
|
||||
updateappearance(O)
|
||||
. = O
|
||||
|
||||
@@ -199,17 +196,8 @@
|
||||
loc.vars[A] = O
|
||||
|
||||
if ( !(tr_flags & TR_KEEPSRC) ) //don't delete src yet if it's needed to finish calling proc
|
||||
var/mob/deleted = src
|
||||
src = O
|
||||
qdel(deleted)
|
||||
qdel(src)
|
||||
|
||||
spawn(22)
|
||||
O.invisibility = 0
|
||||
for(var/obj/item/C in O.loc)
|
||||
O.equip_to_appropriate_slot(C)
|
||||
qdel(animation)
|
||||
|
||||
return
|
||||
|
||||
/mob/new_player/AIize()
|
||||
spawning = 1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file contains all Nano procs/definitions for external classes/objects
|
||||
|
||||
// This file contains all Nano procs/definitions for external classes/objects
|
||||
|
||||
/**
|
||||
* Called when a Nano UI window is closed
|
||||
* This is how Nano handles closed windows
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
if (istype(ui))
|
||||
ui.close()
|
||||
|
||||
|
||||
if(ui.ref)
|
||||
var/href = "close=1"
|
||||
src.Topic(href, params2list(href), ui.ref) // this will direct to the atom's Topic() proc via client.Topic()
|
||||
@@ -31,13 +31,13 @@
|
||||
* ui_interact is currently defined for /atom/movable
|
||||
*
|
||||
* @param user /mob The mob who is interacting with this ui
|
||||
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
|
||||
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
|
||||
* @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
|
||||
return
|
||||
|
||||
// Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob
|
||||
|
||||
// Used by the Nano UI SubSystem (/datum/subsystem/nano) to track UIs opened by this mob
|
||||
/mob/var/list/open_uis = list()
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
// This is the window/UI manager for Nano UI
|
||||
// There should only ever be one (global) instance of nanomanger
|
||||
/datum/nanomanager
|
||||
// a list of current open /nanoui UIs, grouped by src_object and ui_key
|
||||
var/open_uis[0]
|
||||
// a list of current open /nanoui UIs, not grouped, for use in processing
|
||||
var/list/processing_uis = list()
|
||||
|
||||
/**
|
||||
* Create a new nanomanager instance.
|
||||
*
|
||||
* @return /nanomanager new nanomanager object
|
||||
*/
|
||||
/datum/nanomanager/New()
|
||||
return
|
||||
|
||||
/**
|
||||
* Get an open /nanoui ui for the current user, src_object and ui_key and try to update it with data
|
||||
*
|
||||
@@ -25,16 +9,16 @@
|
||||
*
|
||||
* @return /nanoui Returns the found ui, for null if none exists
|
||||
*/
|
||||
/datum/nanomanager/proc/try_update_ui(var/mob/user, src_object, ui_key, var/datum/nanoui/ui, data)
|
||||
/datum/subsystem/nano/proc/try_update_ui(var/mob/user, src_object, ui_key, var/datum/nanoui/ui, data)
|
||||
if (isnull(ui)) // no ui has been passed, so we'll search for one
|
||||
{
|
||||
ui = get_open_ui(user, src_object, ui_key)
|
||||
}
|
||||
if (!isnull(ui))
|
||||
if (!isnull(ui))
|
||||
// The UI is already open so push the data to it
|
||||
ui.push_data(data)
|
||||
return ui
|
||||
|
||||
|
||||
return null
|
||||
|
||||
/**
|
||||
@@ -46,7 +30,7 @@
|
||||
*
|
||||
* @return /nanoui Returns the found ui, or null if none exists
|
||||
*/
|
||||
/datum/nanomanager/proc/get_open_ui(var/mob/user, src_object, ui_key)
|
||||
/datum/subsystem/nano/proc/get_open_ui(var/mob/user, src_object, ui_key)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return null
|
||||
@@ -66,21 +50,21 @@
|
||||
*
|
||||
* @return int The number of uis updated
|
||||
*/
|
||||
/datum/nanomanager/proc/update_uis(src_object)
|
||||
/datum/subsystem/nano/proc/update_uis(src_object)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0
|
||||
return 0
|
||||
|
||||
var/update_count = 0
|
||||
for (var/ui_key in open_uis[src_object_key])
|
||||
for (var/ui_key in open_uis[src_object_key])
|
||||
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user)
|
||||
ui.process(1)
|
||||
update_count++
|
||||
return update_count
|
||||
|
||||
|
||||
/**
|
||||
* Update /nanoui uis belonging to user
|
||||
* Update /nanoui uis belonging to user
|
||||
*
|
||||
* @param user /mob The mob who owns the uis
|
||||
* @param src_object /obj|/mob If src_object is provided, only update uis which are attached to src_object (optional)
|
||||
@@ -88,20 +72,20 @@
|
||||
*
|
||||
* @return int The number of uis updated
|
||||
*/
|
||||
/datum/nanomanager/proc/update_user_uis(var/mob/user, src_object = null, ui_key = null)
|
||||
/datum/subsystem/nano/proc/update_user_uis(var/mob/user, src_object = null, ui_key = null)
|
||||
if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
|
||||
return 0 // has no open uis
|
||||
|
||||
var/update_count = 0
|
||||
for (var/datum/nanoui/ui in user.open_uis)
|
||||
for (var/datum/nanoui/ui in user.open_uis)
|
||||
if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.process(1)
|
||||
update_count++
|
||||
|
||||
|
||||
return update_count
|
||||
|
||||
|
||||
/**
|
||||
* Close /nanoui uis belonging to user
|
||||
* Close /nanoui uis belonging to user
|
||||
*
|
||||
* @param user /mob The mob who owns the uis
|
||||
* @param src_object /obj|/mob If src_object is provided, only close uis which are attached to src_object (optional)
|
||||
@@ -109,16 +93,16 @@
|
||||
*
|
||||
* @return int The number of uis closed
|
||||
*/
|
||||
/datum/nanomanager/proc/close_user_uis(var/mob/user, src_object = null, ui_key = null)
|
||||
/datum/subsystem/nano/proc/close_user_uis(var/mob/user, src_object = null, ui_key = null)
|
||||
if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
|
||||
return 0 // has no open uis
|
||||
|
||||
var/close_count = 0
|
||||
for (var/datum/nanoui/ui in user.open_uis)
|
||||
for (var/datum/nanoui/ui in user.open_uis)
|
||||
if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.close()
|
||||
close_count++
|
||||
|
||||
|
||||
return close_count
|
||||
|
||||
/**
|
||||
@@ -129,7 +113,7 @@
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanomanager/proc/ui_opened(var/datum/nanoui/ui)
|
||||
/datum/subsystem/nano/proc/ui_opened(var/datum/nanoui/ui)
|
||||
var/src_object_key = "\ref[ui.src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
open_uis[src_object_key] = list(ui.ui_key = list())
|
||||
@@ -149,7 +133,7 @@
|
||||
*
|
||||
* @return int 0 if no ui was removed, 1 if removed successfully
|
||||
*/
|
||||
/datum/nanomanager/proc/ui_closed(var/datum/nanoui/ui)
|
||||
/datum/subsystem/nano/proc/ui_closed(var/datum/nanoui/ui)
|
||||
var/src_object_key = "\ref[ui.src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // wasn't open
|
||||
@@ -160,7 +144,7 @@
|
||||
ui.user.open_uis.Remove(ui)
|
||||
var/list/uis = open_uis[src_object_key][ui.ui_key]
|
||||
return uis.Remove(ui)
|
||||
|
||||
|
||||
/**
|
||||
* This is called on user logout
|
||||
* Closes/clears all uis attached to the user's /mob
|
||||
@@ -170,8 +154,8 @@
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
//
|
||||
/datum/nanomanager/proc/user_logout(var/mob/user)
|
||||
//
|
||||
/datum/subsystem/nano/proc/user_logout(var/mob/user)
|
||||
return close_user_uis(user)
|
||||
|
||||
/**
|
||||
@@ -183,7 +167,7 @@
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanomanager/proc/user_transferred(var/mob/oldMob, var/mob/newMob)
|
||||
/datum/subsystem/nano/proc/user_transferred(var/mob/oldMob, var/mob/newMob)
|
||||
if (isnull(oldMob.open_uis) || !istype(oldMob.open_uis, /list) || open_uis.len == 0)
|
||||
return 0 // has no open uis
|
||||
|
||||
@@ -195,6 +179,6 @@
|
||||
newMob.open_uis.Add(ui)
|
||||
|
||||
oldMob.open_uis.Cut()
|
||||
|
||||
|
||||
return 1 // success
|
||||
|
||||
|
||||
+10
-10
@@ -11,7 +11,7 @@ nanoui is used to open and update nano browser uis
|
||||
#define STATUS_UPDATE 1 // ORANGE Visability
|
||||
#define STATUS_DISABLED 0 // RED Visability
|
||||
|
||||
/datum/nanoui
|
||||
/datum/nanoui
|
||||
// the user who opened this ui
|
||||
var/mob/user
|
||||
// the object this ui "belongs" to
|
||||
@@ -180,7 +180,7 @@ nanoui is used to open and update nano browser uis
|
||||
data["ui"] = list(
|
||||
"status" = status,
|
||||
"user" = list("name" = user.name)
|
||||
)
|
||||
)
|
||||
return data
|
||||
|
||||
/**
|
||||
@@ -256,10 +256,10 @@ nanoui is used to open and update nano browser uis
|
||||
*/
|
||||
/datum/nanoui/proc/get_header()
|
||||
var/head_content = ""
|
||||
|
||||
|
||||
for (var/filename in scripts)
|
||||
head_content += "<script type='text/javascript' src='[filename]'></script> "
|
||||
|
||||
|
||||
for (var/filename in stylesheets)
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[filename]'> "
|
||||
|
||||
@@ -284,7 +284,7 @@ nanoui is used to open and update nano browser uis
|
||||
<script type='text/javascript'>
|
||||
function receiveUpdateData(jsonString)
|
||||
{
|
||||
// We need both jQuery and NanoUpdate to be able to recieve data
|
||||
// We need both jQuery and NanoUpdate to be able to recieve data
|
||||
// At the moment any data received before those libraries are loaded will be lost
|
||||
if (typeof NanoUpdate != 'undefined' && typeof jQuery != 'undefined')
|
||||
{
|
||||
@@ -294,7 +294,7 @@ nanoui is used to open and update nano browser uis
|
||||
</script>
|
||||
[head_content]
|
||||
</head>
|
||||
<body scroll=auto data-url-parameters='[url_parameters_json]' data-template-data='[template_data_json]' data-initial-data='[initial_data_json]'>
|
||||
<body scroll=auto data-url-parameters='[url_parameters_json]' data-template-data='[template_data_json]' data-initial-data='[initial_data_json]'>
|
||||
<div id='uiWrapper'>
|
||||
[title ? "<div id='uiTitleWrapper'><div id='uiStatusIcon' class='icon24 uiStatusGood'></div><div id='uiTitle'>[title]</div><div id='uiTitleFluff'></div></div>" : ""]
|
||||
<div id='uiContent'>
|
||||
@@ -340,7 +340,7 @@ nanoui is used to open and update nano browser uis
|
||||
winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map
|
||||
on_close_winset()
|
||||
//onclose(user, window_id)
|
||||
nanomanager.ui_opened(src)
|
||||
SSnano.ui_opened(src)
|
||||
|
||||
/**
|
||||
* Close this UI
|
||||
@@ -349,7 +349,7 @@ nanoui is used to open and update nano browser uis
|
||||
*/
|
||||
/datum/nanoui/proc/close()
|
||||
is_auto_updating = 0
|
||||
nanomanager.ui_closed(src)
|
||||
SSnano.ui_closed(src)
|
||||
user << browse(null, "window=[window_id]")
|
||||
|
||||
/**
|
||||
@@ -392,7 +392,7 @@ nanoui is used to open and update nano browser uis
|
||||
return
|
||||
|
||||
if (src_object && src_object.Topic(href, href_list))
|
||||
nanomanager.update_uis(src_object) // update all UIs attached to src_object
|
||||
SSnano.update_uis(src_object) // update all UIs attached to src_object
|
||||
|
||||
/**
|
||||
* Process this UI, updating the entire UI or just the status (aka visibility)
|
||||
@@ -406,7 +406,7 @@ nanoui is used to open and update nano browser uis
|
||||
if (!src_object || !user)
|
||||
close()
|
||||
return
|
||||
|
||||
|
||||
if (status && (update || is_auto_updating))
|
||||
src_object.ui_interact(user, ui_key, src) // Update the UI (update_status() is called whenever a UI is updated)
|
||||
else
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
/obj/item/weapon/paper/attack_self(mob/user)
|
||||
user.examinate(src)
|
||||
if(rigged && (events.holiday == "April Fool's Day"))
|
||||
if(rigged && (SSevent.holiday == "April Fool's Day"))
|
||||
if(spam_flag == 0)
|
||||
spam_flag = 1
|
||||
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
papers.Remove(P)
|
||||
else
|
||||
P = new /obj/item/weapon/paper
|
||||
if(events.holiday == "April Fool's Day")
|
||||
if(SSevent.holiday == "April Fool's Day")
|
||||
if(prob(30))
|
||||
P.info = "<font face=\"[P.crayonfont]\" color=\"red\"><b>HONK HONK HONK HONK HONK HONK HONK<br>HOOOOOOOOOOOOOOOOOOOOOONK<br>APRIL FOOLS</b></font>"
|
||||
P.rigged = 1
|
||||
|
||||
@@ -155,7 +155,8 @@ proc/cardinalrange(var/center)
|
||||
|
||||
/obj/machinery/am_shielding/proc/setup_core()
|
||||
processing = 1
|
||||
machines.Add(src)
|
||||
machines |= src
|
||||
SSmachine.processing |= src
|
||||
if(!control_unit) return
|
||||
control_unit.linked_cores.Add(src)
|
||||
control_unit.reported_core_efficiency += efficiency
|
||||
|
||||
@@ -714,7 +714,7 @@
|
||||
)
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
|
||||
// rebuild all power networks from scratch - only called at world creation or by the admin verb
|
||||
/proc/makepowernets()
|
||||
/datum/subsystem/power/proc/makepowernets()
|
||||
for(var/datum/powernet/PN in powernets)
|
||||
del(PN)
|
||||
powernets.Cut()
|
||||
@@ -356,10 +356,10 @@
|
||||
////////////////////////////////////////////
|
||||
|
||||
/datum/powernet/New()
|
||||
powernets += src
|
||||
SSpower.powernets += src
|
||||
|
||||
/datum/powernet/Destroy()
|
||||
powernets -= src
|
||||
SSpower.powernets -= src
|
||||
|
||||
/datum/powernet/proc/is_empty()
|
||||
return !cables.len && !nodes.len
|
||||
|
||||
@@ -34,8 +34,7 @@
|
||||
narsie_spawn_animation()
|
||||
|
||||
sleep(70)
|
||||
if(emergency_shuttle)
|
||||
emergency_shuttle.incall(0.3) // Cannot recall
|
||||
SSshuttle.emergency.request(null, 0.3) // Cannot recall
|
||||
|
||||
|
||||
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
src.energy = starting_energy
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
for(var/obj/machinery/power/singularity_beacon/singubeacon in world)
|
||||
if(singubeacon.active)
|
||||
target = singubeacon
|
||||
@@ -40,7 +40,7 @@
|
||||
return
|
||||
|
||||
/obj/singularity/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/singularity/Move(atom/newloc, direct)
|
||||
|
||||
@@ -315,7 +315,7 @@
|
||||
)
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
|
||||
+11
-13
@@ -1,8 +1,6 @@
|
||||
#define SOLAR_MAX_DIST 40
|
||||
#define SOLARGENRATE 1500
|
||||
|
||||
var/list/solars_list = list()
|
||||
|
||||
/obj/machinery/power/solar
|
||||
name = "solar panel"
|
||||
desc = "A solar electrical generator."
|
||||
@@ -108,14 +106,12 @@ var/list/solars_list = list()
|
||||
|
||||
//calculates the fraction of the sunlight that the panel recieves
|
||||
/obj/machinery/power/solar/proc/update_solar_exposure()
|
||||
if(!sun)
|
||||
return
|
||||
if(obscured)
|
||||
sunfrac = 0
|
||||
return
|
||||
|
||||
//find the smaller angle between the direction the panel is facing and the direction of the sun (the sign is not important here)
|
||||
var/p_angle = min(abs(adir - sun.angle), 360 - abs(adir - sun.angle))
|
||||
var/p_angle = min(abs(adir - SSsun.angle), 360 - abs(adir - SSsun.angle))
|
||||
|
||||
if(p_angle > 90) // if facing more than 90deg from sun, zero output
|
||||
sunfrac = 0
|
||||
@@ -127,7 +123,7 @@ var/list/solars_list = list()
|
||||
/obj/machinery/power/solar/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
if(!sun || !control) //if there's no sun or the panel is not linked to a solar control computer, no need to proceed
|
||||
if(!control) //if there's no sun or the panel is not linked to a solar control computer, no need to proceed
|
||||
return
|
||||
|
||||
if(powernet)
|
||||
@@ -178,10 +174,12 @@ var/list/solars_list = list()
|
||||
var/ax = x // start at the solar panel
|
||||
var/ay = y
|
||||
var/turf/T = null
|
||||
var/dx = SSsun.dx
|
||||
var/dy = SSsun.dy
|
||||
|
||||
for(var/i = 1 to 20) // 20 steps is enough
|
||||
ax += sun.dx // do step
|
||||
ay += sun.dy
|
||||
ax += dx // do step
|
||||
ay += dy
|
||||
|
||||
T = locate( round(ax,0.5),round(ay,0.5),z)
|
||||
|
||||
@@ -308,12 +306,12 @@ var/list/solars_list = list()
|
||||
|
||||
/obj/machinery/power/solar_control/disconnect_from_network()
|
||||
..()
|
||||
solars_list.Remove(src)
|
||||
SSsun.solars.Remove(src)
|
||||
|
||||
/obj/machinery/power/solar_control/connect_to_network()
|
||||
var/to_return = ..()
|
||||
if(powernet) //if connected and not already in solar_list...
|
||||
solars_list |= src //... add it
|
||||
SSsun.solars |= src //... add it
|
||||
return to_return
|
||||
|
||||
//search for unconnected panels and trackers in the computer powernet and connect them
|
||||
@@ -341,7 +339,7 @@ var/list/solars_list = list()
|
||||
cdir = targetdir //...the current direction is the targetted one (and rotates panels to it)
|
||||
if(2) // auto-tracking
|
||||
if(connected_tracker)
|
||||
connected_tracker.set_angle(sun.angle)
|
||||
connected_tracker.set_angle(SSsun.angle)
|
||||
|
||||
set_panels(cdir)
|
||||
updateDialog()
|
||||
@@ -475,7 +473,7 @@ var/list/solars_list = list()
|
||||
track = text2num(href_list["track"])
|
||||
if(track == 2)
|
||||
if(connected_tracker)
|
||||
connected_tracker.set_angle(sun.angle)
|
||||
connected_tracker.set_angle(SSsun.angle)
|
||||
set_panels(cdir)
|
||||
else if (track == 1) //begin manual tracking
|
||||
src.targetdir = src.cdir
|
||||
@@ -485,7 +483,7 @@ var/list/solars_list = list()
|
||||
if(href_list["search_connected"])
|
||||
search_for_connected()
|
||||
if(connected_tracker && track == 2)
|
||||
connected_tracker.set_angle(sun.angle)
|
||||
connected_tracker.set_angle(SSsun.angle)
|
||||
set_panels(cdir)
|
||||
|
||||
src.updateUsrDialog()
|
||||
|
||||
@@ -30,11 +30,11 @@ obj/item/weapon/gun/energy/laser/retro
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/captain/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/captain/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
|
||||
@@ -115,11 +115,11 @@ obj/item/weapon/gun/energy/laser/retro
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/bluetag/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/bluetag/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
|
||||
@@ -154,11 +154,11 @@ obj/item/weapon/gun/energy/laser/retro
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/redtag/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/redtag/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/nuclear/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/nuclear/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
M << "<span class='danger'>You feel a wave of heat wash over you.</span>"
|
||||
M.apply_effect(300, IRRADIATE)
|
||||
crit_fail = 1 //break the gun so it stops recharging
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
update_icon()
|
||||
return 0
|
||||
|
||||
@@ -109,4 +109,4 @@
|
||||
/obj/item/weapon/gun/energy/gun/turret
|
||||
name = "hybrid turret gun"
|
||||
desc = "A basic hybrid energy gun with two settings: Stun and kill."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
|
||||
@@ -69,11 +69,11 @@
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun/process()
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/advtaser/cyborg/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/advtaser/cyborg/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/advtaser/cyborg/process() //Every [recharge_time] ticks, recharge a shot for the cyborg
|
||||
@@ -72,11 +72,11 @@
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -46,11 +46,11 @@
|
||||
..()
|
||||
charges = max_charges
|
||||
chambered = new ammo_type(src)
|
||||
if(can_charge) processing_objects.Add(src)
|
||||
if(can_charge) SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/gun/magic/Destroy()
|
||||
if(can_charge) processing_objects.Remove(src)
|
||||
if(can_charge) SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
energy = min(energy + addenergy, max_energy)
|
||||
if(energy != oldenergy)
|
||||
use_power(1500) // This thing uses up alot of power (this is still low as shit for creating reagents from thin air)
|
||||
nanomanager.update_uis(src) // update all UIs attached to src
|
||||
SSnano.update_uis(src) // update all UIs attached to src
|
||||
|
||||
/obj/machinery/chem_dispenser/power_change()
|
||||
if(powered())
|
||||
@@ -36,7 +36,7 @@
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
nanomanager.update_uis(src) // update all UIs attached to src
|
||||
SSnano.update_uis(src) // update all UIs attached to src
|
||||
|
||||
/obj/machinery/chem_dispenser/process()
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
data["chemicals"] = chemicals
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
@@ -158,7 +158,7 @@
|
||||
user.drop_item()
|
||||
B.loc = src
|
||||
user << "You add the beaker to the machine!"
|
||||
nanomanager.update_uis(src) // update all UIs attached to src
|
||||
SSnano.update_uis(src) // update all UIs attached to src
|
||||
overlays += "disp_beaker"
|
||||
|
||||
/obj/machinery/chem_dispenser/attack_ai(mob/user as mob)
|
||||
@@ -668,7 +668,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime)
|
||||
if(archive_diseases[id])
|
||||
var/datum/disease/advance/A = archive_diseases[id]
|
||||
A.AssignName(new_name)
|
||||
for(var/datum/disease/advance/AD in active_diseases)
|
||||
for(var/datum/disease/advance/AD in SSdisease.processing)
|
||||
AD.Refresh()
|
||||
src.updateUsrDialog()
|
||||
|
||||
|
||||
@@ -650,6 +650,10 @@ datum/reagent/space_cleaner/reaction_turf(var/turf/T, var/volume)
|
||||
|
||||
for(var/mob/living/carbon/slime/M in T)
|
||||
M.adjustToxLoss(rand(5,10))
|
||||
if(istype(T, /turf/simulated/floor))
|
||||
var/turf/simulated/floor/F = T
|
||||
if(volume >= 1)
|
||||
F.dirt = 0
|
||||
|
||||
datum/reagent/space_cleaner/reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
|
||||
if(iscarbon(M))
|
||||
@@ -689,6 +693,7 @@ datum/reagent/cryptobiolin/on_mob_life(var/mob/living/M as mob)
|
||||
if(!M.confused)
|
||||
M.confused = 1
|
||||
M.confused = max(M.confused, 20)
|
||||
..()
|
||||
return
|
||||
|
||||
datum/reagent/impedrezene
|
||||
@@ -854,4 +859,4 @@ datum/reagent/plantnutriment/robustharvestnutriment
|
||||
|
||||
|
||||
// Undefine the alias for REAGENTS_EFFECT_MULTIPLER
|
||||
#undef REM
|
||||
#undef REM
|
||||
|
||||
@@ -38,11 +38,11 @@ Borg Hypospray
|
||||
modes[R] = iteration
|
||||
iteration++
|
||||
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/borghypo/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -142,6 +142,16 @@
|
||||
build_path = /obj/item/weapon/circuitboard/destructive_analyzer
|
||||
category = list("Research Machinery")
|
||||
|
||||
/datum/design/experimentor
|
||||
name = "Machine Design (E.X.P.E.R.I-MENTOR Board)"
|
||||
desc = "The circuit board for an E.X.P.E.R.I-MENTOR."
|
||||
id = "experimentor"
|
||||
req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2, "bluespace" = 2)
|
||||
build_type = IMPRINTER
|
||||
materials = list("$glass" = 1000, "sacid" = 20)
|
||||
build_path = /obj/item/weapon/circuitboard/experimentor
|
||||
category = list("Research Machinery")
|
||||
|
||||
/datum/design/protolathe
|
||||
name = "Machine Design (Protolathe Board)"
|
||||
desc = "The circuit board for a protolathe."
|
||||
|
||||
@@ -0,0 +1,392 @@
|
||||
//this is designed to replace the destructive analyzer
|
||||
|
||||
#define SCANTYPE_POKE 1
|
||||
#define SCANTYPE_IRRADIATE 2
|
||||
#define SCANTYPE_GAS 3
|
||||
#define SCANTYPE_HEAT 4
|
||||
#define SCANTYPE_COLD 5
|
||||
#define SCANTYPE_OBLITERATE 6
|
||||
|
||||
#define EFFECT_PROB_VERYLOW 10
|
||||
#define EFFECT_PROB_LOW 20
|
||||
#define EFFECT_PROB_MEDIUM 45
|
||||
#define EFFECT_PROB_HIGH 65
|
||||
#define EFFECT_PROB_VERYHIGH 85
|
||||
|
||||
#define FAIL 7
|
||||
/obj/machinery/r_n_d/experimentor
|
||||
name = "E.X.P.E.R.I-MENTOR"
|
||||
icon = 'icons/obj/machines/heavy_lathe.dmi'
|
||||
icon_state = "h_lathe"
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
var/obj/item/loaded_item = null
|
||||
///
|
||||
var/badThingCoeff = 0
|
||||
var/resetTime = 15
|
||||
var/list/item_reactions = list()
|
||||
var/list/valid_items = list()
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/proc/ConvertReqString2List(var/list/source_list)
|
||||
var/list/temp_list = params2list(source_list)
|
||||
for(var/O in temp_list)
|
||||
temp_list[O] = text2num(temp_list[O])
|
||||
return temp_list
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/proc/SetTypeReactions()
|
||||
for(var/I in typesof(/obj/item))
|
||||
item_reactions["[I]"] = pick(SCANTYPE_POKE,SCANTYPE_IRRADIATE,SCANTYPE_GAS,SCANTYPE_HEAT,SCANTYPE_COLD,SCANTYPE_OBLITERATE)
|
||||
if(ispath(I,/obj/item/weapon/reagent_containers/food) || ispath(I,/obj/item/weapon/stock_parts) || ispath(I,/obj/item/weapon/grenade/chem_grenade) || ispath(I,/obj/item/weapon/kitchen))
|
||||
var/obj/item/tempCheck = new I()
|
||||
if(tempCheck.icon_state != null) //check it's an actual usable item, in a hacky way
|
||||
valid_items += I
|
||||
qdel(tempCheck)
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/experimentor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
SetTypeReactions()
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/RefreshParts()
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
||||
if(resetTime > 0 && (resetTime - M.rating) >= 1)
|
||||
resetTime -= M.rating
|
||||
for(var/obj/item/weapon/stock_parts/scanning_module/M in component_parts)
|
||||
badThingCoeff += M.rating*2
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
|
||||
badThingCoeff += M.rating
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if (shocked)
|
||||
shock(user,50)
|
||||
if (istype(O, /obj/item/weapon/screwdriver))
|
||||
if (!panel_open)
|
||||
panel_open = 1
|
||||
if(linked_console)
|
||||
linked_console.linked_destroy = null
|
||||
linked_console = null
|
||||
icon_state = "h_lathe_maint"
|
||||
user << "<span class='notice'>You open the maintenance hatch of [src].</span>"
|
||||
else
|
||||
panel_open = 0
|
||||
icon_state = "h_lathe"
|
||||
user << "<span class='notice'>You close the maintenance hatch of [src].</span>"
|
||||
return
|
||||
if (panel_open)
|
||||
if(istype(O, /obj/item/weapon/crowbar))
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
|
||||
M.state = 2
|
||||
M.icon_state = "box_1"
|
||||
for(var/obj/I in component_parts)
|
||||
I.loc = src.loc
|
||||
del(src)
|
||||
return 1
|
||||
else
|
||||
user << "<span class='warning'>You can't load the [src.name] while it's opened.</span>"
|
||||
return 1
|
||||
if (disabled)
|
||||
return
|
||||
if (!linked_console)
|
||||
user << "<span class='warning'>The [src] must be linked to an R&D console first!</span>"
|
||||
return
|
||||
if (busy)
|
||||
user << "<span class='warning'>The [src] is busy right now.</span>"
|
||||
return
|
||||
if (istype(O, /obj/item) && !loaded_item)
|
||||
if(!O.origin_tech)
|
||||
user << "<span class='warning'>This doesn't seem to have a tech origin!</span>"
|
||||
return
|
||||
var/list/temp_tech = ConvertReqString2List(O.origin_tech)
|
||||
if (temp_tech.len == 0)
|
||||
user << "<span class='warning'>You cannot experiment on this item!</span>"
|
||||
return
|
||||
if(O.reliability < 90 && O.crit_fail == 0)
|
||||
usr << "<span class='warning'>Item is neither reliable enough or broken enough to learn from.</span>"
|
||||
return
|
||||
busy = 1
|
||||
loaded_item = O
|
||||
user.drop_item()
|
||||
O.loc = src
|
||||
user << "<span class='notice'>You add the [O.name] to the machine!</span>"
|
||||
flick("h_lathe_load", src)
|
||||
spawn(15)
|
||||
icon_state = "h_lathe_wloop"
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/attack_hand(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
var/dat = "<center>"
|
||||
if(!linked_console)
|
||||
dat += "<b><a href='byond://?src=\ref[src];function=search'>Scan for R&D Console</A></b><br>"
|
||||
if(loaded_item)
|
||||
dat += "<b>Loaded Item:</b> [loaded_item]<br>"
|
||||
dat += "<b>Technology</b>:<br>"
|
||||
var/list/D = ConvertReqString2List(loaded_item.origin_tech)
|
||||
for(var/T in D)
|
||||
dat += "[T]<br>"
|
||||
dat += "<br><br>Available tests:"
|
||||
dat += "<br><b><a href='byond://?src=\ref[src];item=\ref[loaded_item];function=[SCANTYPE_POKE]'>Poke</A></b>"
|
||||
dat += "<br><b><a href='byond://?src=\ref[src];item=\ref[loaded_item];function=[SCANTYPE_IRRADIATE];'>Irradiate</A></b>"
|
||||
dat += "<br><b><a href='byond://?src=\ref[src];item=\ref[loaded_item];function=[SCANTYPE_GAS]'>Gas</A></b>"
|
||||
dat += "<br><b><a href='byond://?src=\ref[src];item=\ref[loaded_item];function=[SCANTYPE_HEAT]'>Burn</A></b>"
|
||||
dat += "<br><b><a href='byond://?src=\ref[src];item=\ref[loaded_item];function=[SCANTYPE_COLD]'>Freeze</A></b>"
|
||||
dat += "<br><b><a href='byond://?src=\ref[src];item=\ref[loaded_item];function=[SCANTYPE_OBLITERATE]'>Destroy</A></b><br>"
|
||||
dat += "<br><b><a href='byond://?src=\ref[src];function=eject'>Eject</A>"
|
||||
else
|
||||
dat += "<b>Nothing loaded.</b>"
|
||||
dat += "<br><a href='byond://?src=\ref[src];function=close'>Close</A><br></center>"
|
||||
var/datum/browser/popup = new(user, "experimentor","Experimentor", 700, 400, src)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
onclose(user, "experimentor")
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/proc/matchReaction(var/matching,var/reaction)
|
||||
var/obj/item/D = matching
|
||||
if(D)
|
||||
if(item_reactions.Find("[D.type]"))
|
||||
var/tor = item_reactions["[D.type]"]
|
||||
if(tor == text2num(reaction))
|
||||
return tor
|
||||
else
|
||||
return FAIL
|
||||
else
|
||||
return FAIL
|
||||
else
|
||||
return FAIL
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/proc/ejectItem(var/delete=FALSE)
|
||||
loaded_item.loc = src.loc
|
||||
if(delete)
|
||||
qdel(loaded_item)
|
||||
loaded_item = null
|
||||
|
||||
/*
|
||||
#define EFFECT_PROB_VERYLOW 10
|
||||
#define EFFECT_PROB_LOW 20
|
||||
#define EFFECT_PROB_MEDIUM 45
|
||||
#define EFFECT_PROB_HIGH 65
|
||||
#define EFFECT_PROB_VERYHIGH 85
|
||||
*/
|
||||
/obj/machinery/r_n_d/experimentor/proc/experiment(var/exp,var/obj/item/exp_on)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(exp == SCANTYPE_POKE)
|
||||
visible_message("<span class='notice'>[src] prods at [exp_on] with mechanical arms.</span>")
|
||||
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions and destroys [exp_on], lashing it's arms out at nearby people!.</span>")
|
||||
for(var/mob/living/m in oview(1))
|
||||
m.apply_damage(15,"brute",pick("head","chest","groin"))
|
||||
ejectItem(TRUE)
|
||||
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions!.</span>")
|
||||
exp = SCANTYPE_OBLITERATE
|
||||
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, throwing the [exp_on]!.</span>")
|
||||
var/mob/living/target = locate(/mob/living) in oview(7,src)
|
||||
if(target)
|
||||
var/obj/item/throwing = loaded_item
|
||||
ejectItem()
|
||||
throwing.throw_at(target, 10, 1)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(exp == SCANTYPE_IRRADIATE)
|
||||
visible_message("<span class='notice'>[src] reflects radioactive rays at [exp_on]!</span>")
|
||||
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, melting [exp_on] and leaking radiation!.</span>")
|
||||
for(var/mob/living/m in oview(1))
|
||||
m.apply_effect(25,IRRADIATE)
|
||||
ejectItem(TRUE)
|
||||
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, spewing toxic waste!.</span>")
|
||||
for(var/turf/T in oview(1))
|
||||
if(!T.density)
|
||||
if(prob(EFFECT_PROB_VERYHIGH))
|
||||
new /obj/effect/decal/cleanable/greenglow(T)
|
||||
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, transforming the [exp_on]!.</span>")
|
||||
ejectItem(TRUE)
|
||||
var/newPath = pick(valid_items)
|
||||
loaded_item = new newPath(src)
|
||||
if(istype(loaded_item,/obj/item/weapon/grenade/chem_grenade))
|
||||
var/obj/item/weapon/grenade/chem_grenade/CG = loaded_item
|
||||
CG.prime()
|
||||
ejectItem()
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(exp == SCANTYPE_GAS)
|
||||
visible_message("<span class='notice'>[src] fills it's chamber with gas, [exp_on] included.</span>")
|
||||
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] destroys [exp_on], leaking dangerous gas!.</span>")
|
||||
var/list/chems = list("carbon","radium","toxin","condensedcapsaicin","mushroomhallucinogen","space_drugs","ethanol","beepskysmash")
|
||||
var/datum/reagents/R = new/datum/reagents(50)
|
||||
R.my_atom = src
|
||||
R.add_reagent(pick(chems), 50)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/smoke = new
|
||||
smoke.set_up(R, 1, 0, src, 0, silent = 1)
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.start()
|
||||
R.delete()
|
||||
ejectItem(TRUE)
|
||||
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, spewing harmless gas!.</span>")
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, src.loc, 0)
|
||||
smoke.start()
|
||||
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] melts [exp_on], ionizing the air around it!.</span>")
|
||||
empulse(src.loc, 8, 10)
|
||||
ejectItem(TRUE)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(exp == SCANTYPE_HEAT)
|
||||
visible_message("<span class='notice'>[src] raises [exp_on]'s temperature.</span>")
|
||||
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, melting [exp_on] and releasing a burst of flame!.</span>")
|
||||
explosion(src.loc, -1, 0, 0, 0, 0, flame_range = 2)
|
||||
ejectItem(TRUE)
|
||||
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, melting [exp_on] and leaking hot air!.</span>")
|
||||
var/datum/gas_mixture/env = src.loc.return_air()
|
||||
var/transfer_moles = 0.25 * env.total_moles()
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
if(removed)
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
if(heat_capacity == 0 || heat_capacity == null)
|
||||
heat_capacity = 1
|
||||
removed.temperature = min((removed.temperature*heat_capacity + 100000)/heat_capacity, 1000)
|
||||
env.merge(removed)
|
||||
air_update_turf()
|
||||
ejectItem(TRUE)
|
||||
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, activating it's emergency coolant systems!.</span>")
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, src.loc, 0)
|
||||
smoke.start()
|
||||
for(var/mob/living/m in oview(1))
|
||||
m.apply_damage(5,"burn",pick("head","chest","groin"))
|
||||
ejectItem()
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(exp == SCANTYPE_COLD)
|
||||
visible_message("<span class='notice'>[src] lowers [exp_on]'s temperature.</span>")
|
||||
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, shattering [exp_on] and releasing a dangerous cloud of coolant!</span>")
|
||||
var/datum/reagents/R = new/datum/reagents(50)
|
||||
R.my_atom = src
|
||||
R.add_reagent("frostoil", 50)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/smoke = new
|
||||
smoke.set_up(R, 1, 0, src, 0, silent = 1)
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.start()
|
||||
R.delete()
|
||||
ejectItem(TRUE)
|
||||
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, shattering [exp_on] and leaking cold air!.</span>")
|
||||
var/datum/gas_mixture/env = src.loc.return_air()
|
||||
var/transfer_moles = 0.25 * env.total_moles()
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
if(removed)
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
if(heat_capacity == 0 || heat_capacity == null)
|
||||
heat_capacity = 1
|
||||
removed.temperature = (removed.temperature*heat_capacity - 75000)/heat_capacity
|
||||
env.merge(removed)
|
||||
air_update_turf()
|
||||
ejectItem(TRUE)
|
||||
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src] malfunctions, releasing a flurry of chilly air as [exp_on] pops out!.</span>")
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, src.loc, 0)
|
||||
smoke.start()
|
||||
ejectItem()
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(exp == SCANTYPE_OBLITERATE)
|
||||
visible_message("<span class='notice'>[exp_on] activates the crushing mechanism, [exp_on] is destroyed!</span>")
|
||||
if(linked_console.linked_lathe)
|
||||
linked_console.linked_lathe.m_amount += min((linked_console.linked_lathe.max_material_storage - linked_console.linked_lathe.TotalMaterials()), (exp_on.m_amt))
|
||||
linked_console.linked_lathe.g_amount += min((linked_console.linked_lathe.max_material_storage - linked_console.linked_lathe.TotalMaterials()), (exp_on.g_amt))
|
||||
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src]'s crusher goes way too many levels too high, crushing right through space-time!</span>")
|
||||
playsound(src.loc, 'sound/effects/supermatter.ogg', 50, 1, -3)
|
||||
var/list/throwAt = list()
|
||||
for(var/i in oview(7,src))
|
||||
if(istype(i,/obj/item) || istype(i,/mob/living))
|
||||
throwAt.Add(i)
|
||||
var/counter
|
||||
for(counter = 1, counter < throwAt.len, ++counter)
|
||||
var/cast = throwAt[counter]
|
||||
cast:throw_at(src,10,1)
|
||||
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src]'s crusher goes one level too high, crushing right into space-time!.</span>")
|
||||
playsound(src.loc, 'sound/effects/supermatter.ogg', 50, 1, -3)
|
||||
var/list/oViewStuff = oview(7,src)
|
||||
var/list/throwAt = list()
|
||||
for(var/i in oViewStuff)
|
||||
if(istype(i,/obj/item) || istype(i,/mob/living))
|
||||
throwAt.Add(i)
|
||||
var/counter
|
||||
for(counter = 1, counter < throwAt.len, ++counter)
|
||||
var/cast = throwAt[counter]
|
||||
cast:throw_at(pick(throwAt),10,1)
|
||||
ejectItem(TRUE)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(exp == FAIL)
|
||||
var/a = pick("rumbles","shakes","vibrates","shudders")
|
||||
var/b = pick("crushes","spins","viscerates","smashes","insults")
|
||||
visible_message("<span class='notice'>[exp_on] [a], and [b], the experiment was a failiure!</span>")
|
||||
|
||||
spawn(resetTime)
|
||||
icon_state = "h_lathe"
|
||||
busy = 0
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
usr.set_machine(src)
|
||||
|
||||
var/scantype = href_list["function"]
|
||||
var/obj/item/process = locate(href_list["item"]) in src
|
||||
|
||||
if(scantype == "close")
|
||||
usr << browse(null, "window=experimentor")
|
||||
else if(scantype == "search")
|
||||
var/obj/machinery/computer/rdconsole/D = locate(/obj/machinery/computer/rdconsole) in oview(3,src)
|
||||
if(D)
|
||||
linked_console = D
|
||||
else if(scantype == "eject")
|
||||
ejectItem()
|
||||
else
|
||||
var/dotype = matchReaction(process,scantype)
|
||||
experiment(dotype,process)
|
||||
use_power(750)
|
||||
if(dotype != FAIL)
|
||||
if(process.origin_tech)
|
||||
var/list/temp_tech = ConvertReqString2List(process.origin_tech)
|
||||
for(var/T in temp_tech)
|
||||
linked_console.files.UpdateTech(T, temp_tech[T])
|
||||
linked_console.files.UpdateDesigns(process,process.type)
|
||||
if(scantype != "close")
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
#undef SCANTYPE_POKE
|
||||
#undef SCANTYPE_IRRADIATE
|
||||
#undef SCANTYPE_GAS
|
||||
#undef SCANTYPE_HEAT
|
||||
#undef SCANTYPE_COLD
|
||||
#undef SCANTYPE_OBLITERATE
|
||||
|
||||
#undef EFFECT_PROB_VERYLOW
|
||||
#undef EFFECT_PROB_LOW
|
||||
#undef EFFECT_PROB_MEDIUM
|
||||
#undef EFFECT_PROB_HIGH
|
||||
#undef EFFECT_PROB_VERYHIGH
|
||||
|
||||
#undef FAIL
|
||||
@@ -190,6 +190,11 @@
|
||||
interpreter.SetProc("randseed", /proc/n_randseed)
|
||||
interpreter.SetProc("min", /proc/n_min)
|
||||
interpreter.SetProc("max", /proc/n_max)
|
||||
interpreter.SetProc("sin", /proc/n_sin)
|
||||
interpreter.SetProc("cos", /proc/n_cos)
|
||||
interpreter.SetProc("asin", /proc/n_asin)
|
||||
interpreter.SetProc("acos", /proc/n_acos)
|
||||
interpreter.SetProc("log", /proc/n_log)
|
||||
|
||||
// Time
|
||||
interpreter.SetProc("time", /proc/n_time)
|
||||
|
||||
@@ -262,6 +262,31 @@
|
||||
if(isnum(num)&&isnum(min)&&isnum(max))
|
||||
return ((min <= num) && (num <= max))
|
||||
|
||||
// Returns the sine of num
|
||||
/proc/n_sin(var/num)
|
||||
if(isnum(num))
|
||||
return sin(num)
|
||||
|
||||
// Returns the cosine of num
|
||||
/proc/n_cos(var/num)
|
||||
if(isnum(num))
|
||||
return cos(num)
|
||||
|
||||
// Returns the arcsine of num
|
||||
/proc/n_asin(var/num)
|
||||
if(isnum(num)&&-1<=num&&num<=1)
|
||||
return arcsin(num)
|
||||
|
||||
// Returns the arccosine of num
|
||||
/proc/n_acos(var/num)
|
||||
if(isnum(num)&&-1<=num&&num<=1)
|
||||
return arccos(num)
|
||||
|
||||
// Returns the natural log of num
|
||||
/proc/n_log(var/num)
|
||||
if(isnum(num)&&0<num)
|
||||
return log(num)
|
||||
|
||||
// Replace text
|
||||
/proc/n_replace(text, find, replacement)
|
||||
if(istext(text) && istext(find) && istext(replacement))
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
else if(isobject(b) && !isobject(a))
|
||||
RaiseError(new/runtimeError/TypeMismatch("/", a, b))
|
||||
return null
|
||||
if(b==0)
|
||||
if(b==0 || b==null)
|
||||
RaiseError(new/runtimeError/DivisionByZero())
|
||||
return null
|
||||
return a/b
|
||||
@@ -166,4 +166,4 @@
|
||||
//Unary//
|
||||
Minus(a) return -a
|
||||
LogicalNot(a) return !a
|
||||
BitwiseNot(a) return ~a
|
||||
BitwiseNot(a) return ~a
|
||||
|
||||
@@ -118,13 +118,14 @@
|
||||
for(, src.codepos<=lentext(code), src.codepos++)
|
||||
|
||||
var/char=copytext(code, codepos, codepos+1)
|
||||
var/nextchar=copytext(code, codepos+1, codepos+2)
|
||||
if(char=="\n")
|
||||
line++
|
||||
linepos=codepos
|
||||
|
||||
if(ignore.Find(char))
|
||||
continue
|
||||
else if(char == "/")
|
||||
else if(char == "/" && (nextchar == "/" || nextchar == "*"))
|
||||
ReadComment()
|
||||
else if(end_stmt.Find(char))
|
||||
tokens+=new /token/end(char, line, COL)
|
||||
|
||||
+507
-63
@@ -1,52 +1,472 @@
|
||||
var/obj/list/shuttles = list(("escape" = new /datum/shuttle_manager(/area/shuttle/escape/centcom, 0)), ("pod1" = new /datum/shuttle_manager(/area/shuttle/escape_pod1/station, 0)), ("pod2" = new /datum/shuttle_manager(/area/shuttle/escape_pod2/station, 0)), ("pod3" = new /datum/shuttle_manager(/area/shuttle/escape_pod3/station, 0)), ("pod4" = new /datum/shuttle_manager(/area/shuttle/escape_pod4/station, 0)), ("mining" = new /datum/shuttle_manager(/area/shuttle/mining/station, 10)), ("laborcamp" = new /datum/shuttle_manager(/area/shuttle/laborcamp/station, 10)), ("ferry" = new /datum/shuttle_manager(/area/shuttle/transport1/centcom, 0)))
|
||||
//Pre-made shuttles should have non-number keys, so that buildable shuttles can use numbered keys without allowing 'I build a shuttle console with the escape number as its ID.'
|
||||
datum/shuttle_manager
|
||||
var/tickstomove = 10 //How long does it take to move the shuttle?
|
||||
var/moving = 0 //Is it moving?
|
||||
var/area/shuttle/location //The current location of the actual shuttle
|
||||
//use this define to highlight docking port bounding boxes (ONLY FOR DEBUG USE)
|
||||
//#define DOCKING_PORT_HIGHLIGHT
|
||||
|
||||
datum/shuttle_manager/New(var/area, var/delay) //Create a new shuttle manager for the shuttle starting area, "area" and with a movement delay of tickstomove
|
||||
location = area
|
||||
tickstomove = delay
|
||||
var/area/A = locate(location)
|
||||
A.has_gravity = 1
|
||||
//NORTH default dir
|
||||
/obj/docking_port
|
||||
invisibility = 101
|
||||
icon = 'icons/obj/device.dmi'
|
||||
//icon = 'icons/dirsquare.dmi'
|
||||
icon_state = "pinonfar"
|
||||
|
||||
unacidable = 1
|
||||
anchored = 1
|
||||
|
||||
var/id
|
||||
dir = NORTH //this should point -away- from the dockingport door, ie towards the ship
|
||||
var/width = 0 //size of covered area, perpendicular to dir
|
||||
var/height = 0 //size of covered area, paralell to dir
|
||||
var/dwidth = 0 //position relative to covered area, perpendicular to dir
|
||||
var/dheight = 0 //position relative to covered area, parallel to dir
|
||||
|
||||
//these objects are indestructable
|
||||
Destroy()
|
||||
return 1
|
||||
|
||||
|
||||
datum/shuttle_manager/proc/move_shuttle(var/override_delay)
|
||||
if(moving) return 0
|
||||
moving = 1
|
||||
spawn(override_delay == null ? tickstomove*10 : override_delay)
|
||||
var/area/shuttle/fromArea
|
||||
var/area/shuttle/toArea
|
||||
fromArea = locate(location) //the location of the shuttle
|
||||
toArea = locate(fromArea.destination)
|
||||
//returns a list(x0,y0, x1,y1) where points 0 and 1 are bounding corners of the projected rectangle
|
||||
proc/return_coords(_x, _y, _dir)
|
||||
if(!_dir)
|
||||
_dir = dir
|
||||
if(!_x)
|
||||
_x = x
|
||||
if(!_y)
|
||||
_y = y
|
||||
|
||||
toArea.clear_docking_area()
|
||||
//byond's sin and cos functions are inaccurate. This is faster and perfectly accurate
|
||||
var/cos = 1
|
||||
var/sin = 0
|
||||
switch(_dir)
|
||||
if(WEST)
|
||||
cos = 0
|
||||
sin = 1
|
||||
if(SOUTH)
|
||||
cos = -1
|
||||
sin = 0
|
||||
if(EAST)
|
||||
cos = 0
|
||||
sin = -1
|
||||
|
||||
fromArea.move_contents_to(toArea)
|
||||
location = toArea.type
|
||||
return list(
|
||||
_x + (-dwidth*cos) - (-dheight*sin),
|
||||
_y + (-dwidth*sin) + (-dheight*cos),
|
||||
_x + (-dwidth+width-1)*cos - (-dheight+height-1)*sin,
|
||||
_y + (-dwidth+width-1)*sin + (-dheight+height-1)*cos
|
||||
)
|
||||
|
||||
fromArea.has_gravity = 0
|
||||
toArea.has_gravity = 1
|
||||
|
||||
for(var/obj/machinery/door/D in toArea) //Close any doors on the shuttle
|
||||
spawn(0)
|
||||
D.close()
|
||||
//returns turfs within our projected rectangle in a specific order.
|
||||
//this ensures that turfs are copied over in the same order, regardless of any rotation
|
||||
proc/return_ordered_turfs(_x, _y, _z, _dir)
|
||||
if(!_dir)
|
||||
_dir = dir
|
||||
if(!_x)
|
||||
_x = x
|
||||
if(!_y)
|
||||
_y = y
|
||||
if(!_z)
|
||||
_z = z
|
||||
var/cos = 1
|
||||
var/sin = 0
|
||||
switch(_dir)
|
||||
if(WEST)
|
||||
cos = 0
|
||||
sin = 1
|
||||
if(SOUTH)
|
||||
cos = -1
|
||||
sin = 0
|
||||
if(EAST)
|
||||
cos = 0
|
||||
sin = -1
|
||||
|
||||
for(var/mob/M in toArea)
|
||||
if(M.client)
|
||||
spawn(0)
|
||||
if(M.buckled)
|
||||
shake_camera(M, 2, 1) // turn it down a bit come on
|
||||
. = list()
|
||||
|
||||
var/xi
|
||||
var/yi
|
||||
for(var/dx=0, dx<width, ++dx)
|
||||
for(var/dy=0, dy<height, ++dy)
|
||||
xi = _x + (dx-dwidth)*cos - (dy-dheight)*sin
|
||||
yi = _y + (dy-dheight)*cos + (dx-dwidth)*sin
|
||||
. += locate(xi, yi, _z)
|
||||
|
||||
#ifdef DOCKING_PORT_HIGHLIGHT
|
||||
//Debug proc used to highlight bounding area
|
||||
proc/highlight(_color)
|
||||
var/list/L = return_coords()
|
||||
var/turf/T0 = locate(L[1],L[2],z)
|
||||
var/turf/T1 = locate(L[3],L[4],z)
|
||||
for(var/turf/T in block(T0,T1))
|
||||
T.color = _color
|
||||
T.maptext = null
|
||||
if(_color)
|
||||
var/turf/T = locate(L[1], L[2], z)
|
||||
T.color = "#0f0"
|
||||
T = locate(L[3], L[4], z)
|
||||
T.color = "#00f"
|
||||
#endif
|
||||
|
||||
//return first-found touching dockingport
|
||||
proc/get_docked()
|
||||
return locate(/obj/docking_port/stationary) in loc
|
||||
|
||||
proc/getDockedId()
|
||||
var/obj/docking_port/P = get_docked()
|
||||
if(P) return P.id
|
||||
|
||||
/obj/docking_port/stationary
|
||||
name = "dock"
|
||||
|
||||
var/turf_type = /turf/space
|
||||
var/area_type = /area/space
|
||||
|
||||
New()
|
||||
..()
|
||||
SSshuttle.stationary += src
|
||||
if(!id)
|
||||
id = "[SSshuttle.stationary.len]"
|
||||
if(name == "dock")
|
||||
name = "dock[SSshuttle.stationary.len]"
|
||||
|
||||
#ifdef DOCKING_PORT_HIGHLIGHT
|
||||
highlight("#f00")
|
||||
#endif
|
||||
|
||||
//returns first-found touching shuttleport
|
||||
get_docked()
|
||||
return locate(/obj/docking_port/mobile) in loc
|
||||
/*
|
||||
for(var/turf/T in return_ordered_turfs())
|
||||
. = locate(/obj/docking_port/mobile) in loc
|
||||
if(.)
|
||||
return .
|
||||
*/
|
||||
|
||||
/obj/docking_port/stationary/transit
|
||||
name = "In Transit"
|
||||
turf_type = /turf/space/transit
|
||||
|
||||
New()
|
||||
..()
|
||||
SSshuttle.transit += src
|
||||
|
||||
|
||||
/obj/docking_port/mobile
|
||||
icon_state = "mobile"
|
||||
name = "shuttle"
|
||||
icon_state = "pinonclose"
|
||||
|
||||
var/area/shuttle/areaInstance
|
||||
|
||||
var/timer //used as a timer (if you want time left to complete move, use timeLeft proc)
|
||||
var/mode = SHUTTLE_IDLE //current shuttle mode (see global defines)
|
||||
var/callTime = 50 //time spent in transit (deciseconds)
|
||||
|
||||
var/travelDir = 0 //direction the shuttle would travel in
|
||||
|
||||
var/obj/docking_port/stationary/destination
|
||||
var/obj/docking_port/stationary/previous
|
||||
|
||||
New()
|
||||
..()
|
||||
SSshuttle.mobile += src
|
||||
|
||||
if(!id)
|
||||
id = "[SSshuttle.mobile.len]"
|
||||
if(name == "shuttle")
|
||||
name = "shuttle[SSshuttle.mobile.len]"
|
||||
|
||||
if(!areaInstance)
|
||||
areaInstance = new()
|
||||
areaInstance.name = name
|
||||
areaInstance.contents += return_ordered_turfs()
|
||||
|
||||
#ifdef DOCKING_PORT_HIGHLIGHT
|
||||
highlight("#0f0")
|
||||
#endif
|
||||
|
||||
//this is a hook for custom behaviour. Maybe at some point we could add checks to see if engines are intact
|
||||
proc/canMove()
|
||||
return 0 //0 means we can move
|
||||
|
||||
//this is to check if this shuttle can physically dock at dock S
|
||||
proc/canDock(obj/docking_port/stationary/S)
|
||||
if(!istype(S))
|
||||
return 1
|
||||
if(istype(S, /obj/docking_port/stationary/transit))
|
||||
return 0
|
||||
//check dock is big enough to contain us
|
||||
if(dwidth > S.dwidth)
|
||||
return 2
|
||||
if(width-dwidth > S.width-S.dwidth)
|
||||
return 3
|
||||
if(dheight > S.dheight)
|
||||
return 4
|
||||
if(height-dheight > S.height-S.dheight)
|
||||
return 5
|
||||
//check the dock isn't occupied
|
||||
if(S.get_docked())
|
||||
return 6
|
||||
return 0 //0 means we can dock
|
||||
|
||||
//call the shuttle to destination S
|
||||
proc/request(obj/docking_port/stationary/S)
|
||||
if(canDock(S))
|
||||
ERROR("[type](\"[name]\") cannot dock at [S]\")")
|
||||
return 1 //we can't dock at S
|
||||
|
||||
switch(mode)
|
||||
if(SHUTTLE_CALL)
|
||||
if(S == destination)
|
||||
if(world.time <= timer)
|
||||
timer = world.time
|
||||
else
|
||||
destination = S
|
||||
timer = world.time
|
||||
if(SHUTTLE_RECALL)
|
||||
if(S == destination)
|
||||
timer = world.time - timeLeft(1)
|
||||
else
|
||||
destination = S
|
||||
timer = world.time
|
||||
mode = SHUTTLE_CALL
|
||||
else
|
||||
destination = S
|
||||
mode = SHUTTLE_CALL
|
||||
timer = world.time
|
||||
enterTransit() //hyperspace
|
||||
|
||||
//recall the shuttle to where it was previously
|
||||
proc/cancel()
|
||||
if(mode != SHUTTLE_CALL)
|
||||
return
|
||||
|
||||
timer = world.time - timeLeft(1)
|
||||
mode = SHUTTLE_RECALL
|
||||
|
||||
proc/enterTransit()
|
||||
previous = null
|
||||
// if(!destination)
|
||||
// return
|
||||
var/obj/docking_port/stationary/S0 = get_docked()
|
||||
var/obj/docking_port/stationary/S1 = findTransitDock()
|
||||
if(S1)
|
||||
if(dock(S1))
|
||||
WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].")
|
||||
else
|
||||
previous = S0
|
||||
else
|
||||
WARNING("shuttle \"[id]\" could not enter transit space. S0=[S0 ? S0.id : "null"] S1=[S1 ? S1.id : "null"]")
|
||||
|
||||
//this is the main proc. It instantly moves our mobile port to stationary port S1
|
||||
//it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc
|
||||
proc/dock(obj/docking_port/stationary/S1)
|
||||
. = canDock(S1)
|
||||
if(.)
|
||||
ERROR("[type](\"[name]\") cannot dock at [S1]")
|
||||
return .
|
||||
|
||||
if(canMove())
|
||||
return -1
|
||||
|
||||
closePortDoors()
|
||||
|
||||
// //rotate transit docking ports, so we don't need zillions of variants
|
||||
// if(istype(S1, /obj/docking_port/stationary/transit))
|
||||
// S1.dir = turn(NORTH, -travelDir)
|
||||
|
||||
var/obj/docking_port/stationary/S0 = get_docked()
|
||||
var/turf_type = /turf/space
|
||||
var/area_type = /area/space
|
||||
if(S0)
|
||||
if(S0.turf_type)
|
||||
turf_type = S0.turf_type
|
||||
if(S0.area_type)
|
||||
area_type = S0.area_type
|
||||
|
||||
var/list/L0 = return_ordered_turfs()
|
||||
var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir)
|
||||
|
||||
//remove area surrounding docking port
|
||||
if(areaInstance.contents.len)
|
||||
var/area/A0 = locate("[area_type]")
|
||||
if(!A0)
|
||||
A0 = new area_type(null)
|
||||
for(var/turf/T0 in L0)
|
||||
A0.contents += T0
|
||||
|
||||
//move or squish anything in the way ship at destination
|
||||
roadkill(L1, S1.dir)
|
||||
|
||||
for(var/i=1, i<=L0.len, ++i)
|
||||
var/turf/T0 = L0[i]
|
||||
if(!istype(T0, /turf/simulated/shuttle)) //only move shuttle turfs!
|
||||
continue
|
||||
|
||||
var/turf/T1 = L1[i]
|
||||
if(!T1)
|
||||
continue
|
||||
|
||||
T0.copyTurf(T1)
|
||||
areaInstance.contents += T1
|
||||
|
||||
//copy over air
|
||||
if(istype(T1, /turf/simulated))
|
||||
var/turf/simulated/Ts1 = T1
|
||||
Ts1.copy_air_with_tile(T0)
|
||||
|
||||
//move mobile to new location
|
||||
loc = S1.loc
|
||||
dir = S1.dir
|
||||
|
||||
//move all objects
|
||||
for(var/obj/O in T0)
|
||||
if(O.invisibility >= 101)
|
||||
continue
|
||||
O.loc = T1
|
||||
|
||||
//close open doors
|
||||
if(istype(O, /obj/machinery/door))
|
||||
var/obj/machinery/door/Door = O
|
||||
spawn(-1)
|
||||
if(Door)
|
||||
Door.close()
|
||||
|
||||
for(var/mob/M in T0)
|
||||
if(!M.move_on_shuttle)
|
||||
continue
|
||||
M.loc = T1
|
||||
|
||||
//docking turbulence
|
||||
if(M.client)
|
||||
spawn(0)
|
||||
if(M.buckled)
|
||||
shake_camera(M, 2, 1) // turn it down a bit come on
|
||||
else
|
||||
shake_camera(M, 7, 1)
|
||||
if(istype(M, /mob/living/carbon))
|
||||
if(!M.buckled)
|
||||
M.Weaken(3)
|
||||
|
||||
T0.ChangeTurf(turf_type)
|
||||
|
||||
//air system updates
|
||||
for(var/turf/T1 in L1)
|
||||
T1.shift_to_subarea()
|
||||
SSair.remove_from_active(T1)
|
||||
T1.CalculateAdjacentTurfs()
|
||||
SSair.add_to_active(T1,1)
|
||||
|
||||
for(var/turf/T0 in L0)
|
||||
T0.shift_to_subarea()
|
||||
SSair.remove_from_active(T0)
|
||||
T0.CalculateAdjacentTurfs()
|
||||
SSair.add_to_active(T0,1)
|
||||
|
||||
/*
|
||||
if(istype(S1, /obj/docking_port/stationary/transit))
|
||||
var/d = turn(dir, 180 + travelDir)
|
||||
for(var/turf/space/transit/T in S1.return_ordered_turfs())
|
||||
T.pushdirection = d
|
||||
T.update_icon()
|
||||
*/
|
||||
|
||||
proc/findTransitDock()
|
||||
var/obj/docking_port/stationary/transit/T = SSshuttle.getDock("[id]_transit")
|
||||
if(T && !canDock(T))
|
||||
return T
|
||||
/* commented out due to issues with rotation
|
||||
for(var/obj/docking_port/stationary/transit/S in SSshuttle.transit)
|
||||
if(S.id)
|
||||
continue
|
||||
if(!canDock(S))
|
||||
return S
|
||||
*/
|
||||
|
||||
|
||||
//shuttle-door closing is handled in the dock() proc whilst looping through turfs
|
||||
//this one closes the door where we are docked at, if there is one there.
|
||||
proc/closePortDoors()
|
||||
var/turf/T = get_step(loc, turn(dir,180))
|
||||
if(T)
|
||||
var/obj/machinery/door/Door = locate() in T
|
||||
if(Door)
|
||||
spawn(-1)
|
||||
Door.close()
|
||||
|
||||
proc/roadkill(list/L, dir, x, y)
|
||||
for(var/turf/T in L)
|
||||
for(var/atom/movable/AM in T)
|
||||
if(ismob(AM))
|
||||
if(istype(AM, /mob/living))
|
||||
var/mob/living/M = AM
|
||||
M.Paralyse(10)
|
||||
M.take_organ_damage(80)
|
||||
M.anchored = 0
|
||||
else
|
||||
shake_camera(M, 7, 1)
|
||||
if(istype(M, /mob/living/carbon))
|
||||
if(!M.buckled)
|
||||
M.Weaken(3)
|
||||
continue
|
||||
|
||||
moving = 0
|
||||
return 1
|
||||
if(!AM.anchored)
|
||||
step(AM, dir)
|
||||
else
|
||||
qdel(AM)
|
||||
/*
|
||||
//used to check if atom/A is within the shuttle's bounding box
|
||||
proc/onShuttleCheck(atom/A)
|
||||
var/turf/T = get_turf(A)
|
||||
if(!T)
|
||||
return 0
|
||||
|
||||
var/list/L = return_coords()
|
||||
if(L[1] > L[3])
|
||||
L.Swap(1,3)
|
||||
if(L[2] > L[4])
|
||||
L.Swap(2,4)
|
||||
|
||||
if(L[1] <= T.x && T.x <= L[3])
|
||||
if(L[2] <= T.y && T.y <= L[4])
|
||||
return 1
|
||||
return 0
|
||||
*/
|
||||
//used by shuttle subsystem to check timers
|
||||
proc/check()
|
||||
var/timeLeft = timeLeft(1)
|
||||
if(timeLeft <= 0)
|
||||
switch(mode)
|
||||
if(SHUTTLE_CALL)
|
||||
if(dock(destination))
|
||||
setTimer(20) //can't dock for some reason, try again in 2 seconds
|
||||
return
|
||||
if(SHUTTLE_RECALL)
|
||||
if(dock(previous))
|
||||
setTimer(20) //can't dock for some reason, try again in 2 seconds
|
||||
return
|
||||
mode = SHUTTLE_IDLE
|
||||
timer = 0
|
||||
destination = null
|
||||
|
||||
|
||||
proc/setTimer(wait)
|
||||
if(timer <= 0)
|
||||
timer = world.time
|
||||
timer += wait - timeLeft(1)
|
||||
|
||||
//returns timeLeft
|
||||
proc/timeLeft(divisor)
|
||||
if(divisor <= 0)
|
||||
divisor = 10
|
||||
if(!timer)
|
||||
return round(callTime/divisor, 1)
|
||||
return max( round((timer+callTime-world.time)/divisor,1), 0 )
|
||||
|
||||
proc/getStatusText()
|
||||
var/obj/docking_port/stationary/dockedAt = get_docked()
|
||||
. = (dockedAt && dockedAt.name) ? dockedAt.name : "unknown"
|
||||
if(istype(dockedAt, /obj/docking_port/stationary/transit))
|
||||
var/obj/docking_port/stationary/dst
|
||||
if(mode == SHUTTLE_RECALL)
|
||||
dst = previous
|
||||
else
|
||||
dst = destination
|
||||
. += " towards [dst ? dst.name : "unknown location"] ([timeLeft(600)]mins)"
|
||||
|
||||
/obj/machinery/computer/shuttle
|
||||
name = "Shuttle Console"
|
||||
@@ -54,17 +474,34 @@ datum/shuttle_manager/proc/move_shuttle(var/override_delay)
|
||||
icon_state = "shuttle"
|
||||
req_access = list( )
|
||||
circuit = /obj/item/weapon/circuitboard/shuttle
|
||||
var/id
|
||||
var/shuttleId
|
||||
var/possible_destinations = ""
|
||||
|
||||
/obj/machinery/computer/shuttle/New(location, obj/item/weapon/circuitboard/shuttle/C)
|
||||
..()
|
||||
if(istype(C))
|
||||
possible_destinations = C.possible_destinations
|
||||
shuttleId = C.shuttleId
|
||||
|
||||
/obj/machinery/computer/shuttle/attack_hand(user as mob)
|
||||
if(..(user))
|
||||
return
|
||||
src.add_fingerprint(usr)
|
||||
var/dat
|
||||
dat = text("<center><A href='?src=\ref[src];move=[1]'>Send Shuttle</A></center>")
|
||||
//user << browse("[dat]", "window=miningshuttle;size=200x100")
|
||||
var/datum/browser/popup = new(user, "miningshuttle", name, 200, 140)
|
||||
popup.set_content(dat)
|
||||
|
||||
var/list/options = params2list(possible_destinations)
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
|
||||
var/dat = "Status: [M ? M.getStatusText() : "*Missing*"]<br><br>"
|
||||
if(M)
|
||||
for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
|
||||
if(!options.Find(S.id))
|
||||
continue
|
||||
if(M.canDock(S))
|
||||
continue
|
||||
dat += "<A href='?src=\ref[src];move=[S.id]'>Send to [S.name]</A><br>"
|
||||
dat += "<a href='?src=\ref[user];mach_close=computer'>Close</a>"
|
||||
|
||||
var/datum/browser/popup = new(user, "computer", M ? M.name : "shuttle", 300, 200)
|
||||
popup.set_content("<center>[dat]</center>")
|
||||
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
@@ -76,15 +513,12 @@ datum/shuttle_manager/proc/move_shuttle(var/override_delay)
|
||||
if(!allowed(usr))
|
||||
usr << "<span class='danger'>Access denied.</span>"
|
||||
return
|
||||
|
||||
if(href_list["move"])
|
||||
if(id in shuttles)
|
||||
var/datum/shuttle_manager/s = shuttles[id]
|
||||
if (s.move_shuttle())
|
||||
usr << "<span class='notice'>Shuttle recieved message and will be sent shortly.</span>"
|
||||
else
|
||||
usr << "<span class='notice'>Shuttle is already moving.</span>"
|
||||
else
|
||||
usr << "<span class='warning'>Invalid shuttle requested.</span>"
|
||||
switch(SSshuttle.moveShuttle(shuttleId, href_list["move"], 1))
|
||||
if(0) usr << "<span class='notice'>Shuttle recieved message and will be sent shortly.</span>"
|
||||
if(1) usr << "<span class='warning'>Invalid shuttle requested.</span>"
|
||||
else usr << "<span class='notice'>Unable to comply.</span>"
|
||||
|
||||
/obj/machinery/computer/shuttle/emag_act(mob/user as mob)
|
||||
if(!emagged)
|
||||
@@ -95,20 +529,30 @@ datum/shuttle_manager/proc/move_shuttle(var/override_delay)
|
||||
/obj/machinery/computer/shuttle/ferry
|
||||
name = "transport ferry console"
|
||||
circuit = /obj/item/weapon/circuitboard/ferry
|
||||
id = "ferry"
|
||||
shuttleId = "ferry"
|
||||
possible_destinations = "ferry_home;ferry_away"
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle/ferry/request
|
||||
name = "ferry console"
|
||||
circuit = /obj/item/weapon/circuitboard/ferry/request
|
||||
var/cooldown //prevents spamming admins
|
||||
possible_destinations = "ferry_home"
|
||||
|
||||
/obj/machinery/computer/shuttle/ferry/request/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
if(cooldown)
|
||||
return
|
||||
cooldown = 1
|
||||
usr << "<span class='notice'>Docking locks are engaged. Requesting authorization..."
|
||||
var/datum/shuttle_manager/s = shuttles["ferry"]
|
||||
admins << "<b>FERRY: <font color='blue'>[key_name(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[usr]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=moveferry'>Move</a>)</b> is requesting to move the transport ferry to [s.location == /area/shuttle/transport1/centcom ? "the station" : "Centcom"].</font>"
|
||||
spawn(600) //One minute cooldown
|
||||
cooldown = 0
|
||||
|
||||
|
||||
#undef DOCKING_PORT_HIGHLIGHT
|
||||
|
||||
|
||||
/turf/proc/copyTurf(turf/T)
|
||||
if(T.type != type)
|
||||
T = new type(T)
|
||||
if(T.icon_state != icon_state)
|
||||
T.icon_state = icon_state
|
||||
if(T.icon != icon)
|
||||
T.icon = icon
|
||||
if(T.color != color)
|
||||
T.color = color
|
||||
if(T.dir != dir)
|
||||
T.dir = dir
|
||||
return T
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
//saw bone
|
||||
/datum/surgery_step/saw
|
||||
implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/melee/arm_blade = 75, /obj/item/weapon/hatchet = 35, /obj/item/weapon/butch = 25)
|
||||
implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/melee/arm_blade = 75, /obj/item/weapon/hatchet = 35, /obj/item/weapon/kitchenknife/butcher = 25)
|
||||
time = 64
|
||||
|
||||
/datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
//cut fat
|
||||
/datum/surgery_step/cut_fat
|
||||
implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/hatchet = 35, /obj/item/weapon/butch = 25)
|
||||
implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/hatchet = 35, /obj/item/weapon/kitchenknife/butcher = 25)
|
||||
time = 64
|
||||
|
||||
/datum/surgery_step/cut_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
|
||||
@@ -119,14 +119,14 @@
|
||||
|
||||
/obj/item/weapon/rcs/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
SSobj.processing.Add(src)
|
||||
|
||||
/obj/item/weapon/rcs/examine(mob/user)
|
||||
..()
|
||||
user << "There are [rcharges] charge\s left."
|
||||
|
||||
/obj/item/weapon/rcs/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
/obj/item/weapon/rcs/process()
|
||||
if(rcharges > 10)
|
||||
@@ -154,4 +154,4 @@
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
user << "<span class = 'caution'> You emag the RCS. Click on it to toggle between modes.</span>"
|
||||
user << "<span class = 'caution'> You emag the RCS. Click on it to toggle between modes.</span>"
|
||||
|
||||
Reference in New Issue
Block a user