merge conflict fix

This commit is contained in:
FalseIncarnate
2017-10-28 18:38:20 -04:00
257 changed files with 4495 additions and 2115 deletions
+7
View File
@@ -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
+26 -2
View File
@@ -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"
+185
View File
@@ -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)
+22 -9
View File
@@ -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()
+11 -1
View File
@@ -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'
+17
View File
@@ -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)]-&gt;[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>")
+46
View File
@@ -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>")
+1 -1
View File
@@ -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)
+2
View File
@@ -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])
+12 -7
View File
@@ -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."
+21 -1
View File
@@ -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 -3
View File
@@ -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)
+2 -2
View File
@@ -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>")
+1
View File
@@ -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))
+1 -18
View File
@@ -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")
+34 -2
View File
@@ -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)"
+28 -8
View File
@@ -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
+24 -7
View File
@@ -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
+3
View File
@@ -1,6 +1,9 @@
/mob/living/death(gibbed)
blinded = max(blinded, 1)
if(suiciding)
mind.suicided = TRUE
clear_fullscreens()
update_action_buttons_icon()
+1
View File
@@ -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"
+38 -5
View File
@@ -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>&nbsp;</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
View File
@@ -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")
/*
///////////////////////////////////
/ =---------------------------= /
+104
View File
@@ -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
-2
View File
@@ -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
View File
@@ -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
+12 -6
View File
@@ -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)
+2 -2
View File
@@ -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()
+5 -5
View File
@@ -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)
+5 -5
View File
@@ -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
+4 -4
View File
@@ -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
+9 -9
View File
@@ -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
+15 -15
View File
@@ -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
+18 -1
View File
@@ -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)
+2 -2
View File
@@ -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
+23 -1
View File
@@ -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
+1 -1
View File
@@ -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
+17 -17
View File
@@ -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
+9 -9
View File
@@ -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
+5 -5
View File
@@ -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
+6
View File
@@ -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
+2 -1
View File
@@ -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.")