mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-21 11:07:12 +01:00
merge conflict fix
This commit is contained in:
@@ -21,6 +21,13 @@ var/global/nologevent = 0
|
||||
var/msg = rendered
|
||||
to_chat(C, msg)
|
||||
|
||||
/proc/message_adminTicket(var/msg)
|
||||
msg = "<span class='adminticket'><span class='prefix'>ADMIN TICKET:</span> [msg]</span>"
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
if(C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS))
|
||||
to_chat(C, msg)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////Panels
|
||||
|
||||
|
||||
@@ -108,6 +108,8 @@ var/list/admin_verbs_event = list(
|
||||
/client/proc/toggle_random_events,
|
||||
/client/proc/toggle_ert_calling,
|
||||
/client/proc/cmd_admin_change_custom_event,
|
||||
/client/proc/cmd_admin_custom_event_info,
|
||||
/client/proc/cmd_view_custom_event_info,
|
||||
/datum/admins/proc/access_news_network, /*allows access of newscasters*/
|
||||
/client/proc/cmd_admin_direct_narrate, /*send text directly to a player with no padding. Useful for narratives and fluff-text*/
|
||||
/client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/
|
||||
@@ -171,7 +173,8 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/admin_serialize,
|
||||
/client/proc/admin_deserialize,
|
||||
/client/proc/jump_to_ruin,
|
||||
/client/proc/toggle_medal_disable
|
||||
/client/proc/toggle_medal_disable,
|
||||
/client/proc/startadmintickets,
|
||||
)
|
||||
var/list/admin_verbs_possess = list(
|
||||
/proc/possess,
|
||||
@@ -218,6 +221,11 @@ var/list/admin_verbs_snpc = list(
|
||||
/client/proc/customiseSNPC,
|
||||
/client/proc/hide_snpc_verbs
|
||||
)
|
||||
var/list/admin_verbs_ticket = list(
|
||||
/client/proc/openTicketUI,
|
||||
/client/proc/toggleticketlogs,
|
||||
/client/proc/resolveAllTickets
|
||||
)
|
||||
|
||||
/client/proc/on_holder_add()
|
||||
if(chatOutput && chatOutput.loaded)
|
||||
@@ -230,6 +238,7 @@ var/list/admin_verbs_snpc = list(
|
||||
verbs += /client/proc/togglebuildmodeself
|
||||
if(holder.rights & R_ADMIN)
|
||||
verbs += admin_verbs_admin
|
||||
verbs += admin_verbs_ticket
|
||||
spawn(1)
|
||||
control_freak = 0
|
||||
if(holder.rights & R_BAN)
|
||||
@@ -280,7 +289,8 @@ var/list/admin_verbs_snpc = list(
|
||||
admin_verbs_show_debug_verbs,
|
||||
/client/proc/readmin,
|
||||
admin_verbs_snpc,
|
||||
/client/proc/hide_snpc_verbs
|
||||
/client/proc/hide_snpc_verbs,
|
||||
admin_verbs_ticket
|
||||
)
|
||||
|
||||
/client/proc/hide_verbs()
|
||||
@@ -917,6 +927,20 @@ var/list/admin_verbs_snpc = list(
|
||||
else
|
||||
to_chat(usr, "You now will get admin log messages.")
|
||||
|
||||
/client/proc/toggleticketlogs()
|
||||
set name = "Toggle Admin Ticket Messgaes"
|
||||
set category = "Preferences"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
prefs.toggles ^= CHAT_NO_TICKETLOGS
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & CHAT_NO_TICKETLOGS)
|
||||
to_chat(usr, "You now won't get admin ticket messages.")
|
||||
else
|
||||
to_chat(usr, "You now will get admin ticket messages.")
|
||||
|
||||
/client/proc/toggledrones()
|
||||
set name = "Toggle Maintenance Drones"
|
||||
set category = "Server"
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
Admin ticket system by Birdtalon
|
||||
*/
|
||||
//Global holder
|
||||
|
||||
var/global/datum/adminTicketHolder/globAdminTicketHolder = new /datum/adminTicketHolder
|
||||
|
||||
//Defines
|
||||
//Deciseconds until ticket becomes stale if unanswered. Alerts admins.
|
||||
#define ADMIN_TICKET_TIMEOUT 6000 // 10 minutes
|
||||
//Decisecions before the user is allowed to open another ticket while their existing one is open.
|
||||
#define ADMIN_TICKET_DUPLICATE_COOLDOWN 3000 // 5 minutes
|
||||
|
||||
//Status defines
|
||||
#define ADMIN_TICKET_OPEN 1
|
||||
#define ADMIN_TICKET_CLOSED 2
|
||||
#define ADMIN_TICKET_RESOLVED 3
|
||||
#define ADMIN_TICKET_STALE 4
|
||||
|
||||
//Datum holding all tickets
|
||||
/datum/adminTicketHolder
|
||||
var/ticketCounter = 1 // Counts the tickets and used to assign the id number
|
||||
var/list/allTickets = list()
|
||||
|
||||
//Return the current ticket number ready to be called off.
|
||||
/datum/adminTicketHolder/proc/getTicketCounter()
|
||||
return ticketCounter
|
||||
|
||||
//Return the ticket counter and increment
|
||||
/datum/adminTicketHolder/proc/getTicketCounterAndInc()
|
||||
. = ticketCounter
|
||||
ticketCounter++
|
||||
return
|
||||
|
||||
/datum/adminTicketHolder/proc/resolveAllOpenTickets() // Resolve all open tickets
|
||||
for(var/i in allTickets)
|
||||
var/datum/admin_ticket/T = i
|
||||
resolveTicket(T.ticketNum)
|
||||
|
||||
//Open a new ticket and populate details then add to the list of open tickets
|
||||
/datum/adminTicketHolder/proc/newTicket(var/client/C, var/passedContent, var/title)
|
||||
if(!C || !passedContent)
|
||||
return
|
||||
|
||||
//Check if the user has an open ticket already within the cooldown period, if so we don't create a new one and re-set the cooldown period
|
||||
var/datum/admin_ticket/existingTicket = checkForOpenTicket(C)
|
||||
if(existingTicket)
|
||||
existingTicket.setCooldownPeriod()
|
||||
to_chat(C, "<span class='adminticket'>Your ticket #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.</span>")
|
||||
return
|
||||
|
||||
if(!title)
|
||||
title = passedContent
|
||||
|
||||
var/datum/admin_ticket/T = new /datum/admin_ticket
|
||||
T.clientName = C
|
||||
T.timeOpened = worldtime2text()
|
||||
T.title = title
|
||||
T.content += passedContent
|
||||
T.locationSent = C.mob.loc.loc.name
|
||||
T.mobControlled = C.mob
|
||||
T.ticketState = ADMIN_TICKET_OPEN
|
||||
T.timeUntilStale = world.time + ADMIN_TICKET_TIMEOUT
|
||||
T.setCooldownPeriod()
|
||||
T.ticketNum = getTicketCounterAndInc()
|
||||
allTickets += T
|
||||
|
||||
//Inform the user that they have opened a ticket
|
||||
to_chat(C, "<span class='adminticket'>You have opened admin ticket number #[(globAdminTicketHolder.getTicketCounter() - 1)]! Please be patient and we will help you soon!</span>")
|
||||
|
||||
//Begin the stale count for this ticket.
|
||||
spawn(0)
|
||||
T.beginStaleCount()
|
||||
|
||||
//Set ticket state with key N to open
|
||||
/datum/adminTicketHolder/proc/openTicket(var/N)
|
||||
var/datum/admin_ticket/T = globAdminTicketHolder.allTickets[N]
|
||||
if(T.ticketState != ADMIN_TICKET_OPEN)
|
||||
T.ticketState = ADMIN_TICKET_OPEN
|
||||
return TRUE
|
||||
|
||||
//Set ticket state with key N to resolved
|
||||
/datum/adminTicketHolder/proc/resolveTicket(var/N)
|
||||
var/datum/admin_ticket/T = globAdminTicketHolder.allTickets[N]
|
||||
if(T.ticketState != ADMIN_TICKET_RESOLVED)
|
||||
T.ticketState = ADMIN_TICKET_RESOLVED
|
||||
return TRUE
|
||||
|
||||
//Set ticket state with key N to closed
|
||||
/datum/adminTicketHolder/proc/closeTicket(var/N)
|
||||
var/datum/admin_ticket/T = globAdminTicketHolder.allTickets[N]
|
||||
if(T.ticketState != ADMIN_TICKET_CLOSED)
|
||||
T.ticketState = ADMIN_TICKET_CLOSED
|
||||
return TRUE
|
||||
|
||||
//Check if the user already has a ticket open and within the cooldown period.
|
||||
/datum/adminTicketHolder/proc/checkForOpenTicket(var/client/C)
|
||||
for(var/datum/admin_ticket/T in allTickets)
|
||||
if(T.clientName == C && T.ticketState == ADMIN_TICKET_OPEN && (T.ticketCooldown > world.time))
|
||||
return T
|
||||
return FALSE
|
||||
|
||||
//Check if the user has ANY ticket not resolved or closed.
|
||||
/datum/adminTicketHolder/proc/checkForTicket(var/client/C)
|
||||
var/list/tickets = list()
|
||||
for(var/datum/admin_ticket/T in allTickets)
|
||||
if(T.clientName == C && T.ticketState == ADMIN_TICKET_OPEN || T.ticketState == ADMIN_TICKET_STALE)
|
||||
tickets += T
|
||||
if(tickets.len)
|
||||
return tickets
|
||||
return FALSE
|
||||
|
||||
//return the client of a ticket number
|
||||
/datum/adminTicketHolder/proc/returnClient(var/N)
|
||||
var/datum/admin_ticket/T = globAdminTicketHolder.allTickets[N]
|
||||
return T.clientName
|
||||
|
||||
/datum/adminTicketHolder/proc/assignAdminToTicket(var/client/C, var/N)
|
||||
var/datum/admin_ticket/T = globAdminTicketHolder.allTickets[N]
|
||||
T.assignAdmin(C)
|
||||
return TRUE
|
||||
|
||||
//Single admin ticket
|
||||
|
||||
/datum/admin_ticket
|
||||
var/ticketNum // Ticket number
|
||||
var/clientName // Client which opened the ticket
|
||||
var/timeOpened // Time the ticket was opened
|
||||
var/title //The initial message with links
|
||||
var/list/content = list() // content of the admin help
|
||||
var/lastAdminResponse // Last admin who responded
|
||||
var/lastResponseTime // When the admin last responded
|
||||
var/locationSent // Location the player was when they send the ticket
|
||||
var/mobControlled // Mob they were controlling
|
||||
var/ticketState // State of the ticket, open, closed, resolved etc
|
||||
var/timeUntilStale // When the ticket goes stale
|
||||
var/ticketCooldown // Cooldown before allowing the user to open another ticket.
|
||||
var/adminAssigned // Admin who has assigned themselves to this ticket
|
||||
|
||||
//Ticker called when a ticket is created, checks for stale-ness.
|
||||
/datum/admin_ticket/proc/beginStaleCount()
|
||||
while(world.time < timeUntilStale || !lastAdminResponse || !adminAssigned) // While within the stale period OR no admin responded OR no admin assigned.
|
||||
|
||||
if(!src)
|
||||
return
|
||||
|
||||
sleep(200) // Check every 20 seconds.
|
||||
if(ticketState == ADMIN_TICKET_OPEN && world.time > timeUntilStale)
|
||||
message_adminTicket("<span class='adminticket'>Ticket #[ticketNum] has been open for [ADMIN_TICKET_TIMEOUT * 0.1] seconds. Changing status to stale.</span>")
|
||||
ticketState = ADMIN_TICKET_STALE
|
||||
break
|
||||
|
||||
//Set the cooldown period for the ticket. The time when it's created plus the defined cooldown time.
|
||||
/datum/admin_ticket/proc/setCooldownPeriod()
|
||||
ticketCooldown = world.time + ADMIN_TICKET_DUPLICATE_COOLDOWN
|
||||
|
||||
//Set the last admin who responded as the client passed as an arguement.
|
||||
/datum/admin_ticket/proc/setLastAdminResponse(var/client/C)
|
||||
lastAdminResponse = C
|
||||
lastResponseTime = worldtime2text()
|
||||
|
||||
//Return the ticket state as a colour coded text string.
|
||||
/datum/admin_ticket/proc/state2text()
|
||||
switch(ticketState)
|
||||
if(ADMIN_TICKET_OPEN)
|
||||
return "<font color='green'>OPEN</font>"
|
||||
if(ADMIN_TICKET_RESOLVED)
|
||||
return "<font color='blue'>RESOLVED</font>"
|
||||
if(ADMIN_TICKET_CLOSED)
|
||||
return "<font color='red'>CLOSED</font>"
|
||||
if(ADMIN_TICKET_STALE)
|
||||
return "<font color='orange'>STALE</font>"
|
||||
|
||||
//Assign the client passed to var/adminAsssigned
|
||||
/datum/admin_ticket/proc/assignAdmin(var/client/C, var/N)
|
||||
if(!C)
|
||||
return
|
||||
adminAssigned = C
|
||||
return TRUE
|
||||
|
||||
/datum/admin_ticket/proc/addResponse(var/client/C, var/M as text)
|
||||
if(C.holder)
|
||||
setLastAdminResponse(C)
|
||||
M = "[C]: [M]"
|
||||
content += M
|
||||
@@ -0,0 +1,172 @@
|
||||
/datum/adminTicketHolder/proc/returnUI(var/tab = ADMIN_TICKET_OPEN)
|
||||
set name = "Open Ticket Interface"
|
||||
set category = "Tickets"
|
||||
|
||||
//dat
|
||||
var/trStyle = "border-top:2px solid; border-bottom:2px solid; padding-top: 5px; padding-bottom: 5px;"
|
||||
var/tdStyleleft = "border-top:2px solid; border-bottom:2px solid; width:150px; text-align:center;"
|
||||
var/tdStyle = "border-top:2px solid; border-bottom:2px solid;"
|
||||
var/datum/admin_ticket/ticket
|
||||
var/dat
|
||||
dat += "<head><style>.adminticket{border:2px solid}</style></head>"
|
||||
dat += "<body><h1>Admin Tickets</h1>"
|
||||
|
||||
dat +="<a href='?src=[UID()];refresh=1'>Refresh</a><br /><a href='?src=[UID()];showopen=1'>Open Tickets</a><a href='?src=[UID()];showresolved=1'>Resolved Tickets</a><a href='?src=[UID()];showclosed=1'>Closed Tickets</a>"
|
||||
if(tab == ADMIN_TICKET_OPEN)
|
||||
dat += "<h2>Open Tickets</h2>"
|
||||
dat += "<table style='width:1300px; border: 3px solid;'>"
|
||||
dat +="<tr style='[trStyle]'><th style='[tdStyleleft]'>Control</th><th style='[tdStyle]'>Ticket</th></tr>"
|
||||
if(tab == ADMIN_TICKET_OPEN)
|
||||
for(var/T in allTickets)
|
||||
ticket = T
|
||||
if(ticket.ticketState == ADMIN_TICKET_OPEN || ticket.ticketState == ADMIN_TICKET_STALE)
|
||||
dat += "<tr style='[trStyle]'><td style ='[tdStyleleft]'><a href='?src=[UID()];resolve=[ticket.ticketNum]'>Resolve</a><a href='?src=[UID()];details=[ticket.ticketNum]'>Details</a> <br /> #[ticket.ticketNum] ([ticket.timeOpened]) [ticket.ticketState == ADMIN_TICKET_STALE ? "<font color='red'><b>STALE</font>" : ""] </td><td style='[tdStyle]'><b>[ticket.title]</td></tr>"
|
||||
else
|
||||
continue
|
||||
else if(tab == ADMIN_TICKET_RESOLVED)
|
||||
dat += "<h2>Resolved Tickets</h2>"
|
||||
for(var/T in allTickets)
|
||||
ticket = T
|
||||
if(ticket.ticketState == ADMIN_TICKET_RESOLVED)
|
||||
dat += "<tr style='[trStyle]'><td style ='[tdStyleleft]'><a href='?src=[UID()];resolve=[ticket.ticketNum]'>Resolve</a><a href='?src=[UID()];details=[ticket.ticketNum]'>Details</a> <br /> #[ticket.ticketNum] ([ticket.timeOpened]) </td><td style='[tdStyle]'><b>[ticket.title]</td></tr>"
|
||||
else
|
||||
continue
|
||||
else if(tab == ADMIN_TICKET_CLOSED)
|
||||
dat += "<h2>Closed Tickets</h2>"
|
||||
for(var/T in allTickets)
|
||||
ticket = T
|
||||
if(ticket.ticketState == ADMIN_TICKET_CLOSED)
|
||||
dat += "<tr style='[trStyle]'><td style ='[tdStyleleft]'><a href='?src=[UID()];resolve=[ticket.ticketNum]'>Resolve</a><a href='?src=[UID()];details=[ticket.ticketNum]'>Details</a> <br /> #[ticket.ticketNum] ([ticket.timeOpened]) </td><td style='[tdStyle]'><b>[ticket.title]</td></tr>"
|
||||
else
|
||||
continue
|
||||
|
||||
dat += "</table></body>"
|
||||
|
||||
return dat
|
||||
|
||||
/datum/adminTicketHolder/proc/showUI(var/client/user, var/tab)
|
||||
var/dat = null
|
||||
dat = returnUI(tab)
|
||||
var/datum/browser/popup = new(user, "admintickets", "Admin Tickets", 1400, 600)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/datum/adminTicketHolder/proc/showDetailUI(var/client/user, var/ticketID)
|
||||
var/datum/admin_ticket/T = globAdminTicketHolder.allTickets[ticketID]
|
||||
var/status = "[T.state2text()]"
|
||||
|
||||
var/dat = "<h1>Admin Tickets</h1>"
|
||||
|
||||
dat +="<a href='?src=[UID()];refresh=1'>Show All</a><a href='?src=[UID()];refreshdetail=[T.ticketNum]'>Refresh</a>"
|
||||
|
||||
dat += "<h2>Ticket #[T.ticketNum]</h2>"
|
||||
|
||||
dat += "<h3>[T.clientName] / [T.mobControlled] opened this ticket at [T.timeOpened] at location [T.locationSent]</h3>"
|
||||
dat += "<h4>Ticket Status: <font color='red'>[status]</font>"
|
||||
dat += "<table style='width:950px; border: 3px solid;'>"
|
||||
dat += "<tr><td>[T.title]</td></tr>"
|
||||
|
||||
if(T.content.len > 1)
|
||||
for(var/i = 2, i <= T.content.len, i++)
|
||||
dat += "<tr><td>[T.content[i]]</td></tr>"
|
||||
|
||||
dat += "</table><br /><br />"
|
||||
dat += "<a href='?src=[UID()];detailreopen=[T.ticketNum]'>Re-Open</a><a href='?src=[UID()];detailresolve=[T.ticketNum]'>Resolve</a><br /><br />"
|
||||
|
||||
if(!T.adminAssigned)
|
||||
dat += "No admin assigned to this ticket - <a href='?src=[UID()];assignadmin=[T.ticketNum]'>Take Ticket</a><br />"
|
||||
else
|
||||
dat += "[T.adminAssigned] is assigned to this Ticket. - <a href='?src=[UID()];assignadmin=[T.ticketNum]'>Take Ticket</a><br />"
|
||||
|
||||
if(T.lastAdminResponse)
|
||||
dat += "<b>Last Admin Response:</b> [T.lastAdminResponse] at [T.lastResponseTime]"
|
||||
else
|
||||
dat +="<font color='red'>No Admin Response</font>"
|
||||
|
||||
dat += "<br /><br />"
|
||||
|
||||
dat += "<a href='?src=[UID()];detailclose=[T.ticketNum]'>Close Ticket</a>"
|
||||
|
||||
var/datum/browser/popup = new(user, "adminticketsdetail", "Admin Ticket #[T.ticketNum]", 1000, 600)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/datum/adminTicketHolder/proc/userDetailUI(var/client/user)
|
||||
//dat
|
||||
var/tickets = checkForTicket(user)
|
||||
var/dat
|
||||
dat += "<h1>Your open tickets</h1>"
|
||||
dat += "<table>"
|
||||
for(var/datum/admin_ticket/T in tickets)
|
||||
dat += "<tr><td><h2>Ticket #[T.ticketNum]</h2></td></tr>"
|
||||
for(var/i = 1, i <= T.content.len, i++)
|
||||
dat += "<tr><td>[T.content[i]]</td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
var/datum/browser/popup = new(user, "userticketsdetail", "Tickets", 1000, 600)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/datum/adminTicketHolder/Topic(href, href_list)
|
||||
|
||||
if(href_list["refresh"])
|
||||
showUI(usr)
|
||||
return
|
||||
|
||||
if(href_list["refreshdetail"])
|
||||
var/indexNum = text2num(href_list["refreshdetail"])
|
||||
showDetailUI(usr, indexNum)
|
||||
return
|
||||
|
||||
if(href_list["showopen"])
|
||||
showUI(usr, ADMIN_TICKET_OPEN)
|
||||
return
|
||||
if(href_list["showresolved"])
|
||||
showUI(usr, ADMIN_TICKET_RESOLVED)
|
||||
return
|
||||
if(href_list["showclosed"])
|
||||
showUI(usr, ADMIN_TICKET_CLOSED)
|
||||
return
|
||||
|
||||
if(href_list["details"])
|
||||
var/indexNum = text2num(href_list["details"])
|
||||
showDetailUI(usr.client, indexNum)
|
||||
return
|
||||
|
||||
if(href_list["resolve"])
|
||||
var/indexNum = text2num(href_list["resolve"])
|
||||
if(globAdminTicketHolder.resolveTicket(indexNum))
|
||||
message_adminTicket("[usr.client] / ([usr]) resolved admin ticket number [indexNum]")
|
||||
to_chat(returnClient(indexNum), "<span class='adminticket'>Your admin ticket has now been resolved.</span>")
|
||||
showUI(usr)
|
||||
|
||||
if(href_list["detailresolve"])
|
||||
var/indexNum = text2num(href_list["detailresolve"])
|
||||
if(globAdminTicketHolder.resolveTicket(indexNum))
|
||||
message_adminTicket("[usr.client] / ([usr]) resolved admin ticket number [indexNum]")
|
||||
to_chat(returnClient(indexNum), "<span class='adminticket'>Your admin ticket has now been resolved.</span>")
|
||||
showDetailUI(usr, indexNum)
|
||||
|
||||
if(href_list["detailclose"])
|
||||
var/indexNum = text2num(href_list["detailclose"])
|
||||
if(alert("Are you sure? This will send a negative message.",,"Yes","No") != "Yes")
|
||||
return
|
||||
if(globAdminTicketHolder.closeTicket(indexNum))
|
||||
message_adminTicket("[usr.client] / ([usr]) closed admin ticket number [indexNum]")
|
||||
to_chat(returnClient(indexNum), "<font color='red' size='4'><b>- AdminHelp Rejected! -</b></font>")
|
||||
to_chat(returnClient(indexNum), "<span class='boldmessage'>Please try to be calm, clear, and descriptive in admin helps, do not assume the admin has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.</span>")
|
||||
to_chat(returnClient(indexNum), "<span class='adminticket'>Your ticket has now been closed.</span>")
|
||||
showDetailUI(usr, indexNum)
|
||||
|
||||
if(href_list["detailreopen"])
|
||||
var/indexNum = text2num(href_list["detailreopen"])
|
||||
if(globAdminTicketHolder.openTicket(indexNum))
|
||||
message_adminTicket("[usr.client] / ([usr]) re-opened admin ticket number [indexNum]")
|
||||
showDetailUI(usr, indexNum)
|
||||
|
||||
if(href_list["assignadmin"])
|
||||
var/indexNum = text2num(href_list["assignadmin"])
|
||||
if(globAdminTicketHolder.assignAdminToTicket(usr.client, indexNum))
|
||||
message_adminTicket("[usr.client] / ([usr]) has taken ticket number [indexNum]")
|
||||
to_chat(returnClient(indexNum), "<span class='adminticket'>Your ticket is being handled by [usr.client].")
|
||||
showDetailUI(usr, indexNum)
|
||||
@@ -0,0 +1,51 @@
|
||||
//Verbs
|
||||
|
||||
/client/proc/startadmintickets()
|
||||
set name = "Restart Admin Ticket System"
|
||||
set category = "Debug"
|
||||
|
||||
if(!holder && !check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
if(!globAdminTicketHolder)
|
||||
var/global/datum/adminTicketHolder/globAdminTicketHolder = new /datum/adminTicketHolder
|
||||
else
|
||||
if(alert("Are you sure you want to reboot the admin ticket system?","Reboot Admin Tickets?","Yes","No") != "Yes")
|
||||
return
|
||||
message_admins("<span class='admintickets'>Restarting Admin Ticket System!</span>")
|
||||
globAdminTicketHolder = new /datum/adminTicketHolder
|
||||
message_admins("<span class='admintickets'>Admin Ticket System Restarted!</span>")
|
||||
|
||||
/client/proc/openTicketUI()
|
||||
|
||||
set name = "Open Ticket Interface"
|
||||
set category = "Admin"
|
||||
|
||||
if(!holder && !check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
globAdminTicketHolder.showUI(usr)
|
||||
|
||||
/client/proc/resolveAllTickets()
|
||||
set name = "Resolve All Open Tickets"
|
||||
set category = "Admin"
|
||||
|
||||
if(!holder && !check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(alert("Are you sure you want to resolve ALL open tickets?","Resolve all open tickets?","Yes","No") != "Yes")
|
||||
return
|
||||
|
||||
globAdminTicketHolder.resolveAllOpenTickets()
|
||||
|
||||
|
||||
|
||||
/client/verb/openUserUI()
|
||||
|
||||
set name = "My Tickets"
|
||||
set category = "Admin"
|
||||
|
||||
if(!holder && !check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
globAdminTicketHolder.userDetailUI(usr.client)
|
||||
@@ -26,6 +26,12 @@
|
||||
message_admins("[key_name_admin(usr)] rejected [key_name_admin(C.mob)]'s admin help")
|
||||
log_admin("[key_name(usr)] rejected [key_name(C.mob)]'s admin help")
|
||||
|
||||
if(href_list["openadminticket"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/ticketID = text2num(href_list["openadminticket"])
|
||||
globAdminTicketHolder.showDetailUI(usr, ticketID)
|
||||
|
||||
if(href_list["stickyban"])
|
||||
stickyban(href_list["stickyban"],href_list)
|
||||
|
||||
@@ -242,16 +248,23 @@
|
||||
|
||||
else if(task == "permissions")
|
||||
if(!D) return
|
||||
var/list/permissionlist = list()
|
||||
for(var/i=1, i<=R_MAXPERMISSION, i<<=1) //that <<= is shorthand for i = i << 1. Which is a left bitshift
|
||||
permissionlist[rights2text(i)] = i
|
||||
var/new_permission = input("Select a permission to turn on/off", "Permission toggle", null, null) as null|anything in permissionlist
|
||||
if(!new_permission) return
|
||||
D.rights ^= permissionlist[new_permission]
|
||||
while(TRUE)
|
||||
var/list/permissionlist = list()
|
||||
for(var/i=1, i<=R_MAXPERMISSION, i<<=1) //that <<= is shorthand for i = i << 1. Which is a left bitshift
|
||||
permissionlist[rights2text(i)] = i
|
||||
var/new_permission = input("Select a permission to turn on/off", adm_ckey + "'s Permissions", null, null) as null|anything in permissionlist
|
||||
if(!new_permission)
|
||||
return
|
||||
var/oldrights = D.rights
|
||||
var/toggleresult = "ON"
|
||||
D.rights ^= permissionlist[new_permission]
|
||||
if(oldrights > D.rights)
|
||||
toggleresult = "OFF"
|
||||
|
||||
message_admins("[key_name_admin(usr)] toggled the [new_permission] permission of [adm_ckey] to [toggleresult]")
|
||||
log_admin("[key_name(usr)] toggled the [new_permission] permission of [adm_ckey] to [toggleresult]")
|
||||
log_admin_permission_modification(adm_ckey, permissionlist[new_permission])
|
||||
|
||||
message_admins("[key_name_admin(usr)] toggled the [new_permission] permission of [adm_ckey]")
|
||||
log_admin("[key_name(usr)] toggled the [new_permission] permission of [adm_ckey]")
|
||||
log_admin_permission_modification(adm_ckey, permissionlist[new_permission])
|
||||
|
||||
edit_admin_permissions()
|
||||
|
||||
|
||||
@@ -115,7 +115,17 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
to_chat(X, msg)
|
||||
if("Adminhelp")
|
||||
msg = "<span class='adminhelp'>[selected_type]: </span><span class='boldnotice'>[key_name(src, 1, 1, selected_type)] (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[mob.UID()]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(mob)]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>) (<A HREF='?_src_=holder;rejectadminhelp=[ref_client]'>REJT</A>) [ai_found ? " (<A HREF='?_src_=holder;adminchecklaws=[ref_mob]'>CL</A>)" : ""] (<A HREF='?_src_=holder;take_question=[mob.UID()]'>TAKE</A>) :</span> <span class='adminhelp'>[msg]</span>"
|
||||
var/ticketNum // Holder for the ticket number
|
||||
var/prunedmsg ="[usr.client]: [msg]" // Message without links
|
||||
if(globAdminTicketHolder.checkForOpenTicket(usr.client)) // If user already has an open ticket
|
||||
var/datum/admin_ticket/T = globAdminTicketHolder.checkForOpenTicket(usr.client) // Make T equal to the ticket they have open
|
||||
ticketNum = T.ticketNum // ticketNum is the number of their ticket.
|
||||
T.addResponse(usr.client, msg)
|
||||
else
|
||||
ticketNum = globAdminTicketHolder.getTicketCounter() // ticketNum is the ticket ready to be assigned.
|
||||
msg = "<span class='adminhelp'>[selected_type]: </span><span class='boldnotice'>[key_name(src, 1, 1, selected_type)] (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[mob.UID()]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(mob)]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>) (<A HREF='?_src_=holder;openadminticket=[ticketNum]'>TICKET</A>) [ai_found ? " (<A HREF='?_src_=holder;adminchecklaws=[ref_mob]'>CL</A>)" : ""] :</span> <span class='adminhelp'>[msg]</span>"
|
||||
//Open a new adminticket and inform the user.
|
||||
globAdminTicketHolder.newTicket(src, prunedmsg, msg)
|
||||
for(var/client/X in modholders + adminholders)
|
||||
if(X.prefs.sound & SOUND_ADMINHELP)
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
@@ -183,6 +183,23 @@
|
||||
if(check_rights(R_ADMIN|R_MOD, 0, X.mob))
|
||||
to_chat(X, "<span class='boldnotice'>[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: [emoji_msg]</span>")
|
||||
|
||||
//Check if the mob being PM'd has any open admin tickets.
|
||||
var/tickets = list()
|
||||
tickets = globAdminTicketHolder.checkForTicket(C)
|
||||
if(tickets)
|
||||
for(var/datum/admin_ticket/i in tickets)
|
||||
i.addResponse(src, msg) // Add this response to their open tickets.
|
||||
return
|
||||
|
||||
tickets = globAdminTicketHolder.checkForTicket(src)
|
||||
if(check_rights(R_ADMIN|R_MOD, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets
|
||||
tickets = globAdminTicketHolder.checkForTicket(src)
|
||||
if(tickets)
|
||||
for(var/datum/admin_ticket/i in tickets)
|
||||
i.addResponse(src, msg)
|
||||
return
|
||||
|
||||
|
||||
/client/proc/cmd_admin_irc_pm()
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, "<font color='red'>Error: Private-Message: You are unable to use PM-s (muted).</font>")
|
||||
|
||||
@@ -38,3 +38,49 @@
|
||||
to_chat(src, "<h2 class='alert'>A custom event is taking place. OOC Info:</h2>")
|
||||
to_chat(src, "<span class='alert'>[html_encode(custom_event_msg)]</span>")
|
||||
to_chat(src, "<br>")
|
||||
|
||||
//admin event info to be view by admins
|
||||
|
||||
/client/proc/cmd_admin_custom_event_info()
|
||||
set category = "Event"
|
||||
set name = "Change Custom Admin Event Info"
|
||||
|
||||
if(!check_rights(R_EVENT))
|
||||
to_chat(src, "Only administrators may use this command.")
|
||||
return
|
||||
|
||||
var/input = input(usr, "Enter the description of the custom event. This is informations for admins only. Use it to notify other admins of event info but not players.", "Custom Event Info", custom_event_msg) as message|null
|
||||
if(!input || input == "")
|
||||
custom_event_admin_msg = null
|
||||
log_admin("[key_name(usr)] has cleared the custom admin event info text.")
|
||||
message_admins("[key_name_admin(usr)] has cleared the custom admin event text.")
|
||||
return
|
||||
|
||||
log_admin("[key_name(usr)] has changed the custom admin event info text.")
|
||||
message_admins("[key_name_admin(usr)] has changed the custom admin event info text.")
|
||||
|
||||
custom_event_admin_msg = input
|
||||
|
||||
for(var/client/X in admins)
|
||||
if(check_rights(R_EVENT,0,X.mob))
|
||||
to_chat(X, "<h1 class='alert'>Custom Admin Event Info</h1>")
|
||||
to_chat(X, "<h2 class='alert'>A custom event is starting. OOC Admin Info:</h2>")
|
||||
to_chat(X, "<span class='alert'>[html_encode(custom_event_admin_msg)]</span>")
|
||||
to_chat(X,"<br>")
|
||||
|
||||
/client/proc/cmd_view_custom_event_info()
|
||||
set category = "Event"
|
||||
set name = "Custom Event Admin Info"
|
||||
|
||||
if(!check_rights(R_EVENT))
|
||||
to_chat(src, "Only administrators may use this command.")
|
||||
return
|
||||
|
||||
if(!custom_event_admin_msg || custom_event_admin_msg == "")
|
||||
to_chat(src, "There currently is no known custom admin event taking place.")
|
||||
return
|
||||
|
||||
to_chat(src, "<h1 class='alert'>Custom Event Info</h1>")
|
||||
to_chat(src, "<h2 class='alert'>A custom event is taking place. OOC Info:</h2>")
|
||||
to_chat(src, "<span class='alert'>[html_encode(custom_event_admin_msg)]</span>")
|
||||
to_chat(src, "<br>")
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
if(usr)
|
||||
if(usr.client)
|
||||
if(usr.client.holder)
|
||||
to_chat(M, "<b>old You hear a voice in your head... <i>[msg]</i></b>")
|
||||
to_chat(M, "<b>You hear a voice in your head... <i>[msg]</i></b>")
|
||||
|
||||
log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
|
||||
message_admins("<span class='boldnotice'>SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]</span>", 1)
|
||||
|
||||
@@ -436,6 +436,8 @@
|
||||
on_holder_add()
|
||||
add_admin_verbs()
|
||||
admin_memo_output("Show", 0, 1)
|
||||
if(custom_event_admin_msg && custom_event_admin_msg != "" && check_rights(R_EVENT))
|
||||
cmd_view_custom_event_info()
|
||||
|
||||
// Forcibly enable hardware-accelerated graphics, as we need them for the lighting overlays.
|
||||
// (but turn them off first, since sometimes BYOND doesn't turn them on properly otherwise)
|
||||
|
||||
@@ -155,4 +155,49 @@
|
||||
path = /obj/item/clothing/accessory/corset/blue
|
||||
|
||||
|
||||
/datum/gear/accessory/armband_red
|
||||
display_name = "armband"
|
||||
path = /obj/item/clothing/accessory/armband
|
||||
|
||||
/datum/gear/accessory/armband_civ
|
||||
display_name = "armband, blue-yellow"
|
||||
path = /obj/item/clothing/accessory/armband/yb
|
||||
|
||||
/datum/gear/accessory/armband_sec
|
||||
display_name = " armband, security"
|
||||
path = /obj/item/clothing/accessory/armband/sec
|
||||
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Brig Physician")
|
||||
|
||||
/datum/gear/accessory/armband_cargo
|
||||
display_name = "cargo armband"
|
||||
path = /obj/item/clothing/accessory/armband/cargo
|
||||
allowed_roles = list("Quartermaster","Cargo Technician", "Shaft Miner")
|
||||
|
||||
/datum/gear/accessory/armband_medical
|
||||
display_name = "armband, medical"
|
||||
path = /obj/item/clothing/accessory/armband/med
|
||||
allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Coroner", "Paramedic", "Brig Physician")
|
||||
|
||||
/datum/gear/accessory/armband_emt
|
||||
display_name = "armband, EMT"
|
||||
path = /obj/item/clothing/accessory/armband/medgreen
|
||||
allowed_roles = list("Paramedic", "Brig Physician")
|
||||
|
||||
/datum/gear/accessory/armband_engineering
|
||||
display_name = "armband, engineering"
|
||||
path = /obj/item/clothing/accessory/armband/engine
|
||||
allowed_roles = list("Chief Engineer","Station Engineer", "Life Support Specialist")
|
||||
|
||||
/datum/gear/accessory/armband_hydro
|
||||
display_name = "armband, hydroponics"
|
||||
path = /obj/item/clothing/accessory/armband/hydro
|
||||
allowed_roles = list("Botanist")
|
||||
|
||||
/datum/gear/accessory/armband_sci
|
||||
display_name = "armband, science"
|
||||
path = /obj/item/clothing/accessory/armband/science
|
||||
allowed_roles = list("Research Director","Scientist", "Roboticist")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
dat += "<b>Hair:</b> "
|
||||
dat += "<a href='?_src_=prefs;preference=h_style;task=input'>[h_style]</a>"
|
||||
dat += "<a href='?_src_=prefs;preference=hair;task=input'>Color</a> [color_square(h_colour)]"
|
||||
var/datum/sprite_accessory/temp_hair_style = hair_styles_list[h_style]
|
||||
var/datum/sprite_accessory/temp_hair_style = hair_styles_public_list[h_style]
|
||||
if(temp_hair_style && temp_hair_style.secondary_theme && !temp_hair_style.no_sec_colour)
|
||||
dat += " <a href='?_src_=prefs;preference=secondary_hair;task=input'>Color #2</a> [color_square(h_sec_colour)]"
|
||||
dat += "<br>"
|
||||
@@ -1397,7 +1397,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
|
||||
if("secondary_hair")
|
||||
if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox"))
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_public_list[h_style]
|
||||
if(hair_style.secondary_theme && !hair_style.no_sec_colour)
|
||||
var/new_hair = input(user, "Choose your character's secondary hair colour:", "Character Preference", h_sec_colour) as color|null
|
||||
if(new_hair)
|
||||
@@ -1405,8 +1405,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
|
||||
if("h_style")
|
||||
var/list/valid_hairstyles = list()
|
||||
for(var/hairstyle in hair_styles_list)
|
||||
var/datum/sprite_accessory/SA = hair_styles_list[hairstyle]
|
||||
for(var/hairstyle in hair_styles_public_list)
|
||||
var/datum/sprite_accessory/SA = hair_styles_public_list[hairstyle]
|
||||
|
||||
if(hairstyle == "Bald") //Just in case.
|
||||
valid_hairstyles += hairstyle
|
||||
@@ -1730,7 +1730,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
nanotrasen_relation = new_relation
|
||||
|
||||
if("flavor_text")
|
||||
var/msg = input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(flavor_text)) as message
|
||||
var/msg = input(usr,"Set the flavor text in your 'examine' verb. The flavor text should be a physical descriptor of your character at a glance. SFW Drawn Art of your character is acceptable.","Flavor Text",html_decode(flavor_text)) as message
|
||||
|
||||
if(msg != null)
|
||||
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
|
||||
@@ -1798,7 +1798,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
if("Normal")
|
||||
if(limb == "head")
|
||||
m_styles["head"] = "None"
|
||||
h_style = hair_styles_list["Bald"]
|
||||
h_style = hair_styles_public_list["Bald"]
|
||||
f_style = facial_hair_styles_list["Shaved"]
|
||||
organ_data[limb] = null
|
||||
rlimb_data[limb] = null
|
||||
@@ -1849,7 +1849,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
if(limb == "head")
|
||||
ha_style = "None"
|
||||
alt_head = null
|
||||
h_style = hair_styles_list["Bald"]
|
||||
h_style = hair_styles_public_list["Bald"]
|
||||
f_style = facial_hair_styles_list["Shaved"]
|
||||
m_styles["head"] = "None"
|
||||
rlimb_data[limb] = choice
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
for(var/marking_location in m_colours)
|
||||
m_colours[marking_location] = sanitize_hexcolor(m_colours[marking_location], DEFAULT_MARKING_COLOURS[marking_location])
|
||||
hacc_colour = sanitize_hexcolor(hacc_colour)
|
||||
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
|
||||
h_style = sanitize_inlist(h_style, hair_styles_public_list, initial(h_style))
|
||||
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
|
||||
for(var/marking_location in m_styles)
|
||||
m_styles[marking_location] = sanitize_inlist(m_styles[marking_location], marking_styles_list, DEFAULT_MARKING_STYLES[marking_location])
|
||||
|
||||
@@ -77,13 +77,18 @@
|
||||
/obj/item/clothing/gloves/color/black/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/weapon/wirecutters))
|
||||
if(can_be_cut && icon_state == initial(icon_state))//only if not dyed
|
||||
to_chat(user, "<span class='notice'>You snip the fingertips off of [src].</span>")
|
||||
playsound(user.loc, W.usesound, rand(10,50), 1)
|
||||
var/obj/item/clothing/gloves/fingerless/F = new/obj/item/clothing/gloves/fingerless(user.loc)
|
||||
if(pickpocket)
|
||||
F.pickpocket = 1
|
||||
qdel(src)
|
||||
return
|
||||
var/confirm = alert("Do you want to cut off the gloves fingertips? Warning: It might destroy their functionality.","Cut tips?","Yes","No")
|
||||
if(get_dist(user, src) > 1)
|
||||
to_chat(user, "You have moved too far away.")
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
to_chat(user, "<span class='notice'>You snip the fingertips off of [src].</span>")
|
||||
playsound(user.loc, W.usesound, rand(10,50), 1)
|
||||
var/obj/item/clothing/gloves/fingerless/F = new/obj/item/clothing/gloves/fingerless(user.loc)
|
||||
if(pickpocket)
|
||||
F.pickpocket = FALSE
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/gloves/color/orange
|
||||
|
||||
@@ -347,6 +347,12 @@
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom
|
||||
name = "eagle helmet"
|
||||
desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle."
|
||||
icon_state = "griffinhat"
|
||||
item_state = "griffinhat"
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/syndi
|
||||
name = "blood-red hardsuit"
|
||||
desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
|
||||
@@ -429,6 +435,14 @@
|
||||
name = "elite syndicate hardsuit (combat)"
|
||||
desc = "An elite version of the syndicate hardsuit, with improved armour and fire shielding. It is in combat mode. Property of Gorlex Marauders."
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/syndi/freedom
|
||||
name = "eagle suit"
|
||||
desc = "An advanced, light suit, fabricated from a mixture of synthetic feathers and space-resistant material. A gun holster appears to be integrated into the suit."
|
||||
icon_state = "freedom"
|
||||
item_state = "freedom"
|
||||
|
||||
|
||||
//Wizard hardsuit
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/wizard
|
||||
name = "gem-encrusted hardsuit helmet"
|
||||
|
||||
@@ -246,24 +246,3 @@
|
||||
species_fit = null
|
||||
sprite_sheets = null
|
||||
sprite_sheets_obj = null
|
||||
|
||||
/obj/item/clothing/head/helmet/space/freedom
|
||||
name = "eagle helmet"
|
||||
desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle."
|
||||
icon_state = "griffinhat"
|
||||
item_state = "griffinhat"
|
||||
armor = list(melee = 20, bullet = 40, laser = 30, energy = 25, bomb = 100, bio = 100, rad = 100)
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
unacidable = 1
|
||||
strip_delay = 130
|
||||
|
||||
/obj/item/clothing/suit/space/freedom
|
||||
name = "eagle suit"
|
||||
desc = "An advanced, light suit, fabricated from a mixture of synthetic feathers and space-resistant material. A gun holster appears to be integrated into the suit and the wings appear to be stuck in 'freedom' mode."
|
||||
icon_state = "freedom"
|
||||
item_state = "freedom"
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank)
|
||||
armor = list(melee = 20, bullet = 40, laser = 30, energy = 25, bomb = 100, bio = 100, rad = 100)
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
unacidable = 1
|
||||
strip_delay = 130
|
||||
|
||||
@@ -5,6 +5,18 @@
|
||||
item_color = "red"
|
||||
slot = "armband"
|
||||
|
||||
/obj/item/clothing/accessory/armband/sec
|
||||
name = "security armband"
|
||||
desc = "An armband, worn by the crew to display which department they're assigned to. This one is white and red."
|
||||
icon_state = "whitered"
|
||||
item_color = "whitered"
|
||||
|
||||
/obj/item/clothing/accessory/armband/yb
|
||||
name = "blue-yellow armband"
|
||||
desc = "A fancy blue and yellow armband!"
|
||||
icon_state = "solblue"
|
||||
item_color = "solblue"
|
||||
|
||||
/obj/item/clothing/accessory/armband/cargo
|
||||
name = "cargo armband"
|
||||
desc = "An armband, worn by the crew to display which department they're assigned to. This one is brown."
|
||||
|
||||
@@ -1195,6 +1195,26 @@
|
||||
return 1
|
||||
..()
|
||||
|
||||
/obj/item/fluff/zekemirror //phantasmicdream : Zeke Varloss
|
||||
name = "engraved hand mirror"
|
||||
desc = "A very classy hand mirror, with fancy detailing."
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "hand_mirror"
|
||||
attack_verb = list("smacked")
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
force = 0
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/fluff/zekemirror/attack_self(mob/user)
|
||||
var/mob/living/carbon/human/target = user
|
||||
if(!istype(target) || target.get_species() != "Skrell") // It'd be strange to see other races with head tendrils.
|
||||
return
|
||||
|
||||
if(target.change_hair("Zekes Tentacles", 1))
|
||||
to_chat(target, "<span class='notice'>You take time to admire yourself in [src], brushing your tendrils down and revealing their true length.</span>")
|
||||
|
||||
|
||||
/obj/item/clothing/accessory/necklace/locket/fluff/fethasnecklace //Fethas: Sefra'neem
|
||||
name = "Orange gemmed locket"
|
||||
desc = "A locket with a orange gem set on the front, the picture inside seems to be of a Tajaran."
|
||||
@@ -1212,4 +1232,4 @@
|
||||
righthand_file = 'icons/mob/inhands/fluff_righthand.dmi'
|
||||
icon_state = "sheetcosmos"
|
||||
item_state = "sheetcosmos"
|
||||
item_color = "sheetcosmos"
|
||||
item_color = "sheetcosmos"
|
||||
@@ -1,12 +1,10 @@
|
||||
/datum/event/alien_infestation
|
||||
announceWhen = 400
|
||||
var/spawncount = 1
|
||||
var/spawncount = 2
|
||||
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
|
||||
|
||||
/datum/event/alien_infestation/setup()
|
||||
announceWhen = rand(announceWhen, announceWhen + 50)
|
||||
if(prob(50))
|
||||
spawncount++
|
||||
|
||||
/datum/event/alien_infestation/announce()
|
||||
if(successSpawn)
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
var/list/gunk = list("water","carbon","flour","radium","toxin","cleaner","nutriment","condensedcapsaicin","psilocybin","lube",
|
||||
"atrazine","banana","charcoal","space_drugs","methamphetamine","holywater","ethanol","hot_coco","facid",
|
||||
"blood","morphine","ether","fluorine","mutadone","mutagen","hydrocodone","fuel",
|
||||
"haloperidol","lsd","nanites","lipolicide","frostoil","salglu_solution","beepskysmash",
|
||||
"omnizine", "amanitin", "adminordrazine", "neurotoxin", "synaptizine")
|
||||
"haloperidol","lsd","syndicate_nanites","lipolicide","frostoil","salglu_solution","beepskysmash",
|
||||
"omnizine", "amanitin", "neurotoxin", "synaptizine")
|
||||
var/datum/reagents/R = new/datum/reagents(50)
|
||||
R.my_atom = vent
|
||||
R.add_reagent(pick(gunk), 50)
|
||||
|
||||
@@ -286,7 +286,7 @@
|
||||
drink_container.desc = "[recipe_to_use.description]"
|
||||
flick("bottler_on", src)
|
||||
spawn(45)
|
||||
QDEL_LIST_ASSOC_VAL(slots)
|
||||
resetSlots()
|
||||
bottling = 0
|
||||
drink_container.forceMove(loc)
|
||||
updateUsrDialog()
|
||||
@@ -405,3 +405,7 @@
|
||||
icon_state = "bottler_on"
|
||||
else
|
||||
icon_state = "bottler_off"
|
||||
|
||||
/obj/machinery/bottler/proc/resetSlots()
|
||||
QDEL_LIST_ASSOC_VAL(slots)
|
||||
slots.len = 3
|
||||
@@ -71,8 +71,7 @@
|
||||
|
||||
var/datum/reagent/R = null
|
||||
if(random_reagent)
|
||||
R = pick(subtypesof(/datum/reagent))
|
||||
R = chemical_reagents_list[initial(R.id)]
|
||||
R = get_random_reagent_id()
|
||||
|
||||
queen_bee = new(src)
|
||||
queen_bee.beehome = src
|
||||
@@ -89,13 +88,12 @@
|
||||
B.beehome = src
|
||||
B.assign_reagent(R)
|
||||
|
||||
|
||||
/obj/structure/beebox/premade/random
|
||||
random_reagent = TRUE
|
||||
|
||||
|
||||
/obj/structure/beebox/process()
|
||||
if(queen_bee)
|
||||
if(queen_bee && (!queen_bee.beegent || !queen_bee.beegent.can_synth))
|
||||
if(bee_resources >= BEE_RESOURCE_HONEYCOMB_COST)
|
||||
if(honeycombs.len < get_max_honeycomb())
|
||||
bee_resources = max(bee_resources-BEE_RESOURCE_HONEYCOMB_COST, 0)
|
||||
@@ -172,11 +170,13 @@
|
||||
|
||||
var/obj/item/queen_bee/qb = I
|
||||
user.unEquip(qb)
|
||||
|
||||
qb.queen.forceMove(src)
|
||||
bees += qb.queen
|
||||
queen_bee = qb.queen
|
||||
qb.queen = null
|
||||
if(!qb.queen.beegent || (qb.queen.beegent && qb.queen.beegent.can_synth))
|
||||
qb.queen.forceMove(src)
|
||||
bees += qb.queen
|
||||
queen_bee = qb.queen
|
||||
qb.queen = null
|
||||
else
|
||||
visible_message("<span class='notice'>The [qb] refuses to settle down. Maybe it's something to do with its reagent?</span>")
|
||||
|
||||
if(queen_bee)
|
||||
visible_message("<span class='notice'>[user] sets [qb] down inside the apiary, making it their new home.</span>")
|
||||
|
||||
@@ -151,6 +151,7 @@ datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/livi
|
||||
|
||||
/obj/item/clothing/gloves/color/black/krav_maga
|
||||
var/datum/martial_art/krav_maga/style = new
|
||||
can_be_cut = FALSE
|
||||
|
||||
/obj/item/clothing/gloves/color/black/krav_maga/equipped(mob/user, slot)
|
||||
if(!ishuman(user))
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
var/leap_on_click = 0
|
||||
var/custom_pixel_x_offset = 0 //for admin fuckery.
|
||||
var/custom_pixel_y_offset = 0
|
||||
pressure_resistance = 100 //100 kPa difference required to push
|
||||
throw_pressure_limit = 120 //120 kPa difference required to throw
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/New()
|
||||
|
||||
@@ -149,7 +149,10 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
|
||||
else if(iscorgi(M))
|
||||
var/mob/living/simple_animal/pet/corgi/C = M
|
||||
loc = C
|
||||
if(C.facehugger)
|
||||
var/obj/item/F = C.facehugger
|
||||
F.forceMove(C.loc)
|
||||
forceMove(C)
|
||||
C.facehugger = src
|
||||
C.regenerate_icons()
|
||||
|
||||
@@ -161,7 +164,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
|
||||
if(!target || target.stat == DEAD) //was taken off or something
|
||||
if(!target || target.stat == DEAD || loc != target) //was taken off or something
|
||||
return
|
||||
|
||||
if(iscarbon(target))
|
||||
|
||||
@@ -727,23 +727,6 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
/mob/living/carbon/is_muzzled()
|
||||
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
|
||||
|
||||
/mob/living/carbon/proc/spin(spintime, speed)
|
||||
spawn()
|
||||
var/D = dir
|
||||
while(spintime >= speed)
|
||||
sleep(speed)
|
||||
switch(D)
|
||||
if(NORTH)
|
||||
D = EAST
|
||||
if(SOUTH)
|
||||
D = WEST
|
||||
if(EAST)
|
||||
D = SOUTH
|
||||
if(WEST)
|
||||
D = NORTH
|
||||
dir = D
|
||||
spintime -= speed
|
||||
|
||||
/mob/living/carbon/resist_buckle()
|
||||
spawn(0)
|
||||
resist_muzzle()
|
||||
@@ -1117,4 +1100,4 @@ so that different stomachs can handle things in different ways VB*/
|
||||
update_tint()
|
||||
if(I.flags_inv & HIDEMASK || forced)
|
||||
update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
update_inv_head()
|
||||
@@ -27,8 +27,8 @@
|
||||
var/toxins_alert = 0
|
||||
var/co2_alert = 0
|
||||
var/fire_alert = 0
|
||||
var/list/active_effect = list()
|
||||
|
||||
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
|
||||
var/co2overloadtime = null
|
||||
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
gender = new_gender
|
||||
|
||||
var/datum/sprite_accessory/hair/current_hair = hair_styles_list[H.h_style]
|
||||
var/datum/sprite_accessory/hair/current_hair = hair_styles_full_list[H.h_style]
|
||||
if(current_hair.gender != NEUTER && current_hair.gender != gender)
|
||||
reset_head_hair()
|
||||
|
||||
@@ -35,9 +35,12 @@
|
||||
update_body()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/change_hair(var/hair_style)
|
||||
/mob/living/carbon/human/proc/change_hair(var/hair_style, var/fluff)
|
||||
var/obj/item/organ/external/head/H = get_organ("head")
|
||||
if(!hair_style || !H || H.h_style == hair_style || !(hair_style in hair_styles_list))
|
||||
|
||||
if(!hair_style || !H || H.h_style == hair_style)
|
||||
return
|
||||
if(!(fluff || (hair_style in hair_styles_public_list)))
|
||||
return
|
||||
|
||||
H.h_style = hair_style
|
||||
@@ -339,8 +342,8 @@
|
||||
if(!H)
|
||||
return //No head, no hair.
|
||||
|
||||
for(var/hairstyle in hair_styles_list)
|
||||
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
|
||||
for(var/hairstyle in hair_styles_public_list)
|
||||
var/datum/sprite_accessory/S = hair_styles_public_list[hairstyle]
|
||||
|
||||
if(hairstyle == "Bald") //Just in case.
|
||||
valid_hairstyles += hairstyle
|
||||
|
||||
@@ -140,3 +140,4 @@ var/global/list/body_accessory_by_species = list("None" = null)
|
||||
icon_state = "vulptail6"
|
||||
animated_icon_state = "vulptail6_a"
|
||||
allowed_species = list("Vulpkanin")
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
on_CD = handle_emote_CD(50) //longer cooldown
|
||||
if("fart", "farts", "flip", "flips", "snap", "snaps")
|
||||
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
|
||||
if("cough", "coughs", "slap", "slaps")
|
||||
if("cough", "coughs", "slap", "slaps", "highfive")
|
||||
on_CD = handle_emote_CD()
|
||||
if("sneeze", "sneezes")
|
||||
on_CD = handle_emote_CD()
|
||||
@@ -821,10 +821,42 @@
|
||||
continue
|
||||
M.reagents.add_reagent("jenkem", 1)
|
||||
|
||||
if("hem")
|
||||
message = "<b>[src]</b> hems."
|
||||
|
||||
if("highfive")
|
||||
if(restrained())
|
||||
return
|
||||
if(EFFECT_HIGHFIVE in active_effect)
|
||||
to_chat(src, "You give up on the high-five.")
|
||||
active_effect -= EFFECT_HIGHFIVE
|
||||
return
|
||||
active_effect |= EFFECT_HIGHFIVE
|
||||
for(var/mob/living/carbon/C in orange(1))
|
||||
if(EFFECT_HIGHFIVE in C.active_effect)
|
||||
if((C.mind.special_role == SPECIAL_ROLE_WIZARD) && (mind.special_role == SPECIAL_ROLE_WIZARD))
|
||||
visible_message("<span class='danger'><b>[name]</b> and <b>[C.name]</b> high-five EPICALLY!</span>")
|
||||
status_flags |= GODMODE
|
||||
C.status_flags |= GODMODE
|
||||
explosion(loc,5,2,1,3)
|
||||
status_flags &= ~GODMODE
|
||||
C.status_flags &= ~GODMODE
|
||||
break
|
||||
visible_message("<b>[name]</b> and <b>[C.name]</b> high-five!")
|
||||
C.active_effect -= EFFECT_HIGHFIVE
|
||||
active_effect -= EFFECT_HIGHFIVE
|
||||
playsound('sound/effects/snap.ogg', 50)
|
||||
break
|
||||
if(EFFECT_HIGHFIVE in active_effect)
|
||||
visible_message("<b>[name]</b> requests a highfive.", "You request a highfive.")
|
||||
if(do_after(src, 25, target = src))
|
||||
visible_message("[name] was left hanging. Embarrassing.", "You are left hanging. How embarrassing!")
|
||||
active_effect -= EFFECT_HIGHFIVE
|
||||
|
||||
if("help")
|
||||
var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-(none)/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s),cry, cries, custom, dance, dap(s)(none)/mob," \
|
||||
+ " deathgasp(s), drool(s), eyebrow, fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-(none)/mob, grin(s), groan(s), grumble(s), grin(s)," \
|
||||
+ " handshake-mob, hug(s)-(none)/mob, johnny, jump, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \
|
||||
+ " handshake-mob, hug(s)-(none)/mob, hem, highfive, johnny, jump, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \
|
||||
+ " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-(none)/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-(none)/mob, swag(s), tremble(s), twitch(es), twitch(es)_s," \
|
||||
+ " wag(s), wave(s), whimper(s), wink(s), yawn(s)"
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
QDEL_LIST(bodyparts)
|
||||
splinted_limbs.Cut()
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/dummy
|
||||
@@ -796,7 +797,7 @@
|
||||
if(href_list["criminal"])
|
||||
if(hasHUD(usr,"security"))
|
||||
|
||||
var/modified = 0
|
||||
var/found_record = 0
|
||||
var/perpname = "wot"
|
||||
if(wear_id)
|
||||
var/obj/item/weapon/card/id/I = wear_id.GetID()
|
||||
@@ -814,16 +815,33 @@
|
||||
if(R.fields["id"] == E.fields["id"])
|
||||
|
||||
var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Released", "Cancel")
|
||||
var/t1 = copytext(trim(sanitize(input("Enter Reason:", "Security HUD", null, null) as text)), 1, MAX_MESSAGE_LEN)
|
||||
if(!t1)
|
||||
t1 = "(none)"
|
||||
|
||||
if(hasHUD(usr, "security") && setcriminal != "Cancel")
|
||||
found_record = 1
|
||||
var/their_name = R.fields["name"]
|
||||
var/their_rank = R.fields["rank"]
|
||||
if(R.fields["criminal"] == "*Execute*")
|
||||
to_chat(usr, "<span class='warning'>Unable to modify the sec status of a person with an active Execution order. Use a security computer instead.</span>")
|
||||
else
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/U = usr
|
||||
R.fields["comments"] += "Set to [setcriminal] by [U.get_authentification_name()] ([U.get_assignment()]) on [current_date_string] [worldtime2text()] with comment: [t1]<BR>"
|
||||
if(isrobot(usr))
|
||||
var/mob/living/silicon/robot/U = usr
|
||||
R.fields["comments"] += "Set to [setcriminal] by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [worldtime2text()] with comment: [t1]<BR>"
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
R.fields["comments"] += "Set to [setcriminal] by [U.name] (artificial intelligence) on [current_date_string] [worldtime2text()] with comment: [t1]<BR>"
|
||||
|
||||
if(hasHUD(usr, "security"))
|
||||
if(setcriminal != "Cancel")
|
||||
R.fields["criminal"] = setcriminal
|
||||
modified = 1
|
||||
|
||||
log_admin("[key_name_admin(usr)] set secstatus of [their_rank] [their_name] to [setcriminal], comment: [t1]")
|
||||
spawn()
|
||||
sec_hud_set_security_status()
|
||||
|
||||
if(!modified)
|
||||
if(!found_record)
|
||||
to_chat(usr, "<span class='warning'>Unable to locate a data core entry for this person.</span>")
|
||||
|
||||
if(href_list["secrecord"])
|
||||
@@ -1590,8 +1608,8 @@
|
||||
|
||||
else if(robohead.is_monitor) //Means that the character's head is a monitor (has a screen). Time to customize.
|
||||
var/list/hair = list()
|
||||
for(var/i in hair_styles_list)
|
||||
var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i]
|
||||
for(var/i in hair_styles_public_list)
|
||||
var/datum/sprite_accessory/hair/tmp_hair = hair_styles_public_list[i]
|
||||
if((head_organ.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use.
|
||||
hair += i
|
||||
|
||||
@@ -1761,6 +1779,8 @@
|
||||
var/datum/data/record/R = find_record("name", perpname, data_core.security)
|
||||
if(R && R.fields["criminal"])
|
||||
switch(R.fields["criminal"])
|
||||
if("*Execute*")
|
||||
threatcount += 7
|
||||
if("*Arrest*")
|
||||
threatcount += 5
|
||||
if("Incarcerated")
|
||||
|
||||
@@ -72,3 +72,5 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
|
||||
var/datum/body_accessory/body_accessory = null
|
||||
var/tail // Name of tail image in species effects icon file.
|
||||
|
||||
var/list/splinted_limbs = list() //limbs we know are splinted
|
||||
|
||||
@@ -36,40 +36,45 @@
|
||||
/mob/living/carbon/human/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(.) // did we actually move?
|
||||
if(!lying && !buckled)
|
||||
var/obj/item/clothing/shoes/S = shoes
|
||||
if(!has_gravity(loc))
|
||||
return
|
||||
//Bloody footprints
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/organ/external/l_foot = get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = get_organ("r_foot")
|
||||
var/hasfeet = 1
|
||||
if(!l_foot && !r_foot)
|
||||
hasfeet = 0
|
||||
if(!lying && !buckled && !throwing)
|
||||
for(var/obj/item/organ/external/splinted in splinted_limbs)
|
||||
splinted.update_splints()
|
||||
|
||||
if(!has_gravity(loc))
|
||||
return
|
||||
|
||||
var/obj/item/clothing/shoes/S = shoes
|
||||
|
||||
//Bloody footprints
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/organ/external/l_foot = get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = get_organ("r_foot")
|
||||
var/hasfeet = TRUE
|
||||
if(!l_foot && !r_foot)
|
||||
hasfeet = FALSE
|
||||
|
||||
if(shoes)
|
||||
if(S.bloody_shoes && S.bloody_shoes[S.blood_state])
|
||||
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
|
||||
if(oldFP && oldFP.blood_state == S.blood_state && oldFP.basecolor == S.blood_color)
|
||||
return
|
||||
else
|
||||
//No oldFP or it's a different kind of blood
|
||||
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
|
||||
createFootprintsFrom(shoes, dir, T)
|
||||
update_inv_shoes()
|
||||
else if(hasfeet)
|
||||
if(bloody_feet && bloody_feet[blood_state])
|
||||
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
|
||||
if(oldFP && oldFP.blood_state == blood_state && oldFP.basecolor == feet_blood_color)
|
||||
return
|
||||
else
|
||||
bloody_feet[blood_state] = max(0, bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP)
|
||||
createFootprintsFrom(src, dir, T)
|
||||
update_inv_shoes()
|
||||
//End bloody footprints
|
||||
if(S)
|
||||
S.step_action(src)
|
||||
if(shoes)
|
||||
if(S.bloody_shoes && S.bloody_shoes[S.blood_state])
|
||||
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
|
||||
if(oldFP && oldFP.blood_state == S.blood_state && oldFP.basecolor == S.blood_color)
|
||||
return
|
||||
else
|
||||
//No oldFP or it's a different kind of blood
|
||||
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
|
||||
createFootprintsFrom(shoes, dir, T)
|
||||
update_inv_shoes()
|
||||
else if(hasfeet)
|
||||
if(bloody_feet && bloody_feet[blood_state])
|
||||
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
|
||||
if(oldFP && oldFP.blood_state == blood_state && oldFP.basecolor == feet_blood_color)
|
||||
return
|
||||
else
|
||||
bloody_feet[blood_state] = max(0, bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP)
|
||||
createFootprintsFrom(src, dir, T)
|
||||
update_inv_shoes()
|
||||
//End bloody footprints
|
||||
if(S)
|
||||
S.step_action(src)
|
||||
|
||||
/mob/living/carbon/human/handle_footstep(turf/T)
|
||||
if(..())
|
||||
|
||||
@@ -182,3 +182,9 @@ I use this to standardize shadowling dethrall code
|
||||
odmg += O.brute_dam
|
||||
odmg += O.burn_dam
|
||||
return (health < (100 - odmg))
|
||||
|
||||
/mob/living/carbon/human/proc/handle_splints() //proc that rebuilds the list of splints on this person, for ease of processing
|
||||
splinted_limbs.Cut()
|
||||
for(var/obj/item/organ/external/limb in bodyparts)
|
||||
if(limb.status & ORGAN_SPLINTED)
|
||||
splinted_limbs += limb
|
||||
@@ -94,32 +94,49 @@
|
||||
if(getBrainLoss() >= 60 && stat != DEAD)
|
||||
speech_problem_flag = 1
|
||||
if(prob(3))
|
||||
var/list/s1 = list("IM A PONY NEEEEEEIIIIIIIIIGH",
|
||||
var/list/s1 = list("IM A [pick("PONY","LIZARD","taJaran","kitty","Vulpakin","drASK","BIRDIE","voxxie","race car","combat meCH","SPESSSHIP")] [pick("NEEEEEEIIIIIIIIIGH","sKREEEEEE","MEOW","NYA~","rawr","Barkbark","Hissssss","vROOOOOM","pewpew","choo Choo")]!",
|
||||
"without oxigen blob don't evoluate?",
|
||||
"CAPTAINS A COMDOM",
|
||||
"[pick("", "that damn traitor")] [pick("joerge", "george", "gorge", "gdoruge")] [pick("mellens", "melons", "mwrlins")] is grifing me HAL;P!!!",
|
||||
"can u give me [pick("telikesis","halk","eppilapse")]?",
|
||||
"THe saiyans screwed",
|
||||
"Bi is THE BEST OF BOTH WORLDS>",
|
||||
"Bi is THE BEST OF BOTH WORLDS",
|
||||
"I WANNA PET TEH monkeyS",
|
||||
"stop grifing me!!!!",
|
||||
"SOTP IT#")
|
||||
"SOTP IT!",
|
||||
"HALPZ SITCULITY",
|
||||
"VOXES caN't LOVE",
|
||||
"my dad own this station",
|
||||
"the CHef put [pick("PROTEIN", "toiret waTer", "RiPPleing TendIes", "Einzymes","HORRY WALTER","nuTriments","ReActive MutAngen","TeSLium","sKrektonium")] in my [pick("wiSh soup","Bullito","rAingurber","sOilent GREEn","KoI Susishes","yaya")]!",
|
||||
"the monkey have TASER ARMS!",
|
||||
"qM blew my points on [pick("cOMbat Shtogun","inSuLated gloves","LOTS MASSHEEN!")]",
|
||||
"EI'NATH!",
|
||||
"WAKE UP SHEEPLES!",
|
||||
"et wus my [pick("wittle brother!!","fiancee","friend staying over","entiRe orphanage","love interest","wife","husband","liTTle kids","sentient cAT","accidentally")]!")
|
||||
|
||||
var/list/s2 = list("FUS RO DAH",
|
||||
"fucking 4rries!",
|
||||
"fuckin tangerines!!!",
|
||||
"stat me",
|
||||
">my face",
|
||||
"roll it easy!",
|
||||
"waaaaaagh!!!",
|
||||
"red wonz go fasta",
|
||||
"FOR TEH EMPRAH",
|
||||
"lol2cat",
|
||||
"HAZ A SECURE DAY!!!!",
|
||||
"dem dwarfs man, dem dwarfs",
|
||||
"SPESS MAHREENS",
|
||||
"hwee did eet fhor khayosss",
|
||||
"lifelike texture ;_;",
|
||||
"lifelike texture",
|
||||
"luv can bloooom",
|
||||
"PACKETS!!!")
|
||||
"PACKETS!!!",
|
||||
"[pick("WHERE MY","aYE need","giv me my","bath me inn.")] [pick("dermaline","alKkyZine","dylOvene","inAprovaline","biCaridine","Hyperzine","kELotane","lePorazine","bAcch Salts","tricord","clOnexazone","hydroChloric Acid","chlorine Hydrate","paRoxetine")]!",
|
||||
"mALPRACTICEBAY",
|
||||
"I HavE A pe H dee iN ENTerpriSE resOUrCE pLaNNIN",
|
||||
"h-h-HalP MaINT",
|
||||
"dey come, dey COME! DEY COME!!!",
|
||||
"THE END IS NIGH!",
|
||||
"I FOT AND DIED FOR MUH [pick("RITES","FREEDOM","payCHECK","cARGO points","teCH Level","doG","mAPLe syrup","fluffy fWiends","gateway Loot")]",
|
||||
"KILL DEM [pick("mainTnacE cHickinNS","kiRA CulwnNES","FLOOR CLUWNEs","MIME ASSASSIN","BOMBING TAJARAN","cC offiser","morPhlings","slinglings")]!")
|
||||
switch(pick(1,2,3))
|
||||
if(1)
|
||||
say(pick(s1))
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
node.remove(H)
|
||||
node.loc = M.loc
|
||||
to_chat(M, "<span class='notice'>You hear a loud crunch as you mercilessly pull off [H]'s antennae.</span>")
|
||||
to_chat(H, "<span class='danger'><B>You hear a loud crunch as your antennae is ripped off your head by [M].</span></B>")
|
||||
to_chat(H, "<span class='danger'>You hear a loud crunch as your antennae is ripped off your head by [M].</span>")
|
||||
to_chat(H, "<span class='danger'><span class='danger'><B>It's so quiet...</B></span>")
|
||||
head_organ.h_style = "Bald"
|
||||
H.update_hair()
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
if(L.brute_dam < L.min_broken_damage)
|
||||
L.status &= ~ORGAN_BROKEN
|
||||
L.status &= ~ORGAN_SPLINTED
|
||||
H.handle_splints()
|
||||
L.perma_injury = 0
|
||||
break // We're only checking one limb here, bucko
|
||||
if(prob(3))
|
||||
|
||||
@@ -442,7 +442,7 @@ var/global/list/damage_icon_parts = list()
|
||||
//var/icon/debrained_s = new /icon("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s")
|
||||
|
||||
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
|
||||
var/datum/sprite_accessory/hair/hair_style = hair_styles_list[head_organ.h_style]
|
||||
var/datum/sprite_accessory/hair/hair_style = hair_styles_full_list[head_organ.h_style]
|
||||
//if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN
|
||||
// hair_standing.Blend(debrained_s, ICON_OVERLAY)
|
||||
if(hair_style && hair_style.species_allowed)
|
||||
@@ -759,7 +759,7 @@ var/global/list/damage_icon_parts = list()
|
||||
else
|
||||
new_glasses = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]")
|
||||
|
||||
var/datum/sprite_accessory/hair/hair_style = hair_styles_list[head_organ.h_style]
|
||||
var/datum/sprite_accessory/hair/hair_style = hair_styles_full_list[head_organ.h_style]
|
||||
if(hair_style && hair_style.glasses_over) //Select which layer to use based on the properties of the hair style. Hair styles with hair that don't overhang the arms of the glasses should have glasses_over set to a positive value.
|
||||
overlays_standing[GLASSES_OVER_LAYER] = new_glasses
|
||||
else
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/mob/living/death(gibbed)
|
||||
blinded = max(blinded, 1)
|
||||
|
||||
if(suiciding)
|
||||
mind.suicided = TRUE
|
||||
|
||||
clear_fullscreens()
|
||||
update_action_buttons_icon()
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ var/list/department_radio_keys = list(
|
||||
":U" = "Supply", "#U" = "Supply", ".U" = "Supply",
|
||||
":Z" = "Service", "#Z" = "Service", ".Z" = "Service",
|
||||
":P" = "AI Private", "#P" = "AI Private", ".P" = "AI Private",
|
||||
":$" = "Response Team", "#$" = "Response Team", ".$" = "Response Team",
|
||||
":-" = "Special Ops", "#-" = "Special Ops", ".-" = "Special Ops",
|
||||
":_" = "SyndTeam", "#_" = "SyndTeam", "._" = "SyndTeam",
|
||||
":X" = "cords", "#X" = "cords", ".X" = "cords"
|
||||
|
||||
@@ -68,6 +68,7 @@ var/list/robot_verbs_default = list(
|
||||
var/lockcharge //Used when locking down a borg to preserve cell charge
|
||||
var/speed = 0 //Cause sec borgs gotta go fast //No they dont!
|
||||
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
|
||||
var/pdahide = 0 //Used to hide the borg from the messenger list
|
||||
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
|
||||
var/braintype = "Cyborg"
|
||||
var/base_icon = ""
|
||||
@@ -193,6 +194,7 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/get_default_name(var/prefix as text)
|
||||
if(prefix)
|
||||
modtype = prefix
|
||||
@@ -226,10 +228,12 @@ var/list/robot_verbs_default = list(
|
||||
if(!rbPDA)
|
||||
rbPDA = new(src)
|
||||
rbPDA.set_name_and_job(real_name, braintype)
|
||||
if(scrambledcodes)
|
||||
var/datum/data/pda/app/messenger/M = rbPDA.find_program(/datum/data/pda/app/messenger)
|
||||
if(M)
|
||||
var/datum/data/pda/app/messenger/M = rbPDA.find_program(/datum/data/pda/app/messenger)
|
||||
if(M)
|
||||
if(scrambledcodes)
|
||||
M.hidden = 1
|
||||
if(pdahide)
|
||||
M.toff = 1
|
||||
|
||||
/mob/living/silicon/robot/binarycheck()
|
||||
if(is_component_functioning("comms"))
|
||||
@@ -390,7 +394,7 @@ var/list/robot_verbs_default = list(
|
||||
module.add_subsystems_and_actions(src)
|
||||
|
||||
//Custom_sprite check and entry
|
||||
if(custom_sprite == 1)
|
||||
if(custom_sprite && check_sprite("[ckey]-[modtype]"))
|
||||
module_sprites["Custom"] = "[src.ckey]-[modtype]"
|
||||
|
||||
hands.icon_state = lowertext(module.module_type)
|
||||
@@ -489,7 +493,7 @@ var/list/robot_verbs_default = list(
|
||||
toggle_ionpulse()
|
||||
return
|
||||
|
||||
cell.charge -= 50 // 500 steps on a default cell.
|
||||
cell.charge -= 25 // 500 steps on a default cell.
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/robot/proc/toggle_ionpulse()
|
||||
@@ -1332,11 +1336,13 @@ var/list/robot_verbs_default = list(
|
||||
icon_state = "nano_bloodhound"
|
||||
lawupdate = 0
|
||||
scrambledcodes = 1
|
||||
pdahide = 1
|
||||
modtype = "Commando"
|
||||
faction = list("nanotrasen")
|
||||
designation = "Nanotrasen Combat"
|
||||
req_access = list(access_cent_specops)
|
||||
ionpulse = 1
|
||||
magpulse = 1
|
||||
var/searching_for_ckey = 0
|
||||
|
||||
/mob/living/silicon/robot/deathsquad/New(loc)
|
||||
@@ -1380,11 +1386,13 @@ var/list/robot_verbs_default = list(
|
||||
icon_state = "syndie_bloodhound"
|
||||
lawupdate = 0
|
||||
scrambledcodes = 1
|
||||
pdahide = 1
|
||||
faction = list("syndicate")
|
||||
designation = "Syndicate Assault"
|
||||
modtype = "Syndicate"
|
||||
req_access = list(access_syndicate)
|
||||
ionpulse = 1
|
||||
magpulse = 1
|
||||
lawchannel = "State"
|
||||
var/playstyle_string = "<span class='userdanger'>You are a Syndicate assault cyborg!</span><br>\
|
||||
<b>You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
|
||||
@@ -1446,6 +1454,24 @@ var/list/robot_verbs_default = list(
|
||||
radio.config(module.channels)
|
||||
notify_ai(2)
|
||||
|
||||
/mob/living/silicon/robot/ert
|
||||
designation = "ERT"
|
||||
lawupdate = 0
|
||||
scrambledcodes = 1
|
||||
req_access = list(access_cent_specops)
|
||||
ionpulse = 1
|
||||
|
||||
/mob/living/silicon/robot/ert/init()
|
||||
laws = new /datum/ai_laws/ert_override
|
||||
radio = new /obj/item/device/radio/borg/ert(src)
|
||||
radio.recalculateChannels()
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
|
||||
|
||||
/mob/living/silicon/robot/ert/New(loc)
|
||||
..()
|
||||
cell.maxcharge = 25000
|
||||
cell.charge = 25000
|
||||
|
||||
/mob/living/silicon/robot/nations
|
||||
base_icon = "droidpeace"
|
||||
icon_state = "droidpeace"
|
||||
@@ -1483,3 +1509,10 @@ var/list/robot_verbs_default = list(
|
||||
borked_part.wrapped = new borked_part.external_type
|
||||
borked_part.heal_damage(brute,burn)
|
||||
borked_part.install()
|
||||
|
||||
/mob/living/silicon/robot/proc/check_sprite(spritename)
|
||||
. = FALSE
|
||||
|
||||
var/static/all_borg_icon_states = icon_states('icons/mob/custom_synthetic/custom-synthetic.dmi')
|
||||
if(spritename in all_borg_icon_states)
|
||||
. = TRUE
|
||||
|
||||
@@ -681,11 +681,12 @@
|
||||
if(istype(M,/mob/living/silicon/robot))
|
||||
visible_message("<span class='danger'>[src] bumps into [M]!</span>")
|
||||
else
|
||||
add_logs(src, M, "knocked down")
|
||||
visible_message("<span class='danger'>[src] knocks over [M]!</span>")
|
||||
M.stop_pulling()
|
||||
M.Stun(8)
|
||||
M.Weaken(5)
|
||||
if(!paicard)
|
||||
add_logs(src, M, "knocked down")
|
||||
visible_message("<span class='danger'>[src] knocks over [M]!</span>")
|
||||
M.stop_pulling()
|
||||
M.Stun(8)
|
||||
M.Weaken(5)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/RunOver(mob/living/carbon/human/H)
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
if(can_collar)
|
||||
dat += "<tr><td> </td></tr>"
|
||||
dat += "<tr><td><B>Collar:</B></td><td><A href='?src=[UID()];item=[slot_collar]'>[(collar && !(collar.flags&ABSTRACT)) ? collar : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(facehugger)
|
||||
dat += "<tr><td><B>Facehugger:</B></td><td><A href='?src=[UID()];remove_hugger=1'>[facehugger]</A></td></tr>"
|
||||
dat += {"</table>
|
||||
<A href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
@@ -103,11 +104,10 @@
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/Topic(href, href_list)
|
||||
if(usr.stat) return
|
||||
|
||||
if((!ishuman(usr) && !isrobot(usr)) || !Adjacent(usr))
|
||||
return
|
||||
//Removing from inventory
|
||||
if(href_list["remove_inv"])
|
||||
if(!Adjacent(usr) || !(ishuman(usr) || isrobot(usr) || isalienadult(usr)))
|
||||
return
|
||||
var/remove_from = href_list["remove_inv"]
|
||||
switch(remove_from)
|
||||
if("head")
|
||||
@@ -143,14 +143,9 @@
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>There is nothing to remove from its [remove_from].</span>")
|
||||
return
|
||||
|
||||
show_inv(usr)
|
||||
|
||||
//Adding things to inventory
|
||||
else if(href_list["add_inv"])
|
||||
if(!Adjacent(usr) || !(ishuman(usr) || isrobot(usr) || isalienadult(usr)))
|
||||
return
|
||||
|
||||
var/add_to = href_list["add_inv"]
|
||||
|
||||
switch(add_to)
|
||||
@@ -201,7 +196,16 @@
|
||||
item_to_add.loc = src
|
||||
src.inventory_back = item_to_add
|
||||
regenerate_icons()
|
||||
|
||||
show_inv(usr)
|
||||
//Removing facehuggers
|
||||
else if(href_list["remove_hugger"])
|
||||
if(!facehugger)
|
||||
return
|
||||
var/obj/item/F = facehugger
|
||||
F.forceMove(loc)
|
||||
facehugger = null
|
||||
to_chat(usr, "<span class='notice'>You remove [F] from [src]'s face. [src] pants for air and barks.</span>")
|
||||
regenerate_icons()
|
||||
show_inv(usr)
|
||||
else
|
||||
..()
|
||||
@@ -462,10 +466,7 @@
|
||||
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("dances around.","chases its tail!"))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
spin(20, 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
|
||||
name = "Corgi meat"
|
||||
@@ -550,10 +551,7 @@
|
||||
if(!resting && !buckled)
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("dances around.","chases her tail."))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
spin(20, 1)
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
|
||||
@@ -6,6 +6,4 @@
|
||||
for(var/mob/O in oviewers(src, null))
|
||||
if((O.client && !( O.blinded )))
|
||||
to_chat(O, text("[] [pick("dances around","chases its tail")].", src))
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
spin(20, 1)
|
||||
@@ -23,6 +23,8 @@
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 15
|
||||
heat_damage_per_tick = 20
|
||||
pressure_resistance = 100 //100 kPa difference required to push
|
||||
throw_pressure_limit = 120 //120 kPa difference required to throw
|
||||
faction = list("alien")
|
||||
status_flags = CANPUSH
|
||||
minbodytemp = 0
|
||||
|
||||
@@ -127,9 +127,6 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
|
||||
//Botany Worker Bees
|
||||
/mob/living/simple_animal/hostile/poison/bees/worker
|
||||
//Blank type define in case we need to give them special stuff later, plus organization (currently they are same as base type bee)
|
||||
@@ -253,6 +250,9 @@
|
||||
if(S.reagents.has_reagent("royal_bee_jelly")) //checked twice, because I really don't want royal bee jelly to be duped
|
||||
if(S.reagents.has_reagent("royal_bee_jelly",5))
|
||||
S.reagents.remove_reagent("royal_bee_jelly", 5)
|
||||
if(!queen.beegent.can_synth)
|
||||
to_chat(user, "<span class='warning'>You inject [src] with the royal bee jelly. It's ineffective! Maybe it's something to do with the [src] reagent.</span>")
|
||||
return
|
||||
var/obj/item/queen_bee/qb = new(get_turf(user))
|
||||
qb.queen = new(qb)
|
||||
if(queen && queen.beegent)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
humanize_prompt += " Role: [spider_role_summary]"
|
||||
if(user.ckey in ts_ckey_blacklist)
|
||||
error_on_humanize = "You are not able to control any terror spider this round."
|
||||
else if(user.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
|
||||
error_on_humanize = "You have enabled antag HUD and are unable to re-enter the round."
|
||||
else if(spider_awaymission)
|
||||
error_on_humanize = "Terror spiders that are part of an away mission cannot be controlled by ghosts."
|
||||
else if(!ai_playercontrol_allowtype)
|
||||
|
||||
@@ -38,6 +38,8 @@ var/global/list/ts_spiderling_list = list()
|
||||
// Movement
|
||||
move_to_delay = 6
|
||||
turns_per_move = 5
|
||||
pressure_resistance = 50 //50 kPa difference required to push
|
||||
throw_pressure_limit = 100 //100 kPa difference required to throw
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
// Ventcrawling
|
||||
|
||||
+18
-1
@@ -1264,4 +1264,21 @@ var/list/slot_equipment_priority = list( \
|
||||
.["Add Verb"] = "?_src_=vars;addverb=[UID()]"
|
||||
.["Remove Verb"] = "?_src_=vars;remverb=[UID()]"
|
||||
|
||||
.["Gib"] = "?_src_=vars;gib=[UID()]"
|
||||
.["Gib"] = "?_src_=vars;gib=[UID()]"
|
||||
|
||||
/mob/proc/spin(spintime, speed)
|
||||
set waitfor = 0
|
||||
var/D = dir
|
||||
while(spintime >= speed)
|
||||
sleep(speed)
|
||||
switch(D)
|
||||
if(NORTH)
|
||||
D = EAST
|
||||
if(SOUTH)
|
||||
D = WEST
|
||||
if(EAST)
|
||||
D = SOUTH
|
||||
if(WEST)
|
||||
D = NORTH
|
||||
setDir(D)
|
||||
spintime -= speed
|
||||
@@ -341,7 +341,7 @@
|
||||
face_s.Blend(eyes_s, ICON_OVERLAY)
|
||||
|
||||
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_full_list[h_style]
|
||||
if(hair_style)
|
||||
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
if(current_species.name == "Slime People") // whee I am part of the problem
|
||||
|
||||
@@ -17,16 +17,21 @@
|
||||
conversion in savefile.dm
|
||||
*/
|
||||
|
||||
/proc/init_sprite_accessory_subtypes(var/prototype, var/list/L, var/list/male, var/list/female)
|
||||
/proc/init_sprite_accessory_subtypes(var/prototype, var/list/L, var/list/male, var/list/female, var/list/full_list)
|
||||
if(!istype(L)) L = list()
|
||||
if(!istype(male)) male = list()
|
||||
if(!istype(female)) female = list()
|
||||
if(!istype(full_list)) full_list = list()
|
||||
|
||||
for(var/path in subtypesof(prototype))
|
||||
var/datum/sprite_accessory/D = new path()
|
||||
|
||||
if(D.name)
|
||||
L[D.name] = D
|
||||
if(D.fluff)
|
||||
full_list[D.name] = D
|
||||
else
|
||||
L[D.name] = D
|
||||
full_list[D.name] = D
|
||||
|
||||
switch(D.gender)
|
||||
if(MALE) male[D.name] = D
|
||||
@@ -50,7 +55,7 @@
|
||||
var/marking_location //Specifies which bodypart a body marking is located on.
|
||||
var/secondary_theme = null //If exists, there's a secondary colour to that hair style and the secondary theme's icon state's suffix is equal to this.
|
||||
var/no_sec_colour = null //If exists, prohibit the colouration of the secondary theme.
|
||||
|
||||
var/fluff = 0
|
||||
// Whether or not the accessory can be affected by colouration
|
||||
var/do_colouration = 1
|
||||
|
||||
@@ -65,7 +70,7 @@
|
||||
|
||||
/datum/sprite_accessory/hair
|
||||
icon = 'icons/mob/human_face.dmi' // default icon for all hairs
|
||||
var/glasses_over //Hair styles with hair that don't overhang the arms of glasses should have glasses_over set to a positive value.
|
||||
var/glasses_over //Hair styles with hair that don't overhang the arms of glasses should have glasses_over set to a positive value
|
||||
|
||||
/datum/sprite_accessory/hair/bald
|
||||
name = "Bald"
|
||||
@@ -566,7 +571,7 @@
|
||||
name = "Unathi Side Frills"
|
||||
icon_state = "unathi_sidefrills"
|
||||
secondary_theme = "webbing"
|
||||
|
||||
|
||||
/datum/sprite_accessory/hair/unathi/una_cobra_hood
|
||||
icon = 'icons/mob/human_face.dmi'
|
||||
name = "Unathi Cobra Hood"
|
||||
@@ -742,6 +747,8 @@
|
||||
icon_state = "hair_fingerwave"
|
||||
glasses_over = null
|
||||
|
||||
|
||||
|
||||
/datum/sprite_accessory/hair/vulpkanin
|
||||
species_allowed = list("Vulpkanin")
|
||||
|
||||
@@ -927,6 +934,15 @@
|
||||
icon_state = "nuc_neutron"
|
||||
|
||||
|
||||
|
||||
/datum/sprite_accessory/hair/fluff
|
||||
fluff = 1
|
||||
|
||||
/datum/sprite_accessory/hair/fluff/zeke_fluff_tentacle //Zeke Fluff hair
|
||||
name = "Zekes Tentacles"
|
||||
icon_state = "zeke_fluff_hair"
|
||||
species_allowed = list("Skrell")
|
||||
|
||||
/*
|
||||
///////////////////////////////////
|
||||
/ =---------------------------= /
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/datum/nano_module/ert_manager
|
||||
name = "ERT Manager"
|
||||
var/ert_type = "Code Red"
|
||||
var/commander_slots = 1
|
||||
var/security_slots = 3
|
||||
var/medical_slots = 3
|
||||
var/engineering_slots = 3
|
||||
var/janitor_slots = 0
|
||||
var/paranormal_slots = 0
|
||||
var/cyborg_slots = 0
|
||||
var/autoclose = 0
|
||||
|
||||
|
||||
/datum/nano_module/ert_manager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(ui && autoclose)
|
||||
ui.close()
|
||||
return 0
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ert_config.tmpl", "ERT Panel", 600, 600, state = state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/nano_module/ert_manager/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["set_code"])
|
||||
ert_type = href_list["set_code"]
|
||||
|
||||
if(href_list["set_com"])
|
||||
commander_slots = text2num(href_list["set_com"])
|
||||
|
||||
if(href_list["set_sec"])
|
||||
security_slots = text2num(href_list["set_sec"])
|
||||
|
||||
if(href_list["set_med"])
|
||||
medical_slots = text2num(href_list["set_med"])
|
||||
|
||||
if(href_list["set_eng"])
|
||||
engineering_slots = text2num(href_list["set_eng"])
|
||||
|
||||
if(href_list["set_jan"])
|
||||
janitor_slots = text2num(href_list["set_jan"])
|
||||
|
||||
if(href_list["set_par"])
|
||||
paranormal_slots = text2num(href_list["set_par"])
|
||||
|
||||
if(href_list["set_cyb"])
|
||||
cyborg_slots = text2num(href_list["set_cyb"])
|
||||
|
||||
if(href_list["dispatch_ert"])
|
||||
ert_request_answered = 1
|
||||
var/slots_list = list()
|
||||
if(commander_slots > 0)
|
||||
slots_list += "commander: [commander_slots]"
|
||||
if(security_slots > 0)
|
||||
slots_list += "security: [security_slots]"
|
||||
if(medical_slots > 0)
|
||||
slots_list += "medical: [medical_slots]"
|
||||
if(engineering_slots > 0)
|
||||
slots_list += "engineering: [engineering_slots]"
|
||||
if(janitor_slots > 0)
|
||||
slots_list += "janitor: [janitor_slots]"
|
||||
if(paranormal_slots > 0)
|
||||
slots_list += "paranormal: [paranormal_slots]"
|
||||
if(cyborg_slots > 0)
|
||||
slots_list += "cyborg: [cyborg_slots]"
|
||||
var slot_text = list_implode(slots_list, ", ")
|
||||
notify_ghosts("An ERT is being dispatched. Open positions: [slot_text]")
|
||||
message_admins("[key_name_admin(usr)] dispatched a [ert_type] ERT. Slots: [slot_text]", 1)
|
||||
log_admin("[key_name(usr)] dispatched a [ert_type] ERT. Slots: [slot_text]")
|
||||
autoclose = 1
|
||||
ui_interact(usr)
|
||||
trigger_armed_response_team(convert_ert_string(ert_type), commander_slots, security_slots, medical_slots, engineering_slots, janitor_slots, paranormal_slots, cyborg_slots)
|
||||
return 0
|
||||
|
||||
ui_interact(usr)
|
||||
|
||||
|
||||
/proc/convert_ert_string(thestring)
|
||||
switch(thestring)
|
||||
if("Code Amber")
|
||||
return new /datum/response_team/amber
|
||||
if("Code Red")
|
||||
return new /datum/response_team/red
|
||||
if("Code Gamma")
|
||||
return new /datum/response_team/gamma
|
||||
|
||||
|
||||
/datum/nano_module/ert_manager/ui_data()
|
||||
var/data[0]
|
||||
data["alert_level"] = get_security_level()
|
||||
data["ert_type"] = ert_type
|
||||
data["com"] = commander_slots
|
||||
data["sec"] = security_slots
|
||||
data["med"] = medical_slots
|
||||
data["eng"] = engineering_slots
|
||||
data["jan"] = janitor_slots
|
||||
data["par"] = paranormal_slots
|
||||
data["cyb"] = cyborg_slots
|
||||
|
||||
return data
|
||||
|
||||
@@ -111,8 +111,6 @@ nanoui is used to open and update nano browser uis
|
||||
|
||||
// CodeMirror
|
||||
add_script("codemirror-compressed.js") // A custom minified JavaScript file of CodeMirror, with the following plugins: CSS Mode, NTSL Mode, CSS-hint addon, Search addon, Sublime Keymap.
|
||||
add_stylesheet("codemirror.css") // A CSS sheet containing the basic stylings and formatting information for CodeMirror.
|
||||
add_stylesheet("cm_lesser-dark.css") // A theme for CodeMirror to use, which closely resembles the rest of the NanoUI style.
|
||||
|
||||
/**
|
||||
* Set the current status (also known as visibility) of this ui.
|
||||
|
||||
+125
-120
@@ -1,154 +1,159 @@
|
||||
#define PAPERWORK 1
|
||||
#define PHOTO 2
|
||||
|
||||
/obj/item/weapon/clipboard
|
||||
name = "clipboard"
|
||||
desc = "It looks like you're writing a letter. Want some help?"
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "clipboard"
|
||||
item_state = "clipboard"
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throw_speed = 3
|
||||
throw_range = 10
|
||||
var/obj/item/weapon/pen/haspen //The stored pen.
|
||||
var/obj/item/weapon/toppaper //The topmost piece of paper.
|
||||
var/obj/item/weapon/pen/containedpen
|
||||
var/obj/item/weapon/toppaper
|
||||
slot_flags = SLOT_BELT
|
||||
burn_state = FLAMMABLE
|
||||
|
||||
/obj/item/weapon/clipboard/New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/clipboard/MouseDrop(obj/over_object as obj) //Quick clipboard fix. -Agouri
|
||||
if(ishuman(usr))
|
||||
var/mob/M = usr
|
||||
if(!(istype(over_object, /obj/screen) ))
|
||||
return ..()
|
||||
/obj/item/weapon/clipboard/verb/removePen(mob/user)
|
||||
set category = "Object"
|
||||
set name = "Remove clipboard pen"
|
||||
if(!ishuman(user) || user.incapacitated())
|
||||
return
|
||||
penPlacement(user, containedpen, FALSE)
|
||||
|
||||
if(!M.restrained() && !M.stat)
|
||||
switch(over_object.name)
|
||||
if("r_hand")
|
||||
M.unEquip(src)
|
||||
M.put_in_r_hand(src)
|
||||
if("l_hand")
|
||||
M.unEquip(src)
|
||||
M.put_in_l_hand(src)
|
||||
/obj/item/weapon/clipboard/proc/isPaperwork(obj/item/weapon/W) //This could probably do with being somewhere else but for now it's fine here.
|
||||
if(istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/paper_bundle))
|
||||
return PAPERWORK
|
||||
if(istype(W, /obj/item/weapon/photo))
|
||||
return PHOTO
|
||||
|
||||
add_fingerprint(usr)
|
||||
/obj/item/weapon/clipboard/proc/checkTopPaper()
|
||||
if(toppaper.loc != src) //Oh no! We're missing a top sheet! Better get another one to be at the top.
|
||||
toppaper = locate(/obj/item/weapon/paper) in src
|
||||
if(!toppaper) //In case there's no paper, try find a paper bundle instead (why is paper_bundle not a subtype of paper?)
|
||||
toppaper = locate(/obj/item/weapon/paper_bundle) in src
|
||||
|
||||
/obj/item/weapon/clipboard/examine(mob/user)
|
||||
if(..(user, 1) && toppaper)
|
||||
toppaper.examine(user)
|
||||
|
||||
obj/item/weapon/clipboard/proc/penPlacement(mob/user, obj/item/weapon/pen/P, placing)
|
||||
if(placing)
|
||||
if(containedpen)
|
||||
to_chat(user, "<span class='warning'>There's already a pen in [src]!</span>")
|
||||
return
|
||||
if(!is_pen(P))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You slide [P] into [src].</span>")
|
||||
user.unEquip(P)
|
||||
P.forceMove(src)
|
||||
containedpen = P
|
||||
else
|
||||
if(!containedpen)
|
||||
to_chat(user, "<span class='warning'>There isn't a pen in [src] for you to remove!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You remove [containedpen] from [src].</span>")
|
||||
user.put_in_hands(containedpen)
|
||||
containedpen = null
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/clipboard/proc/showClipboard(mob/user) //Show them what's on the clipboard
|
||||
var/dat = "<title>[src]</title>"
|
||||
dat += "<a href='?src=[UID()];doPenThings=[containedpen ? "Remove" : "Add"]'>[containedpen ? "Remove pen" : "Add pen"]</a><br><hr>"
|
||||
if(toppaper)
|
||||
dat += "<a href='?src=[UID()];remove=\ref[toppaper]'>Remove</a><a href='?src=[UID()];viewOrWrite=\ref[toppaper]'>[toppaper.name]</a><br><hr>"
|
||||
for(var/obj/item/weapon/P in src)
|
||||
if(isPaperwork(P) == PAPERWORK && P != toppaper)
|
||||
dat += "<a href='?src=[UID()];remove=\ref[P]'>Remove</a><a href='?src=[UID()];topPaper=\ref[P]'>Put on top</a><a href='?src=[UID()];viewOrWrite=\ref[P]'>[P.name]</a><br>"
|
||||
if(isPaperwork(P) == PHOTO)
|
||||
dat += "<a href='?src=[UID()];remove=\ref[P]'>Remove</a><a href='?src=[UID()];viewOrWrite=\ref[P]'>[P.name]</a><br>"
|
||||
var/datum/browser/popup = new(user, "clipboard", "[src]", 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/item/weapon/clipboard/update_icon()
|
||||
overlays.Cut()
|
||||
if(toppaper)
|
||||
overlays += toppaper.icon_state
|
||||
overlays += toppaper.overlays
|
||||
if(haspen)
|
||||
if(containedpen)
|
||||
overlays += "clipboard_pen"
|
||||
overlays += "clipboard_over"
|
||||
return
|
||||
|
||||
/obj/item/weapon/clipboard/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
|
||||
if(istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/photo))
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
if(istype(W, /obj/item/weapon/paper))
|
||||
/obj/item/weapon/clipboard/attackby(obj/item/weapon/W, mob/user)
|
||||
if(isPaperwork(W)) //If it's a photo, paper bundle, or piece of paper, place it on the clipboard.
|
||||
user.unEquip(W)
|
||||
W.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You clip [W] onto [src].</span>")
|
||||
playsound(loc, "pageturn", 50, 1)
|
||||
if(isPaperwork(W) == PAPERWORK)
|
||||
toppaper = W
|
||||
to_chat(user, "<span class='notice'>You clip the [W] onto \the [src].</span>")
|
||||
update_icon()
|
||||
else if(is_pen(W))
|
||||
if(!toppaper) //If there's no paper we can write on, just stick the pen into the clipboard
|
||||
penPlacement(user, W, TRUE)
|
||||
return
|
||||
if(containedpen) //If there's a pen in the clipboard, let's just let them write and not bother asking about the pen
|
||||
toppaper.attackby(W, user)
|
||||
return
|
||||
var/writeonwhat = input(user, "Write on [toppaper.name], or place your pen in [src]?", "Pick one!") as null|anything in list("Write", "Place pen")
|
||||
if(!Adjacent(user) || user.incapacitated())
|
||||
return
|
||||
switch(writeonwhat)
|
||||
if("Write")
|
||||
toppaper.attackby(W, user)
|
||||
if("Place pen")
|
||||
penPlacement(user, W, TRUE)
|
||||
else
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/stamp) && toppaper) //We can stamp the topmost piece of paper
|
||||
toppaper.attackby(W, user)
|
||||
update_icon()
|
||||
|
||||
else if(istype(toppaper) && istype(W, /obj/item/weapon/pen))
|
||||
toppaper.attackby(W, usr, params)
|
||||
update_icon()
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/clipboard/attack_self(mob/user as mob)
|
||||
var/dat = "<title>Clipboard</title>"
|
||||
if(haspen)
|
||||
dat += "<A href='?src=[UID()];pen=1'>Remove Pen</A><BR><HR>"
|
||||
else
|
||||
dat += "<A href='?src=[UID()];addpen=1'>Add Pen</A><BR><HR>"
|
||||
|
||||
//The topmost paper. I don't think there's any way to organise contents in byond, so this is what we're stuck with. -Pete
|
||||
if(toppaper)
|
||||
var/obj/item/weapon/paper/P = toppaper
|
||||
dat += "<A href='?src=[UID()];write=\ref[P]'>Write</A> <A href='?src=[UID()];remove=\ref[P]'>Remove</A> - <A href='?src=[UID()];read=\ref[P]'>[P.name]</A><BR><HR>"
|
||||
|
||||
for(var/obj/item/weapon/paper/P in src)
|
||||
if(P==toppaper)
|
||||
continue
|
||||
dat += "<A href='?src=[UID()];remove=\ref[P]'>Remove</A> - <A href='?src=[UID()];read=\ref[P]'>[P.name]</A><BR>"
|
||||
for(var/obj/item/weapon/photo/Ph in src)
|
||||
dat += "<A href='?src=[UID()];remove=\ref[Ph]'>Remove</A> - <A href='?src=[UID()];look=\ref[Ph]'>[Ph.name]</A><BR>"
|
||||
|
||||
user << browse(dat, "window=clipboard")
|
||||
onclose(user, "clipboard")
|
||||
add_fingerprint(usr)
|
||||
return
|
||||
/obj/item/weapon/clipboard/attack_self(mob/user)
|
||||
showClipboard(user)
|
||||
|
||||
/obj/item/weapon/clipboard/Topic(href, href_list)
|
||||
..()
|
||||
if((usr.stat || usr.restrained()))
|
||||
if(!Adjacent(usr) || usr.incapacitated())
|
||||
return
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if(href_list["doPenThings"])
|
||||
if(href_list["doPenThings"] == "Add")
|
||||
penPlacement(usr, I, TRUE)
|
||||
else
|
||||
penPlacement(usr, containedpen, FALSE)
|
||||
else if(href_list["remove"])
|
||||
var/obj/item/P = locate(href_list["remove"])
|
||||
if(isPaperwork(P))
|
||||
usr.put_in_hands(P)
|
||||
to_chat(usr, "<span class='notice'>You remove [P] from [src].</span>")
|
||||
checkTopPaper() //So we don't accidentally make the top sheet not be on the clipboard
|
||||
else if(href_list["viewOrWrite"])
|
||||
var/obj/item/weapon/P = locate(href_list["viewOrWrite"])
|
||||
if(!isPaperwork(P))
|
||||
return
|
||||
if(is_pen(I) && isPaperwork(P) != PHOTO) //Because you can't write on photos that aren't in your hand
|
||||
P.attackby(I, usr)
|
||||
else if(isPaperwork(P) == PAPERWORK) //Why can't these be subtypes of paper
|
||||
P.examine(usr)
|
||||
else if(isPaperwork(P) == PHOTO)
|
||||
var/obj/item/weapon/photo/Ph = P
|
||||
Ph.show(usr)
|
||||
else if(href_list["topPaper"])
|
||||
var/obj/item/weapon/P = locate(href_list["topPaper"])
|
||||
if(P == toppaper)
|
||||
return
|
||||
to_chat(usr, "<span class='notice'>You flick the pages so that [P] is on top.</span>")
|
||||
playsound(loc, "pageturn", 50, 1)
|
||||
toppaper = P
|
||||
update_icon()
|
||||
showClipboard(usr)
|
||||
|
||||
if(src.loc == usr)
|
||||
|
||||
if(href_list["pen"])
|
||||
if(istype(haspen) && (haspen.loc == src))
|
||||
haspen.loc = usr.loc
|
||||
usr.put_in_hands(haspen)
|
||||
haspen = null
|
||||
|
||||
else if(href_list["addpen"])
|
||||
if(!haspen)
|
||||
var/obj/item/weapon/pen/W = usr.get_active_hand()
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
usr.drop_item()
|
||||
W.loc = src
|
||||
haspen = W
|
||||
to_chat(usr, "<span class='notice'>You slot the pen into \the [src].</span>")
|
||||
|
||||
else if(href_list["write"])
|
||||
var/obj/item/weapon/P = locate(href_list["write"])
|
||||
|
||||
if(P && (P.loc == src) && istype(P, /obj/item/weapon/paper) && (P == toppaper) )
|
||||
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
|
||||
if(istype(I, /obj/item/weapon/pen))
|
||||
|
||||
P.attackby(I, usr)
|
||||
|
||||
else if(href_list["remove"])
|
||||
var/obj/item/P = locate(href_list["remove"])
|
||||
|
||||
if(P && (P.loc == src) && (istype(P, /obj/item/weapon/paper) || istype(P, /obj/item/weapon/photo)) )
|
||||
|
||||
P.loc = usr.loc
|
||||
usr.put_in_hands(P)
|
||||
if(P == toppaper)
|
||||
toppaper = null
|
||||
var/obj/item/weapon/paper/newtop = locate(/obj/item/weapon/paper) in src
|
||||
if(newtop && (newtop != P))
|
||||
toppaper = newtop
|
||||
else
|
||||
toppaper = null
|
||||
|
||||
else if(href_list["read"])
|
||||
var/obj/item/weapon/paper/P = locate(href_list["read"])
|
||||
|
||||
if(P && (P.loc == src) && istype(P, /obj/item/weapon/paper) )
|
||||
P.show_content(usr)
|
||||
|
||||
else if(href_list["look"])
|
||||
var/obj/item/weapon/photo/P = locate(href_list["look"])
|
||||
if(P && (P.loc == src) && istype(P, /obj/item/weapon/photo) )
|
||||
P.show(usr)
|
||||
|
||||
else if(href_list["top"]) // currently unused
|
||||
var/obj/item/P = locate(href_list["top"])
|
||||
if(P && (P.loc == src) && istype(P, /obj/item/weapon/paper) )
|
||||
toppaper = P
|
||||
to_chat(usr, "<span class='notice'>You move [P.name] to the top.</span>")
|
||||
|
||||
//Update everything
|
||||
attack_self(usr)
|
||||
update_icon()
|
||||
return
|
||||
#undef PAPERWORK
|
||||
#undef PHOTO
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
name = "Placeholder Generator" //seriously, don't use this. It can't be anchored without VV magic.
|
||||
desc = "A portable generator for emergency backup power"
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "portgen0"
|
||||
icon_state = "portgen0_0"
|
||||
density = 1
|
||||
anchored = 0
|
||||
use_power = 0
|
||||
@@ -13,6 +13,7 @@
|
||||
var/open = 0
|
||||
var/recent_fault = 0
|
||||
var/power_output = 1
|
||||
var/base_icon = "portgen0"
|
||||
|
||||
/obj/machinery/power/port_gen/proc/IsBroken()
|
||||
return (stat & (BROKEN|EMPED))
|
||||
@@ -29,14 +30,17 @@
|
||||
/obj/machinery/power/port_gen/proc/handleInactive()
|
||||
return
|
||||
|
||||
/obj/machinery/power/port_gen/update_icon()
|
||||
icon_state = "[base_icon]_[active]"
|
||||
|
||||
/obj/machinery/power/port_gen/process()
|
||||
if(active && HasFuel() && !IsBroken() && anchored && powernet)
|
||||
add_avail(power_gen * power_output)
|
||||
UseFuel()
|
||||
else
|
||||
active = 0
|
||||
icon_state = initial(icon_state)
|
||||
handleInactive()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/powered()
|
||||
return 1 //doesn't require an external power source
|
||||
@@ -362,11 +366,11 @@
|
||||
if(href_list["action"] == "enable")
|
||||
if(!active && HasFuel() && !IsBroken())
|
||||
active = 1
|
||||
icon_state = "portgen1"
|
||||
update_icon()
|
||||
if(href_list["action"] == "disable")
|
||||
if(active)
|
||||
active = 0
|
||||
icon_state = "portgen0"
|
||||
update_icon()
|
||||
if(href_list["action"] == "eject")
|
||||
if(!active)
|
||||
DropFuel()
|
||||
@@ -382,7 +386,8 @@
|
||||
/obj/machinery/power/port_gen/pacman/super
|
||||
name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator"
|
||||
desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard PACMAN type generators. Rated for 80 kW max safe output."
|
||||
icon_state = "portgen1"
|
||||
icon_state = "portgen1_0"
|
||||
base_icon = "portgen1"
|
||||
sheet_path = /obj/item/stack/sheet/mineral/uranium
|
||||
sheet_name = "Uranium Sheets"
|
||||
time_per_sheet = 576 //same power output, but a 50 sheet stack will last 2 hours at max safe power
|
||||
@@ -420,7 +425,8 @@
|
||||
/obj/machinery/power/port_gen/pacman/mrs
|
||||
name = "M.R.S.P.A.C.M.A.N.-type Portable Generator"
|
||||
desc = "An advanced power generator that runs on diamonds. Rated for 200 kW maximum safe output!"
|
||||
icon_state = "portgen2"
|
||||
icon_state = "portgen2_0"
|
||||
base_icon = "portgen2"
|
||||
sheet_path = /obj/item/stack/sheet/mineral/diamond
|
||||
sheet_name = "Diamond Sheets"
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
projectile_type = /obj/item/projectile/beam/laser
|
||||
select_name = "kill"
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/cyborg //to balance cyborg energy cost seperately
|
||||
e_cost = 250
|
||||
|
||||
/obj/item/ammo_casing/energy/lasergun
|
||||
projectile_type = /obj/item/projectile/beam/laser
|
||||
e_cost = 83
|
||||
@@ -126,6 +129,9 @@
|
||||
e_cost = 50
|
||||
fire_sound = 'sound/weapons/taser2.ogg'
|
||||
|
||||
/obj/item/ammo_casing/energy/disabler/cyborg //seperate balancing for cyborg, again
|
||||
e_cost = 250
|
||||
|
||||
/obj/item/ammo_casing/energy/plasma
|
||||
projectile_type = /obj/item/projectile/plasma
|
||||
select_name = "plasma burst"
|
||||
|
||||
@@ -182,16 +182,19 @@
|
||||
|
||||
/obj/item/ammo_box/magazine/m10mm/fire
|
||||
name = "pistol magazine (10mm incendiary)"
|
||||
icon_state = "9x19pI"
|
||||
desc = "A gun magazine. Loaded with rounds which ignite the target."
|
||||
ammo_type = /obj/item/ammo_casing/c10mm/fire
|
||||
|
||||
/obj/item/ammo_box/magazine/m10mm/hp
|
||||
name = "pistol magazine (10mm HP)"
|
||||
icon_state = "9x19pH"
|
||||
desc= "A gun magazine. Loaded with hollow-point rounds, extremely effective against unarmored targets, but nearly useless against protective clothing."
|
||||
ammo_type = /obj/item/ammo_casing/c10mm/hp
|
||||
|
||||
/obj/item/ammo_box/magazine/m10mm/ap
|
||||
name = "pistol magazine (10mm AP)"
|
||||
icon_state = "9x19pA"
|
||||
desc= "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets"
|
||||
ammo_type = /obj/item/ammo_casing/c10mm/ap
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
/obj/item/weapon/gun/energy/laser/cyborg
|
||||
can_charge = 0
|
||||
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/cyborg)
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/cyborg/newshot()
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
/obj/item/weapon/gun/energy/disabler/cyborg
|
||||
name = "cyborg disabler"
|
||||
desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler/cyborg)
|
||||
can_charge = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/disabler/cyborg/newshot()
|
||||
|
||||
@@ -203,9 +203,10 @@
|
||||
name = "bluespace beam"
|
||||
icon_state = "spark"
|
||||
hitsound = "sparks"
|
||||
damage = 3
|
||||
damage = 0
|
||||
var/obj/item/weapon/gun/energy/wormhole_projector/gun
|
||||
color = "#33CCFF"
|
||||
nodamage = TRUE
|
||||
|
||||
/obj/item/projectile/beam/wormhole/orange
|
||||
name = "orange bluespace beam"
|
||||
|
||||
@@ -332,7 +332,7 @@
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
|
||||
var/datum/sprite_accessory/tmp_hair_style = hair_styles_list["Very Long Hair"]
|
||||
var/datum/sprite_accessory/tmp_hair_style = hair_styles_full_list["Very Long Hair"]
|
||||
var/datum/sprite_accessory/tmp_facial_hair_style = facial_hair_styles_list["Very Long Beard"]
|
||||
|
||||
if(head_organ.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them.
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/meat/slab,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/deepfryholder
|
||||
)
|
||||
blocked |= typesof(/obj/item/weapon/reagent_containers/food/snacks/customizable)
|
||||
|
||||
@@ -193,6 +194,21 @@
|
||||
|
||||
feedback_add_details("slime_cores_used","[type]")
|
||||
var/list/borks = subtypesof(/obj/item/weapon/reagent_containers/food/drinks)
|
||||
var/list/blocked = list(/obj/item/weapon/reagent_containers/food/drinks/cans/adminbooze,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/madminmalt,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/shaker,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/britcup,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/sillycup,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/mushroom_bowl
|
||||
)
|
||||
blocked += typesof(/obj/item/weapon/reagent_containers/food/drinks/flask)
|
||||
blocked += typesof(/obj/item/weapon/reagent_containers/food/drinks/trophy)
|
||||
blocked += typesof(/obj/item/weapon/reagent_containers/food/drinks/cans/bottler)
|
||||
borks -= blocked
|
||||
// BORK BORK BORK
|
||||
|
||||
playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1)
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
var/bypass_protection = 0 //If the hypospray can go through armor or thick material
|
||||
|
||||
var/list/datum/reagents/reagent_list = list()
|
||||
var/list/reagent_ids = list("salglu_solution", "epinephrine", "spaceacillin", "charcoal")
|
||||
//var/list/reagent_ids = list("salbutamol", "silver_sulfadiazine", "styptic_powder", "charcoal", "epinephrine", "spaceacillin")
|
||||
var/list/reagent_ids = list("salglu_solution", "epinephrine", "spaceacillin", "charcoal", "hydrocodone")
|
||||
//var/list/reagent_ids = list("salbutamol", "silver_sulfadiazine", "styptic_powder", "charcoal", "epinephrine", "spaceacillin", "hydrocodone")
|
||||
|
||||
/obj/item/weapon/reagent_containers/borghypo/surgeon
|
||||
reagent_ids = list("styptic_powder", "epinephrine", "salbutamol")
|
||||
@@ -127,4 +127,4 @@
|
||||
empty = 0
|
||||
|
||||
if(empty)
|
||||
to_chat(user, "<span class='notice'>It is currently empty. Allow some time for the internal syntheszier to produce more.</span>")
|
||||
to_chat(user, "<span class='notice'>It is currently empty. Allow some time for the internal syntheszier to produce more.</span>")
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
to_chat(usr, "<span class='warning'>All Emergency Response Teams are dispatched and can not be called at this time.</span>")
|
||||
return
|
||||
to_chat(usr, "<span class = 'notice'>ERT request transmitted.</span>")
|
||||
|
||||
print_centcom_report(ert_reason, worldtime2text() +" ERT Request")
|
||||
|
||||
var/fullmin_count = 0
|
||||
for(var/client/C in admins)
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
// Stationary ports shouldn't move, mobile ones move themselves
|
||||
return 0
|
||||
|
||||
/obj/machinery/door/onShuttleMove()
|
||||
/obj/machinery/door/airlock/onShuttleMove()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
addtimer(src, "close", 0, TRUE, 0, 1)
|
||||
// Close any nearby airlocks as well
|
||||
for(var/obj/machinery/door/D in orange(1, src))
|
||||
for(var/obj/machinery/door/airlock/D in orange(1, src))
|
||||
addtimer(D, "close", 0, TRUE, 0, 1)
|
||||
|
||||
/obj/machinery/door/airlock/onShuttleMove()
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/bonegel = 100, \
|
||||
/obj/item/weapon/screwdriver = 75
|
||||
/obj/item/weapon/screwdriver = 90
|
||||
)
|
||||
can_infect = 1
|
||||
blood_level = 1
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/bonesetter = 100, \
|
||||
/obj/item/weapon/wrench = 75 \
|
||||
/obj/item/weapon/wrench = 90 \
|
||||
)
|
||||
|
||||
time = 32
|
||||
@@ -109,7 +109,7 @@
|
||||
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/bonesetter = 100, \
|
||||
/obj/item/weapon/wrench = 75 \
|
||||
/obj/item/weapon/wrench = 90 \
|
||||
)
|
||||
|
||||
time = 32
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/bonegel = 100, \
|
||||
/obj/item/weapon/screwdriver = 75
|
||||
/obj/item/weapon/screwdriver = 90
|
||||
)
|
||||
can_infect = 1
|
||||
blood_level = 1
|
||||
@@ -168,7 +168,7 @@
|
||||
affected.status &= ~ORGAN_BROKEN
|
||||
affected.status &= ~ORGAN_SPLINTED
|
||||
affected.perma_injury = 0
|
||||
|
||||
target.handle_splints()
|
||||
return 1
|
||||
|
||||
/datum/surgery_step/finish_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
name = "make cavity space"
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/surgicaldrill = 100, \
|
||||
/obj/item/weapon/pen = 75, \
|
||||
/obj/item/stack/rods = 50
|
||||
/obj/item/weapon/pen = 90, \
|
||||
/obj/item/stack/rods = 60
|
||||
)
|
||||
|
||||
time = 54
|
||||
@@ -93,9 +93,9 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser = 100, \
|
||||
/obj/item/weapon/cautery = 100, \
|
||||
/obj/item/clothing/mask/cigarette = 75, \
|
||||
/obj/item/weapon/lighter = 50, \
|
||||
/obj/item/weapon/weldingtool = 25
|
||||
/obj/item/clothing/mask/cigarette = 90, \
|
||||
/obj/item/weapon/lighter = 60, \
|
||||
/obj/item/weapon/weldingtool = 30
|
||||
)
|
||||
|
||||
time = 24
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/circular_saw = 100, \
|
||||
/obj/item/weapon/melee/energy/sword/cyborg/saw = 100, \
|
||||
/obj/item/weapon/hatchet = 75
|
||||
/obj/item/weapon/hatchet = 90
|
||||
)
|
||||
|
||||
time = 54
|
||||
@@ -72,7 +72,7 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser/manager = 100, \
|
||||
/obj/item/weapon/retractor = 100, \
|
||||
/obj/item/weapon/crowbar = 75
|
||||
/obj/item/weapon/crowbar = 90
|
||||
)
|
||||
|
||||
time = 24
|
||||
@@ -123,7 +123,7 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser/manager = 100, \
|
||||
/obj/item/weapon/retractor = 100, \
|
||||
/obj/item/weapon/crowbar = 75
|
||||
/obj/item/weapon/crowbar = 90
|
||||
)
|
||||
|
||||
time = 24
|
||||
@@ -173,7 +173,7 @@
|
||||
name = "mend bone"
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/bonegel = 100, \
|
||||
/obj/item/weapon/screwdriver = 75
|
||||
/obj/item/weapon/screwdriver = 90
|
||||
)
|
||||
|
||||
time = 24
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
name = "make incision"
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel = 100, \
|
||||
/obj/item/weapon/kitchen/knife = 75, \
|
||||
/obj/item/weapon/shard = 50, \
|
||||
/obj/item/weapon/kitchen/knife = 90, \
|
||||
/obj/item/weapon/shard = 60, \
|
||||
)
|
||||
|
||||
time = 16
|
||||
@@ -60,8 +60,8 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser/manager = 100, \
|
||||
/obj/item/weapon/hemostat = 100, \
|
||||
/obj/item/stack/cable_coil = 75, \
|
||||
/obj/item/device/assembly/mousetrap = 10 //I don't know. Don't ask me. But I'm leaving it because hilarity.
|
||||
/obj/item/stack/cable_coil = 90, \
|
||||
/obj/item/device/assembly/mousetrap = 12 //I don't know. Don't ask me. But I'm leaving it because hilarity.
|
||||
)
|
||||
|
||||
time = 24
|
||||
@@ -87,8 +87,8 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser/manager = 100, \
|
||||
/obj/item/weapon/retractor = 100, \
|
||||
/obj/item/weapon/crowbar = 55, \
|
||||
/obj/item/weapon/kitchen/utensil/fork = 75)
|
||||
/obj/item/weapon/crowbar = 65, \
|
||||
/obj/item/weapon/kitchen/utensil/fork = 90)
|
||||
|
||||
time = 64
|
||||
|
||||
@@ -114,9 +114,9 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser = 100, \
|
||||
/obj/item/weapon/cautery = 100, \
|
||||
/obj/item/clothing/mask/cigarette = 75, \
|
||||
/obj/item/weapon/lighter = 50, \
|
||||
/obj/item/weapon/weldingtool = 25
|
||||
/obj/item/clothing/mask/cigarette = 90, \
|
||||
/obj/item/weapon/lighter = 60, \
|
||||
/obj/item/weapon/weldingtool = 30
|
||||
)
|
||||
|
||||
time = 24
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel = 100, \
|
||||
/obj/item/weapon/kitchen/knife = 75, \
|
||||
/obj/item/weapon/shard = 50, \
|
||||
/obj/item/weapon/scissors = 10, \
|
||||
/obj/item/weapon/kitchen/knife = 90, \
|
||||
/obj/item/weapon/shard = 60, \
|
||||
/obj/item/weapon/scissors = 12, \
|
||||
/obj/item/weapon/twohanded/chainsaw = 1, \
|
||||
/obj/item/weapon/claymore = 5, \
|
||||
/obj/item/weapon/melee/energy/ = 5, \
|
||||
/obj/item/weapon/pen/edagger = 5, \
|
||||
/obj/item/weapon/claymore = 6, \
|
||||
/obj/item/weapon/melee/energy/ = 6, \
|
||||
/obj/item/weapon/pen/edagger = 6, \
|
||||
)
|
||||
|
||||
time = 16
|
||||
@@ -60,8 +60,8 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser = 100, \
|
||||
/obj/item/weapon/hemostat = 100, \
|
||||
/obj/item/stack/cable_coil = 75, \
|
||||
/obj/item/device/assembly/mousetrap = 20
|
||||
/obj/item/stack/cable_coil = 90, \
|
||||
/obj/item/device/assembly/mousetrap = 25
|
||||
)
|
||||
|
||||
time = 24
|
||||
@@ -94,8 +94,8 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser/manager = 100, \
|
||||
/obj/item/weapon/retractor = 100, \
|
||||
/obj/item/weapon/crowbar = 75, \
|
||||
/obj/item/weapon/kitchen/utensil/fork = 50
|
||||
/obj/item/weapon/crowbar = 90, \
|
||||
/obj/item/weapon/kitchen/utensil/fork = 60
|
||||
)
|
||||
|
||||
time = 24
|
||||
@@ -149,9 +149,9 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser = 100, \
|
||||
/obj/item/weapon/cautery = 100, \
|
||||
/obj/item/clothing/mask/cigarette = 75, \
|
||||
/obj/item/weapon/lighter = 50, \
|
||||
/obj/item/weapon/weldingtool = 25
|
||||
/obj/item/clothing/mask/cigarette = 90, \
|
||||
/obj/item/weapon/lighter = 60, \
|
||||
/obj/item/weapon/weldingtool = 30
|
||||
)
|
||||
|
||||
time = 24
|
||||
@@ -199,8 +199,8 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/circular_saw = 100, \
|
||||
/obj/item/weapon/melee/energy/sword/cyborg/saw = 100, \
|
||||
/obj/item/weapon/hatchet = 75, \
|
||||
/obj/item/weapon/melee/arm_blade = 60
|
||||
/obj/item/weapon/hatchet = 90, \
|
||||
/obj/item/weapon/melee/arm_blade = 75
|
||||
)
|
||||
|
||||
time = 100
|
||||
|
||||
@@ -81,7 +81,24 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/proc/get_pain_modifier(mob/living/carbon/human/M) //returns modfier to make surgery harder if patient is conscious and feels pain
|
||||
if(M.stat) //stat=0 if CONSCIOUS, 1=UNCONSCIOUS and 2=DEAD. Operating on dead people is easy, too. Just sleeping won't work, though.
|
||||
return 1
|
||||
if(NO_PAIN in M.species.species_traits)//if you don't feel pain, you can hold still
|
||||
return 1
|
||||
if(M.reagents.has_reagent("hydrocodone"))//really good pain killer
|
||||
return 0.99
|
||||
if(M.reagents.has_reagent("morphine"))//Just as effective as Hydrocodone, but has an addiction chance
|
||||
return 0.99
|
||||
if(M.drunk >= 80)//really damn drunk
|
||||
return 0.95
|
||||
if(M.drunk >= 40)//pretty drunk
|
||||
return 0.9
|
||||
if(M.reagents.has_reagent("sal_acid")) //it's better than nothing, as far as painkillers go.
|
||||
return 0.85
|
||||
if(M.drunk >= 15)//a little drunk
|
||||
return 0.85
|
||||
return 0.8 //20% failure chance
|
||||
|
||||
/proc/get_location_modifier(mob/M)
|
||||
var/turf/T = get_turf(M)
|
||||
|
||||
@@ -171,8 +171,8 @@
|
||||
name = "connect limb"
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/hemostat = 100, \
|
||||
/obj/item/stack/cable_coil = 75, \
|
||||
/obj/item/device/assembly/mousetrap = 20
|
||||
/obj/item/stack/cable_coil = 90, \
|
||||
/obj/item/device/assembly/mousetrap = 25
|
||||
)
|
||||
can_infect = 1
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
var/can_grasp
|
||||
var/can_stand
|
||||
|
||||
var/splinted_count = 0 //Time when this organ was last splinted
|
||||
|
||||
/obj/item/organ/external/necrotize(update_sprite=TRUE)
|
||||
if(status & (ORGAN_ROBOT|ORGAN_DEAD))
|
||||
return
|
||||
@@ -84,6 +86,7 @@
|
||||
|
||||
if(owner)
|
||||
owner.bodyparts_by_name[limb_name] = null
|
||||
owner.splinted_limbs -= src
|
||||
|
||||
QDEL_LIST(children)
|
||||
|
||||
@@ -196,6 +199,10 @@
|
||||
|
||||
if(status & ORGAN_BROKEN && prob(40) && brute)
|
||||
owner.emote("scream") //getting hit on broken hand hurts
|
||||
if(status & ORGAN_SPLINTED && prob((brute + burn)*4)) //taking damage to splinted limbs removes the splints
|
||||
status &= ~ORGAN_SPLINTED
|
||||
owner.visible_message("<span class='danger'>The splint on [owner]'s left arm unravels from their [name]!</span>","<span class='userdanger'>The splint on your [name] unravels!</span>")
|
||||
owner.handle_splints()
|
||||
if(used_weapon)
|
||||
add_autopsy_data("[used_weapon]", brute + burn)
|
||||
|
||||
@@ -458,6 +465,18 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
tbrute = 3
|
||||
return "[tbrute][tburn]"
|
||||
|
||||
/obj/item/organ/external/proc/update_splints()
|
||||
if(!(status & ORGAN_SPLINTED))
|
||||
owner.splinted_limbs -= src
|
||||
return
|
||||
if(owner.step_count >= splinted_count + SPLINT_LIFE)
|
||||
status &= ~ORGAN_SPLINTED //oh no, we actually need surgery now!
|
||||
owner.visible_message("<span class='danger'>[owner] screams in pain as their splint pops off their [name]!</span>","<span class='userdanger'>You scream in pain as your splint pops off your [name]!</span>")
|
||||
owner.emote("scream")
|
||||
owner.Stun(2)
|
||||
owner.handle_splints()
|
||||
|
||||
|
||||
/****************************************************
|
||||
DISMEMBERMENT
|
||||
****************************************************/
|
||||
@@ -648,6 +667,9 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
var/is_robotic = status & ORGAN_ROBOT
|
||||
var/mob/living/carbon/human/victim = owner
|
||||
|
||||
if(status & ORGAN_SPLINTED)
|
||||
victim.splinted_limbs -= src
|
||||
|
||||
for(var/obj/item/I in embedded_objects)
|
||||
embedded_objects -= I
|
||||
I.forceMove(src)
|
||||
@@ -754,4 +776,4 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/organ/external/L = X
|
||||
for(var/obj/item/I in L.embedded_objects)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -148,7 +148,7 @@ var/global/list/limb_icon_cache = list()
|
||||
overlays |= facial_s
|
||||
|
||||
if(h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR)))
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_full_list[h_style]
|
||||
if(hair_style && ((species.name in hair_style.species_allowed) || (src.species.bodyflags & ALL_RPARTS)))
|
||||
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
if(species.name == "Slime People") // I am el worstos
|
||||
|
||||
@@ -68,17 +68,17 @@
|
||||
/datum/surgery_step/internal/manipulate_organs
|
||||
name = "manipulate organs"
|
||||
allowed_tools = list(/obj/item/organ/internal = 100, /obj/item/weapon/reagent_containers/food/snacks/organ = 0)
|
||||
var/implements_extract = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/kitchen/utensil/fork = 55)
|
||||
var/implements_extract = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/kitchen/utensil/fork = 70)
|
||||
var/implements_mend = list(/obj/item/stack/medical/bruise_pack = 20,/obj/item/stack/medical/bruise_pack/advanced = 100,/obj/item/stack/nanopaste = 100)
|
||||
var/implements_clean = list(/obj/item/weapon/reagent_containers/dropper = 100,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle = 75,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 70,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle = 65,
|
||||
/obj/item/weapon/reagent_containers/glass/beaker = 60,
|
||||
/obj/item/weapon/reagent_containers/spray = 50,
|
||||
/obj/item/weapon/reagent_containers/glass/bucket = 40)
|
||||
/obj/item/weapon/reagent_containers/glass/bottle = 90,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 85,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle = 80,
|
||||
/obj/item/weapon/reagent_containers/glass/beaker = 75,
|
||||
/obj/item/weapon/reagent_containers/spray = 60,
|
||||
/obj/item/weapon/reagent_containers/glass/bucket = 50)
|
||||
//Finish is just so you can close up after you do other things.
|
||||
var/implements_finsh = list(/obj/item/weapon/scalpel/laser/manager = 100,/obj/item/weapon/retractor = 100 ,/obj/item/weapon/crowbar = 75)
|
||||
var/implements_finsh = list(/obj/item/weapon/scalpel/laser/manager = 100,/obj/item/weapon/retractor = 100 ,/obj/item/weapon/crowbar = 90)
|
||||
var/current_type
|
||||
var/obj/item/organ/internal/I = null
|
||||
var/obj/item/organ/external/affected = null
|
||||
@@ -436,7 +436,7 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/circular_saw = 100, \
|
||||
/obj/item/weapon/melee/energy/sword/cyborg/saw = 100, \
|
||||
/obj/item/weapon/hatchet = 75
|
||||
/obj/item/weapon/hatchet = 90
|
||||
)
|
||||
|
||||
time = 54
|
||||
@@ -464,13 +464,13 @@
|
||||
name = "cut carapace"
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel = 100, \
|
||||
/obj/item/weapon/kitchen/knife = 75, \
|
||||
/obj/item/weapon/shard = 50, \
|
||||
/obj/item/weapon/scissors = 10, \
|
||||
/obj/item/weapon/kitchen/knife = 90, \
|
||||
/obj/item/weapon/shard = 60, \
|
||||
/obj/item/weapon/scissors = 12, \
|
||||
/obj/item/weapon/twohanded/chainsaw = 1, \
|
||||
/obj/item/weapon/claymore = 5, \
|
||||
/obj/item/weapon/melee/energy/ = 5, \
|
||||
/obj/item/weapon/pen/edagger = 5, \
|
||||
/obj/item/weapon/claymore = 6, \
|
||||
/obj/item/weapon/melee/energy/ = 6, \
|
||||
/obj/item/weapon/pen/edagger = 6, \
|
||||
)
|
||||
|
||||
time = 16
|
||||
@@ -499,8 +499,8 @@
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel/laser/manager = 100, \
|
||||
/obj/item/weapon/retractor = 100, \
|
||||
/obj/item/weapon/crowbar = 75, \
|
||||
/obj/item/weapon/kitchen/utensil/fork = 50
|
||||
/obj/item/weapon/crowbar = 90, \
|
||||
/obj/item/weapon/kitchen/utensil/fork = 60
|
||||
)
|
||||
|
||||
time = 24
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
name = "mend internal bleeding"
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/FixOVein = 100, \
|
||||
/obj/item/stack/cable_coil = 75
|
||||
/obj/item/stack/cable_coil = 90
|
||||
)
|
||||
can_infect = 1
|
||||
blood_level = 1
|
||||
@@ -107,8 +107,8 @@
|
||||
name = "remove dead tissue"
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel = 100, \
|
||||
/obj/item/weapon/kitchen/knife = 75, \
|
||||
/obj/item/weapon/shard = 50, \
|
||||
/obj/item/weapon/kitchen/knife = 90, \
|
||||
/obj/item/weapon/shard = 60, \
|
||||
)
|
||||
|
||||
can_infect = 1
|
||||
@@ -156,12 +156,12 @@
|
||||
name = "treat necrosis"
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/reagent_containers/dropper = 100,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle = 75,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 70,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle = 65,
|
||||
/obj/item/weapon/reagent_containers/glass/beaker = 60,
|
||||
/obj/item/weapon/reagent_containers/spray = 50,
|
||||
/obj/item/weapon/reagent_containers/glass/bucket = 40
|
||||
/obj/item/weapon/reagent_containers/glass/bottle = 90,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 85,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle = 80,
|
||||
/obj/item/weapon/reagent_containers/glass/beaker = 75,
|
||||
/obj/item/weapon/reagent_containers/spray = 60,
|
||||
/obj/item/weapon/reagent_containers/glass/bucket = 50
|
||||
)
|
||||
|
||||
can_infect = 0
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
/datum/surgery_step/slime/cut_flesh
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel = 100, \
|
||||
/obj/item/weapon/kitchen/knife = 75, \
|
||||
/obj/item/weapon/shard = 50, \
|
||||
/obj/item/weapon/kitchen/knife = 90, \
|
||||
/obj/item/weapon/shard = 60, \
|
||||
)
|
||||
|
||||
time = 16
|
||||
@@ -46,8 +46,8 @@
|
||||
/datum/surgery_step/slime/cut_innards
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/scalpel = 100, \
|
||||
/obj/item/weapon/kitchen/knife = 75, \
|
||||
/obj/item/weapon/shard = 50, \
|
||||
/obj/item/weapon/kitchen/knife = 90, \
|
||||
/obj/item/weapon/shard = 60, \
|
||||
)
|
||||
|
||||
time = 16
|
||||
@@ -73,7 +73,7 @@
|
||||
/datum/surgery_step/slime/saw_core
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/circular_saw = 100, \
|
||||
/obj/item/weapon/hatchet = 75
|
||||
/obj/item/weapon/hatchet = 90
|
||||
)
|
||||
|
||||
time = 16
|
||||
|
||||
@@ -116,6 +116,12 @@
|
||||
prob_chance = allowed_tools[implement_type]
|
||||
prob_chance *= get_location_modifier(target)
|
||||
|
||||
|
||||
if(!ispath(surgery.steps[surgery.status], /datum/surgery_step/robotics) && !ispath(surgery.steps[surgery.status], /datum/surgery_step/rigsuit))//Repairing robotic limbs doesn't hurt, and neither does cutting someone out of a rig
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target //typecast to human
|
||||
prob_chance *= get_pain_modifier(H)//operating on conscious people is hard.
|
||||
|
||||
if(prob(prob_chance) || isrobot(user))
|
||||
if(end_step(user, target, target_zone, tool, surgery))
|
||||
advance = 1
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
icon = 'icons/vehicles/CargoTrain.dmi'
|
||||
icon_state = "ambulance"
|
||||
anchored = 0
|
||||
throw_pressure_limit = 9001 //Throwing an ambulance trolley can kill the process scheduler.
|
||||
|
||||
/obj/structure/stool/bed/amb_trolley/MouseDrop(obj/over_object as obj)
|
||||
..()
|
||||
@@ -55,4 +56,4 @@
|
||||
to_chat(usr, "You unhook the bed to the ambulance.")
|
||||
else
|
||||
amb.bed = src
|
||||
to_chat(usr, "You hook the bed to the ambulance.")
|
||||
to_chat(usr, "You hook the bed to the ambulance.")
|
||||
|
||||
Reference in New Issue
Block a user