Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Siliconwithoutthebullshit #12874

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
"./tgui-next"
],

"workbench.editorAssociations": [
{
"filenamePattern": "*.dmi",
"viewType": "imagePreview.previewEditor"
}
]
"workbench.editorAssociations": {
"*.dmi": "imagePreview.previewEditor"
}
}
3 changes: 3 additions & 0 deletions code/__DEFINES/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,6 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.

/// Cancels the attack chain entirely.
#define SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN 2
2 changes: 2 additions & 0 deletions code/__DEFINES/machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,5 @@
//cloning defines. These are flags.
#define CLONING_SUCCESS (1<<0)
#define CLONING_DELETE_RECORD (1<<1)
//Program categories
#define PROGRAM_CATEGORY_ROBO "Robotics"
12 changes: 12 additions & 0 deletions code/modules/mob/living/silicon/robot/robot.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1200,3 +1200,15 @@
cell.charge = min(cell.charge + amount, cell.maxcharge)
if(repairs)
heal_bodypart_damage(repairs, repairs - 1)
/mob/living/silicon/robot/proc/logevent(string = "")
if(!string)
return
if(stat == DEAD) //Dead borgs log no longer
return
if(!modularInterface)
stack_trace("Cyborg [src] ( [type] ) was somehow missing their integrated tablet. Please make a bug report.")
create_modularInterface()
modularInterface.borglog += "[station_time_timestamp()] - [string]"
var/datum/computer_file/program/robotact/program = modularInterface.get_robotact()
if(program)
program.force_full_update()
2 changes: 2 additions & 0 deletions code/modules/mob/living/silicon/robot/robot_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@
sleep(5)
to_chat(src, "<span class='danger'>LAW SYNCHRONISATION ERROR</span>")
sleep(5)
if(user)
logevent("LOG: New user \[[replacetext(user.real_name," ","")]\], groups \[root\]")
to_chat(src, "<span class='danger'>Would you like to send a report to NanoTraSoft? Y/N</span>")
sleep(10)
to_chat(src, "<span class='danger'>> N</span>")
Expand Down
17 changes: 17 additions & 0 deletions code/modules/modular_computers/computers/item/computer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@
physical = null
return ..()

/obj/item/modular_computer/pre_attack_secondary(atom/A, mob/living/user, params)
if(active_program?.tap(A, user, params))
user.do_attack_animation(A) //Emulate this animation since we kill the attack in three lines
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), TRUE, -1) //Likewise for the tap sound
addtimer(CALLBACK(src, .proc/play_ping), 0.5 SECONDS, TIMER_UNIQUE) //Slightly delayed ping to indicate success
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
return ..()


/**
* Plays a ping sound.
*
* Timers runtime if you try to make them call playsound. Yep.
*/
/obj/item/modular_computer/proc/play_ping()
playsound(loc, 'sound/machines/ping.ogg', get_clamped_volume(), FALSE, -1)


/obj/item/modular_computer/proc/add_verb(var/path)
switch(path)
Expand Down
32 changes: 32 additions & 0 deletions code/modules/modular_computers/file_system/program.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
var/ui_x = 575 // Default size of TGUI window, in pixels
var/ui_y = 700
var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /icons/program_icons. Be careful not to use too large images!
var/program_icon = "window-maximize-o" // Font Awesome icon to use as this program's icon in the modular computer main menu. Defaults to a basic program maximize window icon if not overridden.



/datum/computer_file/program/New(obj/item/modular_computer/comp = null)
..()
Expand Down Expand Up @@ -52,6 +55,21 @@
return computer.add_log(text)
return 0

/**
*Runs when the device is used to attack an atom in non-combat mode.
*
*Simulates using the device to read or scan something. Tap is called by the computer during pre_attack
*and sends us all of the related info. If we return TRUE, the computer will stop the attack process
*there. What we do with the info is up to us, but we should only return TRUE if we actually perform
*an action of some sort.
*Arguments:
*A is the atom being tapped
*user is the person making the attack action
*params is anything the pre_attack() proc had in the same-named variable.
*/
/datum/computer_file/program/proc/tap(atom/A, mob/living/user, params)
return FALSE

