mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-21 19:17:50 +01:00
Merge pull request #6240 from Markolie/stationgoals
Ports Station Goals from /tg/
This commit is contained in:
@@ -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
|
||||
@@ -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")
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
@@ -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,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()
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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))))
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user