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:
paprka
2015-01-07 14:15:02 -08:00
271 changed files with 17804 additions and 14833 deletions
+7 -9
View File
@@ -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))
+2 -2
View File
@@ -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>"
+37 -18
View File
@@ -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
+1 -17
View File
@@ -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"
+2
View File
@@ -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
+3 -3
View File
@@ -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
View File
@@ -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
+5 -4
View File
@@ -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")
+27
View File
@@ -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
+1 -22
View File
@@ -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
+1 -1
View File
@@ -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..."
+7 -7
View File
@@ -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>")
-24
View File
@@ -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>"
+12 -14
View File
@@ -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>")
+1 -1
View File
@@ -103,7 +103,7 @@
/obj/item/device/assembly/process()
processing_objects.Remove(src)
SSobj.processing.Remove(src)
return
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+4 -4
View File
@@ -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")
+2 -2
View File
@@ -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"
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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 ..()
-282
View File
@@ -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)
+1 -1
View File
@@ -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)
+40 -82
View File
@@ -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
+2 -2
View File
@@ -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)
+2 -2
View File
@@ -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()
-1
View File
@@ -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) \
)
+1 -1
View File
@@ -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)
+23 -7
View File
@@ -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
+3 -1
View File
@@ -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
..()
+19 -16
View File
@@ -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
+2 -1
View File
@@ -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*******************************/
+1
View File
@@ -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
+16 -5
View File
@@ -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)
+2 -1
View File
@@ -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]"
+663
View File
@@ -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
+1 -1
View File
@@ -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"
+18 -13
View File
@@ -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)
+2 -3
View File
@@ -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)
+26 -26
View File
@@ -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))
+7 -3
View File
@@ -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)
+18 -13
View File
@@ -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>"
+1 -1
View File
@@ -17,7 +17,7 @@
see_invisible = SEE_INVISIBLE_LEVEL_TWO
shuttle_caller_list -= src
emergency_shuttle.autoshuttlecall()
SSshuttle.autoEvac()
if(explosive)
spawn(10)
+9 -4
View File
@@ -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)]")
+13 -4
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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))
+25 -33
View File
@@ -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))
+14 -26
View File
@@ -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
+6 -6
View File
@@ -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()
+24 -40
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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
+2 -1
View File
@@ -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
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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
+1 -2
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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()
+4 -4
View File
@@ -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)
..()
+2 -2
View File
@@ -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)
..()
+5 -5
View File
@@ -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."
+392
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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)
+3 -3
View File
@@ -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>"