/datum/computer_file/program/proc/is_supported_by_hardware(hardware_flag = 0, loud = 0, mob/user = null)
if(!(hardware_flag & usage_flags))
if(loud && computer && user)
Expand Down Expand Up @@ -196,3 +214,17 @@
if(program_state != PROGRAM_STATE_ACTIVE) // Our program was closed. Close the ui if it exists.
return UI_CLOSE
return ..()

/**
*
*Called by the device when it is emagged.
*
*Emagging the device allows certain programs to unlock new functions. However, the program will
*need to be downloaded first, and then handle the unlock on their own in their run_emag() proc.
*The device will allow an emag to be run multiple times, so the user can re-emag to run the
*override again, should they download something new. The run_emag() proc should return TRUE if
*the emagging affected anything, and FALSE if no change was made (already emagged, or has no
*emag functions).
**/
/datum/computer_file/program/proc/run_emag()
return FALSE
186 changes: 186 additions & 0 deletions code/modules/modular_computers/file_system/programs/borg_monitor.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/datum/computer_file/program/borg_monitor
filename = "siliconnect"
filedesc = "SiliConnect"
category = PROGRAM_CATEGORY_ROBO
ui_header = "borg_mon.gif"
program_icon_state = "generic"
extended_desc = "This program allows for remote monitoring of station cyborgs."
requires_ntnet = TRUE
transfer_access = ACCESS_ROBOTICS
size = 5
tgui_id = "NtosCyborgRemoteMonitor"
program_icon = "project-diagram"
var/emagged = FALSE ///Bool of if this app has already been emagged
var/list/loglist = list() ///A list to copy a borg's IC log list into
var/mob/living/silicon/robot/DL_source ///reference of a borg if we're downloading a log, or null if not.
var/DL_progress = -1 ///Progress of current download, 0 to 100, -1 for no current download

/datum/computer_file/program/borg_monitor/Destroy()
loglist = null
DL_source = null
return ..()

/datum/computer_file/program/borg_monitor/kill_program(forced = FALSE)
loglist = null //Not everything is saved if you close an app
DL_source = null
DL_progress = 0
return ..()

/datum/computer_file/program/borg_monitor/run_emag()
if(emagged)
return FALSE
emagged = TRUE
return TRUE

/datum/computer_file/program/borg_monitor/tap(atom/A, mob/living/user, params)
var/mob/living/silicon/robot/borgo = A
if(!istype(borgo) || !borgo.modularInterface)
return FALSE
DL_source = borgo
DL_progress = 0

var/username = "unknown user"
var/obj/item/card/id/stored_card = computer.GetID()
if(istype(stored_card) && stored_card.registered_name)
username = "user [stored_card.registered_name]"
to_chat(borgo, "<span class='userdanger'>Request received from [username] for the system log file. Upload in progress.</span>")//Damning evidence may be contained, so warn the borg
borgo.logevent("File request by [username]: /var/logs/syslog")
return TRUE

/datum/computer_file/program/borg_monitor/process_tick()
if(!DL_source)
DL_progress = -1
return

var/turf/here = get_turf(computer)
var/turf/there = get_turf(DL_source)
if(!here.Adjacent(there))//If someone walked away, cancel the download
to_chat(DL_source, "<span class='danger'>Log upload failed: general connection error.</span>")//Let the borg know the upload stopped
DL_source = null
DL_progress = -1
return

if(DL_progress == 100)
if(!DL_source || !DL_source.modularInterface) //sanity check, in case the borg or their modular tablet poofs somehow
loglist = list("System log of unit [DL_source.name]")
loglist += "Error -- Download corrupted."
else
loglist = DL_source.modularInterface.borglog.Copy()
loglist.Insert(1,"System log of unit [DL_source.name]")
DL_progress = -1
DL_source = null
for(var/datum/tgui/window in SStgui.open_uis_by_src[REF(src)])
window.send_full_update()
return

DL_progress += 25

/datum/computer_file/program/borg_monitor/ui_data(mob/user)
var/list/data = get_header_data()

data["card"] = FALSE
if(checkID())
data["card"] = TRUE

data["cyborgs"] = list()
for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
if(!evaluate_borg(R))
continue

var/list/upgrade
for(var/obj/item/borg/upgrade/I in R.upgrades)
upgrade += "\[[I.name]\] "

