Merge pull request #6240 from Markolie/stationgoals

Ports Station Goals from /tg/
This commit is contained in:
Fox McCloud
2017-02-17 12:12:11 -05:00
committed by GitHub
39 changed files with 1356 additions and 249 deletions
+4 -1
View File
@@ -316,4 +316,7 @@
#define DRAKE_SCORE "Drakes Killed"
#define BIRD_SCORE "Hierophants Killed"
#define BOSS_SCORE "Bosses Killed"
#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
// The number of station goals generated each round.
#define STATION_GOAL_BUDGET 1
+17 -1
View File
@@ -46,4 +46,20 @@ var/list/TAGGERLOCATIONS = list("Disposals",
"Robotics", "HoP Office", "Library", "Chapel", "Captain's Office",
"Bar", "Kitchen", "Hydroponics", "Janitor Closet","Genetics","Brig Physician")
var/list/hit_appends = list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF")
var/list/hit_appends = list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF")
var/global/list/greek_letters = list("Alpha", "Beta", "Gamma", "Delta",
"Epsilon", "Zeta", "Eta", "Theta", "Iota", "Kappa", "Lambda", "Mu",
"Nu", "Xi", "Omicron", "Pi", "Rho", "Sigma", "Tau", "Upsilon", "Phi",
"Chi", "Psi", "Omega")
var/global/list/phonetic_alphabet = list("Alpha", "Bravo", "Charlie",
"Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliet",
"Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec",
"Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-ray",
"Yankee", "Zulu")
var/global/list/numbers_as_words = list("One", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",
"Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen",
"Eighteen", "Nineteen")
+3 -2
View File
@@ -35,8 +35,9 @@ var/global/list/tracked_implants = list() //list of all current implants that
var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once.
var/global/list/abductor_equipment = list() //list of all abductor equipment
var/global/list/global_intercoms = list() //list of all intercomms, across all z-levels
var/global/list/global_radios = list() //list of all radios, across all z-levels
var/global/list/poi_list = list() //list of points of interest for observe/follow
var/global/list/meteor_list = list() //list of all meteors
var/global/list/poi_list = list() //list of points of interest for observe/follow
+4 -9
View File
@@ -15,7 +15,6 @@
var/static_beam = 0
var/beam_type = /obj/effect/ebeam //must be subtype
/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam)
endtime = world.time+time
origin = beam_origin
@@ -30,7 +29,6 @@
icon_state = beam_icon_state
beam_type = btype
/datum/beam/proc/Start()
Draw()
while(!finished && origin && target && world.time < endtime && get_dist(origin,target)<max_distance && origin.z == target.z)
@@ -45,23 +43,19 @@
qdel(src)
/datum/beam/proc/End()
finished = 1
/datum/beam/proc/Reset()
for(var/obj/effect/ebeam/B in elements)
qdel(B)
/datum/beam/Destroy()
Reset()
target = null
origin = null
return ..()
/datum/beam/proc/Draw()
var/Angle = round(Get_Angle(origin,target))
@@ -115,17 +109,18 @@
X.pixel_x = Pixel_x
X.pixel_y = Pixel_y
/obj/effect/ebeam
mouse_opacity = 0
anchored = 1
var/datum/beam/owner
/obj/effect/ebeam/Destroy()
owner = null
return ..()
/obj/effect/ebeam/deadly/Crossed(atom/A)
..()
A.ex_act(1)
/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam)
var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type)
+58 -1
View File
@@ -53,6 +53,8 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
var/contraband = 0
var/group = supply_misc
var/list/announce_beacons = list() // Particular beacons that we'll notify the relevant department when we reach
var/special = FALSE //Event/Station Goals/Admin enabled packs
var/special_enabled = FALSE
/datum/supply_packs/New()
@@ -1525,7 +1527,62 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/weapon/beach_ball)
cost = 20
containername = "polo supply crate"
///////////// Station Goals
/datum/supply_packs/misc/bsa
name = "Bluespace Artillery Parts"
cost = 150
special = TRUE
contains = list(/obj/item/weapon/circuitboard/machine/bsa/front,
/obj/item/weapon/circuitboard/machine/bsa/middle,
/obj/item/weapon/circuitboard/machine/bsa/back,
/obj/item/weapon/circuitboard/computer/bsa_control
)
containername = "bluespace artillery parts crate"
/datum/supply_packs/misc/dna_vault
name = "DNA Vault Parts"
cost = 120
special = TRUE
contains = list(
/obj/item/weapon/circuitboard/machine/dna_vault
)
containername = "dna vault parts crate"
/datum/supply_packs/misc/dna_probes
name = "DNA Vault Samplers"
cost = 30
special = TRUE
contains = list(/obj/item/device/dna_probe,
/obj/item/device/dna_probe,
/obj/item/device/dna_probe,
/obj/item/device/dna_probe,
/obj/item/device/dna_probe
)
containername = "dna samplers crate"
/datum/supply_packs/misc/shield_sat
name = "Shield Generator Satellite"
cost = 30
special = TRUE
contains = list(
/obj/machinery/satellite/meteor_shield,
/obj/machinery/satellite/meteor_shield,
/obj/machinery/satellite/meteor_shield
)
containername = "shield sat crate"
/datum/supply_packs/misc/shield_sat_control
name = "Shield System Control Board"
cost = 50
special = TRUE
contains = list(
/obj/item/weapon/circuitboard/computer/sat_control
)
containername = "shield control board crate"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////// Vending /////////////////////////////////////////
@@ -1606,4 +1663,4 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/weapon/vending_refill/cigarette,
/obj/item/weapon/vending_refill/cigarette)
cost = 15
containername = "cigarette supply crate"
containername = "cigarette supply crate"
+3 -10
View File
@@ -8,6 +8,7 @@
..()
return
if(1)
interceptname = "Level 5-6 Biohazard Response Procedures"
intercepttext += "<FONT size = 3><B>Nanotrasen Update</B>: Biohazard Alert.</FONT><HR>"
intercepttext += "Reports indicate the probable transfer of a biohazardous agent onto [station_name()] during the last crew deployment cycle.<BR>"
intercepttext += "Preliminary analysis of the organism classifies it as a level 5 biohazard. Its origin is unknown.<BR>"
@@ -26,6 +27,7 @@
if(is_station_level(bomb.z))
bomb.r_code = nukecode
interceptname = "Classified [command_name()] Update"
intercepttext += "<FONT size = 3><B>Nanotrasen Update</B>: Biohazard Alert.</FONT><HR>"
intercepttext += "Directive 7-12 has been issued for [station_name()].<BR>"
intercepttext += "The biohazard has grown out of control and will soon reach critical mass.<BR>"
@@ -41,17 +43,8 @@
aiPlayer.set_zeroth_law(law)
to_chat(aiPlayer, "Laws Updated: [law]")
for(var/obj/machinery/computer/communications/comm in world)
comm.messagetitle.Add(interceptname)
comm.messagetext.Add(intercepttext)
if(!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc )
playsound(comm.loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1)
intercept.name = "Classified Central Command Update"
intercept.info = intercepttext
print_command_report(intercepttext, interceptname)
event_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg')
return
/datum/station_state
var/floor = 0
+37 -1
View File
@@ -37,6 +37,8 @@
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
var/list/player_draft_log = list()
var/list/datum/mind/xenos = list()
var/list/datum/station_goal/station_goals = list() // A list of all station goals for this game mode
/datum/game_mode/proc/announce() //to be calles when round starts
to_chat(world, "<B>Notice</B>: [src] did not define announce()")
@@ -78,6 +80,7 @@
// if(revdata)
// feedback_set_details("revision","[revdata.revision]")
feedback_set_details("server_ip","[world.internet_address]:[world.port]")
generate_station_goals()
start_state = new /datum/station_state()
start_state.count()
return 1
@@ -222,7 +225,7 @@
/datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere.
return 0
/datum/game_mode/proc/get_players_for_role(var/role, override_jobbans=0)
var/list/players = list()
var/list/candidates = list()
@@ -475,3 +478,36 @@ proc/get_nt_opposed()
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <span class='boldannounce'>Fail.</span>"
count++
return text
/datum/game_mode/proc/generate_station_goals()
var/list/possible = list()
for(var/T in subtypesof(/datum/station_goal))
var/datum/station_goal/G = T
if(config_tag in initial(G.gamemode_blacklist))
continue
possible += T
var/goal_weights = 0
while(possible.len && goal_weights < STATION_GOAL_BUDGET)
var/datum/station_goal/picked = pick_n_take(possible)
goal_weights += initial(picked.weight)
station_goals += new picked
if(station_goals.len)
send_station_goals_message()
/datum/game_mode/proc/send_station_goals_message()
var/message_text = "<div style='text-align:center;'><img src='ntlogo.png'>"
message_text += "<h3>[command_name()] Orders</h3></div><hr>"
message_text += "<b>Special Orders for [station_name()]:</b><br><br>"
for(var/datum/station_goal/G in station_goals)
G.on_report()
message_text += G.get_report()
message_text += "<hr>"
print_command_report(message_text, "[command_name()] Orders")
/datum/game_mode/proc/declare_station_goal_completion()
for(var/V in station_goals)
var/datum/station_goal/G = V
G.print_result()
+3 -1
View File
@@ -416,7 +416,6 @@ var/round_start_time = 0
/datum/controller/gameticker/proc/declare_completion()
nologevent = 1 //end of round murder and shenanigans are legal; there's no need to jam up attack logs past this point.
//Round statistics report
var/datum/station_state/end_state = new /datum/station_state()
@@ -471,6 +470,9 @@ var/round_start_time = 0
scoreboard()
karmareminder()
// Declare the completion of the station goals
mode.declare_station_goal_completion()
//Ask the event manager to print round end information
event_manager.RoundEnd()
+2
View File
@@ -118,11 +118,13 @@
return .
/obj/effect/meteor/Destroy()
meteor_list -= src
walk(src,0) //this cancels the walk_towards() proc
return ..()
/obj/effect/meteor/New()
..()
meteor_list += src
SpinAnimation()
/obj/effect/meteor/Bump(atom/A)
@@ -1,26 +1,14 @@
/datum/event/spawn_swarmer
//name = "Sawrmer Spawn"
//one_shot = 1
startWhen = 3 //30 minutes
announceWhen = 10
/datum/event/spawn_swarmer/announce()
if(prob(25)) //25% chance to announce it to the crew
var/swarmer_report = "<font size=3><b>[command_name()] High-Priority Update</b></span>"
swarmer_report += "<br><br>Our long-range sensors have detected an odd signal emanating from your station's gateway. We recommend immediate investigation of your gateway, as something may have come \
through."
for(var/obj/machinery/computer/communications/C in machines)
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "'Classified [command_name()] Update'"
P.info = swarmer_report
P.update_icon()
C.messagetitle.Add("Classified [command_name()] Update")
C.messagetext.Add(P.info)
command_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg')
print_command_report(swarmer_report, "Classified [command_name()] Update")
event_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg')
/datum/event/spawn_swarmer/start()
if(find_swarmer())
@@ -25,7 +25,7 @@
return 1
ui_interact(user)
/obj/machinery/computer/atmoscontrol/emag_act(var/remaining_carges, var/mob/user)
/obj/machinery/computer/atmoscontrol/emag_act(mob/user)
if(!emagged)
user.visible_message("<span class='warning'>\The [user] does something \the [src], causing the screen to flash!</span>",\
"<span class='warning'>You cause the screen to flash as you gain full control.</span>",\
@@ -30,7 +30,12 @@
var/frame_desc = null
var/contain_parts = 1
/obj/item/weapon/circuitboard/computer
board_type = "computer"
/obj/item/weapon/circuitboard/machine
board_type = "machine"
/obj/item/weapon/circuitboard/message_monitor
name = "Circuit board (Message Monitor)"
build_path = /obj/machinery/computer/message_monitor
+58 -39
View File
@@ -53,6 +53,24 @@
to_chat(user, "<span class='warning'>Access denied.</span>")
return COMM_AUTHENTICATION_NONE
/obj/machinery/computer/communications/proc/change_security_level(var/new_level)
tmp_alertlevel = new_level
var/old_level = security_level
if(!tmp_alertlevel) tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN) tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel > SEC_LEVEL_BLUE) tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
set_security_level(tmp_alertlevel)
if(security_level != old_level)
//Only notify the admins if an actual change happened
log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
switch(security_level)
if(SEC_LEVEL_GREEN)
feedback_inc("alert_comms_green",1)
if(SEC_LEVEL_BLUE)
feedback_inc("alert_comms_blue",1)
tmp_alertlevel = 0
/obj/machinery/computer/communications/Topic(href, href_list)
if(..(href, href_list))
return 1
@@ -100,35 +118,25 @@
if("newalertlevel")
if(isAI(usr) || isrobot(usr))
to_chat(usr, "<span class='warning'>Firewalls prevent you from changing the alert level.</span>")
nanomanager.update_uis(src)
return 1
tmp_alertlevel = text2num(href_list["level"])
else if(usr.can_admin_interact())
change_security_level(text2num(href_list["level"]))
return 1
else if(!ishuman(usr))
to_chat(usr, "<span class='warning'>Security measures prevent you from changing the alert level.</span>")
return 1
var/mob/living/carbon/human/L = usr
var/obj/item/card = L.get_active_hand()
var/obj/item/weapon/card/id/I = (card && card.GetID())||L.wear_id||L.wear_pda
var/obj/item/weapon/card/id/I = (card && card.GetID()) || L.wear_id || L.wear_pda
if(istype(I, /obj/item/device/pda))
var/obj/item/device/pda/pda = I
I = pda.id
if(I && istype(I))
if(access_captain in I.access)
var/old_level = security_level
if(!tmp_alertlevel) tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN) tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel > SEC_LEVEL_BLUE) tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
set_security_level(tmp_alertlevel)
if(security_level != old_level)
//Only notify the admins if an actual change happened
log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
switch(security_level)
if(SEC_LEVEL_GREEN)
feedback_inc("alert_comms_green",1)
if(SEC_LEVEL_BLUE)
feedback_inc("alert_comms_blue",1)
tmp_alertlevel = 0
change_security_level(text2num(href_list["level"]))
else
to_chat(usr, "<span class='warning'>You are not authorized to do this.</span>")
tmp_alertlevel = 0
setMenuState(usr,COMM_SCREEN_MAIN)
else
to_chat(usr, "<span class='warning'>You need to swipe your ID.</span>")
@@ -172,24 +180,26 @@
setMenuState(usr,COMM_SCREEN_MAIN)
if("messagelist")
src.currmsg = 0
currmsg = 0
if(href_list["msgid"])
setCurrentMessage(usr, text2num(href_list["msgid"]))
setMenuState(usr,COMM_SCREEN_MESSAGES)
if("delmessage")
if(href_list["msgid"])
src.currmsg = text2num(href_list["msgid"])
currmsg = text2num(href_list["msgid"])
var/response = alert("Are you sure you wish to delete this message?", "Confirm", "Yes", "No")
if(response == "Yes")
if(src.currmsg)
if(currmsg)
var/id = getCurrentMessage()
var/title = src.messagetitle[id]
var/text = src.messagetext[id]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(currmsg==id) currmsg=0
if(aicurrmsg==id) aicurrmsg=0
var/title = messagetitle[id]
var/text = messagetext[id]
messagetitle.Remove(title)
messagetext.Remove(text)
if(currmsg == id)
currmsg = 0
if(aicurrmsg == id)
aicurrmsg = 0
setMenuState(usr,COMM_SCREEN_MESSAGES)
if("status")
@@ -336,7 +346,7 @@
/obj/machinery/computer/communications/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
var/data[0]
data["is_ai"] = isAI(user)||isrobot(user)
data["is_ai"] = isAI(user) || isrobot(user)
data["menu_state"] = data["is_ai"] ? ai_menu_state : menu_state
data["emagged"] = emagged
data["authenticated"] = is_authenticated(user, 0)
@@ -368,16 +378,15 @@
list("id" = SEC_LEVEL_BLUE, "name" = "Blue"),
//SEC_LEVEL_RED = list("name"="Red"),
)
var/msg_data[0]
for(var/i = 1; i <= src.messagetext.len; i++)
var/cur_msg[0]
cur_msg["title"] = messagetitle[i]
cur_msg["body"] = messagetext[i]
msg_data += list(cur_msg)
var/list/msg_data = list()
for(var/i = 1; i <= messagetext.len; i++)
msg_data.Add(list(list("title" = messagetitle[i], "body" = messagetext[i], "id" = i)))
data["messages"] = msg_data
data["current_message"] = data["is_ai"] ? aicurrmsg : currmsg
if((data["is_ai"] && aicurrmsg) || (!data["is_ai"] && currmsg))
data["current_message"] = data["is_ai"] ? messagetext[aicurrmsg] : messagetext[currmsg]
data["current_message_title"] = data["is_ai"] ? messagetitle[aicurrmsg] : messagetitle[currmsg]
data["lastCallLoc"] = shuttle_master.emergencyLastCallLoc ? format_text(shuttle_master.emergencyLastCallLoc.name) : null
@@ -403,9 +412,9 @@
/obj/machinery/computer/communications/proc/setCurrentMessage(var/mob/user,var/value)
if(isAI(user) || isrobot(user))
aicurrmsg=value
aicurrmsg = value
else
currmsg=value
currmsg = value
/obj/machinery/computer/communications/proc/getCurrentMessage(var/mob/user)
if(isAI(user) || isrobot(user))
@@ -540,3 +549,13 @@
message_admins("All the AI's, communication consoles and boards are destroyed. Shuttle called.", 1)
return ..()
/proc/print_command_report(text = "", title = "Central Command Update")
for(var/obj/machinery/computer/communications/C in machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_contact(C.z))
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(C.loc)
P.name = "paper- '[title]'"
P.info = text
C.messagetitle.Add("[title]")
C.messagetext.Add(text)
P.update_icon()
+2 -1
View File
@@ -110,7 +110,8 @@ var/list/admin_verbs_event = list(
/client/proc/response_team, // Response Teams admin verb
/client/proc/cmd_admin_create_centcom_report,
/client/proc/fax_panel,
/client/proc/event_manager_panel
/client/proc/event_manager_panel,
/client/proc/modify_goals
)
var/list/admin_verbs_spawn = list(
+21
View File
@@ -3115,6 +3115,27 @@
error_viewer.showTo(usr, locate(href_list["viewruntime_backto"]), href_list["viewruntime_linear"])
else
error_viewer.showTo(usr, null, href_list["viewruntime_linear"])
else if(href_list["add_station_goal"])
if(!check_rights(R_EVENT))
return
var/list/type_choices = typesof(/datum/station_goal)
var/picked = input("Choose goal type") in type_choices|null
if(!picked)
return
var/datum/station_goal/G = new picked()
if(picked == /datum/station_goal)
var/newname = input("Enter goal name:") as text|null
if(!newname)
return
G.name = newname
var/description = input("Enter [command_name()] message contents:") as message|null
if(!description)
return
G.report_message = description
message_admins("[key_name_admin(usr)] created \"[G.name]\" station goal.")
ticker.mode.station_goals += G
modify_goals()
/proc/admin_jump_link(var/atom/target)
if(!target) return
+22 -21
View File
@@ -561,36 +561,22 @@ Traitors and the like can also be revived with the previous role mostly intact.
if("Yes")
communications_announcement.Announce(input, customname, , , , from);
if("No")
to_chat(world, "\red [from] available at all communications consoles.")
for(var/obj/machinery/computer/communications/C in machines)
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "[from]"
P.info = input
P.update_icon()
C.messagetitle.Add("[from]")
C.messagetext.Add(P.info)
to_chat(world, "<span class='danger'>[from] available at all communications consoles.</span>")
print_command_report(input, from)
if(type == "Centcom Report")
if(!customname)
customname = "Nanotrasen Update"
switch(alert("Should this be announced to the general population?",,"Yes","No"))
var/announce = alert("Should this be announced to the general population?",,"Yes","No")
switch(announce)
if("Yes")
command_announcement.Announce(input, customname);
if("No")
to_chat(world, "\red New Nanotrasen Update available at all communication consoles.")
to_chat(world, "<span class='danger'>New Nanotrasen Update available at all communication consoles.</span>")
for(var/obj/machinery/computer/communications/C in machines)
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "'[command_name()] Update.'"
P.info = input
P.update_icon()
C.messagetitle.Add("[command_name()] Update")
C.messagetext.Add(P.info)
print_command_report(input, "[announce == "No" ? "Classified " : ""][command_name()] Update")
// world << sound('sound/AI/commandreport.ogg')
log_admin("[key_name(src)] has created a communications report: [input]")
@@ -892,7 +878,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("[key_name_admin(usr)] blanked all telecomms scripts.")
feedback_add_details("admin_verb","RAT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/toggle_ert_calling()
set category = "Event"
set name = "Toggle ERT"
@@ -911,3 +896,19 @@ Traitors and the like can also be revived with the previous role mostly intact.
to_chat(usr, "\red ERT has been <b>Disabled</b>.")
log_admin("Admin [key_name(src)] has disabled ERT calling.")
message_admins("Admin [key_name_admin(usr)] has disabled ERT calling.", 1)
/client/proc/modify_goals()
set category = "Event"
set name = "Modify Station Goals"
if(!check_rights(R_EVENT))
return
holder.modify_goals()
/datum/admins/proc/modify_goals()
var/dat = ""
for(var/datum/station_goal/S in ticker.mode.station_goals)
dat += "[S.name] - <a href='?src=[S.UID()];announce=1'>Announce</a> | <a href='?src=[S.UID()];remove=1'>Remove</a><br>"
dat += "<br><a href='?src=[UID()];add_station_goal=1'>Add New Goal</a>"
usr << browse(dat, "window=goals;size=400x400")
@@ -1,79 +0,0 @@
/obj/machinery/computer/artillerycontrol
name = "bluespace artillery control"
icon_screen = "accelerator"
icon_keyboard = "accelerator_key"
icon_state = "computer-wires"
req_access = list(access_cent_commander)
var/last_fire = 0
var/reload_cooldown = 180 // 3 minute cooldown
var/area/targetarea
light_color = LIGHT_COLOR_LIGHTBLUE
/obj/machinery/computer/artillerycontrol/attack_ai(user as mob)
to_chat(user, "<span class='warning'>Access denied.</span>")
return
/obj/machinery/computer/artillerycontrol/attack_hand(user as mob)
ui_interact(user)
/obj/machinery/computer/artillerycontrol/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "bluespace_artillery.tmpl", "Bluespace Control", 400, 260)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/artillerycontrol/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
var/data[0]
var/time_to_wait = round(reload_cooldown - ((world.time / 10) - last_fire), 1)
var/mins = round(time_to_wait / 60)
var/seconds = time_to_wait - (60*mins)
data["reloadtime_mins"] = mins
data["reloadtime_secs"] = (seconds < 10) ? "0[seconds]" : seconds
if(targetarea)
var/areaname = sanitize(targetarea.name)
data["target"] = "Locked on to [areaname]"
else
data["target"] = "No Lock"
return data
/obj/machinery/computer/artillerycontrol/Topic(href, href_list)
if(..())
return 1
if(href_list["area"])
var/A
A = input("Select the target area.", "Select Area", A) in ghostteleportlocs|null
var/area/thearea = ghostteleportlocs[A]
if(..() || !istype(thearea))
return
targetarea = thearea
if(href_list["fire"])
var/delta = (world.time / 10) - last_fire
if(reload_cooldown > delta)
return 1
event_announcement.Announce("Bluespace artillery fire detected. Brace for impact.")
message_admins("[key_name_admin(usr)] has launched an artillery strike.", 1)
var/list/L = list()
for(var/turf/T in get_area_turfs(targetarea.type))
L += T
var/loc = pick(L)
explosion(loc,2,5,11)
last_fire = world.time / 10
nanomanager.update_uis(src)
/obj/structure/artilleryplaceholder
name = "artillery"
icon = 'icons/obj/machines/artillery.dmi'
anchored = 1
density = 1
/obj/structure/artilleryplaceholder/decorative
density = 0
@@ -86,6 +86,7 @@ emp_act
for(var/obj/item/organ/external/organ in organs)
armorval += getarmor_organ(organ, type)
organnum++
return (armorval/max(organnum, 1))
@@ -99,7 +100,8 @@ emp_act
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & def_zone.body_part)
protection += C.armor[type]
protection += C.armor[type]
return protection
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
+1 -1
View File
@@ -171,7 +171,7 @@
if(gene.is_active(src))
speech_problem_flag = 1
gene.OnMobLife(src)
if(gene_stability < GENETIC_DAMAGE_STAGE_1)
if(!ignore_gene_stability && gene_stability < GENETIC_DAMAGE_STAGE_1)
var/instability = DEFAULT_GENE_STABILITY - gene_stability
if(prob(instability * 0.1))
adjustFireLoss(min(5, instability * 0.67))
@@ -52,6 +52,7 @@
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
var/gene_stability = DEFAULT_GENE_STABILITY
var/ignore_gene_stability = 0
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
+2 -2
View File
@@ -446,7 +446,7 @@
var/packs_list[0]
for(var/set_name in shuttle_master.supply_packs)
var/datum/supply_packs/pack = shuttle_master.supply_packs[set_name]
if(!pack.contraband && !pack.hidden && pack.group == cat)
if(!pack.contraband && !pack.hidden && !pack.special && pack.group == cat)
// 0/1 after the pack name (set_name) is a boolean for ordering multiple crates
packs_list.Add(list(list("name" = pack.name, "amount" = pack.amount, "cost" = pack.cost, "command1" = list("doorder" = "[set_name]0"), "command2" = list("doorder" = "[set_name]1"), "command3" = list("contents" = set_name))))
@@ -595,7 +595,7 @@
var/packs_list[0]
for(var/set_name in shuttle_master.supply_packs)
var/datum/supply_packs/pack = shuttle_master.supply_packs[set_name]
if((pack.hidden && src.hacked) || (pack.contraband && src.can_order_contraband) || (!pack.contraband && !pack.hidden))
if((pack.hidden && hacked) || (pack.contraband && can_order_contraband) || (pack.special && pack.special_enabled) || (!pack.contraband && !pack.hidden && !pack.special))
if(pack.group == cat)
// 0/1 after the pack name (set_name) is a boolean for ordering multiple crates
packs_list.Add(list(list("name" = pack.name, "amount" = pack.amount, "cost" = pack.cost, "command1" = list("doorder" = "[set_name]0"), "command2" = list("doorder" = "[set_name]1"), "command3" = list("contents" = set_name))))
+408
View File
@@ -0,0 +1,408 @@
// Crew has to build a bluespace cannon
// Cargo orders part for high price
// Requires high amount of power
// Requires high level stock parts
/datum/station_goal/bluespace_cannon
name = "Bluespace Artillery"
/datum/station_goal/bluespace_cannon/get_report()
return {"<b>Bluespace Artillery position construction</b><br>
Our military presence is inadequate in your sector. We need you to construct BSA-[rand(1,99)] Artillery position aboard your station.
<br><br>
Its base parts should be available for shipping by your cargo shuttle.
<br>
-Nanotrasen Naval Command"}
/datum/station_goal/bluespace_cannon/on_report()
//Unlock BSA parts
var/datum/supply_packs/misc/bsa/P = shuttle_master.supply_packs["[/datum/supply_packs/misc/bsa]"]
P.special_enabled = TRUE
/datum/station_goal/bluespace_cannon/check_completion()
if(..())
return TRUE
var/obj/machinery/bsa/full/B = locate()
if(B && !B.stat && is_station_contact(B.z))
return TRUE
return FALSE
/obj/machinery/bsa
icon = 'icons/obj/machines/particle_accelerator3.dmi'
density = 1
anchored = 1
/obj/machinery/bsa/back
name = "Bluespace Artillery Generator"
desc = "Generates cannon pulse. Needs to be linked with a fusor. "
icon_state = "power_box"
/obj/machinery/bsa/back/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/device/multitool))
var/obj/item/device/multitool/M = W
M.buffer = src
to_chat(user, "<span class='notice'>You store linkage information in [W]'s buffer.</span>")
else if(istype(W, /obj/item/weapon/wrench))
default_unfasten_wrench(user, W, 10)
return TRUE
else
return ..()
/obj/machinery/bsa/front
name = "Bluespace Artillery Bore"
desc = "Do not stand in front of cannon during operation. Needs to be linked with a fusor."
icon_state = "emitter_center"
/obj/machinery/bsa/front/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/device/multitool))
var/obj/item/device/multitool/M = W
M.buffer = src
to_chat(user, "<span class='notice'>You store linkage information in [W]'s buffer.</span>")
else if(istype(W, /obj/item/weapon/wrench))
default_unfasten_wrench(user, W, 10)
return TRUE
else
return ..()
/obj/machinery/bsa/middle
name = "Bluespace Artillery Fusor"
desc = "Contents classifed by Nanotrasen Naval Command. Needs to be linked with the other BSA parts using multitool."
icon_state = "fuel_chamber"
var/obj/machinery/bsa/back/back
var/obj/machinery/bsa/front/front
/obj/machinery/bsa/middle/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/device/multitool))
var/obj/item/device/multitool/M = W
if(M.buffer)
if(istype(M.buffer,/obj/machinery/bsa/back))
back = M.buffer
M.buffer = null
to_chat(user, "<span class='notice'>You link [src] with [back].</span>")
else if(istype(M.buffer,/obj/machinery/bsa/front))
front = M.buffer
M.buffer = null
to_chat(user, "<span class='notice'>You link [src] with [front].</span>")
else if(istype(W, /obj/item/weapon/wrench))
default_unfasten_wrench(user, W, 10)
return TRUE
else
return ..()
/obj/machinery/bsa/middle/proc/check_completion()
if(!front || !back)
return "No linked parts detected!"
if(!front.anchored || !back.anchored || !anchored)
return "Linked parts unwrenched!"
if(front.y != y || back.y != y || !(front.x > x && back.x < x || front.x < x && back.x > x) || front.z != z || back.z != z)
return "Parts misaligned!"
if(!has_space())
return "Not enough free space!"
/obj/machinery/bsa/middle/proc/has_space()
var/cannon_dir = get_cannon_direction()
var/x_min
var/x_max
switch(cannon_dir)
if(EAST)
x_min = x - 4 //replace with defines later
x_max = x + 6
if(WEST)
x_min = x + 4
x_max = x - 6
for(var/turf/T in block(locate(x_min,y-1,z),locate(x_max,y+1,z)))
if(T.density || isspaceturf(T))
return FALSE
return TRUE
/obj/machinery/bsa/middle/proc/get_cannon_direction()
if(front.x > x && back.x < x)
return EAST
else if(front.x < x && back.x > x)
return WEST
/obj/machinery/bsa/full
name = "Bluespace Artillery"
desc = "Long range bluespace artillery."
icon = 'icons/obj/lavaland/cannon.dmi'
icon_state = "cannon_west"
var/obj/machinery/computer/bsa_control/controller
var/cannon_direction = WEST
var/static/image/top_layer = null
var/ex_power = 3
var/power_used_per_shot = 2000000 //enough to kil standard apc - todo : make this use wires instead and scale explosion power with it
var/last_fire_time = 0 // The time at which the gun was last fired
var/reload_cooldown = 600 // The gun's cooldown
pixel_y = -32
pixel_x = -192
bound_width = 352
bound_x = -192
/obj/machinery/bsa/full/Destroy()
if(controller && controller.cannon == src)
controller.cannon = null
controller = null
return ..()
/obj/machinery/bsa/full/east
icon_state = "cannon_east"
cannon_direction = EAST
/obj/machinery/bsa/full/admin
power_used_per_shot = 0
reload_cooldown = 100
/obj/machinery/bsa/full/admin/east
icon_state = "cannon_east"
cannon_direction = EAST
/obj/machinery/bsa/full/proc/get_front_turf()
switch(dir)
if(WEST)
return locate(x - 6,y,z)
if(EAST)
return locate(x + 4,y,z)
return get_turf(src)
/obj/machinery/bsa/full/proc/get_back_turf()
switch(dir)
if(WEST)
return locate(x + 4,y,z)
if(EAST)
return locate(x - 6,y,z)
return get_turf(src)
/obj/machinery/bsa/full/proc/get_target_turf()
switch(dir)
if(WEST)
return locate(1,y,z)
if(EAST)
return locate(world.maxx,y,z)
return get_turf(src)
/obj/machinery/bsa/full/New(loc, direction)
..()
if(direction)
cannon_direction = direction
switch(cannon_direction)
if(WEST)
dir = WEST
pixel_x = -192
top_layer = image("icons/obj/lavaland/orbital_cannon.dmi", "top_west")
top_layer.layer = 4.1
icon_state = "cannon_west"
if(EAST)
dir = EAST
top_layer = image("icons/obj/lavaland/orbital_cannon.dmi", "top_east")
top_layer.layer = 4.1
icon_state = "cannon_east"
overlays += top_layer
reload()
/obj/machinery/bsa/full/proc/fire(mob/user, turf/bullseye)
var/turf/point = get_front_turf()
for(var/turf/T in getline(get_step(point,dir),get_target_turf()))
T.ex_act(1)
for(var/atom/A in T)
A.ex_act(1)
point.Beam(get_target_turf(), icon_state = "bsa_beam", time = 50, maxdistance = world.maxx, beam_type = /obj/effect/ebeam/deadly) //ZZZAP
playsound(src, 'sound/machines/bsa_fire.ogg', 100, 1)
message_admins("[key_name_admin(user)] has launched an artillery strike.")
explosion(bullseye,ex_power,ex_power*2,ex_power*4)
reload()
/obj/machinery/bsa/full/proc/reload()
use_power(power_used_per_shot)
last_fire_time = world.time / 10
/obj/item/weapon/circuitboard/machine/bsa/back
name = "Bluespace Artillery Generator (Machine Board)"
build_path = /obj/machinery/bsa/back
origin_tech = "engineering=2;combat=2;bluespace=2" //No freebies!
req_components = list(
/obj/item/weapon/stock_parts/capacitor/quadratic = 5,
/obj/item/stack/cable_coil = 2)
/obj/item/weapon/circuitboard/machine/bsa/middle
name = "Bluespace Artillery Fusor (Machine Board)"
build_path = /obj/machinery/bsa/middle
origin_tech = "engineering=2;combat=2;bluespace=2"
req_components = list(
/obj/item/weapon/ore/bluespace_crystal = 20,
/obj/item/stack/cable_coil = 2)
/obj/item/weapon/circuitboard/machine/bsa/front
name = "Bluespace Artillery Bore (Machine Board)"
build_path = /obj/machinery/bsa/front
origin_tech = "engineering=2;combat=2;bluespace=2"
req_components = list(
/obj/item/weapon/stock_parts/manipulator/femto = 5,
/obj/item/stack/cable_coil = 2)
/obj/item/weapon/circuitboard/computer/bsa_control
name = "Bluespace Artillery Controls (Computer Board)"
build_path = /obj/machinery/computer/bsa_control
origin_tech = "engineering=2;combat=2;bluespace=2"
/obj/machinery/computer/bsa_control
name = "Bluespace Artillery Control"
var/obj/machinery/bsa/full/cannon
var/notice
var/target
use_power = 0
circuit = /obj/item/weapon/circuitboard/computer/bsa_control
icon = 'icons/obj/machines/particle_accelerator3.dmi'
icon_state = "control_boxp"
var/icon_state_broken = "control_box"
var/icon_state_nopower = "control_boxw"
var/icon_state_reloading = "control_boxp1"
var/icon_state_active = "control_boxp0"
layer = 3.1 // Just above the cannon sprite
var/area_aim = FALSE //should also show areas for targeting
var/target_all_areas = FALSE //allows all areas (including admin areas) to be targeted
/obj/machinery/computer/bsa_control/admin
area_aim = TRUE
target_all_areas = TRUE
/obj/machinery/computer/bsa_control/admin/initialize()
..()
if(!cannon)
cannon = deploy()
/obj/machinery/computer/bsa_control/Destroy()
if(cannon && cannon.controller == src)
cannon.controller = null
cannon = null
return ..()
/obj/machinery/computer/bsa_control/process()
..()
update_icon()
/obj/machinery/computer/bsa_control/update_icon()
if(stat & BROKEN)
icon_state = icon_state_broken
else if(stat & NOPOWER)
icon_state = icon_state_nopower
else if(cannon && (cannon.last_fire_time + cannon.reload_cooldown) > (world.time / 10))
icon_state = icon_state_reloading
else if(cannon)
icon_state = icon_state_active
else
icon_state = initial(icon_state)
/obj/machinery/computer/bsa_control/attack_hand(mob/user)
if(..())
return 1
ui_interact(user)
/obj/machinery/computer/bsa_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "bsa.tmpl", name, 400, 305)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/bsa_control/ui_data(mob/user, ui_key = "main", datum/topic_state/state = physical_state)
var/list/data = list()
data["connected"] = cannon
data["notice"] = notice
if(target)
data["target"] = get_target_name()
if(cannon)
var/reload_cooldown = cannon.reload_cooldown
var/last_fire_time = cannon.last_fire_time
var/time_to_wait = max(0, round(reload_cooldown - ((world.time / 10) - last_fire_time)))
var/minutes = max(0, round(time_to_wait / 60))
var/seconds = max(0, time_to_wait - (60 * minutes))
data["reloadtime_mins"] = minutes
data["reloadtime_secs"] = (seconds < 10) ? "0[seconds]" : seconds
data["ready"] = minutes == 0 && seconds == 0
else
data["ready"] = FALSE
return data
/obj/machinery/computer/bsa_control/Topic(href, href_list)
if(..())
return 1
if(href_list["build"])
cannon = deploy()
. = TRUE
else if(href_list["fire"])
fire(usr)
. = TRUE
else if(href_list["recalibrate"])
calibrate(usr)
. = TRUE
update_icon()
/obj/machinery/computer/bsa_control/proc/calibrate(mob/user)
var/list/gps_locators = list()
for(var/obj/item/device/gps/G in GPS_list) //nulls on the list somehow
gps_locators[G.gpstag] = G
var/list/options = gps_locators
if(area_aim)
options += target_all_areas ? ghostteleportlocs : teleportlocs
var/V = input(user,"Select target", "Select target",null) in options|null
target = options[V]
/obj/machinery/computer/bsa_control/proc/get_target_name()
if(istype(target,/area))
var/area/A = target
return A.name
else if(istype(target,/obj/item/device/gps))
var/obj/item/device/gps/G = target
return G.gpstag
/obj/machinery/computer/bsa_control/proc/get_impact_turf()
if(istype(target,/area))
return pick(get_area_turfs(target))
else if(istype(target,/obj/item/device/gps))
return get_turf(target)
/obj/machinery/computer/bsa_control/proc/fire(mob/user)
if(!cannon || !target)
return
if(cannon.stat)
notice = "Cannon unpowered!"
return
notice = null
cannon.fire(user, get_impact_turf())
/obj/machinery/computer/bsa_control/proc/deploy()
var/obj/machinery/bsa/full/prebuilt = locate() in range(7, src) //In case of adminspawn
if(prebuilt)
prebuilt.controller = src
return prebuilt
var/obj/machinery/bsa/middle/centerpiece = locate() in range(7, src)
if(!centerpiece)
notice = "No BSA parts detected nearby."
return null
notice = centerpiece.check_completion()
if(notice)
return null
//Totally nanite construction system not an immersion breaking spawning
var/datum/effect/system/harmless_smoke_spread/s = new /datum/effect/system/harmless_smoke_spread()
s.set_up(4, 0, get_turf(centerpiece))
s.start()
var/obj/machinery/bsa/full/cannon = new(get_turf(centerpiece),centerpiece.get_cannon_direction())
cannon.controller = src
qdel(centerpiece.front)
qdel(centerpiece.back)
qdel(centerpiece)
return cannon
+301
View File
@@ -0,0 +1,301 @@
//Crew has to create dna vault
// Cargo can order DNA samplers + DNA vault boards
// DNA vault requires x animals ,y plants, z human dna
// DNA vaults require high tier stock parts and cold
// After completion each crewmember can receive single upgrade chosen out of 2 for the mob.
#define VAULT_SPACEIMMUNE "Space Immunity"
#define VAULT_XRAY "X-Ray Vision"
#define VAULT_TELEKINESIS "Telekinesis"
#define VAULT_PSYCHIC "Psychic Powers"
#define VAULT_SPEED "Speediness"
/datum/station_goal/dna_vault
name = "DNA Vault"
var/animal_count
var/human_count
var/plant_count
/datum/station_goal/dna_vault/New()
..()
animal_count = rand(15,20) //might be too few given ~15 roundstart stationside ones
human_count = rand(round(0.75 * ticker.mode.num_players_started()), ticker.mode.num_players_started()) // 75%+ roundstart population.
var/non_standard_plants = non_standard_plants_count()
plant_count = rand(round(0.5 * non_standard_plants),round(0.7 * non_standard_plants))
/datum/station_goal/dna_vault/proc/non_standard_plants_count()
. = 0
for(var/T in subtypesof(/obj/item/seeds)) //put a cache if it's used anywhere else
var/obj/item/seeds/S = T
if(initial(S.rarity) > 0)
.++
/datum/station_goal/dna_vault/get_report()
return {"<b>DNA Vault construction</b><br>
Our long term prediction systems say there's 99% chance of system-wide cataclysm in near future. As such, we need you to construct a DNA Vault aboard your station.
<br><br>
The DNA Vault needs to contain samples of:
<ul style='margin-top: 10px; margin-bottom: 10px;'>
<li>[animal_count] unique animal data.</li>
<li>[plant_count] unique non-standard plant data.</li>
<li>[human_count] unique sapient humanoid DNA data.</li>
</ul>
The base vault parts should be available for shipping by your cargo shuttle."}
/datum/station_goal/dna_vault/on_report()
var/datum/supply_packs/P = shuttle_master.supply_packs["[/datum/supply_packs/misc/dna_vault]"]
P.special_enabled = TRUE
P = shuttle_master.supply_packs["[/datum/supply_packs/misc/dna_probes]"]
P.special_enabled = TRUE
/datum/station_goal/dna_vault/check_completion()
if(..())
return TRUE
for(var/obj/machinery/dna_vault/V in machines)
if(V.animals.len >= animal_count && V.plants.len >= plant_count && V.dna.len >= human_count && is_station_contact(V.z))
return TRUE
return FALSE
/obj/item/device/dna_probe
name = "DNA Sampler"
desc = "Can be used to take chemical and genetic samples of pretty much anything."
icon = 'icons/obj/hypo.dmi'
item_state = "hypo"
icon_state = "hypo"
flags = NOBLUDGEON
var/list/animals = list()
var/list/plants = list()
var/list/dna = list()
/obj/item/device/dna_probe/proc/clear_data()
animals = list()
plants = list()
dna = list()
var/list/non_simple_animals = typecacheof(list(/mob/living/carbon/human/monkey,/mob/living/carbon/alien))
/obj/item/device/dna_probe/afterattack(atom/target, mob/user, proximity)
..()
if(!proximity || !target)
return
//tray plants
if(istype(target,/obj/machinery/hydroponics))
var/obj/machinery/hydroponics/H = target
if(!H.myseed)
return
if(!H.harvest)// So it's bit harder.
to_chat(user, "<span clas='warning'>Plants needs to be ready to harvest to perform full data scan.</span>") //Because space dna is actually magic
return
if(plants[H.myseed.type])
to_chat(user, "<span class='notice'>Plant data already present in local storage.<span>")
return
plants[H.myseed.type] = 1
to_chat(user, "<span class='notice'>Plant data added to local storage.<span>")
//animals
if(isanimal(target) || is_type_in_typecache(target, non_simple_animals))
if(isanimal(target))
var/mob/living/simple_animal/A = target
if(!A.healable)//simple approximation of being animal not a robot or similar
to_chat(user, "<span class='warning'>No compatible DNA detected</span>")
return
if(animals[target.type])
to_chat(user, "<span class='notice'>Animal data already present in local storage.<span>")
return
animals[target.type] = 1
to_chat(user, "<span class='notice'>Animal data added to local storage.<span>")
//humans
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(dna[H.dna.uni_identity])
to_chat(user, "<span class='notice'>Humanoid data already present in local storage.<span>")
return
dna[H.dna.uni_identity] = 1
to_chat(user, "<span class='notice'>Humanoid data added to local storage.<span>")
/obj/item/weapon/circuitboard/machine/dna_vault
name = "DNA Vault (Machine Board)"
build_path = /obj/machinery/dna_vault
origin_tech = "engineering=2;combat=2;bluespace=2" //No freebies!
req_components = list(
/obj/item/weapon/stock_parts/capacitor/quadratic = 5,
/obj/item/stack/cable_coil = 2)
/obj/structure/filler
name = "big machinery part"
density = 1
anchored = 1
invisibility = 101
var/obj/machinery/parent
/obj/structure/filler/ex_act()
return
/obj/machinery/dna_vault
name = "DNA Vault"
desc = "Break glass in case of apocalypse."
icon = 'icons/obj/machines/dna_vault.dmi'
icon_state = "vault"
density = 1
anchored = 1
idle_power_usage = 5000
pixel_x = -32
pixel_y = -64
luminosity = 1
//High defaults so it's not completed automatically if there's no station goal
var/animals_max = 100
var/plants_max = 100
var/dna_max = 100
var/list/animals = list()
var/list/plants = list()
var/list/dna = list()
var/completed = FALSE
var/list/power_lottery = list()
var/list/obj/structure/fillers = list()
/obj/machinery/dna_vault/New()
//TODO: Replace this,bsa and gravgen with some big machinery datum
var/list/occupied = list()
for(var/direct in list(EAST,WEST,SOUTHEAST,SOUTHWEST))
occupied += get_step(src,direct)
occupied += locate(x+1,y-2,z)
occupied += locate(x-1,y-2,z)
for(var/T in occupied)
var/obj/structure/filler/F = new(T)
F.parent = src
fillers += F
if(ticker.mode)
for(var/datum/station_goal/dna_vault/G in ticker.mode.station_goals)
animals_max = G.animal_count
plants_max = G.plant_count
dna_max = G.human_count
break
/obj/machinery/dna_vault/Destroy()
for(var/V in fillers)
var/obj/structure/filler/filler = V
filler.parent = null
qdel(filler)
. = ..()
/obj/machinery/dna_vault/attack_ghost(mob/user)
if(stat & (BROKEN|MAINT))
return
return ui_interact(user)
/obj/machinery/dna_vault/attack_hand(mob/user)
if(..())
return 1
ui_interact(user)
/obj/machinery/dna_vault/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
roll_powers(user)
ui = new(user, src, ui_key, "dna_vault.tmpl", name, 550, 400)
ui.open()
/obj/machinery/dna_vault/proc/roll_powers(mob/user)
if(user in power_lottery)
return
var/list/L = list()
var/list/possible_powers = list(VAULT_SPACEIMMUNE,VAULT_XRAY,VAULT_TELEKINESIS,VAULT_PSYCHIC,VAULT_SPEED)
L += pick_n_take(possible_powers)
L += pick_n_take(possible_powers)
power_lottery[user] = L
/obj/machinery/dna_vault/ui_data(mob/user, ui_key = "main", datum/topic_state/state = physical_state) //TODO Make it % bars maybe
var/list/data = list()
data["plants"] = plants.len
data["plants_max"] = plants_max
data["animals"] = animals.len
data["animals_max"] = animals_max
data["dna"] = dna.len
data["dna_max"] = dna_max
data["completed"] = completed
data["used"] = TRUE
data["choiceA"] = ""
data["choiceB"] = ""
if(user && completed)
var/list/L = power_lottery[user]
if(L && L.len)
data["used"] = FALSE
data["choiceA"] = L[1]
data["choiceB"] = L[2]
return data
/obj/machinery/dna_vault/Topic(href, href_list)
if(..())
return 1
if(href_list["gene"])
upgrade(usr,href_list["choice"])
. = TRUE
/obj/machinery/dna_vault/proc/check_goal()
if(plants.len >= plants_max && animals.len >= animals_max && dna.len >= dna_max)
completed = TRUE
/obj/machinery/dna_vault/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/device/dna_probe))
var/obj/item/device/dna_probe/P = I
var/uploaded = 0
for(var/plant in P.plants)
if(!plants[plant])
uploaded++
plants[plant] = 1
for(var/animal in P.animals)
if(!animals[animal])
uploaded++
animals[animal] = 1
for(var/ui in P.dna)
if(!dna[ui])
uploaded++
dna[ui] = 1
check_goal()
to_chat(user, "<span class='notice'>[uploaded] new datapoints uploaded.</span>")
else
return ..()
/obj/machinery/dna_vault/proc/upgrade(mob/living/carbon/human/H, upgrade_type)
if(!(upgrade_type in power_lottery[H]))
return
if(!completed)
return
if(!H.ignore_gene_stability)
to_chat(H, "<span class='notice'>[src] stabilizes your genes, granting you the ability to have multiple powers.</span>")
H.ignore_gene_stability = 1
switch(upgrade_type)
if(VAULT_SPACEIMMUNE)
to_chat(H, "<span class='notice'>You suddenly don't feel the need to breathe anymore. You also don't feel any cold anymore.</span>")
grant_power(H, NOBREATHBLOCK, NO_BREATH)
grant_power(H, FIREBLOCK, RESIST_COLD)
if(VAULT_XRAY)
to_chat(H, "<span class='notice'>You can suddenly see through walls.</span>")
grant_power(H, XRAYBLOCK, XRAY)
if(VAULT_TELEKINESIS)
to_chat(H, "<span class='notice'>You gain the ability to control objects from a distance.</span>")
grant_power(H, TELEBLOCK, TK)
if(VAULT_PSYCHIC)
to_chat(H, "<span class='notice'>Your mind expands, giving you psychic powers.</span>")
grant_power(H, REMOTETALKBLOCK, REMOTE_TALK)
grant_power(H, REMOTEVIEWBLOCK, REMOTE_VIEW)
grant_power(H, EMPATHBLOCK, EMPATH)
grant_power(H, PSYRESISTBLOCK, PSY_RESIST)
if(VAULT_SPEED)
to_chat(H, "<span class='notice'>You feel very fast and agile.</span>")
grant_power(H, JUMPBLOCK, JUMPY)
grant_power(H, INCREASERUNBLOCK, RUN)
power_lottery[H] = list()
/obj/machinery/dna_vault/proc/grant_power(mob/living/carbon/human/H, block, power)
H.dna.SetSEState(block, 1, 1)
H.mutations |= power
genemutcheck(H, block, null, MUTCHK_FORCED)
+193
View File
@@ -0,0 +1,193 @@
//Station Shield
// A chain of satellites encircles the station
// Satellites be actived to generate a shield that will block unorganic matter from passing it.
/datum/station_goal/station_shield
name = "Station Shield"
var/coverage_goal = 500
/datum/station_goal/station_shield/get_report()
return {"<b>Station Shield construction</b><br>
The station is located in a zone full of space debris. We have a prototype shielding system you will deploy to reduce collision related accidents.
<br><br>
You can order the satellites and control systems through cargo shuttle."}
/datum/station_goal/station_shield/on_report()
//Unlock
var/datum/supply_packs/P = shuttle_master.supply_packs["[/datum/supply_packs/misc/shield_sat]"]
P.special_enabled = TRUE
P = shuttle_master.supply_packs["[/datum/supply_packs/misc/shield_sat_control]"]
P.special_enabled = TRUE
/datum/station_goal/station_shield/check_completion()
if(..())
return TRUE
if(get_coverage() >= coverage_goal)
return TRUE
return FALSE
/datum/station_goal/proc/get_coverage()
var/list/coverage = list()
for(var/obj/machinery/satellite/meteor_shield/A in machines)
if(!A.active || !is_station_level(A.z))
continue
coverage |= view(A.kill_range, A)
return coverage.len
/obj/item/weapon/circuitboard/computer/sat_control
name = "Satellite Network Control (Computer Board)"
build_path = /obj/machinery/computer/sat_control
origin_tech = "engineering=3"
/obj/machinery/computer/sat_control
name = "Satellite control"
desc = "Used to control the satellite network."
circuit = /obj/item/weapon/circuitboard/computer/sat_control
icon_screen = "accelerator"
icon_keyboard = "accelerator_key"
var/notice
/obj/machinery/computer/sat_control/attack_hand(mob/user)
if(..())
return 1
ui_interact(user)
/obj/machinery/computer/sat_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "sat_control.tmpl", name, 475, 400)
ui.open()
/obj/machinery/computer/sat_control/Topic(href, href_list)
if(..())
return 1
if(href_list["toggle"])
toggle(text2num(href_list["id"]))
. = TRUE
/obj/machinery/computer/sat_control/proc/toggle(id)
for(var/obj/machinery/satellite/S in machines)
if(S.id == id && atoms_share_level(src, S))
S.toggle()
/obj/machinery/computer/sat_control/ui_data(mob/user, ui_key = "main", datum/topic_state/state = physical_state)
var/list/data = list()
data["satellites"] = list()
for(var/obj/machinery/satellite/S in machines)
data["satellites"] += list(list(
"id" = S.id,
"active" = S.active,
"mode" = S.mode
))
data["notice"] = notice
var/datum/station_goal/station_shield/G = locate() in ticker.mode.station_goals
if(G)
data["meteor_shield"] = 1
data["meteor_shield_coverage"] = G.get_coverage()
data["meteor_shield_coverage_max"] = G.coverage_goal
data["meteor_shield_coverage_percentage"] = (G.get_coverage() / G.coverage_goal) * 100
return data
/obj/machinery/satellite
name = "Defunct Satellite"
desc = ""
icon = 'icons/obj/machines/satellite.dmi'
icon_state = "sat_inactive"
var/mode = "NTPROBEV0.8"
var/active = FALSE
density = 1
use_power = FALSE
var/static/gid = 0
var/id = 0
/obj/machinery/satellite/New()
..()
id = gid++
/obj/machinery/satellite/attack_hand(mob/user)
if(..())
return 1
interact(user)
/obj/machinery/satellite/interact(mob/user)
toggle(user)
/obj/machinery/satellite/proc/toggle(mob/user)
if(!active && !isinspace())
if(user)
to_chat(user, "<span class='warning'>You can only active the [src] in space.</span>")
return TRUE
if(user)
to_chat(user, "<span class='notice'>You [active ? "deactivate": "activate"] the [src]</span>")
active = !active
if(active)
animate(src, pixel_y = 2, time = 10, loop = -1)
anchored = 1
else
animate(src, pixel_y = 0, time = 10)
anchored = 0
update_icon()
/obj/machinery/satellite/update_icon()
icon_state = active ? "sat_active" : "sat_inactive"
/obj/machinery/satellite/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/device/multitool))
to_chat(user, "<span class='notice'>// NTSAT-[id] // Mode : [active ? "PRIMARY" : "STANDBY"] //[emagged ? "DEBUG_MODE //" : ""]</span>")
else
return ..()
/obj/machinery/satellite/meteor_shield
name = "Meteor Shield Satellite"
desc = "Meteor Point Defense Satellite"
mode = "M-SHIELD"
speed_process = TRUE
var/kill_range = 14
/obj/machinery/satellite/meteor_shield/proc/space_los(meteor)
for(var/turf/T in getline(src,meteor))
if(!isspaceturf(T))
return FALSE
return TRUE
/obj/machinery/satellite/meteor_shield/process()
if(!active)
return
for(var/obj/effect/meteor/M in meteor_list)
if(M.z != z)
continue
if(get_dist(M, src) > kill_range)
continue
if(!emagged && space_los(M))
Beam(get_turf(M), icon_state = "sat_beam", time = 5, maxdistance = kill_range)
qdel(M)
/obj/machinery/satellite/meteor_shield/toggle(user)
if(..(user))
return TRUE
if(emagged)
if(active)
change_meteor_chance(2)
else
change_meteor_chance(0.5)
/obj/machinery/satellite/meteor_shield/proc/change_meteor_chance(mod)
for(var/datum/event_container/container in event_manager.event_containers)
for(var/datum/event_meta/M in container.available_events)
if(M.event_type == /datum/event/meteor_wave)
M.weight *= mod
/obj/machinery/satellite/meteor_shield/Destroy()
. = ..()
if(active && emagged)
change_meteor_chance(0.5)
/obj/machinery/satellite/meteor_shield/emag_act(mob/user)
if(!emagged)
to_chat(user, "<span class='danger'>You override the shield's circuits, causing it to attract meteors instead of destroying them.</span>")
emagged = 1
if(active)
change_meteor_chance(2)
@@ -0,0 +1,49 @@
//TODO
// Admin button to override with your own
// Sabotage objective for tators
// Multiple goals with less impact but more department focused
/datum/station_goal
var/name = "Generic Goal"
var/weight = 1 //In case of multiple goals later.
var/required_crew = 10
var/list/gamemode_blacklist = list()
var/completed = FALSE
var/report_message = "Complete this goal."
/datum/station_goal/proc/send_report()
priority_announcement.Announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", 'sound/AI/commandreport.ogg')
print_command_report(get_report(), "Nanotrasen Directive [pick(phonetic_alphabet)] \Roman[rand(1,50)]")
on_report()
/datum/station_goal/proc/on_report()
//Additional unlocks/changes go here
return
/datum/station_goal/proc/get_report()
return report_message
/datum/station_goal/proc/check_completion()
return completed
/datum/station_goal/proc/print_result()
if(check_completion())
to_chat(world, "<b>Station Goal</b> : [name] : <span class='greenannounce'>Completed!</span>")
else
to_chat(world, "<b>Station Goal</b> : [name] : <span class='boldannounce'>Failed!</span>")
/datum/station_goal/Destroy()
ticker.mode.station_goals -= src
. = ..()
/datum/station_goal/Topic(href, href_list)
..()
if(!check_rights(R_EVENT))
return
if(href_list["announce"])
on_report()
send_report()
else if(href_list["remove"])
qdel(src)