diff --git a/code/game/objects/items/devices/holowarrant.dm b/code/game/objects/items/devices/holowarrant.dm
new file mode 100644
index 0000000000..e2fdd4269e
--- /dev/null
+++ b/code/game/objects/items/devices/holowarrant.dm
@@ -0,0 +1,110 @@
+/obj/item/device/holowarrant
+ name = "warrant projector"
+ desc = "The practical paperwork replacement for the officer on the go."
+ icon_state = "holowarrant"
+ item_state = "flashtool"
+ throwforce = 5
+ w_class = ITEMSIZE_SMALL
+ throw_speed = 4
+ throw_range = 10
+ var/datum/data/record/warrant/active
+
+//look at it
+/obj/item/device/holowarrant/examine(mob/user)
+ . = ..()
+ if(active)
+ to_chat(user, "It's a holographic warrant for '[active.fields["namewarrant"]]'.")
+ if(in_range(user, src) || isghost(user))
+ show_content(user)
+ else
+ to_chat(user, "You have to go closer if you want to read it.")
+
+//hit yourself with it
+/obj/item/device/holowarrant/attack_self(mob/living/user as mob)
+ active = null
+ var/list/warrants = list()
+ if(!isnull(data_core.general))
+ for(var/datum/data/record/warrant/W in data_core.warrants)
+ warrants += W.fields["namewarrant"]
+ if(warrants.len == 0)
+ to_chat(user,"There are no warrants available")
+ return
+ var/temp
+ temp = input(user, "Which warrant would you like to load?") as null|anything in warrants
+ for(var/datum/data/record/warrant/W in data_core.warrants)
+ if(W.fields["namewarrant"] == temp)
+ active = W
+ update_icon()
+
+/obj/item/device/holowarrant/attackby(obj/item/weapon/W, mob/user)
+ if(active)
+ var/obj/item/weapon/card/id/I = W.GetIdCard()
+ if(I)
+ var/choice = alert(user, "Would you like to authorize this warrant?","Warrant authorization","Yes","No")
+ if(choice == "Yes")
+ active.fields["auth"] = "[I.registered_name] - [I.assignment ? I.assignment : "(Unknown)"]"
+ user.visible_message("You swipe \the [I] through the [src].", \
+ "[user] swipes \the [I] through the [src].")
+ return 1
+ ..()
+
+//hit other people with it
+/obj/item/device/holowarrant/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ user.visible_message("You show the warrant to [M].", \
+ "[user] holds up a warrant projector and shows the contents to [M].")
+ M.examinate(src)
+
+/obj/item/device/holowarrant/update_icon()
+ if(active)
+ icon_state = "holowarrant_filled"
+ else
+ icon_state = "holowarrant"
+
+/obj/item/device/holowarrant/proc/show_content(mob/user, forceshow)
+ if(!active)
+ return
+ if(active.fields["arrestsearch"] == "arrest")
+ var/output = {"
+
[active.fields["namewarrant"]]
+ Sol Central Government Colonial Marshal Bureau
+ in the jurisdiction of the
+ [using_map.boss_name] in [using_map.system_name]
+
+ ARREST WARRANT
+
+ This document serves as authorization and notice for the arrest of _[active.fields["namewarrant"]]____ for the crime(s) of:[active.fields["charges"]]
+
+ Vessel or habitat: _[using_map.station_name]____
+ _[active.fields["auth"]]____
+ Person authorizing arrest
+
+ "}
+
+ show_browser(user, output, "window=Warrant for the arrest of [active.fields["namewarrant"]]")
+ if(active.fields["arrestsearch"] == "search")
+ var/output= {"
+ Search Warrant: [active.fields["namewarrant"]]
+ in the jurisdiction of the
+ [using_map.boss_name] in [using_map.system_name]
+
+ SEARCH WARRANT
+
+ The Security Officer(s) bearing this Warrant are hereby authorized by the Issuer
+ to conduct a one time lawful search of the Suspect's person/belongings/premises and/or Department
+ for any items and materials that could be connected to the suspected criminal act described below,
+ pending an investigation in progress. The Security Officer(s) are obligated to remove any and all
+ such items from the Suspects posession and/or Department and file it as evidence. The Suspect/Department
+ staff is expected to offer full co-operation. In the event of the Suspect/Department staff attempting
+ to resist/impede this search or flee, they must be taken into custody immediately!
+ All confiscated items must be filed and taken to Evidence!
+
+ Suspect's/location name: [active.fields["namewarrant"]]
+
+ For the following reasons: [active.fields["charges"]]
+
+ Warrant issued by: [active.fields ["auth"]]
+
+ Vessel or habitat: _[using_map.station_name]____
+
+ "}
+ show_browser(user, output, "window=Search warrant for [active.fields["namewarrant"]]")
\ No newline at end of file
diff --git a/code/modules/modular_computers/computers/subtypes/preset_console.dm b/code/modules/modular_computers/computers/subtypes/preset_console.dm
index 6bdb081202..d2f409b51e 100644
--- a/code/modules/modular_computers/computers/subtypes/preset_console.dm
+++ b/code/modules/modular_computers/computers/subtypes/preset_console.dm
@@ -121,12 +121,3 @@
..()
//hard_drive.store_file(new/datum/computer_file/program/merchant())
hard_drive.store_file(new/datum/computer_file/program/wordprocessor())
-
-// Library
-/obj/item/modular_computer/console/preset/library/install_default_programs()
- ..()
- hard_drive.store_file(new/datum/computer_file/program/nttransfer())
- hard_drive.store_file(new/datum/computer_file/program/newsbrowser())
- hard_drive.store_file(new/datum/computer_file/program/email_client())
- hard_drive.store_file(new/datum/computer_file/program/wordprocessor())
- hard_drive.store_file(new/datum/computer_file/program/library())
diff --git a/code/modules/modular_computers/file_system/programs/generic/library.dm b/code/modules/modular_computers/file_system/programs/generic/library.dm
deleted file mode 100644
index b686cda14e..0000000000
--- a/code/modules/modular_computers/file_system/programs/generic/library.dm
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
-In reply to this set of comments on lib_machines.dm:
-// TODO: Make this an actual /obj/machinery/computer that can be crafted from circuit boards and such
-// It is August 22nd, 2012... This TODO has already been here for months.. I wonder how long it'll last before someone does something about it.
-
-The answer was five and a half years -ZeroBits
-*/
-
-/datum/computer_file/program/library
- filename = "library"
- filedesc = "Library"
- extended_desc = "This program can be used to view e-books from an external archive."
- program_icon_state = "word"
- program_key_state = "atmos_key"
- program_menu_icon = "note"
- size = 6
- requires_ntnet = 1
- available_on_ntnet = 1
-
- nanomodule_path = /datum/nano_module/library
-
-/datum/nano_module/library
- name = "Library"
- var/error_message = ""
- var/current_book
- var/obj/machinery/libraryscanner/scanner
- var/sort_by = "id"
-
-/datum/nano_module/library/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
- var/list/data = host.initial_data()
-
- if(error_message)
- data["error"] = error_message
- else if(current_book)
- data["current_book"] = current_book
- else
- var/list/all_entries[0]
- establish_old_db_connection()
- if(!dbcon_old.IsConnected())
- error_message = "Unable to contact External Archive. Please contact your system administrator for assistance."
- else
- var/DBQuery/query = dbcon_old.NewQuery("SELECT id, author, title, category FROM library ORDER BY "+sanitizeSQL(sort_by))
- query.Execute()
-
- while(query.NextRow())
- all_entries.Add(list(list(
- "id" = query.item[1],
- "author" = query.item[2],
- "title" = query.item[3],
- "category" = query.item[4]
- )))
- data["book_list"] = all_entries
- data["scanner"] = istype(scanner)
-
- ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
- if (!ui)
- ui = new(user, src, ui_key, "library.tmpl", "Library Program", 575, 700, state = state)
- ui.auto_update_layout = 1
- ui.set_initial_data(data)
- ui.open()
-
-/datum/nano_module/library/Topic(href, href_list)
- if(..())
- return 1
- if(href_list["viewbook"])
- view_book(href_list["viewbook"])
- return 1
- if(href_list["viewid"])
- view_book(sanitizeSQL(input("Enter USBN:") as num|null))
- return 1
- if(href_list["closebook"])
- current_book = null
- return 1
- if(href_list["connectscanner"])
- if(!nano_host())
- return 1
- for(var/d in GLOB.cardinal)
- var/obj/machinery/libraryscanner/scn = locate(/obj/machinery/libraryscanner, get_step(nano_host(), d))
- if(scn && scn.anchored)
- scanner = scn
- return 1
- if(href_list["uploadbook"])
- if(!scanner || !scanner.anchored)
- scanner = null
- error_message = "Hardware Error: No scanner detected. Unable to access cache."
- return 1
- if(!scanner.cache)
- error_message = "Interface Error: Scanner cache does not contain any data. Please scan a book."
- return 1
-
- var/obj/item/weapon/book/B = scanner.cache
-
- if(B.unique)
- error_message = "Interface Error: Cached book is copy-protected."
- return 1
-
- //B.SetName(input(usr, "Enter Book Title", "Title", B.name) as text|null)
- B.author = input(usr, "Enter Author Name", "Author", B.author) as text|null
-
- if(!B.author)
- B.author = "Anonymous"
- else if(lowertext(B.author) == "edgar allen poe" || lowertext(B.author) == "edgar allan poe")
- error_message = "User Error: Upload something original."
- return 1
-
- if(!B.title)
- B.title = "Untitled"
-
- var/choice = input(usr, "Upload [B.name] by [B.author] to the External Archive?") in list("Yes", "No")
- if(choice == "Yes")
- establish_old_db_connection()
- if(!dbcon_old.IsConnected())
- error_message = "Network Error: Connection to the Archive has been severed."
- return 1
-
- var/upload_category = input(usr, "Upload to which category?") in list("Fiction", "Non-Fiction", "Reference", "Religion")
-
- var/sqltitle = sanitizeSQL(B.name)
- var/sqlauthor = sanitizeSQL(B.author)
- var/sqlcontent = sanitizeSQL(B.dat)
- var/sqlcategory = sanitizeSQL(upload_category)
- var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO library (author, title, content, category) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]')")
- if(!query.Execute())
- to_chat(usr, query.ErrorMsg())
- error_message = "Network Error: Unable to upload to the Archive. Contact your system Administrator for assistance."
- return 1
- else
- log_and_message_admins("has uploaded the book titled [B.name], [length(B.dat)] signs")
- log_game("[usr.name]/[usr.key] has uploaded the book titled [B.name], [length(B.dat)] signs")
- alert("Upload Complete.")
- return 1
-
- return 0
-
- if(href_list["printbook"])
- if(!current_book)
- error_message = "Software Error: Unable to print; book not found."
- return 1
-
- //PRINT TO BINDER
- if(!nano_host())
- return 1
- for(var/d in GLOB.cardinal)
- var/obj/machinery/bookbinder/bndr = locate(/obj/machinery/bookbinder, get_step(nano_host(), d))
- if(bndr && bndr.anchored)
- var/obj/item/weapon/book/B = new(bndr.loc)
- //B.SetName(current_book["title"])
- B.title = current_book["title"]
- B.author = current_book["author"]
- B.dat = current_book["content"]
- B.icon_state = "book[rand(1,7)]"
- B.desc = current_book["author"]+", "+current_book["title"]+", "+"USBN "+current_book["id"]
- bndr.visible_message("\The [bndr] whirs as it prints and binds a new book.")
- return 1
-
- //Regular printing
- print_text("Author: [current_book["author"]]
USBN: [current_book["id"]]
[current_book["title"]]
[current_book["content"]]", usr)
- return 1
- if(href_list["sortby"])
- sort_by = href_list["sortby"]
- return 1
- if(href_list["reseterror"])
- if(error_message)
- current_book = null
- scanner = null
- sort_by = "id"
- error_message = ""
- return 1
-
-/datum/nano_module/library/proc/view_book(var/id)
- if(current_book || !id)
- return 0
-
- var/sqlid = sanitizeSQL(id)
- establish_old_db_connection()
- if(!dbcon_old.IsConnected())
- error_message = "Network Error: Connection to the Archive has been severed."
- return 1
-
- var/DBQuery/query = dbcon_old.NewQuery("SELECT * FROM library WHERE id=[sqlid]")
- query.Execute()
-
- while(query.NextRow())
- current_book = list(
- "id" = query.item[1],
- "author" = query.item[2],
- "title" = query.item[3],
- "content" = query.item[4]
- )
- break
- return 1
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 0f8d1d245b..ca0c0f9854 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/nano/templates/digitalwarrant.tmpl b/nano/templates/digitalwarrant.tmpl
new file mode 100644
index 0000000000..8693bca239
--- /dev/null
+++ b/nano/templates/digitalwarrant.tmpl
@@ -0,0 +1,89 @@
+{{if data.warrantauth}}
+
+
+ {{if data.type == "arrest"}}
+
+ Name:
+
+ {{/if}}
+ {{if data.type == "search"}}
+
+ Location:
+
+ {{/if}}
+
+ {{:data.warrantname}}
+
+
+
+ {{if data.type == "arrest"}}
+
+ Charges:
+
+ {{/if}}
+ {{if data.type == "search"}}
+
+ Reason:
+
+ {{/if}}
+
+ {{:data.warrantcharges}}
+
+
+
+
+ Authorized by:
+
+
+ {{:data.warrantauth}}
+
+
+
+
+ Actions:
+
+
+
+ {{if data.type == "arrest"}}
+ | {{:helper.link('Edit Name', null, {'editwarrantname' : 1})}}{{:helper.link('Custom Name', null, {'editwarrantnamecustom' : 1})}}
+ |
| {{:helper.link('Edit Charges', null, {'editwarrantcharges' : 1})}}
+ {{/if}}
+ {{if data.type == "search"}}
+ |
| {{:helper.link('Edit Location', null, {'editwarrantnamecustom' : 1})}}
+ |
| {{:helper.link('Edit Reason', null, {'editwarrantcharges' : 1})}}
+ {{/if}}
+ |
| {{:helper.link('Authorize', null, {'editwarrantauth' : 1})}}
+ |
| {{:helper.link('Save', null, {'savewarrant' : 1})}}
+ | {{:helper.link('Delete', null, {'deletewarrant' : 1})}}
+ |
| {{:helper.link('Back to Menu', null, {'back' : 1})}}
+ |
+
+
+
+{{else}}
+
+ {{:helper.link('Add a Warrant', null, {'addwarrant' : 1})}}
+ Arrest warrants
+
+ | Name | Charges | Authorized By
+ {{for data.allwarrants}}
+ {{if value.arrestsearch == "arrest"}}
+ |
|---|
| {{:helper.link(value.warrantname, null, {'editwarrant' : value.id})}} |
+ {{:value.charges}} |
+ {{:value.auth}} |
+ {{/if}}
+ {{/for}}
+
+ Search warrants
+
+ | Location | Reason | Authorized By
+ {{for data.allwarrants}}
+ {{if value.arrestsearch == "search"}}
+ |
|---|
| {{:helper.link(value.warrantname, null, {'editwarrant' : value.id})}} |
+ {{:value.charges}} |
+ {{:value.auth}} |
+ {{/if}}
+ {{/for}}
+
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/library.tmpl b/nano/templates/library.tmpl
deleted file mode 100644
index fa8f3f6622..0000000000
--- a/nano/templates/library.tmpl
+++ /dev/null
@@ -1,75 +0,0 @@
-{{if data.error}}
- Error
- {{:data.error}}
- {{:helper.link("Reset", null, {'reseterror' : 1})}}
-{{else data.current_book}}
- {{:data.current_book.title}}
-
-
- Author:
-
-
- {{:data.current_book.author}}
-
-
- USBN:
-
-
- {{:data.current_book.id}}
-
-
- Commands:
-
-
- {{:helper.link("Close", null, {'closebook' : 1})}}
- {{:helper.link("Print", null, {'printbook' : 1})}}
-
-
-
- {{:data.current_book.content}}
-
-{{else}}
- External Archives
-
-
- Scanner:
-
-
- {{:data.scanner ? 'Connected' : 'Not Connected'}}
-
-
-
-
- Commands:
-
-
- {{:helper.link("View By USBN", null, {'viewid' : 1})}}
- {{:helper.link("Upload From Scanner", null, {'uploadbook' : 1})}}
- {{:helper.link("Connect to Scanner", null, {'connectscanner' : 1})}}
-
-
-
-
- Sort by:
-
-
- {{:helper.link("Title", null, {'sortby' : 'title'})}}
- {{:helper.link("Author", null, {'sortby' : 'author'})}}
- {{:helper.link("Category", null, {'sortby' : 'category'})}}
- {{:helper.link("USBN", null, {'sortby' : 'id'})}}
-
-
-
-
- | Commands | Title | Author | Category | USBN
- {{for data.book_list}}
- |
|---|
| {{:helper.link("View", null, {'viewbook' : value.id})}}
- | {{:value.title}}
- | {{:value.author}}
- | {{:value.category}}
- | {{:value.id}}
-
- {{/for}}
- |
-{{/if}}
-
NTOS v2.0.4b Copyright NanoTrasen 2557 - 2561
diff --git a/polaris.dme b/polaris.dme
index 26838190d4..00e281fb66 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -2134,7 +2134,6 @@
#include "code\modules\modular_computers\file_system\programs\generic\email_client.dm"
#include "code\modules\modular_computers\file_system\programs\generic\file_browser.dm"
#include "code\modules\modular_computers\file_system\programs\generic\game.dm"
-#include "code\modules\modular_computers\file_system\programs\generic\library.dm"
#include "code\modules\modular_computers\file_system\programs\generic\news_browser.dm"
#include "code\modules\modular_computers\file_system\programs\generic\ntdownloader.dm"
#include "code\modules\modular_computers\file_system\programs\generic\ntnrc_client.dm"