var/shell = FALSE
if(R.shell && !R.ckey)
shell = TRUE

var/list/cyborg_data = list(
name = R.name,
integ = round((R.health + 100) / 2), //mob heath is -100 to 100, we want to scale that to 0 - 100
locked_down = R.lockcharge,
status = R.stat,
shell_discon = shell,
charge = R.cell ? round(R.cell.percent()) : null,
module = R.model ? "[R.model.name] Model" : "No Model Detected",
upgrades = upgrade,
ref = REF(R)
)
data["cyborgs"] += list(cyborg_data)
data["DL_progress"] = DL_progress
return data

/datum/computer_file/program/borg_monitor/ui_static_data(mob/user)
var/list/data = list()
data["borglog"] = loglist
return data

/datum/computer_file/program/borg_monitor/ui_act(action, params)
. = ..()
if(.)
return

switch(action)
if("messagebot")
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
if(!istype(R))
return
var/ID = checkID()
if(!ID)
return
if(R.stat == DEAD) //Dead borgs will listen to you no longer
to_chat(usr, "<span class='warn'>Error -- Could not open a connection to unit:[R]</span>")
var/message = stripped_input(usr, message = "Enter message to be sent to remote cyborg.", title = "Send Message")
if(!message)
return
to_chat(R, "<br><br><span class='notice'>Message from [ID] -- \"[message]\"</span><br>")
to_chat(usr, "Message sent to [R]: [message]")
R.logevent("Message from [ID] -- \"[message]\"")
SEND_SOUND(R, 'sound/machines/twobeep_high.ogg')
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='notice'>Message from [ID] to [R] -- \"[message]\"</span><br>")
SEND_SOUND(R.connected_ai, 'sound/machines/twobeep_high.ogg')
usr.log_talk(message, LOG_PDA, tag="Cyborg Monitor Program: ID name \"[ID]\" to [R]")

///This proc is used to determin if a borg should be shown in the list (based on the borg's scrambledcodes var). Syndicate version overrides this to show only syndicate borgs.
/datum/computer_file/program/borg_monitor/proc/evaluate_borg(mob/living/silicon/robot/R)
if((get_turf(computer)).z != (get_turf(R)).z)
return FALSE
if(R.scrambledcodes)
return FALSE
return TRUE

///Gets the ID's name, if one is inserted into the device. This is a seperate proc solely to be overridden by the syndicate version of the app.
/datum/computer_file/program/borg_monitor/proc/checkID()
var/obj/item/card/id/ID = computer.GetID()
if(!ID)
if(emagged)
return "STDERR:UNDF"
return FALSE
return ID.registered_name

/datum/computer_file/program/borg_monitor/syndicate
filename = "roboverlord"
filedesc = "Roboverlord"
category = PROGRAM_CATEGORY_ROBO
ui_header = "borg_mon.gif"
program_icon_state = "generic"
extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs."
requires_ntnet = FALSE
available_on_ntnet = FALSE
available_on_syndinet = TRUE
transfer_access = null
tgui_id = "NtosCyborgRemoteMonitorSyndicate"

/datum/computer_file/program/borg_monitor/syndicate/run_emag()
return FALSE

/datum/computer_file/program/borg_monitor/syndicate/evaluate_borg(mob/living/silicon/robot/R)
if((get_turf(computer)).z != (get_turf(R)).z)
return FALSE
if(!R.scrambledcodes)
return FALSE
return TRUE

/datum/computer_file/program/borg_monitor/syndicate/checkID()
return "\[CLASSIFIED\]" //no ID is needed for the syndicate version's message function, and the borg will see "[CLASSIFIED]" as the message sender.
1 change: 1 addition & 0 deletions hippiestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -2353,6 +2353,7 @@
#include "code\modules\modular_computers\hardware\network_card.dm"
#include "code\modules\modular_computers\hardware\portable_disk.dm"
#include "code\modules\modular_computers\hardware\printer.dm"
#include "code\modules\modular_computers\file_system\programs\borg_monitor.dm"
#include "code\modules\modular_computers\hardware\recharger.dm"
#include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm"
#include "code\modules\ninja\__ninjaDefines.dm"
Expand Down
Loading