mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 11:34:19 +01:00
Merge branch 'master' into set_species
# Conflicts: # code/game/gamemodes/changeling/powers/transform.dm
This commit is contained in:
@@ -60,9 +60,9 @@ var/global/nologevent = 0
|
||||
body += "<a href='?_src_=holder;traitor=\ref[M]'>TP</a> - "
|
||||
body += "<a href='?src=[usr.UID()];priv_msg=\ref[M]'>PM</a> - "
|
||||
body += "<a href='?_src_=holder;subtlemessage=\ref[M]'>SM</a> - "
|
||||
body += "[admin_jump_link(M)]\] </b><br>"
|
||||
if(ishuman(M) && M.mind)
|
||||
body += "<a href='?_src_=holder;HeadsetMessage=[M.UID()]'>HM</a>"
|
||||
body += "<a href='?_src_=holder;HeadsetMessage=[M.UID()]'>HM</a> -"
|
||||
body += "[admin_jump_link(M)]\] </b><br>"
|
||||
body += "<b>Mob type:</b> [M.type]<br>"
|
||||
if(M.client)
|
||||
if(M.client.related_accounts_cid.len)
|
||||
@@ -566,7 +566,7 @@ var/global/nologevent = 0
|
||||
if(!check_rights(R_SERVER,0))
|
||||
message = adminscrub(message,500)
|
||||
message = replacetext(message, "\n", "<br>") // required since we're putting it in a <p> tag
|
||||
to_chat(world, "<span class=notice><b>[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:</b><p style='text-indent: 50px'>[message]</p></span>")
|
||||
to_chat(world, "<span class='notice'><b>[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:</b><p style='text-indent: 50px'>[message]</p></span>")
|
||||
log_admin("Announce: [key_name(usr)] : [message]")
|
||||
feedback_add_details("admin_verb","A") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -170,7 +170,6 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/admin_serialize,
|
||||
/client/proc/jump_to_ruin,
|
||||
/client/proc/toggle_medal_disable,
|
||||
/client/proc/startadmintickets,
|
||||
)
|
||||
var/list/admin_verbs_possess = list(
|
||||
/proc/possess,
|
||||
|
||||
@@ -407,11 +407,11 @@
|
||||
dat += "Current Game Mode: <B>[ticker.mode.name]</B><BR>"
|
||||
dat += "Round Duration: <B>[round(ROUND_TIME / 36000)]:[add_zero(num2text(ROUND_TIME / 600 % 60), 2)]:[add_zero(num2text(ROUND_TIME / 10 % 60), 2)]</B><BR>"
|
||||
dat += "<B>Emergency shuttle</B><BR>"
|
||||
if(shuttle_master.emergency.mode < SHUTTLE_CALL)
|
||||
if(SSshuttle.emergency.mode < SHUTTLE_CALL)
|
||||
dat += "<a href='?src=[UID()];call_shuttle=1'>Call Shuttle</a><br>"
|
||||
else
|
||||
var/timeleft = shuttle_master.emergency.timeLeft()
|
||||
if(shuttle_master.emergency.mode < SHUTTLE_DOCKED)
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
if(SSshuttle.emergency.mode < SHUTTLE_DOCKED)
|
||||
dat += "ETA: <a href='?_src_=holder;edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
|
||||
dat += "<a href='?_src_=holder;call_shuttle=2'>Send Back</a><br>"
|
||||
else
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,172 +0,0 @@
|
||||
/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)
|
||||
@@ -1,51 +1,33 @@
|
||||
//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))
|
||||
if(!holder || !check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
globAdminTicketHolder.showUI(usr)
|
||||
SStickets.showUI(usr)
|
||||
|
||||
/client/proc/resolveAllTickets()
|
||||
set name = "Resolve All Open Tickets"
|
||||
set category = "Admin"
|
||||
|
||||
if(!holder && !check_rights(R_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()
|
||||
|
||||
|
||||
SStickets.resolveAllOpenTickets()
|
||||
|
||||
/client/proc/openUserUI()
|
||||
|
||||
set name = "My Tickets"
|
||||
set category = "Admin"
|
||||
|
||||
if(!holder && !check_rights(R_ADMIN))
|
||||
if(!holder || !check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
globAdminTicketHolder.userDetailUI(usr.client)
|
||||
SStickets.userDetailUI(usr)
|
||||
|
||||
+14
-15
@@ -30,7 +30,7 @@
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/ticketID = text2num(href_list["openadminticket"])
|
||||
globAdminTicketHolder.showDetailUI(usr, ticketID)
|
||||
SStickets.showDetailUI(usr, ticketID)
|
||||
|
||||
if(href_list["stickyban"])
|
||||
stickyban(href_list["stickyban"],href_list)
|
||||
@@ -274,22 +274,22 @@
|
||||
|
||||
switch(href_list["call_shuttle"])
|
||||
if("1")
|
||||
if(shuttle_master.emergency.mode >= SHUTTLE_DOCKED)
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
|
||||
return
|
||||
shuttle_master.emergency.request()
|
||||
SSshuttle.emergency.request()
|
||||
log_admin("[key_name(usr)] called the Emergency Shuttle")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>")
|
||||
|
||||
if("2")
|
||||
if(shuttle_master.emergency.mode >= SHUTTLE_DOCKED)
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
|
||||
return
|
||||
switch(shuttle_master.emergency.mode)
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
shuttle_master.emergency.cancel()
|
||||
SSshuttle.emergency.cancel()
|
||||
log_admin("[key_name(usr)] sent the Emergency Shuttle back")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] sent the Emergency Shuttle back</span>")
|
||||
else
|
||||
shuttle_master.emergency.cancel()
|
||||
SSshuttle.emergency.cancel()
|
||||
log_admin("[key_name(usr)] called the Emergency Shuttle")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>")
|
||||
|
||||
@@ -299,10 +299,10 @@
|
||||
else if(href_list["edit_shuttle_time"])
|
||||
if(!check_rights(R_SERVER)) return
|
||||
|
||||
var/timer = input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", shuttle_master.emergency.timeLeft() ) as num
|
||||
shuttle_master.emergency.setTimer(timer*10)
|
||||
var/timer = input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", SSshuttle.emergency.timeLeft() ) as num
|
||||
SSshuttle.emergency.setTimer(timer*10)
|
||||
log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds")
|
||||
minor_announcement.Announce("The emergency shuttle will reach its destination in [round(shuttle_master.emergency.timeLeft(600))] minutes.")
|
||||
minor_announcement.Announce("The emergency shuttle will reach its destination in [round(SSshuttle.emergency.timeLeft(600))] minutes.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds</span>")
|
||||
href_list["secrets"] = "check_antagonist"
|
||||
|
||||
@@ -1216,8 +1216,7 @@
|
||||
|
||||
//strip their stuff and stick it in the crate
|
||||
for(var/obj/item/I in M)
|
||||
M.unEquip(I)
|
||||
if(I)
|
||||
if(M.unEquip(I))
|
||||
I.loc = locker
|
||||
I.layer = initial(I.layer)
|
||||
I.plane = initial(I.plane)
|
||||
@@ -2860,21 +2859,21 @@
|
||||
if("moveminingshuttle")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","ShM")
|
||||
if(!shuttle_master.toggleShuttle("mining","mining_home","mining_away"))
|
||||
if(!SSshuttle.toggleShuttle("mining","mining_home","mining_away"))
|
||||
message_admins("[key_name_admin(usr)] moved mining shuttle")
|
||||
log_admin("[key_name(usr)] moved the mining shuttle")
|
||||
|
||||
if("movelaborshuttle")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","ShL")
|
||||
if(!shuttle_master.toggleShuttle("laborcamp","laborcamp_home","laborcamp_away"))
|
||||
if(!SSshuttle.toggleShuttle("laborcamp","laborcamp_home","laborcamp_away"))
|
||||
message_admins("[key_name_admin(usr)] moved labor shuttle")
|
||||
log_admin("[key_name(usr)] moved the labor shuttle")
|
||||
|
||||
if("moveferry")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","ShF")
|
||||
if(!shuttle_master.toggleShuttle("ferry","ferry_home","ferry_away"))
|
||||
if(!SSshuttle.toggleShuttle("ferry","ferry_home","ferry_away"))
|
||||
message_admins("[key_name_admin(usr)] moved the centcom ferry")
|
||||
log_admin("[key_name(usr)] moved the centcom ferry")
|
||||
|
||||
|
||||
@@ -117,15 +117,15 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
if("Adminhelp")
|
||||
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
|
||||
if(SStickets.checkForOpenTicket(usr)) // If user already has an open ticket
|
||||
var/datum/admin_ticket/T = SStickets.checkForOpenTicket(usr) // 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.
|
||||
ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
|
||||
msg = "<span class='adminhelp'>[selected_type]: </span><span class='boldnotice'>[key_name(src, TRUE, 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>)" : ""](<A HREF='?_src_=holder;take_question=[mob.UID()]'>TAKE</A>) :</span> <span class='adminhelp'>[msg]</span>"
|
||||
//Open a new adminticket and inform the user.
|
||||
globAdminTicketHolder.newTicket(src, prunedmsg, msg)
|
||||
SStickets.newTicket(src, prunedmsg, msg)
|
||||
for(var/client/X in modholders + adminholders)
|
||||
if(X.prefs.sound & SOUND_ADMINHELP)
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
@@ -187,15 +187,15 @@
|
||||
return
|
||||
//Check if the mob being PM'd has any open admin tickets.
|
||||
var/tickets = list()
|
||||
tickets = globAdminTicketHolder.checkForTicket(C)
|
||||
tickets = SStickets.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)
|
||||
tickets = SStickets.checkForTicket(C)
|
||||
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)
|
||||
tickets = SStickets.checkForTicket(C)
|
||||
if(tickets)
|
||||
for(var/datum/admin_ticket/i in tickets)
|
||||
i.addResponse(src, msg)
|
||||
|
||||
@@ -271,7 +271,13 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
return 0
|
||||
var/obj/item/paicard/card = new(T)
|
||||
var/mob/living/silicon/pai/pai = new(card)
|
||||
pai.name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text
|
||||
var/raw_name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text
|
||||
var/new_name = reject_bad_name(raw_name, 1)
|
||||
if(new_name)
|
||||
pai.name = new_name
|
||||
pai.real_name = new_name
|
||||
else
|
||||
to_chat(usr, "<font color='red'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .</font>")
|
||||
pai.real_name = pai.name
|
||||
pai.key = choice.key
|
||||
card.setPersonality(pai)
|
||||
|
||||
@@ -32,7 +32,7 @@ client/proc/one_click_antag()
|
||||
if(M.stat || !M.mind || M.mind.special_role)
|
||||
return FALSE
|
||||
if(temp)
|
||||
if(M.mind.assigned_role in temp.restricted_jobs || M.client.prefs.species in temp.protected_species)
|
||||
if((M.mind.assigned_role in temp.restricted_jobs) || (M.client.prefs.species in temp.protected_species))
|
||||
return FALSE
|
||||
if(role) // Don't even bother evaluating if there's no role
|
||||
if(player_old_enough_antag(M.client,role) && (role in M.client.prefs.be_special) && (!jobban_isbanned(M, role)))
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
prayer_type = "CULTIST PRAYER"
|
||||
deity = ticker.cultdat.entity_name
|
||||
|
||||
log_say("(PRAYER) [msg]", usr)
|
||||
msg = "<span class='notice'>[bicon(cross)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]:</font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=[UID()]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) ([admin_jump_link(src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>) (<A HREF='?_src_=holder;Bless=[UID()]'>BLESS</A>) (<A HREF='?_src_=holder;Smite=[UID()]'>SMITE</A>):</b> [msg]</span>"
|
||||
|
||||
for(var/client/X in admins)
|
||||
@@ -36,7 +37,6 @@
|
||||
to_chat(usr, "Your prayers have been received by the gods.")
|
||||
|
||||
feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//log_admin("HELP: [key_name(src)]: [msg]")
|
||||
|
||||
/proc/Centcomm_announce(var/text , var/mob/Sender)
|
||||
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
|
||||
|
||||
@@ -435,6 +435,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
//Now for special roles and equipment.
|
||||
switch(new_character.mind.special_role)
|
||||
if("traitor")
|
||||
job_master.AssignRank(new_character, new_character.mind.assigned_role, 0)
|
||||
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)
|
||||
ticker.mode.equip_traitor(new_character)
|
||||
if("Wizard")
|
||||
@@ -465,6 +466,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
call(/datum/game_mode/proc/add_law_zero)(new_character)
|
||||
//Add aliens.
|
||||
else
|
||||
job_master.AssignRank(new_character, new_character.mind.assigned_role, 0)
|
||||
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
|
||||
|
||||
//Announces the character on all the systems, based on the record.
|
||||
@@ -794,7 +796,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Admin"
|
||||
set name = "Call Shuttle"
|
||||
|
||||
if(shuttle_master.emergency.mode >= SHUTTLE_DOCKED)
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
|
||||
return
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
@@ -804,11 +806,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(confirm != "Yes") return
|
||||
|
||||
if(alert("Set Shuttle Recallable (Select Yes unless you know what this does)", "Recallable?", "Yes", "No") == "Yes")
|
||||
shuttle_master.emergency.canRecall = TRUE
|
||||
SSshuttle.emergency.canRecall = TRUE
|
||||
else
|
||||
shuttle_master.emergency.canRecall = FALSE
|
||||
SSshuttle.emergency.canRecall = FALSE
|
||||
|
||||
shuttle_master.emergency.request()
|
||||
SSshuttle.emergency.request()
|
||||
|
||||
feedback_add_details("admin_verb","CSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] admin-called the emergency shuttle.")
|
||||
@@ -823,20 +825,20 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
return
|
||||
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return
|
||||
|
||||
if(shuttle_master.emergency.mode >= SHUTTLE_DOCKED)
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
|
||||
return
|
||||
|
||||
if(shuttle_master.emergency.canRecall == FALSE)
|
||||
if(SSshuttle.emergency.canRecall == FALSE)
|
||||
if(alert("Shuttle is currently set to be nonrecallable. Recalling may break things. Respect Recall Status?", "Override Recall Status?", "Yes", "No") == "Yes")
|
||||
return
|
||||
else
|
||||
var/keepStatus = alert("Maintain recall status on future shuttle calls?", "Maintain Status?", "Yes", "No") == "Yes" //Keeps or drops recallability
|
||||
shuttle_master.emergency.canRecall = TRUE // must be true for cancel proc to work
|
||||
shuttle_master.emergency.cancel()
|
||||
SSshuttle.emergency.canRecall = TRUE // must be true for cancel proc to work
|
||||
SSshuttle.emergency.cancel()
|
||||
if(keepStatus)
|
||||
shuttle_master.emergency.canRecall = FALSE // restores original status
|
||||
SSshuttle.emergency.canRecall = FALSE // restores original status
|
||||
else
|
||||
shuttle_master.emergency.cancel()
|
||||
SSshuttle.emergency.cancel()
|
||||
|
||||
feedback_add_details("admin_verb","CCSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] admin-recalled the emergency shuttle.")
|
||||
@@ -853,11 +855,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(shuttle_master)
|
||||
shuttle_master.emergencyNoEscape = !shuttle_master.emergencyNoEscape
|
||||
if(SSshuttle)
|
||||
SSshuttle.emergencyNoEscape = !SSshuttle.emergencyNoEscape
|
||||
|
||||
log_admin("[key_name(src)] has [shuttle_master.emergencyNoEscape ? "denied" : "allowed"] the shuttle to be called.")
|
||||
message_admins("[key_name_admin(usr)] has [shuttle_master.emergencyNoEscape ? "denied" : "allowed"] the shuttle to be called.")
|
||||
log_admin("[key_name(src)] has [SSshuttle.emergencyNoEscape ? "denied" : "allowed"] the shuttle to be called.")
|
||||
message_admins("[key_name_admin(usr)] has [SSshuttle.emergencyNoEscape ? "denied" : "allowed"] the shuttle to be called.")
|
||||
|
||||
/client/proc/cmd_admin_attack_log(mob/M as mob in mob_list)
|
||||
set category = "Admin"
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
spawn_antag(C, get_turf(src.loc), "syndieborg")
|
||||
else
|
||||
checking = FALSE
|
||||
to_chat(user, "<span class='notice'>Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.</span>")
|
||||
to_chat(user, "<span class='notice'>Unable to connect to Syndicate command. Please wait and try again later or refund your teleporter through your uplink.</span>")
|
||||
return
|
||||
|
||||
/obj/item/antag_spawner/borg_tele/spawn_antag(client/C, turf/T, type = "")
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
icon_state = "clawmachine_on"
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 40
|
||||
var/tokens = 0
|
||||
var/freeplay = 0 //for debugging and admin kindness
|
||||
@@ -112,28 +112,7 @@
|
||||
to_chat(user, "Unable to access account: incorrect credentials.")
|
||||
return 0
|
||||
|
||||
if(token_price > customer_account.money)
|
||||
to_chat(user, "Insufficient funds in account.")
|
||||
return 0
|
||||
else
|
||||
// Okay to move the money at this point
|
||||
|
||||
// debit money from the purchaser's account
|
||||
customer_account.money -= token_price
|
||||
|
||||
// create entry in the purchaser's account log
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = "[src.name]"
|
||||
T.purpose = "Purchase of [src.name] credit"
|
||||
if(token_price > 0)
|
||||
T.amount = "([token_price])"
|
||||
else
|
||||
T.amount = "[token_price]"
|
||||
T.source_terminal = src.name
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
customer_account.transaction_log.Add(T)
|
||||
return 1
|
||||
return customer_account.charge(token_price, null, "Purchase of [name] credit", name, name)
|
||||
|
||||
/obj/machinery/arcade/proc/start_play(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
@@ -159,4 +138,4 @@
|
||||
|
||||
/obj/machinery/arcade/Destroy()
|
||||
src.close_game()
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
window_name = "Claw Game"
|
||||
var/machine_image = "_1"
|
||||
var/bonus_prize_chance = 5 //chance to dispense a SECOND prize if you win, increased by matter bin rating
|
||||
|
||||
//This is to make sure the images are available
|
||||
var/list/img_resources = list('icons/obj/arcade_images/backgroundsprite.png',
|
||||
'icons/obj/arcade_images/clawpieces.png',
|
||||
@@ -49,26 +48,25 @@
|
||||
icon_state = "clawmachine[machine_image]_off"
|
||||
else
|
||||
icon_state = "clawmachine[machine_image]_on"
|
||||
return
|
||||
|
||||
/obj/machinery/arcade/claw/win()
|
||||
icon_state = "clawmachine[machine_image]_win"
|
||||
visible_message("<span class='game say'><span class='name'>[src.name]</span> beeps, \"WINNER!\"</span>")
|
||||
if(prob(bonus_prize_chance))
|
||||
//double prize mania!
|
||||
if(prob(bonus_prize_chance)) //double prize mania!
|
||||
atom_say("DOUBLE PRIZE!")
|
||||
new /obj/item/toy/prizeball(get_turf(src))
|
||||
else
|
||||
atom_say("WINNER!")
|
||||
new /obj/item/toy/prizeball(get_turf(src))
|
||||
playsound(src.loc, 'sound/arcade/Win.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
spawn(10)
|
||||
update_icon()
|
||||
addtimer(CALLBACK(src, .update_icon), 10)
|
||||
|
||||
/obj/machinery/arcade/claw/start_play(mob/user as mob)
|
||||
..()
|
||||
user << browse_rsc('page.css')
|
||||
for(var/i=1, i<=img_resources.len, i++)
|
||||
for(var/i in 1 to img_resources.len)
|
||||
user << browse_rsc(img_resources[i])
|
||||
var/my_game_html = replacetext(claw_game_html, "/* ref src */", UID())
|
||||
user << browse(my_game_html, "window=[window_name];size=700x600")
|
||||
user << browse(my_game_html, "window=[window_name];size=915x600;can_resize=0")
|
||||
|
||||
/obj/machinery/arcade/claw/Topic(href, list/href_list)
|
||||
if(..())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Crane game</title>
|
||||
<title>Claw Game</title>
|
||||
<link rel="stylesheet" type="text/css" href="page.css" />
|
||||
<script src="libraries.min.js"></script>
|
||||
<!-- Prize.js --><script>
|
||||
@@ -22,7 +22,6 @@
|
||||
$(pic).append(ball);
|
||||
$('#game').append(pic);
|
||||
|
||||
//console.log(crane);
|
||||
this.GetState = function() {return state};
|
||||
|
||||
var CheckBoundaries = function () {
|
||||
@@ -38,12 +37,11 @@
|
||||
top = 347;
|
||||
state = 'resting';
|
||||
} else if(top > 500 && state =='won') {
|
||||
top=500;
|
||||
top = 500;
|
||||
}
|
||||
};
|
||||
|
||||
var CheckGrabbed = function() {
|
||||
|
||||
var tmp = Math.floor(Math.random()*100);
|
||||
if(tmp>error) {
|
||||
setTimeout(function(){
|
||||
@@ -51,8 +49,9 @@
|
||||
$('#debug-streak').html(0); //reset streak
|
||||
setTimeout(gameShutDown,500); //end game because you dropped it
|
||||
},4*error+300);
|
||||
}
|
||||
|
||||
}else{
|
||||
prizeWon = true; // Incase you are interupted, you still get a prize.
|
||||
}
|
||||
state = 'is grabbed';
|
||||
};
|
||||
|
||||
@@ -63,7 +62,7 @@
|
||||
top = 347;
|
||||
|
||||
left = crane.GetLeft()+23;
|
||||
if(left <= 60) {
|
||||
if(left <= 60) { // Claw has reached the drop-off with payload.
|
||||
left = 60;
|
||||
state = 'won';
|
||||
}
|
||||
@@ -95,10 +94,8 @@
|
||||
top += vspd;
|
||||
|
||||
if(state=='won' && top > 460) {
|
||||
$('#prize'+id).remove();//css({visibility:'hidden'});
|
||||
$('#prize'+id).remove();
|
||||
state='hidden';
|
||||
|
||||
prizeWon = true;
|
||||
gameShutDown();
|
||||
}
|
||||
|
||||
@@ -107,16 +104,14 @@
|
||||
|
||||
this.Repaint = function () {
|
||||
$('#prize'+id).css({'top':top, 'left':left});
|
||||
//$('#'+id+' #crane-handle-top').css({height: handleHeight});
|
||||
};
|
||||
|
||||
}</script>
|
||||
<!-- Crane.js --><script>
|
||||
function Crane(id) {
|
||||
//console.log("crane created");
|
||||
var top = 131; //private
|
||||
var left = 100;
|
||||
var hspd = 6;
|
||||
var hspd = 5;
|
||||
var vspd = 4;
|
||||
var state = false;
|
||||
var handleHeight = 83;
|
||||
@@ -131,34 +126,39 @@
|
||||
this.GetTop = function() {return top};
|
||||
|
||||
var Grab = function () {
|
||||
top += (state == 'down')?vspd:-vspd;
|
||||
handleHeight += (state == 'down')?vspd:-vspd;
|
||||
|
||||
if(top > 300 && state == 'down') { //when going down
|
||||
top = 300;
|
||||
//handleHeight = ;
|
||||
state = 'up';
|
||||
$('#'+id+' #crane-claw').css(frames['half']);
|
||||
} else if(top < 131 && state == 'up') { //when going up
|
||||
top = 131;
|
||||
handleHeight = 83;
|
||||
state = 'drop';
|
||||
|
||||
} else if(state == 'drop') { //when up and dropping
|
||||
left -= hspd;
|
||||
top = 131;
|
||||
handleHeight = 83;
|
||||
if(left < 30) {
|
||||
left = 30;
|
||||
$('#'+id+' #crane-claw').css(frames['open']);
|
||||
setTimeout(function(){$('#'+id+' #crane-claw').css(frames['normal']);state = false;},500);
|
||||
|
||||
}
|
||||
switch (state) {
|
||||
case 'up':
|
||||
top -= vspd;
|
||||
handleHeight -= vspd;
|
||||
if(top < 131) { // when going up
|
||||
top = 131;
|
||||
handleHeight = 83;
|
||||
state = 'drop';
|
||||
}
|
||||
break;
|
||||
case 'down': // when going down
|
||||
top += vspd;
|
||||
handleHeight += vspd;
|
||||
if(top > 300) {
|
||||
top = 300;
|
||||
state = 'up';
|
||||
$('#'+id+' #crane-claw').css(frames['half']);
|
||||
}
|
||||
break;
|
||||
case 'drop': // when up and dropping
|
||||
left -= hspd;
|
||||
top = 131;
|
||||
handleHeight = 83;
|
||||
if(left < 30) {
|
||||
left = 30;
|
||||
$('#'+id+' #crane-claw').css(frames['open']);
|
||||
setTimeout(function(){$('#'+id+' #crane-claw').css(frames['normal']);state = false;},500);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
var CheckBoundaries = function () {
|
||||
|
||||
if(left < 30)
|
||||
left = 30;
|
||||
else if(left > 788)
|
||||
@@ -166,20 +166,18 @@
|
||||
};
|
||||
|
||||
this.Update = function () {
|
||||
//console.log(left);
|
||||
if(keys["left"] && !state) //left
|
||||
left -= hspd;
|
||||
|
||||
if(keys["right"] && !state) //right
|
||||
left += hspd;
|
||||
|
||||
if(keys["down"] && !state) { //drop
|
||||
state = 'down';
|
||||
|
||||
$('#'+id+' #crane-claw').css(frames['open']);
|
||||
}
|
||||
|
||||
if(state) {
|
||||
if(!state){
|
||||
if(keys["left"]) //Move claw left
|
||||
left -= hspd;
|
||||
|
||||
if(keys["right"]) // Move claw right
|
||||
left += hspd;
|
||||
|
||||
if(keys["down"]){ // Drop claw.
|
||||
state = 'down';
|
||||
$('#'+id+' #crane-claw').css(frames['open']);
|
||||
}
|
||||
}else{
|
||||
Grab();
|
||||
}
|
||||
|
||||
@@ -204,57 +202,49 @@
|
||||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
function(callback){
|
||||
window.setTimeout(callback, 1000 / 30);
|
||||
window.setTimeout(callback, 33.333); //1000 / 30
|
||||
};
|
||||
})();
|
||||
|
||||
function animate(){
|
||||
//console.log("animate called");
|
||||
crane.Update();
|
||||
|
||||
for(var i = 0; i< prizes.length; i++)
|
||||
for(var i=0; i<prizes.length; i++){
|
||||
prizes[i].Update();
|
||||
|
||||
for(var i = 0; i< prizes.length; i++)
|
||||
prizes[i].Repaint();
|
||||
}
|
||||
|
||||
crane.Repaint();
|
||||
|
||||
requestAnimFrame(function(){
|
||||
animate();
|
||||
});
|
||||
}
|
||||
|
||||
function joystickControlOn(direction){
|
||||
//console.log(direction);
|
||||
keys[direction] = true;
|
||||
}
|
||||
|
||||
function joystickControlOff(direction){
|
||||
//console.log(direction);
|
||||
keys[direction] = false;
|
||||
}
|
||||
|
||||
function gameStartUp(){ //main function
|
||||
//console.log("game start!");
|
||||
document.getElementById("play_btn").disabled = true; //to prevent button-mashing the start button.
|
||||
for(var i = 0; i< 5; i++)
|
||||
for(var i=0; i<5; i++){ // Creates prize balls.
|
||||
prizes[i] = new Prize(i,{top: Math.ceil(Math.random()*100),left: 400+i*100-Math.ceil(Math.random()*50)},crane);
|
||||
//console.log("prize made");
|
||||
|
||||
//crane.Repaint();
|
||||
}
|
||||
animate();
|
||||
}
|
||||
|
||||
function gameShutDown(){
|
||||
document.getElementById("play_btn").disabled = true;
|
||||
var close_game_link = '<h2>TRY AGAIN!</h2><br><a href="byond://?src=/* ref src */;prizeWon=0">\[Close Game\]</a>'
|
||||
if(prizeWon)
|
||||
close_game_link = '<h2>YOU WON!</h2><br><a href="byond://?src=/* ref src */;prizeWon=1">\[Close Game\]</a>'
|
||||
document.getElementById('game').innerHTML = '<center><h1> GAME OVER!</h1><br>'+close_game_link+'</center>'
|
||||
function checkPrize(){
|
||||
// Tells the machine if it should drop a prize.
|
||||
prizeWon?document.getElementById("close_nao").href = "byond://?src=/* ref src */;prizeWon=1":document.getElementById("close_nao").href = "byond://?src=/* ref src */;prizeWon=0";
|
||||
}
|
||||
|
||||
function gameShutDown(){
|
||||
checkPrize();
|
||||
if(prizeWon){ emergencyShutDown(); }else{
|
||||
document.getElementById('game').innerHTML = '<br><br><br><div class="end-text"><center><h1> GAME OVER!</h1><br><h2>BETTER LUCK NEXT TIME!</h2></center></div>';
|
||||
}
|
||||
}
|
||||
// Runs if close window or press close button.
|
||||
function emergencyShutDown(){
|
||||
checkPrize();
|
||||
document.getElementById("close_nao").click();
|
||||
}
|
||||
</script>
|
||||
@@ -278,11 +268,14 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div id='controls' style='position: absolute; top: 550px'>
|
||||
<br><button id="play_btn" onclick="gameStartUp()">Play Now!</button> <button id="close_btn" onclick="gameShutDown()">Close Game.</button><a id="close_nao" hidden="true" href="byond://?src=/* ref src */;prizeWon=0"></a>
|
||||
<div id='controls' style='position: absolute; top: 515px; left: 385px;'>
|
||||
<br>
|
||||
<button class="button" id="play_btn" onclick="gameStartUp()">Play Now!</button>
|
||||
<button class="button" id="close_btn" onclick="emergencyShutDown()">Close.</button>
|
||||
<a id="close_nao" hidden="true" href="byond://?src=/* ref src */;prizeWon=0"></a>
|
||||
<br>
|
||||
<button onmouseover="joystickControlOn('left')" onmouseout="joystickControlOff('left')">/==<br>\==</button>
|
||||
<button onmousedown="joystickControlOn('down')" onmouseup="joystickControlOff('down')">DROP<br>CLAW</button>
|
||||
<button class="button" onmousedown="joystickControlOn('down')" onmouseup="joystickControlOff('down')">DROP<br>CLAW</button>
|
||||
<button onmouseover="joystickControlOn('right')" onmouseout="joystickControlOff('right')">==\<br>==/</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/Destroy()
|
||||
eject_card(1)
|
||||
if(mob_hunt_server)
|
||||
if(mob_hunt_server.battle_turn)
|
||||
mob_hunt_server.battle_turn = null
|
||||
if(mob_hunt_server.red_terminal == src)
|
||||
mob_hunt_server.red_terminal = null
|
||||
if(mob_hunt_server.blue_terminal == src)
|
||||
mob_hunt_server.blue_terminal = null
|
||||
if(SSmob_hunt)
|
||||
if(SSmob_hunt.battle_turn)
|
||||
SSmob_hunt.battle_turn = null
|
||||
if(SSmob_hunt.red_terminal == src)
|
||||
SSmob_hunt.red_terminal = null
|
||||
if(SSmob_hunt.blue_terminal == src)
|
||||
SSmob_hunt.blue_terminal = null
|
||||
QDEL_NULL(avatar)
|
||||
return ..()
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/eject_card(override = 0)
|
||||
if(!override)
|
||||
if(ready && mob_hunt_server.battle_turn != team)
|
||||
if(ready && SSmob_hunt.battle_turn != team)
|
||||
audible_message("You can't recall on your rival's turn!", null, 2)
|
||||
return
|
||||
card.mob_data = mob_info
|
||||
@@ -126,7 +126,7 @@
|
||||
dat += "<h1>No Nano-Mob card loaded.</h1>"
|
||||
dat += "</td>"
|
||||
dat += "</tr>"
|
||||
if(ready && mob_hunt_server.battle_turn) //offer the surrender option if they are in a battle (ready), but don't have a card loaded
|
||||
if(ready && SSmob_hunt.battle_turn) //offer the surrender option if they are in a battle (ready), but don't have a card loaded
|
||||
dat += "<tr>"
|
||||
dat += "<td><a href='?src=[UID()];surrender=1'>Surrender!</a></td>"
|
||||
dat += "</tr>"
|
||||
@@ -170,7 +170,7 @@
|
||||
dat += "<tr>"
|
||||
dat += "<td><a href='?src=[UID()];ready=1'>Battle!</a></td>"
|
||||
dat += "</tr>"
|
||||
if(ready && !mob_hunt_server.battle_turn)
|
||||
if(ready && !SSmob_hunt.battle_turn)
|
||||
dat += "<tr>"
|
||||
dat += "<td><a href='?src=[UID()];ready=2'>Cancel Battle!</a></td>"
|
||||
dat += "</tr>"
|
||||
@@ -205,23 +205,23 @@
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/check_connection()
|
||||
if(team == "Red")
|
||||
if(mob_hunt_server && !mob_hunt_server.red_terminal)
|
||||
mob_hunt_server.red_terminal = src
|
||||
if(SSmob_hunt && !SSmob_hunt.red_terminal)
|
||||
SSmob_hunt.red_terminal = src
|
||||
else if(team == "Blue")
|
||||
if(mob_hunt_server && !mob_hunt_server.blue_terminal)
|
||||
mob_hunt_server.blue_terminal = src
|
||||
if(SSmob_hunt && !SSmob_hunt.blue_terminal)
|
||||
SSmob_hunt.blue_terminal = src
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/do_attack()
|
||||
if(!ready) //no attacking if you arent ready to fight (duh)
|
||||
return
|
||||
if(!mob_hunt_server || team != mob_hunt_server.battle_turn) //don't attack unless it is actually our turn
|
||||
if(!SSmob_hunt || team != SSmob_hunt.battle_turn) //don't attack unless it is actually our turn
|
||||
return
|
||||
else
|
||||
var/message = "[mob_info.mob_name] attacks!"
|
||||
if(mob_info.nickname)
|
||||
message = "[mob_info.nickname] attacks!"
|
||||
audible_message(message, null, 5)
|
||||
mob_hunt_server.launch_attack(team, mob_info.get_raw_damage(), mob_info.get_attack_type())
|
||||
SSmob_hunt.launch_attack(team, mob_info.get_raw_damage(), mob_info.get_attack_type())
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/start_battle()
|
||||
if(ready) //don't do anything if we are still ready
|
||||
@@ -230,20 +230,20 @@
|
||||
return
|
||||
ready = 1
|
||||
audible_message("[team] Player is ready for battle! Waiting for rival...", null, 5)
|
||||
mob_hunt_server.start_check()
|
||||
SSmob_hunt.start_check()
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/receive_attack(raw_damage, datum/mob_type/attack_type)
|
||||
var/message = mob_info.take_damage(raw_damage, attack_type)
|
||||
avatar.audible_message(message, null, 5)
|
||||
if(!mob_info.cur_health)
|
||||
mob_hunt_server.end_battle(team)
|
||||
SSmob_hunt.end_battle(team)
|
||||
eject_card(1) //force the card out, they were defeated
|
||||
else
|
||||
mob_hunt_server.end_turn()
|
||||
SSmob_hunt.end_turn()
|
||||
|
||||
/obj/machinery/computer/mob_battle_terminal/proc/surrender()
|
||||
audible_message("[team] Player surrenders the battle!", null, 5)
|
||||
mob_hunt_server.end_battle(team, 1)
|
||||
SSmob_hunt.end_battle(team, 1)
|
||||
|
||||
//////////////////////////////
|
||||
// Mob Healing Terminal //
|
||||
|
||||
@@ -94,33 +94,33 @@
|
||||
P.audible_message(message, null, 4)
|
||||
|
||||
/obj/effect/nanomob/proc/despawn()
|
||||
if(mob_hunt_server)
|
||||
if(SSmob_hunt)
|
||||
if(mob_info.is_trap)
|
||||
mob_hunt_server.trap_spawns -= src
|
||||
SSmob_hunt.trap_spawns -= src
|
||||
else
|
||||
mob_hunt_server.normal_spawns -= src
|
||||
SSmob_hunt.normal_spawns -= src
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/nanomob/proc/reveal()
|
||||
if(!mob_hunt_server)
|
||||
if(!SSmob_hunt)
|
||||
return
|
||||
var/list/show_to = list()
|
||||
for(var/A in mob_hunt_server.connected_clients)
|
||||
if((A in clients_encountered) || !mob_hunt_server.connected_clients[A])
|
||||
for(var/A in SSmob_hunt.connected_clients)
|
||||
if((A in clients_encountered) || !SSmob_hunt.connected_clients[A])
|
||||
continue
|
||||
show_to |= mob_hunt_server.connected_clients[A]
|
||||
show_to |= SSmob_hunt.connected_clients[A]
|
||||
display_alt_appearance("nanomob_avatar", show_to)
|
||||
|
||||
/obj/effect/nanomob/proc/conceal(list/hide_from)
|
||||
if(!mob_hunt_server)
|
||||
if(!SSmob_hunt)
|
||||
return
|
||||
var/list/hiding_from = list()
|
||||
if(hide_from)
|
||||
hiding_from = hide_from
|
||||
else
|
||||
for(var/A in mob_hunt_server.connected_clients)
|
||||
if((A in clients_encountered) && mob_hunt_server.connected_clients[A])
|
||||
hiding_from |= mob_hunt_server.connected_clients[A]
|
||||
for(var/A in SSmob_hunt.connected_clients)
|
||||
if((A in clients_encountered) && SSmob_hunt.connected_clients[A])
|
||||
hiding_from |= SSmob_hunt.connected_clients[A]
|
||||
hide_alt_appearance("nanomob_avatar", hiding_from)
|
||||
|
||||
// BATTLE MOB AVATARS
|
||||
|
||||
@@ -72,12 +72,12 @@
|
||||
secondary_type = new secondary_type()
|
||||
if(no_register) //for booster pack cards
|
||||
return
|
||||
if(mob_hunt_server)
|
||||
if(SSmob_hunt)
|
||||
if(set_trap)
|
||||
if(mob_hunt_server.register_trap(src))
|
||||
if(SSmob_hunt.register_trap(src))
|
||||
return
|
||||
else if(select_spawn())
|
||||
if(mob_hunt_server.register_spawn(src))
|
||||
if(SSmob_hunt.register_spawn(src))
|
||||
return
|
||||
qdel(src) //if you reach this, the datum is just pure clutter, so delete it
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
body {
|
||||
/* Disables scroll bars */
|
||||
overflow:hidden;
|
||||
}
|
||||
#background {
|
||||
width:900px;
|
||||
height:406px;
|
||||
@@ -81,4 +85,8 @@
|
||||
//-webkit-border-radius: 30px;
|
||||
//border-radius: 30px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.button {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
icon_state = "prize_counter-on"
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 40
|
||||
var/tickets = 0
|
||||
|
||||
@@ -205,4 +205,4 @@ th.cost.toomuch {background:maroon;}
|
||||
print_tickets()
|
||||
else
|
||||
new /obj/item/stack/tickets(get_turf(src), tickets)
|
||||
tickets = 0
|
||||
tickets = 0
|
||||
|
||||
@@ -10,46 +10,67 @@
|
||||
|
||||
bomb_name = "voice-activated bomb"
|
||||
|
||||
describe()
|
||||
if(recorded || listening)
|
||||
return "A meter on [src] flickers with every nearby sound."
|
||||
else
|
||||
return "[src] is deactivated."
|
||||
/obj/item/assembly/voice/describe()
|
||||
if(recorded || listening)
|
||||
return "A meter on [src] flickers with every nearby sound."
|
||||
else
|
||||
return "[src] is deactivated."
|
||||
|
||||
hear_talk(mob/living/M as mob, msg)
|
||||
hear_input(M, msg, 0)
|
||||
/obj/item/assembly/voice/hear_talk(mob/living/M as mob, msg)
|
||||
hear_input(M, msg, 0)
|
||||
|
||||
hear_message(mob/living/M as mob, msg)
|
||||
/obj/item/assembly/voice/hear_message(mob/living/M as mob, msg)
|
||||
hear_input(M, msg, 1)
|
||||
|
||||
proc/hear_input(mob/living/M as mob, msg, type)
|
||||
if(!istype(M,/mob/living))
|
||||
return
|
||||
if(listening)
|
||||
recorded = msg
|
||||
recorded_type = type
|
||||
listening = 0
|
||||
var/turf/T = get_turf(src) //otherwise it won't work in hand
|
||||
T.visible_message("[bicon(src)] beeps, \"Activation message is [type ? "the sound when one [recorded]" : "'[recorded]'."]\"")
|
||||
else
|
||||
if(findtext(msg, recorded) && type == recorded_type)
|
||||
pulse(0)
|
||||
var/turf/T = get_turf(src) //otherwise it won't work in hand
|
||||
T.visible_message("<span class='warning'>[bicon(src)] beeps!</span>")
|
||||
/obj/item/assembly/voice/proc/hear_input(mob/living/M as mob, msg, type)
|
||||
if(!istype(M,/mob/living))
|
||||
return
|
||||
if(listening)
|
||||
recorded = msg
|
||||
recorded_type = type
|
||||
listening = 0
|
||||
var/turf/T = get_turf(src) //otherwise it won't work in hand
|
||||
T.visible_message("[bicon(src)] beeps, \"Activation message is [type ? "the sound when one [recorded]" : "'[recorded]'."]\"")
|
||||
else if(findtext(msg, recorded) && type == recorded_type)
|
||||
pulse(0)
|
||||
var/turf/T = get_turf(src) //otherwise it won't work in hand
|
||||
T.visible_message("<span class='warning'>[bicon(src)] beeps!</span>")
|
||||
|
||||
activate()
|
||||
return // previously this toggled listning when not in a holder, that's a little silly. It was only called in attack_self that way.
|
||||
/obj/item/assembly/voice/activate()
|
||||
return // previously this toggled listning when not in a holder, that's a little silly. It was only called in attack_self that way.
|
||||
|
||||
|
||||
attack_self(mob/user)
|
||||
if(!user || !secured) return 0
|
||||
/obj/item/assembly/voice/attack_self(mob/user)
|
||||
if(!user || !secured) return 0
|
||||
|
||||
listening = !listening
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("[bicon(src)] beeps, \"[listening ? "Now" : "No longer"] recording input.\"")
|
||||
return 1
|
||||
listening = !listening
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("[bicon(src)] beeps, \"[listening ? "Now" : "No longer"] recording input.\"")
|
||||
return 1
|
||||
|
||||
|
||||
toggle_secure()
|
||||
. = ..()
|
||||
listening = 0
|
||||
/obj/item/assembly/voice/toggle_secure()
|
||||
. = ..()
|
||||
listening = 0
|
||||
|
||||
/obj/item/assembly/voice/noise
|
||||
name = "noise sensor"
|
||||
desc = "A simple noise sensor that triggers on vocalizations other then speech."
|
||||
icon_state = "voice"
|
||||
materials = list(MAT_METAL=100, MAT_GLASS=10)
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
bomb_name = "noise-activated bomb"
|
||||
|
||||
/obj/item/assembly/voice/noise/attack_self(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/voice/noise/describe()
|
||||
return "[src] does not appear to have any controls."
|
||||
|
||||
/obj/item/assembly/voice/noise/hear_talk(mob/living/M as mob, msg)
|
||||
return
|
||||
|
||||
/obj/item/assembly/voice/hear_message(mob/living/M as mob, msg)
|
||||
pulse(0)
|
||||
var/turf/T = get_turf(src) //otherwise it won't work in hand
|
||||
T.visible_message("<span class='warning'>[bicon(src)] beeps!</span>")
|
||||
+497
-250
@@ -4,295 +4,542 @@
|
||||
|
||||
//To do: Allow corpses to appear mangled, bloody, etc. Allow customizing the bodies appearance (they're all bald and white right now).
|
||||
|
||||
/obj/effect/landmark/corpse
|
||||
/obj/effect/mob_spawn
|
||||
name = "Unknown"
|
||||
var/mobname = "Unknown" //Unused now but it'd fuck up maps to remove it now
|
||||
var/mob_species = null //Set to make a mob of another race, currently used only in ruins
|
||||
var/corpseuniform = null //Set this to an object path to have the slot filled with said object on the corpse.
|
||||
var/corpsesuit = null
|
||||
var/corpseshoes = null
|
||||
var/corpsegloves = null
|
||||
var/corpseradio = null
|
||||
var/corpseglasses = null
|
||||
var/corpsemask = null
|
||||
var/corpsehelmet = null
|
||||
var/corpsebelt = null
|
||||
var/corpsepocket1 = null
|
||||
var/corpsepocket2 = null
|
||||
var/corpseback = null
|
||||
var/corpseid = 0 //Just set to 1 if you want them to have an ID
|
||||
var/corpseidjob = null // Needs to be in quotes, such as "Clown" or "Chef." This just determines what the ID reads as, not their access
|
||||
var/corpseidaccess = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access.
|
||||
var/corpseidicon = null //For setting it to be a gold, silver, centcomm etc ID
|
||||
var/timeofdeath = null
|
||||
var/coffin = 0
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remains"
|
||||
var/mob_type = null
|
||||
var/mob_name = ""
|
||||
var/mob_gender = null
|
||||
var/death = TRUE //Kill the mob
|
||||
var/roundstart = TRUE //fires on initialize
|
||||
var/instant = FALSE //fires on New
|
||||
var/flavour_text = "The mapper forgot to set this!"
|
||||
var/faction = null
|
||||
var/permanent = FALSE //If true, the spawner will not disappear upon running out of uses.
|
||||
var/random = FALSE //Don't set a name or gender, just go random
|
||||
var/objectives = null
|
||||
var/uses = 1 //how many times can we spawn from it. set to -1 for infinite.
|
||||
var/brute_damage = 0
|
||||
var/oxy_damage = 0
|
||||
var/burn_damage = 0
|
||||
var/datum/disease/disease = null //Do they start with a pre-spawned disease?
|
||||
var/mob_color //Change the mob's color
|
||||
var/assignedrole
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/banType = "lavaland"
|
||||
|
||||
/obj/effect/landmark/corpse/Initialize()
|
||||
..()
|
||||
if(istype(src,/obj/effect/landmark/corpse/clown))
|
||||
var/obj/effect/landmark/corpse/clown/C = src
|
||||
C.chooseRank()
|
||||
createCorpse()
|
||||
|
||||
/obj/effect/landmark/corpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it.
|
||||
var/mob/living/carbon/human/M = new /mob/living/carbon/human(src.loc)
|
||||
M.real_name = src.name
|
||||
M.death(1) //Kills the new mob
|
||||
/obj/effect/mob_spawn/attack_ghost(mob/user)
|
||||
if(ticker.current_state != GAME_STATE_PLAYING || !loc)
|
||||
return
|
||||
if(!uses)
|
||||
to_chat(user, "<span class='warning'>This spawner is out of charges!</span>")
|
||||
return
|
||||
if(jobban_isbanned(user, banType))
|
||||
to_chat(user, "<span class='warning'>You are jobanned!</span>")
|
||||
return
|
||||
var/ghost_role = alert("Become [mob_name]? (Warning, You can no longer be cloned!)",,"Yes","No")
|
||||
if(ghost_role == "No" || !loc)
|
||||
return
|
||||
log_game("[user.ckey] became [mob_name]")
|
||||
create(ckey = user.ckey)
|
||||
|
||||
/obj/effect/mob_spawn/Initialize(mapload)
|
||||
. = ..()
|
||||
if(instant || (roundstart && (ticker && ticker.current_state > GAME_STATE_SETTING_UP)))
|
||||
create()
|
||||
else
|
||||
poi_list |= src
|
||||
LAZYADD(GLOB.mob_spawners[name], src)
|
||||
|
||||
/obj/effect/mob_spawn/Destroy()
|
||||
poi_list -= src
|
||||
var/list/spawners = GLOB.mob_spawners[name]
|
||||
LAZYREMOVE(spawners, src)
|
||||
if(!LAZYLEN(spawners))
|
||||
GLOB.mob_spawners -= name
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/proc/special(mob/M)
|
||||
return
|
||||
|
||||
/obj/effect/mob_spawn/proc/equip(mob/M)
|
||||
return
|
||||
|
||||
/obj/effect/mob_spawn/proc/create(ckey, flavour = TRUE, name)
|
||||
var/mob/living/M = new mob_type(get_turf(src)) //living mobs only
|
||||
if(!random)
|
||||
M.real_name = mob_name ? mob_name : M.name
|
||||
if(!mob_gender)
|
||||
mob_gender = pick(MALE, FEMALE)
|
||||
M.gender = mob_gender
|
||||
if(faction)
|
||||
M.faction = list(faction)
|
||||
if(disease)
|
||||
M.ForceContractDisease(new disease)
|
||||
if(death)
|
||||
M.death(1) //Kills the new mob
|
||||
|
||||
M.adjustOxyLoss(oxy_damage)
|
||||
M.adjustBruteLoss(brute_damage)
|
||||
M.timeofdeath = timeofdeath
|
||||
if(mob_species)
|
||||
M.set_species(mob_species)
|
||||
if(corpseuniform)
|
||||
M.equip_to_slot_or_del(new corpseuniform(M), slot_w_uniform)
|
||||
if(corpsesuit)
|
||||
M.equip_to_slot_or_del(new corpsesuit(M), slot_wear_suit)
|
||||
if(corpseshoes)
|
||||
M.equip_to_slot_or_del(new corpseshoes(M), slot_shoes)
|
||||
if(corpsegloves)
|
||||
M.equip_to_slot_or_del(new corpsegloves(M), slot_gloves)
|
||||
if(corpseradio)
|
||||
M.equip_to_slot_or_del(new corpseradio(M), slot_l_ear)
|
||||
if(corpseglasses)
|
||||
M.equip_to_slot_or_del(new corpseglasses(M), slot_glasses)
|
||||
if(corpsemask)
|
||||
M.equip_to_slot_or_del(new corpsemask(M), slot_wear_mask)
|
||||
if(corpsehelmet)
|
||||
M.equip_to_slot_or_del(new corpsehelmet(M), slot_head)
|
||||
if(corpsebelt)
|
||||
M.equip_to_slot_or_del(new corpsebelt(M), slot_belt)
|
||||
if(corpsepocket1)
|
||||
M.equip_to_slot_or_del(new corpsepocket1(M), slot_r_store)
|
||||
if(corpsepocket2)
|
||||
M.equip_to_slot_or_del(new corpsepocket2(M), slot_l_store)
|
||||
if(corpseback)
|
||||
M.equip_to_slot_or_del(new corpseback(M), slot_back)
|
||||
if(corpseid == 1)
|
||||
var/obj/item/card/id/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card"
|
||||
var/datum/job/jobdatum
|
||||
for(var/jobtype in typesof(/datum/job))
|
||||
var/datum/job/J = new jobtype
|
||||
if(J.title == corpseidaccess)
|
||||
jobdatum = J
|
||||
break
|
||||
if(corpseidicon)
|
||||
W.icon_state = corpseidicon
|
||||
if(corpseidaccess)
|
||||
if(jobdatum)
|
||||
W.access = jobdatum.get_access()
|
||||
else
|
||||
W.access = list()
|
||||
if(corpseidjob)
|
||||
W.assignment = corpseidjob
|
||||
W.registered_name = M.real_name
|
||||
M.equip_to_slot_or_del(W, slot_wear_id)
|
||||
if(coffin == 1)
|
||||
var/obj/structure/closet/coffin/sarcophagus/sarc = locate(/obj/structure/closet/coffin/sarcophagus) in loc
|
||||
if(sarc) M.loc = sarc
|
||||
qdel(src)
|
||||
M.adjustFireLoss(burn_damage)
|
||||
M.color = mob_color
|
||||
equip(M, TRUE)
|
||||
|
||||
// I'll work on making a list of corpses people request for maps, or that I think will be commonly used. Syndicate operatives for example.
|
||||
/obj/effect/landmark/corpse/damaged
|
||||
if(ckey)
|
||||
M.ckey = ckey
|
||||
if(flavour)
|
||||
to_chat(M, "[flavour_text]")
|
||||
var/datum/mind/MM = M.mind
|
||||
if(objectives)
|
||||
for(var/objective in objectives)
|
||||
MM.objectives += new/datum/objective(objective)
|
||||
if(assignedrole)
|
||||
M.mind.assigned_role = assignedrole
|
||||
special(M, name)
|
||||
MM.name = M.real_name
|
||||
if(uses > 0)
|
||||
uses--
|
||||
if(!permanent && !uses)
|
||||
qdel(src)
|
||||
|
||||
// Base version - place these on maps/templates.
|
||||
/obj/effect/mob_spawn/human
|
||||
mob_type = /mob/living/carbon/human
|
||||
//Human specific stuff.
|
||||
var/mob_species = null //Set species
|
||||
var/datum/outfit/outfit = /datum/outfit //If this is a path, it will be instanced in Initialize()
|
||||
var/disable_pda = TRUE
|
||||
var/disable_sensors = TRUE
|
||||
//All of these only affect the ID that the outfit has placed in the ID slot
|
||||
var/id_job = null //Such as "Clown" or "Chef." This just determines what the ID reads as, not their access
|
||||
var/id_access = null //This is for access. See access.dm for which jobs give what access. Use "Captain" if you want it to be all access.
|
||||
var/id_access_list = null //Allows you to manually add access to an ID card.
|
||||
assignedrole = "Ghost Role"
|
||||
|
||||
var/husk = null
|
||||
//these vars are for lazy mappers to override parts of the outfit
|
||||
//these cannot be null by default, or mappers cannot set them to null if they want nothing in that slot
|
||||
var/uniform = -1
|
||||
var/r_hand = -1
|
||||
var/l_hand = -1
|
||||
var/suit = -1
|
||||
var/shoes = -1
|
||||
var/gloves = -1
|
||||
var/ears = -1
|
||||
var/glasses = -1
|
||||
var/mask = -1
|
||||
var/head = -1
|
||||
var/belt = -1
|
||||
var/r_pocket = -1
|
||||
var/l_pocket = -1
|
||||
var/back = -1
|
||||
var/id = -1
|
||||
var/neck = -1
|
||||
var/pda = -1
|
||||
var/backpack_contents = -1
|
||||
var/suit_store = -1
|
||||
|
||||
var/hair_style
|
||||
var/facial_hair_style
|
||||
var/skin_tone
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/Initialize()
|
||||
if(ispath(outfit))
|
||||
outfit = new outfit()
|
||||
if(!outfit)
|
||||
outfit = new /datum/outfit
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/equip(mob/living/carbon/human/H)
|
||||
if(mob_species)
|
||||
if(H.set_species(mob_species))
|
||||
H.regenerate_icons()
|
||||
if(husk)
|
||||
H.ChangeToHusk()
|
||||
else //Because for some reason I can't track down, things are getting turned into husks even if husk = false. It's in some damage proc somewhere.
|
||||
H.mutations.Remove(HUSK)
|
||||
H.underwear = "Nude"
|
||||
H.undershirt = "Nude"
|
||||
H.socks = "Nude"
|
||||
var/obj/item/organ/external/head/D = H.get_organ("head")
|
||||
if(istype(D))
|
||||
if(hair_style)
|
||||
D.h_style = hair_style
|
||||
else
|
||||
D.h_style = random_hair_style(gender)
|
||||
D.hair_colour = rand_hex_color()
|
||||
if(facial_hair_style)
|
||||
D.f_style = facial_hair_style
|
||||
else
|
||||
D.f_style = random_facial_hair_style(gender)
|
||||
D.facial_colour = rand_hex_color()
|
||||
if(skin_tone)
|
||||
H.s_tone = skin_tone
|
||||
else
|
||||
H.s_tone = random_skin_tone()
|
||||
H.update_hair()
|
||||
H.update_body()
|
||||
if(outfit)
|
||||
var/static/list/slots = list("uniform", "r_hand", "l_hand", "suit", "shoes", "gloves", "ears", "glasses", "mask", "head", "belt", "r_pocket", "l_pocket", "back", "id", "neck", "backpack_contents", "suit_store")
|
||||
for(var/slot in slots)
|
||||
var/T = vars[slot]
|
||||
if(!isnum(T))
|
||||
outfit.vars[slot] = T
|
||||
H.equipOutfit(outfit, TRUE)
|
||||
var/list/del_types = list(/obj/item/pda, /obj/item/radio/headset)
|
||||
for(var/del_type in del_types)
|
||||
var/obj/item/I = locate(del_type) in H
|
||||
qdel(I)
|
||||
|
||||
if(disable_pda)
|
||||
// We don't want corpse PDAs to show up in the messenger list.
|
||||
var/obj/item/pda/PDA = locate(/obj/item/pda) in H
|
||||
if(PDA)
|
||||
var/datum/data/pda/app/messenger/M = PDA.find_program(/datum/data/pda/app/messenger)
|
||||
M.toff = 1
|
||||
if(disable_sensors)
|
||||
// Using crew monitors to find corpses while creative makes finding certain ruins too easy.
|
||||
var/obj/item/clothing/under/C = H.w_uniform
|
||||
if(istype(C))
|
||||
C.sensor_mode = SUIT_SENSOR_OFF
|
||||
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
if(W)
|
||||
if(id_access)
|
||||
for(var/jobtype in typesof(/datum/job))
|
||||
var/datum/job/J = new jobtype
|
||||
if(J.title == id_access)
|
||||
W.access = J.get_access()
|
||||
break
|
||||
if(id_access_list)
|
||||
if(!islist(W.access))
|
||||
W.access = list()
|
||||
W.access |= id_access_list
|
||||
if(id_job)
|
||||
W.assignment = id_job
|
||||
W.registered_name = H.real_name
|
||||
W.update_label()
|
||||
|
||||
//Instant version - use when spawning corpses during runtime
|
||||
/obj/effect/mob_spawn/human/corpse
|
||||
roundstart = FALSE
|
||||
instant = TRUE
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/damaged
|
||||
brute_damage = 1000
|
||||
|
||||
/obj/effect/landmark/corpse/syndicatesoldier
|
||||
name = "Syndicate Operative"
|
||||
corpseuniform = /obj/item/clothing/under/syndicate
|
||||
corpsesuit = /obj/item/clothing/suit/armor/vest
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
corpsegloves = /obj/item/clothing/gloves/combat
|
||||
corpseradio = /obj/item/radio/headset
|
||||
corpsemask = /obj/item/clothing/mask/gas
|
||||
corpsehelmet = /obj/item/clothing/head/helmet/swat
|
||||
corpseback = /obj/item/storage/backpack
|
||||
corpseid = 1
|
||||
corpseidjob = "Operative"
|
||||
corpseidaccess = "Syndicate"
|
||||
|
||||
/obj/effect/mob_spawn/human/alive
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper"
|
||||
death = FALSE
|
||||
roundstart = FALSE //you could use these for alive fake humans on roundstart but this is more common scenario
|
||||
|
||||
|
||||
//Non-human spawners
|
||||
|
||||
/obj/effect/landmark/corpse/syndicatecommando
|
||||
name = "Syndicate Commando"
|
||||
corpseuniform = /obj/item/clothing/under/syndicate
|
||||
corpsesuit = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
corpseshoes = /obj/item/clothing/shoes/magboots/syndie
|
||||
corpsegloves = /obj/item/clothing/gloves/combat
|
||||
corpseradio = /obj/item/radio/headset
|
||||
corpsemask = /obj/item/clothing/mask/gas/syndicate
|
||||
corpsehelmet = /obj/item/clothing/head/helmet/space/hardsuit/syndi
|
||||
corpseback = /obj/item/tank/jetpack/oxygen
|
||||
corpsepocket1 = /obj/item/tank/emergency_oxygen
|
||||
corpseid = 1
|
||||
corpseidjob = "Operative"
|
||||
corpseidaccess = "Syndicate"
|
||||
/obj/effect/mob_spawn/mouse
|
||||
name = "sleeper"
|
||||
mob_name = "space mouse"
|
||||
mob_type = /mob/living/simple_animal/mouse
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper"
|
||||
flavour_text = "Squeak!"
|
||||
|
||||
/obj/effect/mob_spawn/cow
|
||||
name = "sleeper"
|
||||
mob_name = "space cow"
|
||||
mob_type = /mob/living/simple_animal/cow
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
mob_gender = FEMALE
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper"
|
||||
flavour_text = "Moo!"
|
||||
|
||||
|
||||
///////////Civilians//////////////////////
|
||||
|
||||
///////////Support//////////////////////
|
||||
/obj/effect/mob_spawn/human/corpse/assistant
|
||||
name = "Assistant"
|
||||
id_job = "Assistant"
|
||||
outfit = /datum/outfit/job/assistant
|
||||
|
||||
/obj/effect/landmark/corpse/chef
|
||||
name = "Chef"
|
||||
corpseuniform = /obj/item/clothing/under/rank/chef
|
||||
corpsesuit = /obj/item/clothing/suit/chef/classic
|
||||
corpseshoes = /obj/item/clothing/shoes/black
|
||||
corpsehelmet = /obj/item/clothing/head/chefhat
|
||||
corpseback = /obj/item/storage/backpack
|
||||
corpseradio = /obj/item/radio/headset
|
||||
corpseid = 1
|
||||
corpseidjob = "Chef"
|
||||
corpseidaccess = "Chef"
|
||||
/obj/effect/mob_spawn/human/corpse/assistant/beesease_infection
|
||||
disease = /datum/disease/beesease
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/assistant/brainrot_infection
|
||||
disease = /datum/disease/brainrot
|
||||
|
||||
/obj/effect/landmark/corpse/doctor
|
||||
/obj/effect/mob_spawn/human/corpse/assistant/spanishflu_infection
|
||||
disease = /datum/disease/fluspanish
|
||||
|
||||
/obj/effect/mob_spawn/human/cook
|
||||
name = "Cook"
|
||||
id_job = "Chef"
|
||||
outfit = /datum/outfit/job/chef
|
||||
|
||||
/obj/effect/mob_spawn/human/doctor
|
||||
name = "Doctor"
|
||||
corpseradio = /obj/item/radio/headset/headset_med
|
||||
corpseuniform = /obj/item/clothing/under/rank/medical
|
||||
corpsesuit = /obj/item/clothing/suit/storage/labcoat
|
||||
corpseback = /obj/item/storage/backpack/medic
|
||||
corpsepocket1 = /obj/item/flashlight/pen
|
||||
corpseshoes = /obj/item/clothing/shoes/black
|
||||
corpseid = 1
|
||||
corpseidjob = "Medical Doctor"
|
||||
corpseidaccess = "Medical Doctor"
|
||||
id_job = "Medical Doctor"
|
||||
outfit = /datum/outfit/job/doctor
|
||||
|
||||
/obj/effect/landmark/corpse/engineer
|
||||
/obj/effect/mob_spawn/human/doctor/alive
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
random = TRUE
|
||||
name = "sleeper"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper"
|
||||
flavour_text = "You are a space doctor!"
|
||||
assignedrole = "Space Doctor"
|
||||
|
||||
/obj/effect/mob_spawn/human/doctor/alive/equip(mob/living/carbon/human/H)
|
||||
..()
|
||||
// Remove radio and PDA so they wouldn't annoy station crew.
|
||||
var/list/del_types = list(/obj/item/pda, /obj/item/radio/headset)
|
||||
for(var/del_type in del_types)
|
||||
var/obj/item/I = locate(del_type) in H
|
||||
qdel(I)
|
||||
|
||||
/obj/effect/mob_spawn/human/engineer
|
||||
name = "Engineer"
|
||||
corpseradio = /obj/item/radio/headset/headset_eng
|
||||
corpseuniform = /obj/item/clothing/under/rank/engineer
|
||||
corpseback = /obj/item/storage/backpack/industrial
|
||||
corpseshoes = /obj/item/clothing/shoes/workboots
|
||||
corpsebelt = /obj/item/storage/belt/utility/full
|
||||
corpsegloves = /obj/item/clothing/gloves/color/yellow
|
||||
corpsehelmet = /obj/item/clothing/head/hardhat
|
||||
corpseid = 1
|
||||
corpseidjob = "Station Engineer"
|
||||
corpseidaccess = "Station Engineer"
|
||||
id_job = "Engineer"
|
||||
outfit = /datum/outfit/job/engineer
|
||||
|
||||
/obj/effect/landmark/corpse/engineer/hardsuit
|
||||
corpsesuit = /obj/item/clothing/suit/space/hardsuit
|
||||
corpsemask = /obj/item/clothing/mask/breath
|
||||
corpsehelmet = /obj/item/clothing/head/helmet/space/hardsuit
|
||||
/obj/effect/mob_spawn/human/engineer/hardsuit
|
||||
outfit = /datum/outfit/job/engineer/suit
|
||||
|
||||
/obj/effect/landmark/corpse/clown
|
||||
/datum/outfit/job/engineer/suit
|
||||
name = "Station Engineer"
|
||||
|
||||
/obj/effect/landmark/corpse/clown/proc/chooseRank()
|
||||
if(prob(10))
|
||||
name = "Clown Officer"
|
||||
corpseuniform = /obj/item/clothing/under/officeruniform
|
||||
corpsesuit = /obj/item/clothing/suit/officercoat
|
||||
corpseshoes = /obj/item/clothing/shoes/clown_shoes
|
||||
corpseradio = /obj/item/radio/headset
|
||||
corpsemask = /obj/item/clothing/mask/gas/clown_hat
|
||||
corpsepocket1 = /obj/item/bikehorn
|
||||
corpseback = /obj/item/storage/backpack/clown
|
||||
corpsehelmet = /obj/item/clothing/head/naziofficer
|
||||
corpseid = 1
|
||||
corpseidjob = "Clown Officer"
|
||||
corpseidaccess = "Clown"
|
||||
timeofdeath = -50000
|
||||
else
|
||||
name = "Clown Soldier"
|
||||
corpseuniform = /obj/item/clothing/under/soldieruniform
|
||||
corpsesuit = /obj/item/clothing/suit/soldiercoat
|
||||
corpseshoes = /obj/item/clothing/shoes/clown_shoes
|
||||
corpseradio = /obj/item/radio/headset
|
||||
corpsemask = /obj/item/clothing/mask/gas/clown_hat
|
||||
corpsepocket1 = /obj/item/bikehorn
|
||||
corpseback = /obj/item/storage/backpack/clown
|
||||
corpsehelmet = /obj/item/clothing/head/stalhelm
|
||||
corpseid = 1
|
||||
corpseidjob = "Clown Soldier"
|
||||
corpseidaccess = "Clown"
|
||||
timeofdeath = -50000
|
||||
uniform = /obj/item/clothing/under/rank/engineer
|
||||
belt = /obj/item/storage/belt/utility/full
|
||||
suit = /obj/item/clothing/suit/space/hardsuit
|
||||
shoes = /obj/item/clothing/shoes/workboots
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
id = /obj/item/card/id/engineering
|
||||
l_pocket = /obj/item/t_scanner
|
||||
|
||||
/obj/effect/landmark/corpse/clownking
|
||||
name = "Clown King"
|
||||
corpseuniform = /obj/item/clothing/under/rank/clown
|
||||
corpseshoes = /obj/item/clothing/shoes/clown_shoes
|
||||
corpseradio = /obj/item/radio/headset
|
||||
corpsemask = /obj/item/clothing/mask/gas/clown_hat
|
||||
corpsehelmet = /obj/item/clothing/head/crown
|
||||
corpsepocket1 = /obj/item/bikehorn
|
||||
corpseback = /obj/item/bedsheet/clown
|
||||
corpseid = 1
|
||||
corpseidjob = "Clown King"
|
||||
corpseidaccess = "Clown"
|
||||
timeofdeath = -50000
|
||||
coffin = 1
|
||||
backpack = /obj/item/storage/backpack/industrial
|
||||
|
||||
/obj/effect/landmark/corpse/mime
|
||||
|
||||
/obj/effect/mob_spawn/human/clown
|
||||
name = "Clown"
|
||||
mob_name = "Clown"
|
||||
id_job = "Clown"
|
||||
outfit = /datum/outfit/job/clown
|
||||
|
||||
/obj/effect/mob_spawn/human/clown/Initialize()
|
||||
mob_name = pick(clown_names)
|
||||
..()
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/clownmili
|
||||
name = "Clown Soldier"
|
||||
outfit = /datum/outfit/clownsoldier
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/clownmili/Initialize()
|
||||
mob_name = "Officer [pick(clown_names)]"
|
||||
..()
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/clownoff
|
||||
name = "Clown Officer"
|
||||
outfit = /datum/outfit/clownofficer
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/clownoff/Initialize()
|
||||
mob_name = "Honk Specialist [pick(clown_names)]"
|
||||
..()
|
||||
|
||||
|
||||
/datum/outfit/clownsoldier
|
||||
uniform = /obj/item/clothing/under/soldieruniform
|
||||
suit = /obj/item/clothing/suit/soldiercoat
|
||||
shoes = /obj/item/clothing/shoes/clown_shoes
|
||||
l_ear = /obj/item/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat
|
||||
l_pocket = /obj/item/bikehorn
|
||||
back = /obj/item/storage/backpack/clown
|
||||
head = /obj/item/clothing/head/stalhelm
|
||||
|
||||
/datum/outfit/clownofficer
|
||||
uniform = /obj/item/clothing/under/officeruniform
|
||||
suit = /obj/item/clothing/suit/officercoat
|
||||
shoes = /obj/item/clothing/shoes/clown_shoes
|
||||
l_ear = /obj/item/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat
|
||||
l_pocket = /obj/item/bikehorn
|
||||
back = /obj/item/storage/backpack/clown
|
||||
head = /obj/item/clothing/head/naziofficer
|
||||
|
||||
/obj/effect/mob_spawn/human/mime
|
||||
name = "Mime"
|
||||
corpseuniform = /obj/item/clothing/under/mime
|
||||
corpseshoes = /obj/item/clothing/shoes/black
|
||||
corpseradio = /obj/item/radio/headset
|
||||
corpsemask = /obj/item/clothing/mask/gas/mime
|
||||
corpseback = /obj/item/storage/backpack
|
||||
corpseid = 1
|
||||
corpseidjob = "Mime"
|
||||
corpseidaccess = "Mime"
|
||||
timeofdeath = -50000
|
||||
mob_name = "Mime"
|
||||
id_job = "Mime"
|
||||
outfit = /datum/outfit/job/mime
|
||||
|
||||
/obj/effect/landmark/corpse/scientist
|
||||
/obj/effect/mob_spawn/human/mime/Initialize()
|
||||
mob_name = pick(mime_names)
|
||||
..()
|
||||
|
||||
/obj/effect/mob_spawn/human/scientist
|
||||
name = "Scientist"
|
||||
corpseradio = /obj/item/radio/headset/headset_sci
|
||||
corpseuniform = /obj/item/clothing/under/rank/scientist
|
||||
corpsesuit = /obj/item/clothing/suit/storage/labcoat/science
|
||||
corpseback = /obj/item/storage/backpack
|
||||
corpseshoes = /obj/item/clothing/shoes/white
|
||||
corpseid = 1
|
||||
corpseidjob = "Scientist"
|
||||
corpseidaccess = "Scientist"
|
||||
id_job = "Scientist"
|
||||
outfit = /datum/outfit/job/scientist
|
||||
|
||||
/obj/effect/landmark/corpse/miner
|
||||
corpseradio = /obj/item/radio/headset/headset_cargo
|
||||
corpseuniform = /obj/item/clothing/under/rank/miner
|
||||
corpsegloves = /obj/item/clothing/gloves/fingerless
|
||||
corpseback = /obj/item/storage/backpack/industrial
|
||||
corpseshoes = /obj/item/clothing/shoes/black
|
||||
corpseid = 1
|
||||
corpseidjob = "Shaft Miner"
|
||||
corpseidaccess = "Shaft Miner"
|
||||
/obj/effect/mob_spawn/human/miner
|
||||
name = "Shaft Miner"
|
||||
id_job = "Shaft Miner"
|
||||
outfit = /datum/outfit/job/mining/suit
|
||||
|
||||
/obj/effect/landmark/corpse/miner/hardsuit
|
||||
corpsesuit = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
corpsemask = /obj/item/clothing/mask/breath
|
||||
corpsehelmet = /obj/item/clothing/head/helmet/space/hardsuit/mining
|
||||
/datum/outfit/job/mining/suit
|
||||
name = "Station Engineer"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/mining
|
||||
uniform = /obj/item/clothing/under/rank/miner
|
||||
gloves = /obj/item/clothing/gloves/fingerless
|
||||
shoes = /obj/item/clothing/shoes/workboots
|
||||
l_ear = /obj/item/radio/headset/headset_cargo/mining
|
||||
id = /obj/item/card/id/supply
|
||||
l_pocket = /obj/item/reagent_containers/food/pill/patch/styptic
|
||||
r_pocket = /obj/item/flashlight/seclite
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/bartender
|
||||
name = "Space Bartender"
|
||||
id_job = "Bartender"
|
||||
id_access_list = list(access_bar)
|
||||
outfit = /datum/outfit/spacebartender
|
||||
|
||||
/obj/effect/mob_spawn/human/bartender/alive
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
random = TRUE
|
||||
name = "bartender sleeper"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper"
|
||||
flavour_text = "You are a space bartender!"
|
||||
assignedrole = "Space Bartender"
|
||||
|
||||
/datum/outfit/spacebartender
|
||||
name = "Space Bartender"
|
||||
uniform = /obj/item/clothing/under/rank/bartender
|
||||
suit = /obj/item/clothing/suit/armor/vest
|
||||
belt = /obj/item/storage/belt/bandolier/full
|
||||
shoes = /obj/item/clothing/shoes/black
|
||||
glasses = /obj/item/clothing/glasses/sunglasses/reagent
|
||||
id = /obj/item/card/id
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/beach
|
||||
outfit = /datum/outfit/beachbum
|
||||
|
||||
/obj/effect/mob_spawn/human/beach/alive
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
random = TRUE
|
||||
mob_name = "Beach Bum"
|
||||
name = "beach bum sleeper"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper"
|
||||
flavour_text = "You are a beach bum!"
|
||||
assignedrole = "Beach Bum"
|
||||
|
||||
/datum/outfit/beachbum
|
||||
name = "Beach Bum"
|
||||
glasses = /obj/item/clothing/glasses/sunglasses
|
||||
uniform = /obj/item/clothing/under/shorts/red
|
||||
|
||||
/////////////////Spooky Undead//////////////////////
|
||||
|
||||
/obj/effect/mob_spawn/human/skeleton
|
||||
name = "skeletal remains"
|
||||
mob_name = "skeleton"
|
||||
mob_species = /datum/species/skeleton
|
||||
mob_gender = NEUTER
|
||||
|
||||
/obj/effect/mob_spawn/human/skeleton/alive
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remains"
|
||||
flavour_text = "By unknown powers, your skeletal remains have been reanimated! Walk this mortal plain and terrorize all living adventurers who dare cross your path."
|
||||
assignedrole = "Skeleton"
|
||||
|
||||
/////////////////Officers//////////////////////
|
||||
|
||||
/obj/effect/landmark/corpse/bridgeofficer
|
||||
/obj/effect/mob_spawn/human/bridgeofficer
|
||||
name = "Bridge Officer"
|
||||
corpseradio = /obj/item/radio/headset/heads/hop
|
||||
corpseuniform = /obj/item/clothing/under/rank/centcom_officer
|
||||
corpsesuit = /obj/item/clothing/suit/armor/bulletproof
|
||||
corpseshoes = /obj/item/clothing/shoes/black
|
||||
corpseglasses = /obj/item/clothing/glasses/sunglasses
|
||||
corpseid = 1
|
||||
corpseidjob = "Bridge Officer"
|
||||
corpseidaccess = "Captain"
|
||||
id_job = "Bridge Officer"
|
||||
id_access = "Captain"
|
||||
outfit = /datum/outfit/nanotrasenbridgeofficercorpse
|
||||
|
||||
/obj/effect/landmark/corpse/commander
|
||||
/datum/outfit/nanotrasenbridgeofficercorpse
|
||||
name = "Bridge Officer Corpse"
|
||||
l_ear = /obj/item/radio/headset/heads/hop
|
||||
uniform = /obj/item/clothing/under/rank/centcom_officer
|
||||
suit = /obj/item/clothing/suit/armor/bulletproof
|
||||
shoes = /obj/item/clothing/shoes/black
|
||||
glasses = /obj/item/clothing/glasses/sunglasses
|
||||
id = /obj/item/card/id
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/commander
|
||||
name = "Commander"
|
||||
corpseuniform = /obj/item/clothing/under/rank/centcom_commander
|
||||
corpsesuit = /obj/item/clothing/suit/armor/bulletproof
|
||||
corpseradio = /obj/item/radio/headset/heads/captain
|
||||
corpseglasses = /obj/item/clothing/glasses/eyepatch
|
||||
corpsemask = /obj/item/clothing/mask/cigarette/cigar/cohiba
|
||||
corpsehelmet = /obj/item/clothing/head/centhat
|
||||
corpsegloves = /obj/item/clothing/gloves/combat
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
corpsepocket1 = /obj/item/lighter/zippo
|
||||
corpseid = 1
|
||||
corpseidjob = "Commander"
|
||||
corpseidaccess = "Captain"
|
||||
id_job = "Commander"
|
||||
id_access = "Captain"
|
||||
outfit = /datum/outfit/nanotrasencommandercorpse
|
||||
|
||||
/obj/effect/landmark/corpse/abductor //Connected to ruins, for some reason?
|
||||
/datum/outfit/nanotrasencommandercorpse
|
||||
name = "Commander Corpse"
|
||||
|
||||
uniform = /obj/item/clothing/under/rank/centcom/officer
|
||||
gloves = /obj/item/clothing/gloves/color/white
|
||||
shoes = /obj/item/clothing/shoes/centcom
|
||||
head = /obj/item/clothing/head/beret/centcom/officer
|
||||
glasses = /obj/item/clothing/glasses/hud/security/sunglasses
|
||||
id = /obj/item/card/id/centcom
|
||||
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/abductor
|
||||
name = "abductor"
|
||||
mobname = "???"
|
||||
mob_name = "alien"
|
||||
mob_species = /datum/species/abductor
|
||||
corpseuniform = /obj/item/clothing/under/color/grey
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
outfit = /datum/outfit/abductorcorpse
|
||||
|
||||
/datum/outfit/abductorcorpse
|
||||
name = "Abductor Corpse"
|
||||
uniform = /obj/item/clothing/under/color/grey
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
|
||||
//For ghost bar.
|
||||
/obj/effect/mob_spawn/human/alive/space_bar_patron
|
||||
name = "Bar cryogenics"
|
||||
mob_name = "Bar patron"
|
||||
random = TRUE
|
||||
permanent = TRUE
|
||||
uses = -1
|
||||
outfit = /datum/outfit/spacebartender
|
||||
assignedrole = "Space Bar Patron"
|
||||
|
||||
/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user)
|
||||
var/despawn = alert("Return to cryosleep? (Warning, Your mob will be deleted!)",,"Yes","No")
|
||||
if(despawn == "No" || !loc || !Adjacent(user))
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user.name] climbs back into cryosleep...</span>")
|
||||
qdel(user)
|
||||
|
||||
/datum/outfit/cryobartender
|
||||
name = "Cryogenic Bartender"
|
||||
uniform = /obj/item/clothing/under/rank/bartender
|
||||
back = /obj/item/storage/backpack
|
||||
shoes = /obj/item/clothing/shoes/black
|
||||
suit = /obj/item/clothing/suit/armor/vest
|
||||
glasses = /obj/item/clothing/glasses/sunglasses/reagent
|
||||
@@ -31,7 +31,7 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
/obj/machinery/gateway/centerstation
|
||||
density = 1
|
||||
icon_state = "offcenter"
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
//warping vars
|
||||
var/list/linked = list()
|
||||
@@ -96,9 +96,12 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
|
||||
|
||||
/obj/machinery/gateway/centerstation/proc/toggleon(mob/user as mob)
|
||||
if(!ready) return
|
||||
if(linked.len != 8) return
|
||||
if(!powered()) return
|
||||
if(!ready)
|
||||
return
|
||||
if(linked.len != 8)
|
||||
return
|
||||
if(!powered())
|
||||
return
|
||||
if(!awaygate)
|
||||
awaygate = locate(/obj/machinery/gateway/centeraway) in world
|
||||
if(!awaygate)
|
||||
@@ -135,9 +138,12 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
|
||||
//okay, here's the good teleporting stuff
|
||||
/obj/machinery/gateway/centerstation/Bumped(atom/movable/M as mob|obj)
|
||||
if(!ready) return
|
||||
if(!active) return
|
||||
if(!awaygate) return
|
||||
if(!ready)
|
||||
return
|
||||
if(!active)
|
||||
return
|
||||
if(!awaygate)
|
||||
return
|
||||
|
||||
if(awaygate.calibrated)
|
||||
M.forceMove(get_step(awaygate.loc, SOUTH))
|
||||
@@ -163,7 +169,7 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
/obj/machinery/gateway/centeraway
|
||||
density = 1
|
||||
icon_state = "offcenter"
|
||||
use_power = 0
|
||||
use_power = NO_POWER_USE
|
||||
var/calibrated = 1
|
||||
var/list/linked = list() //a list of the connected gateway chunks
|
||||
var/ready = 0
|
||||
@@ -207,8 +213,10 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
|
||||
|
||||
/obj/machinery/gateway/centeraway/proc/toggleon(mob/user as mob)
|
||||
if(!ready) return
|
||||
if(linked.len != 8) return
|
||||
if(!ready)
|
||||
return
|
||||
if(linked.len != 8)
|
||||
return
|
||||
if(!stationgate)
|
||||
stationgate = locate(/obj/machinery/gateway/centerstation) in world
|
||||
if(!stationgate)
|
||||
@@ -241,13 +249,20 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
|
||||
|
||||
/obj/machinery/gateway/centeraway/Bumped(atom/movable/M as mob|obj)
|
||||
if(!ready) return
|
||||
if(!active) return
|
||||
if(!ready)
|
||||
return
|
||||
if(!active)
|
||||
return
|
||||
if(istype(M, /mob/living/carbon))
|
||||
if(exilecheck(M)) return
|
||||
if(exilecheck(M))
|
||||
return
|
||||
if(istype(M, /obj))
|
||||
if(M.can_buckle && M.has_buckled_mobs())
|
||||
if(exilecheck(M.buckled_mob))
|
||||
return
|
||||
for(var/mob/living/carbon/F in M)
|
||||
if(exilecheck(F)) return
|
||||
if(exilecheck(F))
|
||||
return
|
||||
M.forceMove(get_step(stationgate.loc, SOUTH))
|
||||
M.dir = SOUTH
|
||||
|
||||
|
||||
@@ -1,677 +0,0 @@
|
||||
/*
|
||||
SwapMaps library by Lummox JR
|
||||
developed for digitalBYOND
|
||||
http://www.digitalbyond.org
|
||||
|
||||
Version 2.1
|
||||
|
||||
The purpose of this library is to make it easy for authors to swap maps
|
||||
in and out of their game using savefiles. Swapped-out maps can be
|
||||
transferred between worlds for an MMORPG, sent to the client, etc.
|
||||
This is facilitated by the use of a special datum and a global list.
|
||||
|
||||
Uses of swapmaps:
|
||||
|
||||
- Temporary battle arenas
|
||||
- House interiors
|
||||
- Individual custom player houses
|
||||
- Virtually unlimited terrain
|
||||
- Sharing maps between servers running different instances of the same
|
||||
game
|
||||
- Loading and saving pieces of maps for reusable room templates
|
||||
*/
|
||||
|
||||
/*
|
||||
User Interface:
|
||||
|
||||
VARS:
|
||||
|
||||
swapmaps_iconcache
|
||||
An associative list of icon files with names, like
|
||||
'player.dmi' = "player"
|
||||
swapmaps_mode
|
||||
This must be set at runtime, like in world/New().
|
||||
|
||||
SWAPMAPS_SAV 0 (default)
|
||||
Uses .sav files for raw /savefile output.
|
||||
SWAPMAPS_TEXT 1
|
||||
Uses .txt files via ExportText() and ImportText(). These maps
|
||||
are easily editable and appear to take up less space in the
|
||||
current version of BYOND.
|
||||
|
||||
PROCS:
|
||||
|
||||
SwapMaps_Find(id)
|
||||
Find a map by its id
|
||||
SwapMaps_Load(id)
|
||||
Load a map by its id
|
||||
SwapMaps_Save(id)
|
||||
Save a map by its id (calls swapmap.Save())
|
||||
SwapMaps_Unload(id)
|
||||
Save and unload a map by its id (calls swapmap.Unload())
|
||||
SwapMaps_Save_All()
|
||||
Save all maps
|
||||
SwapMaps_DeleteFile(id)
|
||||
Delete a map file
|
||||
SwapMaps_CreateFromTemplate(id)
|
||||
Create a new map by loading another map to use as a template.
|
||||
This map has id==src and will not be saved. To make it savable,
|
||||
change id with swapmap.SetID(newid).
|
||||
SwapMaps_LoadChunk(id,turf/locorner)
|
||||
Load a swapmap as a "chunk", at a specific place. A new datum is
|
||||
created but it's not added to the list of maps to save or unload.
|
||||
The new datum can be safely deleted without affecting the turfs
|
||||
it loaded. The purpose of this is to load a map file onto part of
|
||||
another swapmap or an existing part of the world.
|
||||
locorner is the corner turf with the lowest x,y,z values.
|
||||
SwapMaps_SaveChunk(id,turf/corner1,turf/corner2)
|
||||
Save a piece of the world as a "chunk". A new datum is created
|
||||
for the chunk, but it can be deleted without destroying any turfs.
|
||||
The chunk file can be reloaded as a swapmap all its own, or loaded
|
||||
via SwapMaps_LoadChunk() to become part of another map.
|
||||
SwapMaps_GetSize(id)
|
||||
Return a list corresponding to the x,y,z sizes of a map file,
|
||||
without loading the map.
|
||||
Returns null if the map is not found.
|
||||
SwapMaps_AddIconToCache(name,icon)
|
||||
Cache an icon file by name for space-saving storage
|
||||
|
||||
swapmap.New(id,x,y,z)
|
||||
Create a new map; specify id, width (x), height (y), and
|
||||
depth (z)
|
||||
Default size is world.maxx,world.maxy,1
|
||||
swapmap.New(id,turf1,turf2)
|
||||
Create a new map; specify id and 2 corners
|
||||
This becomes a /swapmap for one of the compiled-in maps, for
|
||||
easy saving.
|
||||
swapmap.New()
|
||||
Create a new map datum, but does not allocate space or assign an
|
||||
ID (used for loading).
|
||||
swapmap.Del()
|
||||
Deletes a map but does not save
|
||||
swapmap.Save()
|
||||
Saves to map_[id].sav
|
||||
Maps with id==src are not saved.
|
||||
swapmap.Unload()
|
||||
Saves the map and then deletes it
|
||||
Maps with id==src are not saved.
|
||||
swapmap.SetID(id)
|
||||
Change the map's id and make changes to the lookup list
|
||||
swapmap.AllTurfs(z)
|
||||
Returns a block of turfs encompassing the entire map, or on just
|
||||
one z-level
|
||||
z is in world coordinates; it is optional
|
||||
swapmap.Contains(turf/T)
|
||||
Returns nonzero if T is inside the map's boundaries.
|
||||
Also works for objs and mobs, but the proc is not area-safe.
|
||||
swapmap.InUse()
|
||||
Returns nonzero if a mob with a key is within the map's
|
||||
boundaries.
|
||||
swapmap.LoCorner(z=z1)
|
||||
Returns locate(x1,y1,z), where z=z1 if none is specified.
|
||||
swapmap.HiCorner(z=z2)
|
||||
Returns locate(x2,y2,z), where z=z2 if none is specified.
|
||||
swapmap.BuildFilledRectangle(turf/corner1,turf/corner2,item)
|
||||
Builds a filled rectangle of item from one corner turf to the
|
||||
other, on multiple z-levels if necessary. The corners may be
|
||||
specified in any order.
|
||||
item is a type path like /turf/wall or /obj/barrel{full=1}.
|
||||
swapmap.BuildRectangle(turf/corner1,turf/corner2,item)
|
||||
Builds an unfilled rectangle of item from one corner turf to
|
||||
the other, on multiple z-levels if necessary.
|
||||
swapmap.BuildInTurfs(list/turfs,item)
|
||||
Builds item on all of the turfs listed. The list need not
|
||||
contain only turfs, or even only atoms.
|
||||
*/
|
||||
|
||||
swapmap
|
||||
var/id // a string identifying this map uniquely
|
||||
var/x1 // minimum x,y,z coords
|
||||
var/y1
|
||||
var/z1
|
||||
var/x2 // maximum x,y,z coords (also used as width,height,depth until positioned)
|
||||
var/y2
|
||||
var/z2
|
||||
var/tmp/locked // don't move anyone to this map; it's saving or loading
|
||||
var/tmp/mode // save as text-mode
|
||||
var/ischunk // tells the load routine to load to the specified location
|
||||
|
||||
New(_id,x,y,z)
|
||||
if(isnull(_id)) return
|
||||
id=_id
|
||||
mode=swapmaps_mode
|
||||
if(isturf(x) && isturf(y))
|
||||
/*
|
||||
Special format: Defines a map as an existing set of turfs;
|
||||
this is useful for saving a compiled map in swapmap format.
|
||||
Because this is a compiled-in map, its turfs are not deleted
|
||||
when the datum is deleted.
|
||||
*/
|
||||
x1=min(x:x,y:x);x2=max(x:x,y:x)
|
||||
y1=min(x:y,y:y);y2=max(x:y,y:y)
|
||||
z1=min(x:z,y:z);z2=max(x:z,y:z)
|
||||
InitializeSwapMaps()
|
||||
if(z2>swapmaps_compiled_maxz ||\
|
||||
y2>swapmaps_compiled_maxy ||\
|
||||
x2>swapmaps_compiled_maxx)
|
||||
qdel(src)
|
||||
return
|
||||
x2=x?(x):world.maxx
|
||||
y2=y?(y):world.maxy
|
||||
z2=z?(z):1
|
||||
AllocateSwapMap()
|
||||
|
||||
Destroy()
|
||||
// a temporary datum for a chunk can be deleted outright
|
||||
// for others, some cleanup is necessary
|
||||
if(!ischunk)
|
||||
swapmaps_loaded-=src
|
||||
swapmaps_byname-=id
|
||||
if(z2>swapmaps_compiled_maxz ||\
|
||||
y2>swapmaps_compiled_maxy ||\
|
||||
x2>swapmaps_compiled_maxx)
|
||||
var/list/areas=new
|
||||
for(var/atom/A in block(locate(x1,y1,z1),locate(x2,y2,z2)))
|
||||
for(var/obj/O in A) qdel(O)
|
||||
for(var/mob/M in A)
|
||||
if(!M.key) qdel(M)
|
||||
else M.loc=null
|
||||
areas[A.loc]=null
|
||||
qdel(A)
|
||||
// delete areas that belong only to this map
|
||||
for(var/area/a in areas)
|
||||
if(a && !a.contents.len) qdel(a)
|
||||
if(x2>=world.maxx || y2>=world.maxy || z2>=world.maxz) CutXYZ()
|
||||
qdel(areas)
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/*
|
||||
Savefile format:
|
||||
map
|
||||
id
|
||||
x // size, not coords
|
||||
y
|
||||
z
|
||||
areas // list of areas, not including default
|
||||
[each z; 1 to depth]
|
||||
[each y; 1 to height]
|
||||
[each x; 1 to width]
|
||||
type // of turf
|
||||
AREA // if non-default; saved as a number (index into areas list)
|
||||
vars // all other changed vars
|
||||
*/
|
||||
Write(savefile/S)
|
||||
var/x
|
||||
var/y
|
||||
var/z
|
||||
var/n
|
||||
var/list/areas
|
||||
var/area/defarea=locate(world.area)
|
||||
if(!defarea) defarea=new world.area
|
||||
areas=list()
|
||||
for(var/turf/T in block(locate(x1,y1,z1),locate(x2,y2,z2)))
|
||||
areas[T.loc]=null
|
||||
for(n in areas) // quickly eliminate associations for smaller storage
|
||||
areas-=n
|
||||
areas+=n
|
||||
areas-=defarea
|
||||
InitializeSwapMaps()
|
||||
locked=1
|
||||
S["id"] << id
|
||||
S["z"] << z2-z1+1
|
||||
S["y"] << y2-y1+1
|
||||
S["x"] << x2-x1+1
|
||||
S["areas"] << areas
|
||||
for(n in 1 to areas.len) areas[areas[n]]=n
|
||||
var/oldcd=S.cd
|
||||
for(z in z1 to z2)
|
||||
S.cd="[z-z1+1]"
|
||||
for(y in y1 to y2)
|
||||
S.cd="[y-y1+1]"
|
||||
for(x in x1 to x2)
|
||||
S.cd="[x-x1+1]"
|
||||
var/turf/T=locate(x,y,z)
|
||||
S["type"] << T.type
|
||||
if(T.loc!=defarea) S["AREA"] << areas[T.loc]
|
||||
T.Write(S)
|
||||
S.cd=".."
|
||||
S.cd=".."
|
||||
sleep()
|
||||
S.cd=oldcd
|
||||
locked=0
|
||||
qdel(areas)
|
||||
|
||||
Read(savefile/S,_id,turf/locorner)
|
||||
var/x
|
||||
var/y
|
||||
var/z
|
||||
var/n
|
||||
var/list/areas
|
||||
var/area/defarea=locate(world.area)
|
||||
id=_id
|
||||
if(locorner)
|
||||
ischunk=1
|
||||
x1=locorner.x
|
||||
y1=locorner.y
|
||||
z1=locorner.z
|
||||
if(!defarea) defarea=new world.area
|
||||
if(!_id)
|
||||
S["id"] >> id
|
||||
else
|
||||
var/dummy
|
||||
S["id"] >> dummy
|
||||
S["z"] >> z2 // these are depth,
|
||||
S["y"] >> y2 // height,
|
||||
S["x"] >> x2 // width
|
||||
S["areas"] >> areas
|
||||
locked=1
|
||||
AllocateSwapMap() // adjust x1,y1,z1 - x2,y2,z2 coords
|
||||
var/oldcd=S.cd
|
||||
for(z in z1 to z2)
|
||||
S.cd="[z-z1+1]"
|
||||
for(y in y1 to y2)
|
||||
S.cd="[y-y1+1]"
|
||||
for(x in x1 to x2)
|
||||
S.cd="[x-x1+1]"
|
||||
var/tp
|
||||
S["type"]>>tp
|
||||
var/turf/T=locate(x,y,z)
|
||||
T.loc.contents-=T
|
||||
T=new tp(locate(x,y,z))
|
||||
if("AREA" in S.dir)
|
||||
S["AREA"]>>n
|
||||
var/area/A=areas[n]
|
||||
A.contents+=T
|
||||
else defarea.contents+=T
|
||||
// clear the turf
|
||||
for(var/obj/O in T) qdel(O)
|
||||
for(var/mob/M in T)
|
||||
if(!M.key) qdel(M)
|
||||
else M.loc=null
|
||||
// finish the read
|
||||
T.Read(S)
|
||||
S.cd=".."
|
||||
S.cd=".."
|
||||
sleep()
|
||||
S.cd=oldcd
|
||||
locked=0
|
||||
qdel(areas)
|
||||
|
||||
/*
|
||||
Find an empty block on the world map in which to load this map.
|
||||
If no space is found, increase world.maxz as necessary. (If the
|
||||
map is greater in x,y size than the current world, expand
|
||||
world.maxx and world.maxy too.)
|
||||
|
||||
Ignore certain operations if loading a map as a chunk. Use the
|
||||
x1,y1,z1 position for it, and *don't* count it as a loaded map.
|
||||
*/
|
||||
proc/AllocateSwapMap()
|
||||
InitializeSwapMaps()
|
||||
world.maxx=max(x2,world.maxx) // stretch x/y if necessary
|
||||
world.maxy=max(y2,world.maxy)
|
||||
if(!ischunk)
|
||||
if(world.maxz<=swapmaps_compiled_maxz)
|
||||
z1=swapmaps_compiled_maxz+1
|
||||
x1=1;y1=1
|
||||
else
|
||||
var/list/l=ConsiderRegion(1,1,world.maxx,world.maxy,swapmaps_compiled_maxz+1)
|
||||
x1=l[1]
|
||||
y1=l[2]
|
||||
z1=l[3]
|
||||
qdel(l)
|
||||
x2+=x1-1
|
||||
y2+=y1-1
|
||||
z2+=z1-1
|
||||
space_manager.increase_max_zlevel_to(z2) // stretch z if necessary
|
||||
if(!ischunk)
|
||||
swapmaps_loaded[src]=null
|
||||
swapmaps_byname[id]=src
|
||||
|
||||
proc/ConsiderRegion(X1,Y1,X2,Y2,Z1,Z2)
|
||||
while(1)
|
||||
var/nextz=0
|
||||
var/swapmap/M
|
||||
for(M in swapmaps_loaded)
|
||||
if(M.z2<Z1 || (Z2 && M.z1>Z2) || M.z1>=Z1+z2 ||\
|
||||
M.x1>X2 || M.x2<X1 || M.x1>=X1+x2 ||\
|
||||
M.y1>Y2 || M.y2<Y1 || M.y1>=Y1+y2) continue
|
||||
// look for sub-regions with a defined ceiling
|
||||
var/nz2=Z2?(Z2):Z1+z2-1+M.z2-M.z1
|
||||
if(M.x1>=X1+x2)
|
||||
.=ConsiderRegion(X1,Y1,M.x1-1,Y2,Z1,nz2)
|
||||
if(.) return
|
||||
else if(M.x2<=X2-x2)
|
||||
.=ConsiderRegion(M.x2+1,Y1,X2,Y2,Z1,nz2)
|
||||
if(.) return
|
||||
if(M.y1>=Y1+y2)
|
||||
.=ConsiderRegion(X1,Y1,X2,M.y1-1,Z1,nz2)
|
||||
if(.) return
|
||||
else if(M.y2<=Y2-y2)
|
||||
.=ConsiderRegion(X1,M.y2+1,X2,Y2,Z1,nz2)
|
||||
if(.) return
|
||||
nextz=nextz?min(nextz,M.z2+1):(M.z2+1)
|
||||
if(!M)
|
||||
/* If nextz is not 0, then at some point there was an overlap that
|
||||
could not be resolved by using an area to the side */
|
||||
if(nextz) Z1=nextz
|
||||
if(!nextz || (Z2 && Z2-Z1+1<z2))
|
||||
return (!Z2 || Z2-Z1+1>=z2)?list(X1,Y1,Z1):null
|
||||
X1=1;X2=world.maxx
|
||||
Y1=1;Y2=world.maxy
|
||||
|
||||
proc/CutXYZ()
|
||||
var/mx=swapmaps_compiled_maxx
|
||||
var/my=swapmaps_compiled_maxy
|
||||
var/mz=swapmaps_compiled_maxz
|
||||
for(var/swapmap/M in swapmaps_loaded) // may not include src
|
||||
mx=max(mx,M.x2)
|
||||
my=max(my,M.y2)
|
||||
mz=max(mz,M.z2)
|
||||
world.maxx=mx
|
||||
world.maxy=my
|
||||
space_manager.cut_levels_downto(mz)
|
||||
|
||||
// save and delete
|
||||
proc/Unload()
|
||||
Save()
|
||||
qdel(src)
|
||||
|
||||
proc/Save()
|
||||
if(id==src) return 0
|
||||
var/savefile/S=mode?(new):new("map_[id].sav")
|
||||
S << src
|
||||
while(locked) sleep(1)
|
||||
if(mode)
|
||||
fdel("map_[id].txt")
|
||||
S.ExportText("/","map_[id].txt")
|
||||
return 1
|
||||
|
||||
// this will not delete existing savefiles for this map
|
||||
proc/SetID(newid)
|
||||
swapmaps_byname-=id
|
||||
id=newid
|
||||
swapmaps_byname[id]=src
|
||||
|
||||
proc/AllTurfs(z)
|
||||
if(isnum(z) && (z<z1 || z>z2)) return null
|
||||
return block(LoCorner(z),HiCorner(z))
|
||||
|
||||
// this could be safely called for an obj or mob as well, but
|
||||
// probably not an area
|
||||
proc/Contains(turf/T)
|
||||
return (T && T.x>=x1 && T.x<=x2\
|
||||
&& T.y>=y1 && T.y<=y2\
|
||||
&& T.z>=z1 && T.z<=z2)
|
||||
|
||||
proc/InUse()
|
||||
for(var/turf/T in AllTurfs())
|
||||
for(var/mob/M in T) if(M.key) return 1
|
||||
|
||||
proc/LoCorner(z=z1)
|
||||
return locate(x1,y1,z)
|
||||
proc/HiCorner(z=z2)
|
||||
return locate(x2,y2,z)
|
||||
|
||||
/*
|
||||
Build procs: Take 2 turfs as corners, plus an item type.
|
||||
An item may be like:
|
||||
|
||||
/turf/wall
|
||||
/obj/fence{icon_state="iron"}
|
||||
*/
|
||||
proc/BuildFilledRectangle(turf/T1,turf/T2,item)
|
||||
if(!Contains(T1) || !Contains(T2)) return
|
||||
var/turf/T=T1
|
||||
// pick new corners in a block()-friendly form
|
||||
T1=locate(min(T1.x,T2.x),min(T1.y,T2.y),min(T1.z,T2.z))
|
||||
T2=locate(max(T.x,T2.x),max(T.y,T2.y),max(T.z,T2.z))
|
||||
for(T in block(T1,T2)) new item(T)
|
||||
|
||||
proc/BuildRectangle(turf/T1,turf/T2,item)
|
||||
if(!Contains(T1) || !Contains(T2)) return
|
||||
var/turf/T=T1
|
||||
// pick new corners in a block()-friendly form
|
||||
T1=locate(min(T1.x,T2.x),min(T1.y,T2.y),min(T1.z,T2.z))
|
||||
T2=locate(max(T.x,T2.x),max(T.y,T2.y),max(T.z,T2.z))
|
||||
if(T2.x-T1.x<2 || T2.y-T1.y<2) BuildFilledRectangle(T1,T2,item)
|
||||
else
|
||||
//for(T in block(T1,T2)-block(locate(T1.x+1,T1.y+1,T1.z),locate(T2.x-1,T2.y-1,T2.z)))
|
||||
for(T in block(T1,locate(T2.x,T1.y,T2.z))) new item(T)
|
||||
for(T in block(locate(T1.x,T2.y,T1.z),T2)) new item(T)
|
||||
for(T in block(locate(T1.x,T1.y+1,T1.z),locate(T1.x,T2.y-1,T2.z))) new item(T)
|
||||
for(T in block(locate(T2.x,T1.y+1,T1.z),locate(T2.x,T2.y-1,T2.z))) new item(T)
|
||||
|
||||
/*
|
||||
Supplementary build proc: Takes a list of turfs, plus an item
|
||||
type. Actually the list doesn't have to be just turfs.
|
||||
*/
|
||||
proc/BuildInTurfs(list/turfs,item)
|
||||
for(var/T in turfs) new item(T)
|
||||
|
||||
atom
|
||||
Write(savefile/S)
|
||||
for(var/V in vars-"x"-"y"-"z"-"contents"-"icon"-"overlays"-"underlays")
|
||||
if(issaved(vars[V]))
|
||||
if(vars[V]!=initial(vars[V])) S[V]<<vars[V]
|
||||
else S.dir.Remove(V)
|
||||
if(icon!=initial(icon))
|
||||
if(swapmaps_iconcache && swapmaps_iconcache[icon])
|
||||
S["icon"]<<swapmaps_iconcache[icon]
|
||||
else S["icon"]<<icon
|
||||
// do not save mobs with keys; do save other mobs
|
||||
var/mob/M
|
||||
for(M in src) if(M.key) break
|
||||
if(overlays.len) S["overlays"]<<overlays
|
||||
if(underlays.len) S["underlays"]<<underlays
|
||||
if(contents.len && !isarea(src))
|
||||
var/list/l=contents
|
||||
if(M)
|
||||
l=l.Copy()
|
||||
for(M in src) if(M.key) l-=M
|
||||
if(l.len) S["contents"]<<l
|
||||
if(l!=contents) qdel(l)
|
||||
Read(savefile/S)
|
||||
var/list/l
|
||||
if(contents.len) l=contents
|
||||
..()
|
||||
// if the icon was a text string, it would not have loaded properly
|
||||
// replace it from the cache list
|
||||
if(!icon && ("icon" in S.dir))
|
||||
var/ic
|
||||
S["icon"]>>ic
|
||||
if(istext(ic)) icon=swapmaps_iconcache[ic]
|
||||
if(l && contents!=l)
|
||||
contents+=l
|
||||
qdel(l)
|
||||
|
||||
|
||||
// set this up (at runtime) as follows:
|
||||
// list(\
|
||||
// 'player.dmi'="player",\
|
||||
// 'monster.dmi'="monster",\
|
||||
// ...
|
||||
// 'item.dmi'="item")
|
||||
var/list/swapmaps_iconcache
|
||||
|
||||
// preferred mode; sav or text
|
||||
var/const/SWAPMAPS_SAV=0
|
||||
var/const/SWAPMAPS_TEXT=1
|
||||
var/swapmaps_mode=SWAPMAPS_SAV
|
||||
|
||||
var/swapmaps_compiled_maxx
|
||||
var/swapmaps_compiled_maxy
|
||||
var/swapmaps_compiled_maxz
|
||||
var/swapmaps_initialized
|
||||
var/swapmaps_loaded
|
||||
var/swapmaps_byname
|
||||
|
||||
proc/InitializeSwapMaps()
|
||||
if(swapmaps_initialized) return
|
||||
swapmaps_initialized=1
|
||||
swapmaps_compiled_maxx=world.maxx
|
||||
swapmaps_compiled_maxy=world.maxy
|
||||
swapmaps_compiled_maxz=world.maxz
|
||||
swapmaps_loaded=list()
|
||||
swapmaps_byname=list()
|
||||
if(swapmaps_iconcache)
|
||||
for(var/V in swapmaps_iconcache)
|
||||
// reverse-associate everything
|
||||
// so you can look up an icon file by name or vice-versa
|
||||
swapmaps_iconcache[swapmaps_iconcache[V]]=V
|
||||
|
||||
proc/SwapMaps_AddIconToCache(name,icon)
|
||||
if(!swapmaps_iconcache) swapmaps_iconcache=list()
|
||||
swapmaps_iconcache[name]=icon
|
||||
swapmaps_iconcache[icon]=name
|
||||
|
||||
proc/SwapMaps_Find(id)
|
||||
InitializeSwapMaps()
|
||||
return swapmaps_byname[id]
|
||||
|
||||
proc/SwapMaps_Load(id)
|
||||
InitializeSwapMaps()
|
||||
var/swapmap/M=swapmaps_byname[id]
|
||||
if(!M)
|
||||
var/savefile/S
|
||||
var/text=0
|
||||
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[id].txt"))
|
||||
text=1
|
||||
else if(fexists("map_[id].sav"))
|
||||
S=new("map_[id].sav")
|
||||
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[id].txt"))
|
||||
text=1
|
||||
else return // no file found
|
||||
if(text)
|
||||
S=new
|
||||
S.ImportText("/",file("map_[id].txt"))
|
||||
S >> M
|
||||
while(M.locked) sleep(1)
|
||||
M.mode=text
|
||||
return M
|
||||
|
||||
proc/SwapMaps_Save(id)
|
||||
InitializeSwapMaps()
|
||||
var/swapmap/M=swapmaps_byname[id]
|
||||
if(M) M.Save()
|
||||
return M
|
||||
|
||||
proc/SwapMaps_Save_All()
|
||||
InitializeSwapMaps()
|
||||
for(var/swapmap/M in swapmaps_loaded)
|
||||
if(M) M.Save()
|
||||
|
||||
proc/SwapMaps_Unload(id)
|
||||
InitializeSwapMaps()
|
||||
var/swapmap/M=swapmaps_byname[id]
|
||||
if(!M) return // return silently from an error
|
||||
M.Unload()
|
||||
return 1
|
||||
|
||||
proc/SwapMaps_DeleteFile(id)
|
||||
fdel("map_[id].sav")
|
||||
fdel("map_[id].txt")
|
||||
|
||||
proc/SwapMaps_CreateFromTemplate(template_id)
|
||||
var/swapmap/M=new
|
||||
var/savefile/S
|
||||
var/text=0
|
||||
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[template_id].txt"))
|
||||
text=1
|
||||
else if(fexists("map_[template_id].sav"))
|
||||
S=new("map_[template_id].sav")
|
||||
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[template_id].txt"))
|
||||
text=1
|
||||
else
|
||||
log_world("SwapMaps error in SwapMaps_CreateFromTemplate(): map_[template_id] file not found.")
|
||||
return
|
||||
if(text)
|
||||
S=new
|
||||
S.ImportText("/",file("map_[template_id].txt"))
|
||||
/*
|
||||
This hacky workaround is needed because S >> M will create a brand new
|
||||
M to fill with data. There's no way to control the Read() process
|
||||
properly otherwise. The //.0 path should always match the map, however.
|
||||
*/
|
||||
S.cd="//.0"
|
||||
M.Read(S,M)
|
||||
M.mode=text
|
||||
while(M.locked) sleep(1)
|
||||
return M
|
||||
|
||||
proc/SwapMaps_LoadChunk(chunk_id,turf/locorner)
|
||||
var/swapmap/M=new
|
||||
var/savefile/S
|
||||
var/text=0
|
||||
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[chunk_id].txt"))
|
||||
text=1
|
||||
else if(fexists("map_[chunk_id].sav"))
|
||||
S=new("map_[chunk_id].sav")
|
||||
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[chunk_id].txt"))
|
||||
text=1
|
||||
else
|
||||
log_world("SwapMaps error in SwapMaps_LoadChunk(): map_[chunk_id] file not found.")
|
||||
return
|
||||
if(text)
|
||||
S=new
|
||||
S.ImportText("/",file("map_[chunk_id].txt"))
|
||||
/*
|
||||
This hacky workaround is needed because S >> M will create a brand new
|
||||
M to fill with data. There's no way to control the Read() process
|
||||
properly otherwise. The //.0 path should always match the map, however.
|
||||
*/
|
||||
S.cd="//.0"
|
||||
M.Read(S,M,locorner)
|
||||
while(M.locked) sleep(1)
|
||||
qdel(M)
|
||||
return 1
|
||||
|
||||
proc/SwapMaps_SaveChunk(chunk_id,turf/corner1,turf/corner2)
|
||||
if(!corner1 || !corner2)
|
||||
log_world("SwapMaps error in SwapMaps_SaveChunk():")
|
||||
if(!corner1) log_world(" corner1 turf is null")
|
||||
if(!corner2) log_world(" corner2 turf is null")
|
||||
return
|
||||
var/swapmap/M=new
|
||||
M.id=chunk_id
|
||||
M.ischunk=1 // this is a chunk
|
||||
M.x1=min(corner1.x,corner2.x)
|
||||
M.y1=min(corner1.y,corner2.y)
|
||||
M.z1=min(corner1.z,corner2.z)
|
||||
M.x2=max(corner1.x,corner2.x)
|
||||
M.y2=max(corner1.y,corner2.y)
|
||||
M.z2=max(corner1.z,corner2.z)
|
||||
M.mode=swapmaps_mode
|
||||
M.Save()
|
||||
while(M.locked) sleep(1)
|
||||
qdel(M)
|
||||
return 1
|
||||
|
||||
proc/SwapMaps_GetSize(id)
|
||||
var/savefile/S
|
||||
var/text=0
|
||||
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[id].txt"))
|
||||
text=1
|
||||
else if(fexists("map_[id].sav"))
|
||||
S=new("map_[id].sav")
|
||||
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[id].txt"))
|
||||
text=1
|
||||
else
|
||||
log_world("SwapMaps error in SwapMaps_GetSize(): map_[id] file not found.")
|
||||
return
|
||||
if(text)
|
||||
S=new
|
||||
S.ImportText("/",file("map_[id].txt"))
|
||||
/*
|
||||
The //.0 path should always be the map. There's no other way to
|
||||
read this data.
|
||||
*/
|
||||
S.cd="//.0"
|
||||
var/x
|
||||
var/y
|
||||
var/z
|
||||
S["x"] >> x
|
||||
S["y"] >> y
|
||||
S["z"] >> z
|
||||
return list(x,y,z)
|
||||
@@ -181,7 +181,7 @@
|
||||
|
||||
/obj/item/paper/terrorspiders9
|
||||
name = "paper - 'Research Notes'"
|
||||
info = "<b>The notes appear gibberish to you. Perhaps a destructive analyser in R&D could make sense of them.</b>"
|
||||
info = "<b>The notes appear gibberish to you. Perhaps a destructive analyzer in R&D could make sense of them.</b>"
|
||||
origin_tech = "combat=4;materials=4;engineering=4;biotech=4"
|
||||
|
||||
/obj/item/gun/energy/laser/awaymission_aeg
|
||||
@@ -257,5 +257,3 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Your ID card already has all the access this machine can give.</span>")
|
||||
. = 1
|
||||
|
||||
|
||||
|
||||
@@ -19,4 +19,9 @@
|
||||
/area/awaymission/BMPship/Fore
|
||||
name = "\improper Fore Block"
|
||||
icon_state = "away3"
|
||||
requires_power = 1
|
||||
|
||||
/area/awaymission/BMPship/Gate
|
||||
name = "\improper Gateway Block"
|
||||
icon_state = "away4"
|
||||
requires_power = 1
|
||||
@@ -28,10 +28,10 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
use_power = 0
|
||||
use_power = NO_POWER_USE
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
|
||||
active = 1
|
||||
locked = 1
|
||||
state = 2
|
||||
state = 2
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
D.account = get_card_account(id, occupant)
|
||||
if(!D.account)
|
||||
return null
|
||||
if(!D.account.charge(100, transaction_purpose = "10 minutes", dest_name = name))
|
||||
if(!D.account.charge(100, null, "10 minutes hotel stay", "Biesel GalaxyNet Terminal [rand(111,1111)]", "[name]"))
|
||||
return null
|
||||
|
||||
D.occupant = occupant
|
||||
@@ -251,7 +251,7 @@
|
||||
if(!D || !D.occupant)
|
||||
return
|
||||
|
||||
if(D.account.charge(100, transaction_purpose = "10 minutes", dest_name = name))
|
||||
if(D.account.charge(100, null, "10 minutes hotel stay extension", "Biesel GalaxyNet Terminal [rand(111,1111)]", "[name]"))
|
||||
D.roomtimer = addtimer(CALLBACK(src, .proc/process_room, roomid), PAY_INTERVAL, TIMER_STOPPABLE)
|
||||
else
|
||||
force_checkout(roomid)
|
||||
@@ -299,4 +299,4 @@
|
||||
return
|
||||
|
||||
S.retal_target = target
|
||||
S.retal = 1
|
||||
S.retal = 1
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
anchored = 1
|
||||
density = 1
|
||||
use_power = 0
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
var/chargesa = 1
|
||||
var/insistinga = 0
|
||||
@@ -72,7 +72,7 @@
|
||||
else
|
||||
chargesa--
|
||||
insistinga = 0
|
||||
var/wish = input("You want...","Wish") as null|anything in list("Power","Wealth","Immortality","To Kill","Peace")
|
||||
var/wish = input("You want...","Wish") as null|anything in list("Power","Wealth","Immortality","Peace")
|
||||
switch(wish)
|
||||
if("Power")
|
||||
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
|
||||
@@ -115,28 +115,6 @@
|
||||
to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.")
|
||||
human.set_species(/datum/species/shadow)
|
||||
user.regenerate_icons()
|
||||
if("To Kill")
|
||||
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
|
||||
to_chat(user, "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart.")
|
||||
ticker.mode.traitors += user.mind
|
||||
user.mind.special_role = SPECIAL_ROLE_TRAITOR
|
||||
var/datum/objective/hijack/hijack = new
|
||||
hijack.owner = user.mind
|
||||
user.mind.objectives += hijack
|
||||
to_chat(user, "<B>Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!</B>")
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/OBJ in user.mind.objectives)
|
||||
to_chat(user, "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]")
|
||||
obj_count++
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human = user
|
||||
if(!isshadowperson(human))
|
||||
to_chat(user, "<span class='warning'>Your flesh rapidly mutates!</span>")
|
||||
to_chat(user, "<b>You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.</b>")
|
||||
to_chat(user, "<span class='warning'>Your body reacts violently to light.</span> <span class='notice'>However, it naturally heals in darkness.</span>")
|
||||
to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.")
|
||||
human.set_species(/datum/species/shadow)
|
||||
user.regenerate_icons()
|
||||
if("Peace")
|
||||
to_chat(user, "<B>Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence.</B>")
|
||||
to_chat(user, "You feel as if you just narrowly avoided a terrible fate...")
|
||||
@@ -288,4 +266,4 @@
|
||||
say("How could you betray the Syndicate?")
|
||||
for(var/mob/living/simple_animal/hostile/syndicate/ranged/wildwest/W in living_mob_list)
|
||||
W.on_alert = TRUE
|
||||
..(gibbed)
|
||||
..(gibbed)
|
||||
|
||||
@@ -200,6 +200,7 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
|
||||
"large_stamp-law.png" = 'icons/paper_icons/large_stamp-law.png',
|
||||
"large_stamp-cent.png" = 'icons/paper_icons/large_stamp-cent.png',
|
||||
"large_stamp-syndicate.png" = 'icons/paper_icons/large_stamp-syndicate.png',
|
||||
"large_stamp-rep.png" = 'icons/paper_icons/large_stamp-rep.png',
|
||||
"talisman.png" = 'icons/paper_icons/talisman.png',
|
||||
"ntlogo.png" = 'icons/paper_icons/ntlogo.png'
|
||||
)
|
||||
@@ -348,4 +349,4 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
|
||||
register_asset(asset_name, assets[asset_name])
|
||||
|
||||
/datum/asset/mob_hunt/send(client)
|
||||
send_asset_list(client, assets, verify)
|
||||
send_asset_list(client, assets, verify)
|
||||
|
||||
@@ -109,136 +109,42 @@
|
||||
if("shop")
|
||||
if(href_list["KarmaBuy"])
|
||||
var/karma=verify_karma()
|
||||
if(isnull(karma)) //Doesn't display anything if karma database is down.
|
||||
return
|
||||
switch(href_list["KarmaBuy"])
|
||||
if("1")
|
||||
if(karma <5)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Barber?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_job_unlock("Barber",5)
|
||||
return
|
||||
karma_purchase(karma,5,"job","Barber")
|
||||
if("2")
|
||||
if(karma <5)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Brig Physician?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_job_unlock("Brig Physician",5)
|
||||
return
|
||||
karma_purchase(karma,5,"job","Brig Physician")
|
||||
if("3")
|
||||
if(karma <30)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Nanotrasen Representative?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_job_unlock("Nanotrasen Representative",30)
|
||||
return
|
||||
karma_purchase(karma,30,"job","Nanotrasen Representative")
|
||||
if("5")
|
||||
if(karma <30)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Blueshield?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_job_unlock("Blueshield",30)
|
||||
return
|
||||
karma_purchase(karma,30,"job","Blueshield")
|
||||
if("6")
|
||||
if(karma <30)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Mechanic?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_job_unlock("Mechanic",30)
|
||||
return
|
||||
karma_purchase(karma,30,"job","Mechanic")
|
||||
if("7")
|
||||
if(karma <45)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Magistrate?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_job_unlock("Magistrate",45)
|
||||
return
|
||||
karma_purchase(karma,45,"job","Magistrate")
|
||||
if("9")
|
||||
if(karma <30)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Security Pod Pilot?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_job_unlock("Security Pod Pilot",30)
|
||||
return
|
||||
karma_purchase(karma,30,"job","Security Pod Pilot")
|
||||
if(href_list["KarmaBuy2"])
|
||||
var/karma=verify_karma()
|
||||
if(isnull(karma)) //Doesn't display anything if karma database is down.
|
||||
return
|
||||
switch(href_list["KarmaBuy2"])
|
||||
if("1")
|
||||
if(karma <15)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Machine People?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_species_unlock("Machine",15)
|
||||
return
|
||||
karma_purchase(karma,15,"species","Machine People","Machine")
|
||||
if("2")
|
||||
if(karma <30)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Kidan?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_species_unlock("Kidan",30)
|
||||
return
|
||||
karma_purchase(karma,30,"species","Kidan")
|
||||
if("3")
|
||||
if(karma <30)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Grey?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_species_unlock("Grey",30)
|
||||
return
|
||||
karma_purchase(karma,30,"species","Grey")
|
||||
if("4")
|
||||
if(karma <45)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Vox?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_species_unlock("Vox",45)
|
||||
return
|
||||
karma_purchase(karma,45,"species","Vox")
|
||||
if("5")
|
||||
if(karma <45)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Slime People?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_species_unlock("Slime People",45)
|
||||
return
|
||||
karma_purchase(karma,45,"species","Slime People")
|
||||
if("6")
|
||||
if(karma <100)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Plasmaman?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_species_unlock("Plasmaman",100)
|
||||
return
|
||||
karma_purchase(karma,100,"species","Plasmaman")
|
||||
if("7")
|
||||
if(karma <30)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
else
|
||||
if(alert("Are you sure you want to unlock Drask?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
DB_species_unlock("Drask",30)
|
||||
return
|
||||
karma_purchase(karma,30,"species","Drask")
|
||||
if(href_list["KarmaRefund"])
|
||||
var/type = href_list["KarmaRefundType"]
|
||||
var/job = href_list["KarmaRefund"]
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
/datum/gear/lipstick
|
||||
display_name = "lipstick, red"
|
||||
path = /obj/item/lipstick
|
||||
sort_category = "Cosmetics"
|
||||
|
||||
/datum/gear/lipstick/black
|
||||
display_name = "lipstick, black"
|
||||
path = /obj/item/lipstick/black
|
||||
sort_category = "Cosmetics"
|
||||
|
||||
/datum/gear/lipstick/jade
|
||||
display_name = "lipstick, jade"
|
||||
@@ -11,9 +15,13 @@
|
||||
display_name = "lipstick, purple"
|
||||
path = /obj/item/lipstick/purple
|
||||
|
||||
/datum/gear/lipstick/red
|
||||
display_name = "lipstick, red"
|
||||
path = /obj/item/lipstick
|
||||
/datum/gear/lipstick/blue
|
||||
display_name = "lipstick, blue"
|
||||
path = /obj/item/lipstick/blue
|
||||
|
||||
/datum/gear/lipstick/lime
|
||||
display_name = "lipstick, lime"
|
||||
path = /obj/item/lipstick/lime
|
||||
|
||||
/datum/gear/monocle
|
||||
display_name = "monocle"
|
||||
|
||||
@@ -561,6 +561,7 @@ BLIND // can't see anything
|
||||
strip_delay = 80
|
||||
put_on_delay = 80
|
||||
burn_state = FIRE_PROOF
|
||||
hide_tail_by_species = null
|
||||
species_restricted = list("exclude","Diona","Vox","Wryn")
|
||||
|
||||
//Under clothing
|
||||
|
||||
@@ -202,7 +202,27 @@
|
||||
var/aggressiveness = 1
|
||||
var/safety = 1
|
||||
actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/adjust, /datum/action/item_action/selectphrase)
|
||||
|
||||
var/phrase_list = list(
|
||||
|
||||
"halt" = "HALT! HALT! HALT! HALT!",
|
||||
"bobby" = "Stop in the name of the Law.",
|
||||
"compliance" = "Compliance is in your best interest.",
|
||||
"justice" = "Prepare for justice!",
|
||||
"running" = "Running will only increase your sentence.",
|
||||
"dontmove" = "Don't move, Creep!",
|
||||
"floor" = "Down on the floor, Creep!",
|
||||
"robocop" = "Dead or alive you're coming with me.",
|
||||
"god" = "God made today for the crooks we could not catch yesterday.",
|
||||
"freeze" = "Freeze, Scum Bag!",
|
||||
"imperial" = "Stop right there, criminal scum!",
|
||||
"bash" = "Stop or I'll bash you.",
|
||||
"harry" = "Go ahead, make my day.",
|
||||
"asshole" = "Stop breaking the law, asshole.",
|
||||
"stfu" = "You have the right to shut the fuck up",
|
||||
"shutup" = "Shut up crime!",
|
||||
"super" = "Face the wrath of the golden bolt.",
|
||||
"dredd" = "I am, the LAW!"
|
||||
)
|
||||
/obj/item/clothing/mask/gas/sechailer/hos
|
||||
name = "\improper HOS SWAT mask"
|
||||
desc = "A close-fitting tactical mask with an especially aggressive Compli-o-nator 3000. It has a tan stripe."
|
||||
@@ -250,133 +270,34 @@
|
||||
else if(actiontype == /datum/action/item_action/adjust)
|
||||
adjustmask(user)
|
||||
else if(actiontype == /datum/action/item_action/selectphrase)
|
||||
var/key = phrase_list[phrase]
|
||||
var/message = phrase_list[key]
|
||||
|
||||
if (!safety)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: FUCK YOUR CUNT YOU SHIT EATING COCKSUCKER MAN EAT A DONG FUCKING ASS RAMMING SHIT FUCK EAT PENISES IN YOUR FUCK FACE AND SHIT OUT ABORTIONS OF FUCK AND DO SHIT IN YOUR ASS YOU COCK FUCK SHIT MONKEY FUCK ASS WANKER FROM THE DEPTHS OF SHIT.</span>")
|
||||
return
|
||||
|
||||
switch(aggressiveness)
|
||||
if(1)
|
||||
switch(phrase)
|
||||
if(1)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Stop in the name of the Law.</span>")
|
||||
phrase = 2
|
||||
if(2)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Compliance is in your best interest.</span>")
|
||||
phrase = 3
|
||||
if(3)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Prepare for justice.</span>")
|
||||
phrase = 4
|
||||
if(4)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Running will only increase your sentence.</span>")
|
||||
phrase = 5
|
||||
if(5)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Don't move, Creep!</span>")
|
||||
phrase = 6
|
||||
if(6)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: HALT! HALT! HALT! HALT!</span>")
|
||||
phrase = 1
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: HALT! HALT! HALT! HALT!</span>")
|
||||
phrase = 1
|
||||
phrase = (phrase < 6) ? (phrase + 1) : 1
|
||||
key = phrase_list[phrase]
|
||||
message = phrase_list[key]
|
||||
to_chat(user,"<span class='notice'>You set the restrictor to: [message]</span>")
|
||||
if(2)
|
||||
switch(phrase)
|
||||
if(7)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Dead or alive you're coming with me.</span>")
|
||||
phrase = 8
|
||||
if(8)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: God made today for the crooks we could not catch yesterday.</span>")
|
||||
phrase = 9
|
||||
if(9)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Freeze, Scum Bag!</span>")
|
||||
phrase = 10
|
||||
if(10)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Stop right there, criminal scum!</span>")
|
||||
phrase = 11
|
||||
if(11)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Down on the floor, Creep!</span>")
|
||||
phrase = 7
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Down on the floor, Creep!</span>")
|
||||
phrase = 7
|
||||
phrase = (phrase < 11 && phrase >= 7) ? (phrase + 1) : 7
|
||||
key = phrase_list[phrase]
|
||||
message = phrase_list[key]
|
||||
to_chat(user,"<span class='notice'>You set the restrictor to: [message]</span>")
|
||||
if(3)
|
||||
switch(phrase)
|
||||
if(12)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Go ahead, make my day.</span>")
|
||||
phrase = 13
|
||||
if(13)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Stop breaking the law, ass hole.</span>")
|
||||
phrase = 14
|
||||
if(14)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: You have the right to shut the fuck up.</span>")
|
||||
phrase = 15
|
||||
if(15)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Shut up crime!</span>")
|
||||
phrase = 16
|
||||
if(16)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Face the wrath of the golden bolt.</span>")
|
||||
phrase = 17
|
||||
if(17)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: I am, the LAW!</span>")
|
||||
phrase = 18
|
||||
if(18)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Stop or I'll bash you.</span>")
|
||||
phrase = 12
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Go ahead, make my day.</span>")
|
||||
phrase = 13
|
||||
|
||||
phrase = (phrase < 18 && phrase >= 12 ) ? (phrase + 1) : 12
|
||||
key = phrase_list[phrase]
|
||||
message = phrase_list[key]
|
||||
to_chat(user,"<span class='notice'>You set the restrictor to: [message]</span>")
|
||||
if(4)
|
||||
switch(phrase)
|
||||
if(1)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Stop in the name of the Law.</span>")
|
||||
phrase = 2
|
||||
if(2)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Compliance is in your best interest.</span>")
|
||||
phrase = 3
|
||||
if(3)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Prepare for justice.</span>")
|
||||
phrase = 4
|
||||
if(4)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Running will only increase your sentence.</span>")
|
||||
phrase = 5
|
||||
if(5)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Don't move, Creep!</span>")
|
||||
phrase = 6
|
||||
if(6)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Down on the floor, Creep!</span>")
|
||||
phrase = 7
|
||||
if(7)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Dead or alive you're coming with me.</span>")
|
||||
phrase = 8
|
||||
if(8)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: God made today for the crooks we could not catch yesterday.</span>")
|
||||
phrase = 9
|
||||
if(9)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Freeze, Scum Bag!</span>")
|
||||
phrase = 10
|
||||
if(10)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Stop right there, criminal scum!</span>")
|
||||
phrase = 11
|
||||
if(11)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Stop or I'll bash you.</span>")
|
||||
phrase = 12
|
||||
if(12)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Go ahead, make my day.</span>")
|
||||
phrase = 13
|
||||
if(13)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Stop breaking the law, ass hole.</span>")
|
||||
phrase = 14
|
||||
if(14)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: You have the right to shut the fuck up.</span>")
|
||||
phrase = 15
|
||||
if(15)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Shut up crime!</span>")
|
||||
phrase = 16
|
||||
if(16)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: Face the wrath of the golden bolt.</span>")
|
||||
phrase = 17
|
||||
if(17)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: I am, the LAW!</span>")
|
||||
phrase = 18
|
||||
if(18)
|
||||
to_chat(user, "<span class='notice'>You set the restrictor to: HALT! HALT! HALT! HALT!</span>")
|
||||
phrase = 1
|
||||
phrase = (phrase < 18 && phrase >= 1 ) ? (phrase + 1) : 1
|
||||
key = phrase_list[phrase]
|
||||
message = phrase_list[key]
|
||||
to_chat(user,"<span class='notice'>You set the restrictor to: [message]</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>It's broken.</span>")
|
||||
|
||||
@@ -419,77 +340,20 @@
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/gas/sechailer/proc/halt()
|
||||
var/phrase_text = null
|
||||
var/phrase_sound = null
|
||||
var/key = phrase_list[phrase]
|
||||
var/message = phrase_list[key]
|
||||
|
||||
|
||||
if(cooldown < world.time - 35) // A cooldown, to stop people being jerks
|
||||
if(!safety)
|
||||
phrase_text = "FUCK YOUR CUNT YOU SHIT EATING COCKSUCKER MAN EAT A DONG FUCKING ASS RAMMING SHIT FUCK EAT PENISES IN YOUR FUCK FACE AND SHIT OUT ABORTIONS OF FUCK AND DO SHIT IN YOUR ASS YOU COCK FUCK SHIT MONKEY FUCK ASS WANKER FROM THE DEPTHS OF SHIT."
|
||||
usr.visible_message("[usr]'s Compli-o-Nator: <font color='red' size='4'><b>[phrase_text]</b></font>")
|
||||
message = "FUCK YOUR CUNT YOU SHIT EATING COCKSUCKER MAN EAT A DONG FUCKING ASS RAMMING SHIT FUCK EAT PENISES IN YOUR FUCK FACE AND SHIT OUT ABORTIONS OF FUCK AND DO SHIT IN YOUR ASS YOU COCK FUCK SHIT MONKEY FUCK ASS WANKER FROM THE DEPTHS OF SHIT."
|
||||
usr.visible_message("[usr]'s Compli-o-Nator: <font color='red' size='4'><b>[message]</b></font>")
|
||||
playsound(src.loc, 'sound/voice/binsult.ogg', 100, 0, 4)
|
||||
cooldown = world.time
|
||||
return
|
||||
|
||||
|
||||
switch(phrase) //sets the properties of the chosen phrase
|
||||
if(1) // good cop
|
||||
phrase_text = "HALT! HALT! HALT! HALT!"
|
||||
phrase_sound = "halt"
|
||||
if(2)
|
||||
phrase_text = "Stop in the name of the Law."
|
||||
phrase_sound = "bobby"
|
||||
if(3)
|
||||
phrase_text = "Compliance is in your best interest."
|
||||
phrase_sound = "compliance"
|
||||
if(4)
|
||||
phrase_text = "Prepare for justice!"
|
||||
phrase_sound = "justice"
|
||||
if(5)
|
||||
phrase_text = "Running will only increase your sentence."
|
||||
phrase_sound = "running"
|
||||
if(6) // bad cop
|
||||
phrase_text = "Don't move, Creep!"
|
||||
phrase_sound = "dontmove"
|
||||
if(7)
|
||||
phrase_text = "Down on the floor, Creep!"
|
||||
phrase_sound = "floor"
|
||||
if(8)
|
||||
phrase_text = "Dead or alive you're coming with me."
|
||||
phrase_sound = "robocop"
|
||||
if(9)
|
||||
phrase_text = "God made today for the crooks we could not catch yesterday."
|
||||
phrase_sound = "god"
|
||||
if(10)
|
||||
phrase_text = "Freeze, Scum Bag!"
|
||||
phrase_sound = "freeze"
|
||||
if(11)
|
||||
phrase_text = "Stop right there, criminal scum!"
|
||||
phrase_sound = "imperial"
|
||||
if(12) // LA-PD
|
||||
phrase_text = "Stop or I'll bash you."
|
||||
phrase_sound = "bash"
|
||||
if(13)
|
||||
phrase_text = "Go ahead, make my day."
|
||||
phrase_sound = "harry"
|
||||
if(14)
|
||||
phrase_text = "Stop breaking the law, ass hole."
|
||||
phrase_sound = "asshole"
|
||||
if(15)
|
||||
phrase_text = "You have the right to shut the fuck up."
|
||||
phrase_sound = "stfu"
|
||||
if(16)
|
||||
phrase_text = "Shut up crime!"
|
||||
phrase_sound = "shutup"
|
||||
if(17)
|
||||
phrase_text = "Face the wrath of the golden bolt."
|
||||
phrase_sound = "super"
|
||||
if(18)
|
||||
phrase_text = "I am, the LAW!"
|
||||
phrase_sound = "dredd"
|
||||
|
||||
usr.visible_message("[usr]'s Compli-o-Nator: <font color='red' size='4'><b>[phrase_text]</b></font>")
|
||||
playsound(src.loc, "sound/voice/complionator/[phrase_sound].ogg", 100, 0, 4)
|
||||
usr.visible_message("[usr]'s Compli-o-Nator: <font color='red' size='4'><b>[message]</b></font>")
|
||||
playsound(src.loc, "sound/voice/complionator/[key].ogg", 100, 0, 4)
|
||||
cooldown = world.time
|
||||
|
||||
|
||||
|
||||
@@ -120,6 +120,78 @@
|
||||
mute = MUZZLE_MUTE_NONE
|
||||
security_lock = TRUE
|
||||
locked = FALSE
|
||||
materials = list(MAT_METAL=500, MAT_GLASS=50)
|
||||
|
||||
/obj/item/clothing/mask/muzzle/safety/shock
|
||||
name = "shock muzzle"
|
||||
desc = "A muzzle designed to prevent biting. This one is fitted with a behavior correction system."
|
||||
var/obj/item/assembly/trigger = null
|
||||
origin_tech = "materials=1;engineering=1"
|
||||
materials = list(MAT_METAL=500, MAT_GLASS=50)
|
||||
|
||||
/obj/item/clothing/mask/muzzle/safety/shock/attackby(obj/item/W, mob/user, params)
|
||||
if(isscrewdriver(W) && trigger)
|
||||
to_chat(user, "<span class='notice'>You disassemble [src].</span>")
|
||||
trigger.forceMove(get_turf(user))
|
||||
trigger.master = null
|
||||
trigger.holder = null
|
||||
trigger = null
|
||||
return TRUE
|
||||
else if(istype(W, /obj/item/assembly/signaler) || istype(W, /obj/item/assembly/voice))
|
||||
if(istype(trigger, /obj/item/assembly/signaler) || istype(trigger, /obj/item/assembly/voice))
|
||||
to_chat(user, "<span class='notice'>Something is already attached to [src].</span>")
|
||||
return FALSE
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "<span class='warning'>You are unable to insert [W] into [src].</span>")
|
||||
return FALSE
|
||||
trigger = W
|
||||
trigger.forceMove(src)
|
||||
trigger.master = src
|
||||
trigger.holder = src
|
||||
to_chat(user, "<span class='notice'>You attach the [W] to [src].</span>")
|
||||
return TRUE
|
||||
else if(istype(W, /obj/item/assembly))
|
||||
to_chat(user, "<span class='notice'>That won't fit in [src]. Perhaps a signaler or voice analyzer would?</span>")
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/clothing/mask/muzzle/safety/shock/proc/can_shock(obj/item/clothing/C)
|
||||
if(istype(C))
|
||||
if(isliving(C.loc))
|
||||
return C.loc
|
||||
else if(isliving(loc))
|
||||
return loc
|
||||
return FALSE
|
||||
|
||||
/obj/item/clothing/mask/muzzle/safety/shock/proc/process_activation(var/obj/D, var/normal = 1, var/special = 1)
|
||||
visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
|
||||
var/mob/M = can_shock(loc)
|
||||
if(M)
|
||||
to_chat(M, "<span class='danger'>You feel a sharp shock!</span>")
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, M)
|
||||
s.start()
|
||||
|
||||
M.Weaken(5)
|
||||
M.Stuttering(1)
|
||||
M.Jitter(20)
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/muzzle/safety/shock/HasProximity(atom/movable/AM as mob|obj)
|
||||
if(trigger)
|
||||
trigger.HasProximity(AM)
|
||||
|
||||
|
||||
/obj/item/clothing/mask/muzzle/safety/shock/hear_talk(mob/living/M as mob, msg)
|
||||
if(trigger)
|
||||
trigger.hear_talk(M, msg)
|
||||
|
||||
/obj/item/clothing/mask/muzzle/safety/shock/hear_message(mob/living/M as mob, msg)
|
||||
if(trigger)
|
||||
trigger.hear_message(M, msg)
|
||||
|
||||
|
||||
|
||||
/obj/item/clothing/mask/surgical
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/t_scanner, /obj/item/rcd, /obj/item/crowbar, \
|
||||
/obj/item/screwdriver, /obj/item/weldingtool, /obj/item/wirecutters, /obj/item/wrench, /obj/item/multitool, \
|
||||
/obj/item/radio, /obj/item/analyzer, /obj/item/gun/energy/laser, /obj/item/gun/energy/pulse, \
|
||||
/obj/item/gun/energy/gun/advtaser, /obj/item/melee/baton, /obj/item/gun/energy/gun)
|
||||
/obj/item/gun/energy/gun/advtaser, /obj/item/melee/baton, /obj/item/gun/energy/gun, /obj/item/gun/projectile/automatic/lasercarbine, /obj/item/gun/energy/gun/blueshield)
|
||||
strip_delay = 130
|
||||
species_fit = list("Drask", "Vox")
|
||||
sprite_sheets = list(
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/t_scanner, /obj/item/rcd)
|
||||
siemens_coefficient = 0
|
||||
|
||||
hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran")
|
||||
species_restricted = list("exclude","Diona","Wryn")
|
||||
sprite_sheets = list(
|
||||
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
|
||||
@@ -313,7 +314,7 @@
|
||||
on = 1
|
||||
actions_types = list(/datum/action/item_action/toggle_helmet_mode)
|
||||
flags = BLOCKHAIR | STOPSPRESSUREDMAGE | THICKMATERIAL
|
||||
visor_flags_inv = HIDEMASK|HIDEEYES|HIDEFACE
|
||||
visor_flags_inv = HIDEMASK|HIDEEYES|HIDEFACE|HIDETAIL
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon()
|
||||
icon_state = "hardsuit[on]-[item_color]"
|
||||
@@ -379,7 +380,7 @@
|
||||
desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
|
||||
slowdown = 1
|
||||
flags = STOPSPRESSUREDMAGE | THICKMATERIAL
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
|
||||
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You switch your hardsuit to combat mode. You will take damage in zero pressure environments, but you are more suited for a fight.</span>")
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
slowdown = 0
|
||||
flags = STOPSPRESSUREDMAGE
|
||||
flags_size = ONESIZEFITSALL
|
||||
allowed = list(/obj/item) //for stuffing exta special presents
|
||||
allowed = list(/obj/item) //for stuffing extra special presents
|
||||
|
||||
//Space pirate outfit
|
||||
/obj/item/clothing/head/helmet/space/pirate
|
||||
@@ -139,13 +139,20 @@
|
||||
//Paramedic EVA suit
|
||||
/obj/item/clothing/head/helmet/space/eva/paramedic
|
||||
name = "Paramedic EVA helmet"
|
||||
desc = "A paramedic EVA helmet. Used in the recovery of bodies from space."
|
||||
desc = "A brand new paramedic EVA helmet. It seems to mold to your head shape. Used for retrieving bodies in space."
|
||||
icon_state = "paramedic-eva-helmet"
|
||||
item_state = "paramedic-eva-helmet"
|
||||
species_fit = list("Vox", "Grey")
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20)
|
||||
species_restricted = list("exclude", "Diona", "Wryn")
|
||||
species_fit = list("Vox", "Grey" , "Skrell" , "Tajaran" , "Drask" , "Unathi" , "Vulpkanin")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/helmet.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi',
|
||||
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/helmet.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/helmet.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi',
|
||||
)
|
||||
sprite_sheets_obj = list(
|
||||
"Vox" = 'icons/obj/clothing/species/vox/hats.dmi'
|
||||
@@ -155,10 +162,18 @@
|
||||
name = "Paramedic EVA suit"
|
||||
icon_state = "paramedic-eva"
|
||||
item_state = "paramedic-eva"
|
||||
desc = "A paramedic EVA suit. Used in the recovery of bodies from space."
|
||||
species_fit = list("Vox")
|
||||
desc = "A brand new paramedic EVA suit. The nitrile seems a bit too thin to be space proof. Used for retrieving bodies in space."
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20)
|
||||
species_restricted = list("exclude", "Diona", "Wryn")
|
||||
species_fit = list("Vox", "Grey" , "Skrell" , "Tajaran" , "Drask" , "Unathi" , "Vulpkanin")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/suit.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/suit.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/suit.dmi',
|
||||
"Skrell" = 'icons/mob/species/skrell/suit.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/suit.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi',
|
||||
)
|
||||
sprite_sheets_obj = list(
|
||||
"Vox" = 'icons/obj/clothing/species/vox/suits.dmi'
|
||||
|
||||
@@ -243,7 +243,6 @@
|
||||
/obj/item/clothing/accessory/holobadge/cord
|
||||
icon_state = "holobadge-cord"
|
||||
item_color = "holobadge-cord"
|
||||
slot_flags = SLOT_MASK | SLOT_TIE
|
||||
|
||||
/obj/item/clothing/accessory/holobadge/attack_self(mob/user as mob)
|
||||
if(!stored_name)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
return
|
||||
|
||||
if(!user.canUnEquip(W, 0))
|
||||
to_chat(user, "<span class='warning'>You can't let go of the [W]!<span>")
|
||||
to_chat(user, "<span class='warning'>You can't let go of the [W]!</span>")
|
||||
return
|
||||
|
||||
holstered = W
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "It's a high visibility jumpsuit given to those engineers insane enough to achieve the rank of \"Chief engineer\". It has minor radiation shielding."
|
||||
name = "chief engineer's jumpsuit"
|
||||
icon_state = "chiefengineer"
|
||||
item_state = "g_suit"
|
||||
item_state = "chief"
|
||||
item_color = "chief"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 10)
|
||||
flags_size = ONESIZEFITSALL
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
item_color = "centcom"
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/officer
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Lieutenant-Commander\" and bears \"N.C.V. Fearless CV-286\" on the left shounder."
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Lieutenant-Commander\" and bears \"N.C.V. Fearless CV-286\" on the left shoulder."
|
||||
name = "\improper Nanotrasen Officers Uniform"
|
||||
icon_state = "officer"
|
||||
item_state = "g_suit"
|
||||
@@ -112,7 +112,7 @@
|
||||
flags_size = ONESIZEFITSALL
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/captain
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Captain\" and bears \"N.C.V. Fearless CV-286\" on the left shounder."
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Captain\" and bears \"N.C.V. Fearless CV-286\" on the left shoulder."
|
||||
name = "\improper Nanotrasen Captains Uniform"
|
||||
icon_state = "centcom"
|
||||
item_state = "dg_suit"
|
||||
@@ -120,7 +120,7 @@
|
||||
displays_id = 0
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/blueshield
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Lieutenant\" and bears \"N.S.S. Cyberiad\" on the left shounder."
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Lieutenant\" and bears \"N.S.S. Cyberiad\" on the left shoulder."
|
||||
name = "\improper Nanotrasen Navy Uniform"
|
||||
icon_state = "officer"
|
||||
item_state = "g_suit"
|
||||
@@ -128,8 +128,12 @@
|
||||
displays_id = 0
|
||||
flags_size = ONESIZEFITSALL
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/blueshield/New()
|
||||
..()
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Lieutenant\" and bears [station_name()] on the left shoulder."
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/representative
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Ensign\" and bears \"N.S.S. Cyberiad\" on the left shounder."
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Ensign\" and bears \"N.S.S. Cyberiad\" on the left shoulder."
|
||||
name = "\improper Nanotrasen Navy Uniform"
|
||||
icon_state = "officer"
|
||||
item_state = "g_suit"
|
||||
@@ -137,6 +141,10 @@
|
||||
displays_id = 0
|
||||
flags_size = ONESIZEFITSALL
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/representative/New()
|
||||
..()
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Ensign\" and bears [station_name()] on the left shoulder."
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/diplomatic
|
||||
desc = "A very gaudy and official looking uniform of the Nanotrasen Diplomatic Corps."
|
||||
name = "\improper Nanotrasen Diplomatic Uniform"
|
||||
@@ -831,4 +839,4 @@
|
||||
icon_state = "medicalgown"
|
||||
item_state = "medicalgown"
|
||||
item_color = "medicalgown"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO
|
||||
|
||||
@@ -563,6 +563,61 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't modify [target]!</span>")
|
||||
|
||||
#define USED_MOD_HELM 1
|
||||
#define USED_MOD_SUIT 2
|
||||
|
||||
/obj/item/fluff/pyro_wintersec_kit //DarkLordpyro: Valthorne Haliber
|
||||
name = "winter sec conversion kit"
|
||||
desc = "A securirty hardsuit conversion kit."
|
||||
icon_state = "modkit"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/fluff/pyro_wintersec_kit/afterattack(atom/target, mob/user, proximity)
|
||||
if(!proximity || !ishuman(user) || user.incapacitated())
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
if(istype(target, /obj/item/clothing/head/helmet/space/hardsuit/security))
|
||||
if(used & USED_MOD_HELM)
|
||||
to_chat(H, "<span class='notice'>The kit's helmet modifier has already been used.</span>")
|
||||
return
|
||||
to_chat(H, "<span class='notice'>You modify the appearance of [target].</span>")
|
||||
used |= USED_MOD_HELM
|
||||
|
||||
var/obj/item/clothing/head/helmet/space/hardsuit/security/P = target
|
||||
P.name = "winterised security hardsuit helmet"
|
||||
P.desc = "A rare winterised variant of the security hardsuit helmet, used on colder mining worlds for security patrols."
|
||||
P.icon = 'icons/obj/custom_items.dmi'
|
||||
P.icon_state = "hardsuit0-secf"
|
||||
P.item_state = "hardsuit0-secf"
|
||||
P.sprite_sheets = null
|
||||
P.item_color = "secf"
|
||||
user.update_icons()
|
||||
|
||||
if(P == H.head)
|
||||
H.update_inv_head()
|
||||
return
|
||||
if(istype(target, /obj/item/clothing/suit/space/hardsuit/security))
|
||||
if(used & USED_MOD_SUIT)
|
||||
to_chat(user, "<span class='notice'>The kit's suit modifier has already been used.</span>")
|
||||
return
|
||||
to_chat(H, "<span class='notice'>You modify the appearance of [target].</span>")
|
||||
used |= USED_MOD_SUIT
|
||||
|
||||
var/obj/item/clothing/suit/space/hardsuit/security/P = target
|
||||
P.name = "winterised security hardsuit"
|
||||
P.desc = "A rare winterised variant of the security hardsuit, used on colder mining worlds for securiry patrols, this one has 'Haliber' written on an ID patch located on the right side of the chest."
|
||||
P.icon = 'icons/obj/custom_items.dmi'
|
||||
P.icon_state = "hardsuit-secf"
|
||||
P.item_state = "hardsuit-secf"
|
||||
P.sprite_sheets = null
|
||||
user.update_icons()
|
||||
|
||||
if(P == H.wear_suit)
|
||||
H.update_inv_wear_suit()
|
||||
return
|
||||
to_chat(user, "<span class='warning'>You can't modify [target]!</span>")
|
||||
|
||||
//////////////////////////////////
|
||||
//////////// Clothing ////////////
|
||||
//////////////////////////////////
|
||||
@@ -945,6 +1000,14 @@
|
||||
flags_inv = HIDEEARS
|
||||
|
||||
//////////// Uniforms ////////////
|
||||
/obj/item/clothing/under/fluff/benjaminfallout // Benjaminfallout: Pretzel Brassheart
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
name = "Pretzel's dress"
|
||||
desc = "A nice looking dress"
|
||||
icon_state = "fallout_dress"
|
||||
item_state = "fallout_dress"
|
||||
item_color = "fallout_dress"
|
||||
|
||||
/obj/item/clothing/under/fluff/soviet_casual_uniform // Norstead : Natalya Sokolova
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
name = "Soviet Casual Uniform"
|
||||
@@ -1043,6 +1106,15 @@
|
||||
item_color = "aegisuniform"
|
||||
displays_id = 0
|
||||
|
||||
/obj/item/clothing/under/fluff/elo_turtleneck // vforcebomber: E.L.O.
|
||||
name = "E.L.O's Turtleneck"
|
||||
desc = "This TurtleNeck belongs to the IPC E.L.O. And has her name sown into the upper left breast, a very wooly jumper."
|
||||
icon = 'icons/obj/custom_items.dmi' // for the floor sprite
|
||||
icon_override = 'icons/obj/custom_items.dmi' // for the mob sprite
|
||||
icon_state = "eloturtleneckfloor"
|
||||
item_color = "eloturtleneck"
|
||||
displays_id = FALSE
|
||||
|
||||
//////////// Masks ////////////
|
||||
|
||||
/obj/item/clothing/mask/bandana/fluff/dar //sasanek12: Dar'Konr
|
||||
@@ -1135,6 +1207,15 @@
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEFACE
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/fluff/arachno_boots
|
||||
name = "Arachno-Man boots"
|
||||
desc = "These boots were made for crawlin'"
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "superior_boots"
|
||||
item_state = "superior_boots"
|
||||
|
||||
|
||||
/obj/item/nullrod/fluff/chronx //chronx100: Hughe O'Splash
|
||||
fluff_transformations = list(/obj/item/nullrod/fluff/chronx/scythe)
|
||||
|
||||
@@ -1219,6 +1300,13 @@
|
||||
species_fit = null
|
||||
sprite_sheets = null
|
||||
|
||||
/obj/item/storage/backpack/fluff/syndiesatchel //SkeletalElite: Rawkkihiki
|
||||
name= "Military Satchel"
|
||||
desc = "A well made satchel for military operations. Totally not made by an enemy corporation"
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "rawk_satchel"
|
||||
sprite_sheets = null
|
||||
|
||||
/obj/item/storage/backpack/fluff/krich_back //lizardzsi: Krichahka
|
||||
name = "Voxcaster"
|
||||
desc = "Battered, Sol-made military radio backpack that had its speakers fried from playing Vox opera. The words 'Swift-Talon' are crudely scratched onto its side."
|
||||
@@ -1387,3 +1475,12 @@
|
||||
item_state = "panzermedal"
|
||||
item_color = "panzermedal"
|
||||
slot_flags = SLOT_TIE
|
||||
|
||||
/obj/item/clothing/accessory/medal/fluff/XannZxiax //Sagrotter: Xann Zxiax
|
||||
name = "Zxiax Garnet"
|
||||
desc = "Green Garnet on fancy blue cord, when you look at the Garnet, you feel strangely appeased."
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "Xann_necklace"
|
||||
item_state = "Xann_necklace"
|
||||
item_color = "Xann_necklace"
|
||||
slot_flags = SLOT_TIE
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.put_in_hands(P)
|
||||
to_chat(M, "<span class='notice'>Report printed. Log cleared.<span>")
|
||||
to_chat(M, "<span class='notice'>Report printed. Log cleared.</span>")
|
||||
|
||||
// Clear the logs
|
||||
log = list()
|
||||
|
||||
@@ -19,7 +19,7 @@ log transactions
|
||||
icon = 'icons/obj/terminals.dmi'
|
||||
icon_state = "atm"
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 10
|
||||
var/obj/machinery/computer/account_database/linked_db
|
||||
var/datum/money_account/authenticated_account
|
||||
@@ -97,18 +97,9 @@ log transactions
|
||||
if(!powered())
|
||||
return
|
||||
var/obj/item/stack/spacecash/C = I
|
||||
authenticated_account.money += C.amount
|
||||
playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 50, 1)
|
||||
|
||||
//create a transaction log entry
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = authenticated_account.owner_name
|
||||
T.purpose = "Credit deposit"
|
||||
T.amount = C.amount
|
||||
T.source_terminal = machine_id
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
authenticated_account.credit(C.amount, "Credit deposit", machine_id, authenticated_account.owner_name)
|
||||
|
||||
to_chat(user, "<span class='info'>You insert [C] into [src].</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
@@ -175,19 +166,8 @@ log transactions
|
||||
else if(transfer_amount <= authenticated_account.money)
|
||||
var/target_account_number = text2num(href_list["target_acc_number"])
|
||||
var/transfer_purpose = href_list["purpose"]
|
||||
if(linked_db.charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
|
||||
if(linked_db.charge_to_account(target_account_number, authenticated_account, transfer_purpose, machine_id, transfer_amount))
|
||||
to_chat(usr, "[bicon(src)]<span class='info'>Funds transfer successful.</span>")
|
||||
authenticated_account.money -= transfer_amount
|
||||
|
||||
//create an entry in the account transaction log
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = "Account #[target_account_number]"
|
||||
T.purpose = transfer_purpose
|
||||
T.source_terminal = machine_id
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
T.amount = "([transfer_amount])"
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
else
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Funds transfer failed.</span>")
|
||||
|
||||
@@ -263,15 +243,7 @@ log transactions
|
||||
authenticated_account.money -= amount
|
||||
withdraw_arbitrary_sum(amount)
|
||||
|
||||
//create an entry in the account transaction log
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = authenticated_account.owner_name
|
||||
T.purpose = "Credit withdrawal"
|
||||
T.amount = "([amount])"
|
||||
T.source_terminal = machine_id
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
authenticated_account.charge(amount, null, "Credit withdrawal", machine_id, authenticated_account.owner_name)
|
||||
else
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>You don't have enough funds to do that!</span>")
|
||||
if("balance_statement")
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
var/global/current_date_string
|
||||
#define STATION_CREATION_DATE "2 April, 2555"
|
||||
#define STATION_CREATION_TIME "11:24:30"
|
||||
#define STATION_START_CASH 75000
|
||||
#define STATION_SOURCE_TERMINAL "Biesel GalaxyNet Terminal #227"
|
||||
#define DEPARTMENT_START_CASH 5000
|
||||
|
||||
var/global/num_financial_terminals = 1
|
||||
var/global/datum/money_account/station_account
|
||||
var/global/list/datum/money_account/department_accounts = list()
|
||||
@@ -15,19 +20,13 @@ var/global/list/all_money_accounts = list()
|
||||
station_account.owner_name = "[station_name()] Station Account"
|
||||
station_account.account_number = rand(111111, 999999)
|
||||
station_account.remote_access_pin = rand(1111, 111111)
|
||||
station_account.money = 75000
|
||||
station_account.money = STATION_START_CASH
|
||||
|
||||
//create an entry in the account transaction log for when it was created
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = station_account.owner_name
|
||||
T.purpose = "Account creation"
|
||||
T.amount = 75000
|
||||
T.date = "2nd April, 2555"
|
||||
T.time = "11:24"
|
||||
T.source_terminal = "Biesel GalaxyNet Terminal #277"
|
||||
station_account.makeTransactionLog(STATION_START_CASH, "Account Creation", STATION_SOURCE_TERMINAL, station_account.owner_name, FALSE,
|
||||
STATION_CREATION_DATE, STATION_CREATION_TIME)
|
||||
|
||||
//add the account
|
||||
station_account.transaction_log.Add(T)
|
||||
all_money_accounts.Add(station_account)
|
||||
|
||||
/proc/create_department_account(department)
|
||||
@@ -37,19 +36,13 @@ var/global/list/all_money_accounts = list()
|
||||
department_account.owner_name = "[department] Account"
|
||||
department_account.account_number = rand(111111, 999999)
|
||||
department_account.remote_access_pin = rand(1111, 111111)
|
||||
department_account.money = 5000
|
||||
department_account.money = DEPARTMENT_START_CASH
|
||||
|
||||
//create an entry in the account transaction log for when it was created
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = department_account.owner_name
|
||||
T.purpose = "Account creation"
|
||||
T.amount = department_account.money
|
||||
T.date = "2nd April, 2555"
|
||||
T.time = "11:24"
|
||||
T.source_terminal = "Biesel GalaxyNet Terminal #277"
|
||||
department_account.makeTransactionLog(DEPARTMENT_START_CASH, "Account Creation", STATION_SOURCE_TERMINAL, department_account.owner_name, FALSE,
|
||||
STATION_CREATION_DATE, STATION_CREATION_TIME)
|
||||
|
||||
//add the account
|
||||
department_account.transaction_log.Add(T)
|
||||
all_money_accounts.Add(department_account)
|
||||
|
||||
department_accounts[department] = department_account
|
||||
@@ -73,7 +66,7 @@ var/global/list/all_money_accounts = list()
|
||||
if(!source_db)
|
||||
//set a random date, time and location some time over the past few decades
|
||||
T.date = "[num2text(rand(1,31))] [pick(month_names)], [rand(game_year - 20,game_year - 1)]"
|
||||
T.time = "[rand(0,23)]:[rand(0,59)]"
|
||||
T.time = "[rand(0,23)]:[rand(0,59)]:[rand(0,59)]"
|
||||
T.source_terminal = "NTGalaxyNet Terminal #[rand(111,1111)]"
|
||||
|
||||
M.account_number = rand(111111, 999999)
|
||||
@@ -104,7 +97,7 @@ var/global/list/all_money_accounts = list()
|
||||
<i>Date and time:</i> [station_time_timestamp()], [current_date_string]<br><br>
|
||||
<i>Creation terminal ID:</i> [source_db.machine_id]<br>
|
||||
<i>Authorised NT officer overseeing creation:</i> [overseer]<br>"}
|
||||
// END AUTOFIX
|
||||
|
||||
//stamp the paper
|
||||
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
|
||||
stampoverlay.icon_state = "paper_stamp-cent"
|
||||
@@ -133,7 +126,6 @@ var/global/list/all_money_accounts = list()
|
||||
|
||||
/datum/money_account/New()
|
||||
..()
|
||||
//security_level = pick (0,1) //Stealing is now slightly viable
|
||||
|
||||
/datum/transaction
|
||||
var/target_name = ""
|
||||
@@ -142,222 +134,14 @@ var/global/list/all_money_accounts = list()
|
||||
var/date = ""
|
||||
var/time = ""
|
||||
var/source_terminal = ""
|
||||
/*
|
||||
/obj/machinery/account_database
|
||||
name = "Accounts database"
|
||||
desc = "Holds transaction logs, account data and all kinds of other financial records."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "analyser"
|
||||
density = 1
|
||||
req_one_access = list(access_hop, access_captain)
|
||||
var/receipt_num
|
||||
var/machine_id = ""
|
||||
var/obj/item/card/id/held_card
|
||||
var/access_level = 0
|
||||
var/datum/money_account/detailed_account_view
|
||||
var/creating_new_account = 0
|
||||
var/activated = 1
|
||||
|
||||
/obj/machinery/account_database/New()
|
||||
..()
|
||||
if(!station_account)
|
||||
create_station_account()
|
||||
|
||||
if(department_accounts.len == 0)
|
||||
for(var/department in station_departments)
|
||||
create_department_account(department)
|
||||
if(!vendor_account)
|
||||
create_department_account("Vendor")
|
||||
vendor_account = department_accounts["Vendor"]
|
||||
|
||||
if(!current_date_string)
|
||||
current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 2557"
|
||||
|
||||
machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]"
|
||||
|
||||
/obj/machinery/account_database/attack_hand(mob/user as mob)
|
||||
if(ishuman(user) && !user.stat && get_dist(src,user) <= 1)
|
||||
var/dat = "<b>Accounts Database</b><br>"
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm:171: dat += "<i>[machine_id]</i><br>"
|
||||
dat += {"<i>[machine_id]</i><br>
|
||||
Confirm identity: <a href='?src=[UID()];choice=insert_card'>[held_card ? held_card : "-----"]</a><br>"}
|
||||
// END AUTOFIX
|
||||
if(access_level > 0)
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm:175: dat += "<a href='?src=[UID()];toggle_activated=1'>[activated ? "Disable" : "Enable"] remote access</a><br>"
|
||||
dat += {"<a href='?src=[UID()];toggle_activated=1'>[activated ? "Disable" : "Enable"] remote access</a><br>
|
||||
You may not edit accounts at this terminal, only create and view them.<br>"}
|
||||
// END AUTOFIX
|
||||
if(creating_new_account)
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm:178: dat += "<br>"
|
||||
dat += {"<br>
|
||||
<a href='?src=[UID()];choice=view_accounts_list;'>Return to accounts list</a>
|
||||
<form name='create_account' action='?src=[UID()]' method='get'>
|
||||
<input type='hidden' name='src' value='[UID()]'>
|
||||
<input type='hidden' name='choice' value='finalise_create_account'>
|
||||
<b>Holder name:</b> <input type='text' id='holder_name' name='holder_name' style='width:250px; background-color:white;'><br>
|
||||
<b>Initial funds:</b> <input type='text' id='starting_funds' name='starting_funds' style='width:250px; background-color:white;'> (subtracted from station account)<br>
|
||||
<i>New accounts are automatically assigned a secret number and pin, which are printed separately in a sealed package.</i><br>
|
||||
<input type='submit' value='Create'><br>
|
||||
</form>"}
|
||||
// END AUTOFIX
|
||||
else
|
||||
if(detailed_account_view)
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm:190: dat += "<br>"
|
||||
dat += {"<br>
|
||||
<a href='?src=[UID()];choice=view_accounts_list;'>Return to accounts list</a><hr>
|
||||
<b>Account number:</b> #[detailed_account_view.account_number]<br>
|
||||
<b>Account holder:</b> [detailed_account_view.owner_name]<br>
|
||||
<b>Account balance:</b> $[detailed_account_view.money]<br>
|
||||
<table border=1 style='width:100%'>
|
||||
<tr>
|
||||
<td><b>Date</b></td>
|
||||
<td><b>Time</b></td>
|
||||
<td><b>Target</b></td>
|
||||
<td><b>Purpose</b></td>
|
||||
<td><b>Value</b></td>
|
||||
<td><b>Source terminal ID</b></td>
|
||||
</tr>"}
|
||||
// END AUTOFIX
|
||||
for(var/datum/transaction/T in detailed_account_view.transaction_log)
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm:205: dat += "<tr>"
|
||||
dat += {"<tr>
|
||||
<td>[T.date]</td>
|
||||
<td>[T.time]</td>
|
||||
<td>[T.target_name]</td>
|
||||
<td>[T.purpose]</td>
|
||||
<td>$[T.amount]</td>
|
||||
<td>[T.source_terminal]</td>
|
||||
</tr>"}
|
||||
// END AUTOFIX
|
||||
dat += "</table>"
|
||||
else
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm:215: dat += "<a href='?src=[UID()];choice=create_account;'>Create new account</a><br><br>"
|
||||
dat += {"<a href='?src=[UID()];choice=create_account;'>Create new account</a><br><br>
|
||||
<table border=1 style='width:100%'>"}
|
||||
// END AUTOFIX
|
||||
for(var/i=1, i<=all_money_accounts.len, i++)
|
||||
var/datum/money_account/D = all_money_accounts[i]
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm:219: dat += "<tr>"
|
||||
dat += {"<tr>
|
||||
<td>#[D.account_number]</td>
|
||||
<td>[D.owner_name]</td>
|
||||
<td><a href='?src=[UID()];choice=view_account_detail;account_index=[i]'>View in detail</a></td>
|
||||
</tr>"}
|
||||
// END AUTOFIX
|
||||
dat += "</table>"
|
||||
|
||||
user << browse(dat,"window=account_db;size=700x650")
|
||||
else
|
||||
user << browse(null,"window=account_db")
|
||||
|
||||
/obj/machinery/account_database/attackby(O as obj, user as mob)//TODO:SANITY
|
||||
if(istype(O, /obj/item/card))
|
||||
var/obj/item/card/id/idcard = O
|
||||
if(!held_card)
|
||||
usr.drop_item()
|
||||
idcard.loc = src
|
||||
held_card = idcard
|
||||
|
||||
if(access_cent_captain in idcard.access)
|
||||
access_level = 2
|
||||
else if(access_hop in idcard.access || access_captain in idcard.access)
|
||||
access_level = 1
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/account_database/Topic(var/href, var/href_list)
|
||||
..()
|
||||
if(href_list["toggle_activated"])
|
||||
activated = !activated
|
||||
|
||||
if(href_list["choice"])
|
||||
switch(href_list["choice"])
|
||||
if("create_account")
|
||||
creating_new_account = 1
|
||||
if("finalise_create_account")
|
||||
var/account_name = href_list["holder_name"]
|
||||
var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
|
||||
create_account(account_name, starting_funds, src)
|
||||
if(starting_funds > 0)
|
||||
//subtract the money
|
||||
station_account.money -= starting_funds
|
||||
|
||||
//create a transaction log entry
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = account_name
|
||||
T.purpose = "New account funds initialisation"
|
||||
T.amount = "([starting_funds])"
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
T.source_terminal = machine_id
|
||||
station_account.transaction_log.Add(T)
|
||||
|
||||
creating_new_account = 0
|
||||
if("insert_card")
|
||||
if(held_card)
|
||||
held_card.loc = src.loc
|
||||
|
||||
if(ishuman(usr) && !usr.get_active_hand())
|
||||
usr.put_in_hands(held_card)
|
||||
held_card = null
|
||||
access_level = 0
|
||||
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if(istype(I, /obj/item/card/id))
|
||||
var/obj/item/card/id/C = I
|
||||
usr.drop_item()
|
||||
C.loc = src
|
||||
held_card = C
|
||||
|
||||
if(access_cent_captain in C.access)
|
||||
access_level = 2
|
||||
else if(access_hop in C.access || access_captain in C.access)
|
||||
access_level = 1
|
||||
if("view_account_detail")
|
||||
var/index = text2num(href_list["account_index"])
|
||||
if(index && index <= all_money_accounts.len)
|
||||
detailed_account_view = all_money_accounts[index]
|
||||
if("view_accounts_list")
|
||||
detailed_account_view = null
|
||||
creating_new_account = 0
|
||||
|
||||
src.attack_hand(usr)
|
||||
*/
|
||||
/obj/machinery/computer/account_database/proc/charge_to_account(var/attempt_account_number, var/source_name, var/purpose, var/terminal_id, var/amount)
|
||||
/obj/machinery/computer/account_database/proc/charge_to_account(attempt_account_number, datum/money_account/source, purpose, terminal_id, amount)
|
||||
if(!activated)
|
||||
return 0
|
||||
for(var/datum/money_account/D in all_money_accounts)
|
||||
if(D.account_number == attempt_account_number && !D.suspended)
|
||||
D.money += amount
|
||||
|
||||
//create a transaction log entry
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = source_name
|
||||
T.purpose = purpose
|
||||
if(amount < 0)
|
||||
T.amount = "([amount])"
|
||||
else
|
||||
T.amount = "[amount]"
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
T.source_terminal = terminal_id
|
||||
D.transaction_log.Add(T)
|
||||
|
||||
source.charge(amount, D, purpose, terminal_id, "Account #[D.account_number]", "Transfer from [source.owner_name]",
|
||||
"[D.owner_name]")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
@@ -378,3 +162,9 @@ var/global/list/all_money_accounts = list()
|
||||
for(var/datum/money_account/D in all_money_accounts)
|
||||
if(D.account_number == attempt_account_number)
|
||||
return D
|
||||
|
||||
#undef STATION_CREATION_DATE
|
||||
#undef STATION_CREATION_TIME
|
||||
#undef STATION_START_CASH
|
||||
#undef STATION_SOURCE_TERMINAL
|
||||
#undef DEPARTMENT_START_CASH
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var/global/current_date_string
|
||||
|
||||
/obj/machinery/computer/account_database
|
||||
name = "Accounts Uplink Terminal"
|
||||
@@ -15,34 +16,6 @@
|
||||
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/machinery/computer/account_database/proc/get_access_level(var/mob/user)
|
||||
if(user.can_admin_interact())
|
||||
return 2
|
||||
if(!held_card)
|
||||
return 0
|
||||
if(access_cent_commander in held_card.access)
|
||||
return 2
|
||||
else if(access_hop in held_card.access || access_captain in held_card.access)
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/account_database/proc/create_transation(target, reason, amount)
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = target
|
||||
T.purpose = reason
|
||||
T.amount = amount
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
T.source_terminal = machine_id
|
||||
return T
|
||||
|
||||
/obj/machinery/computer/account_database/proc/accounting_letterhead(report_name)
|
||||
return {"
|
||||
<center><h1><b>[report_name]</b></h1></center>
|
||||
<center><small><i>[station_name()] Accounting Report</i></small></center>
|
||||
<hr>
|
||||
<u>Generated By:</u> [held_card.registered_name], [held_card.assignment]<br>
|
||||
"}
|
||||
|
||||
/obj/machinery/computer/account_database/New()
|
||||
if(!station_account)
|
||||
create_station_account()
|
||||
@@ -55,11 +28,29 @@
|
||||
vendor_account = department_accounts["Vendor"]
|
||||
|
||||
if(!current_date_string)
|
||||
current_date_string = "[time2text(world.timeofday, "DD MM")], [game_year]"
|
||||
current_date_string = "[time2text(world.timeofday, "DD Month")], [game_year]"
|
||||
|
||||
machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]"
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/account_database/proc/get_access_level(var/mob/user)
|
||||
if(user.can_admin_interact())
|
||||
return 2
|
||||
if(!held_card)
|
||||
return 0
|
||||
if(access_cent_commander in held_card.access)
|
||||
return 2
|
||||
else if(access_hop in held_card.access || access_captain in held_card.access)
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/account_database/proc/accounting_letterhead(report_name)
|
||||
return {"
|
||||
<center><h1><b>[report_name]</b></h1></center>
|
||||
<center><small><i>[station_name()] Accounting Report</i></small></center>
|
||||
<hr>
|
||||
<u>Generated By:</u> [held_card.registered_name], [held_card.assignment]<br>
|
||||
"}
|
||||
|
||||
/obj/machinery/computer/account_database/attackby(obj/O, mob/user, params)
|
||||
if(!istype(O, /obj/item/card/id))
|
||||
return ..()
|
||||
@@ -160,16 +151,6 @@
|
||||
if("create_account")
|
||||
creating_new_account = 1
|
||||
|
||||
if("add_funds")
|
||||
var/amount = input("Enter the amount you wish to add", "Silently add funds") as num
|
||||
if(detailed_account_view)
|
||||
detailed_account_view.money += amount
|
||||
|
||||
if("remove_funds")
|
||||
var/amount = input("Enter the amount you wish to remove", "Silently remove funds") as num
|
||||
if(detailed_account_view)
|
||||
detailed_account_view.money -= amount
|
||||
|
||||
if("toggle_suspension")
|
||||
if(detailed_account_view)
|
||||
detailed_account_view.suspended = !detailed_account_view.suspended
|
||||
@@ -182,14 +163,10 @@
|
||||
starting_funds = Clamp(starting_funds, 0, station_account.money) // Not authorized to put the station in debt.
|
||||
starting_funds = min(starting_funds, fund_cap) // Not authorized to give more than the fund cap.
|
||||
|
||||
create_account(account_name, starting_funds, src)
|
||||
var/datum/money_account/M = create_account(account_name, starting_funds, src)
|
||||
if(starting_funds > 0)
|
||||
//subtract the money
|
||||
station_account.money -= starting_funds
|
||||
|
||||
//create a transaction log entry
|
||||
var/trx = create_transation(account_name, "New account activation", "([starting_funds])")
|
||||
station_account.transaction_log.Add(trx)
|
||||
station_account.charge(starting_funds, null, "New account activation",
|
||||
"", "New account activation", M.owner_name)
|
||||
|
||||
creating_new_account = 0
|
||||
ui.close()
|
||||
@@ -205,19 +182,6 @@
|
||||
detailed_account_view = null
|
||||
creating_new_account = 0
|
||||
|
||||
if("revoke_payroll")
|
||||
var/funds = detailed_account_view.money
|
||||
var/account_trx = create_transation(station_account.owner_name, "Revoke payroll", "([funds])")
|
||||
var/station_trx = create_transation(detailed_account_view.owner_name, "Revoke payroll", funds)
|
||||
|
||||
station_account.money += funds
|
||||
detailed_account_view.money = 0
|
||||
|
||||
detailed_account_view.transaction_log.Add(account_trx)
|
||||
station_account.transaction_log.Add(station_trx)
|
||||
|
||||
callHook("revoke_payroll", list(detailed_account_view))
|
||||
|
||||
if("print")
|
||||
var/text
|
||||
playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1)
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
desc = "Swipe your ID card to make purchases electronically."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "eftpos"
|
||||
var/machine_id = ""
|
||||
var/eftpos_name = "Default EFTPOS scanner"
|
||||
var/machine_name = ""
|
||||
var/transaction_locked = 0
|
||||
var/transaction_paid = 0
|
||||
var/transaction_amount = 0
|
||||
@@ -15,7 +14,7 @@
|
||||
|
||||
/obj/item/eftpos/New()
|
||||
..()
|
||||
machine_id = "[station_name()] EFTPOS #[num_financial_terminals++]"
|
||||
machine_name = "[station_name()] EFTPOS #[num_financial_terminals++]"
|
||||
access_code = rand(1111,111111)
|
||||
reconnect_database()
|
||||
spawn(0)
|
||||
@@ -28,14 +27,10 @@
|
||||
/obj/item/eftpos/proc/print_reference()
|
||||
playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1)
|
||||
var/obj/item/paper/R = new(loc)
|
||||
R.name = "Reference: [eftpos_name]"
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\EFTPOS.dm:31: R.info = "<b>[eftpos_name] reference</b><br><br>"
|
||||
R.info = {"<b>[eftpos_name] reference</b><br><br>
|
||||
R.name = "Reference: [machine_name]"
|
||||
R.info = {"<b>[machine_name] reference</b><br><br>
|
||||
Access code: [access_code]<br><br>
|
||||
<b>Do not lose or misplace this code.</b><br>"}
|
||||
// END AUTOFIX
|
||||
//stamp the paper
|
||||
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
|
||||
stampoverlay.icon_state = "paper_stamp-cent"
|
||||
@@ -86,8 +81,7 @@
|
||||
|
||||
/obj/item/eftpos/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
|
||||
var/data[0]
|
||||
data["eftpos_name"] = eftpos_name
|
||||
data["machine_id"] = machine_id
|
||||
data["machine_name"] = machine_name
|
||||
data["transaction_locked"] = transaction_locked
|
||||
data["transaction_paid"] = transaction_paid
|
||||
data["transaction_purpose"] = transaction_purpose
|
||||
@@ -112,15 +106,6 @@
|
||||
print_reference()
|
||||
else
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Incorrect code entered.</span>")
|
||||
if("change_id")
|
||||
var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm EFTPOS code"))
|
||||
if(attempt_code == access_code)
|
||||
var/name = input("Enter a new terminal ID for this device", "Enter new EFTPOS ID") as text|null
|
||||
if(name)
|
||||
eftpos_name = "[name] EFTPOS scanner"
|
||||
print_reference()
|
||||
else
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Incorrect code entered.</span>")
|
||||
if("link_account")
|
||||
if(!linked_db)
|
||||
reconnect_database()
|
||||
@@ -179,48 +164,34 @@
|
||||
if(istype(I, /obj/item/card/id))
|
||||
var/obj/item/card/id/C = I
|
||||
visible_message("<span class='info'>[user] swipes a card through [src].</span>")
|
||||
if(transaction_locked && !transaction_paid)
|
||||
if(linked_account)
|
||||
var/attempt_pin = input("Enter pin code", "EFTPOS transaction") as num
|
||||
var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2)
|
||||
if(D)
|
||||
if(transaction_amount <= D.money)
|
||||
playsound(src, 'sound/machines/chime.ogg', 50, 1)
|
||||
visible_message("[bicon(src)] The [src] chimes.")
|
||||
transaction_paid = 1
|
||||
|
||||
//transfer the money
|
||||
D.money -= transaction_amount
|
||||
linked_account.money += transaction_amount
|
||||
if(!transaction_locked || transaction_paid)
|
||||
return
|
||||
|
||||
if(!linked_account)
|
||||
to_chat(user, "[bicon(src)]<span class='warning'>EFTPOS is not connected to an account.</span>")
|
||||
return
|
||||
|
||||
var/confirm = alert("Are you sure you want to pay $[transaction_amount] to Account: [linked_account.owner_name] ", "Confirm transaction", "Yes", "No")
|
||||
if(confirm == "No")
|
||||
return
|
||||
var/attempt_pin = input("Enter pin code", "EFTPOS transaction") as num
|
||||
var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2)
|
||||
|
||||
if(!D)
|
||||
to_chat(user, "[bicon(src)]<span class='warning'>Unable to access account. Check security settings and try again.</span>")
|
||||
|
||||
if(transaction_amount > D.money)
|
||||
to_chat(user, "[bicon(src)]<span class='warning'>You don't have that much money!</span>")
|
||||
return
|
||||
|
||||
var/transSuccess = D.charge(transaction_amount, linked_account, transaction_purpose, machine_name, D.owner_name)
|
||||
if(transSuccess == TRUE)
|
||||
playsound(src, 'sound/machines/chime.ogg', 50, 1)
|
||||
visible_message("[bicon(src)] The [src] chimes.")
|
||||
transaction_paid = 1
|
||||
|
||||
//create entries in the two account transaction logs
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = "[linked_account.owner_name] (via [eftpos_name])"
|
||||
T.purpose = transaction_purpose
|
||||
if(transaction_amount > 0)
|
||||
T.amount = "([transaction_amount])"
|
||||
else
|
||||
T.amount = "[transaction_amount]"
|
||||
T.source_terminal = machine_id
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
D.transaction_log.Add(T)
|
||||
//
|
||||
T = new()
|
||||
T.target_name = D.owner_name
|
||||
T.purpose = transaction_purpose
|
||||
T.amount = "[transaction_amount]"
|
||||
T.source_terminal = machine_id
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
linked_account.transaction_log.Add(T)
|
||||
else
|
||||
to_chat(user, "[bicon(src)]<span class='warning'>You don't have that much money!</span>")
|
||||
else
|
||||
to_chat(user, "[bicon(src)]<span class='warning'>Unable to access account. Check security settings and try again.</span>")
|
||||
else
|
||||
to_chat(user, "[bicon(src)]<span class='warning'>EFTPOS is not connected to an account.</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
//emag?
|
||||
//emag?
|
||||
|
||||
@@ -46,47 +46,69 @@
|
||||
/datum/money_account/proc/fmtBalance()
|
||||
return "$[num2septext(money)]"
|
||||
|
||||
/datum/money_account/proc/charge(var/transaction_amount,var/datum/money_account/dest,var/transaction_purpose, var/terminal_name="", var/terminal_id=0, var/dest_name = "UNKNOWN")
|
||||
// Seperated from charge so they can reuse the code and also because there's many instances where a log will be made without actually making a transaction
|
||||
/datum/money_account/proc/makeTransactionLog(transaction_amount = 0, transaction_purpose, terminal_name = "",
|
||||
dest_name = "UNKNOWN", charging = TRUE, date = current_date_string, time = "")
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = dest_name
|
||||
T.purpose = transaction_purpose
|
||||
if(!charging || transaction_amount == 0)
|
||||
T.amount = "[transaction_amount]"
|
||||
else
|
||||
T.amount = "([transaction_amount])"
|
||||
|
||||
T.source_terminal = terminal_name
|
||||
T.date = date
|
||||
if(time == "")
|
||||
T.time = station_time_timestamp()
|
||||
else
|
||||
T.time = time
|
||||
transaction_log.Add(T)
|
||||
|
||||
// Charge is for transferring money from an account to another. The destination account can possibly not exist (Magical money sink)
|
||||
/datum/money_account/proc/charge(transaction_amount = 0, datum/money_account/dest, transaction_purpose,
|
||||
terminal_name = "", dest_name = "UNKNOWN", dest_purpose, dest_target_name)
|
||||
if(suspended)
|
||||
to_chat(usr, "<span class='warning'>Unable to access source account: account suspended.</span>")
|
||||
return 0
|
||||
|
||||
|
||||
if(transaction_amount <= money)
|
||||
//transfer the money
|
||||
money -= transaction_amount
|
||||
makeTransactionLog(transaction_amount, transaction_purpose, terminal_name, dest_name)
|
||||
if(dest)
|
||||
dest.money += transaction_amount
|
||||
dest.makeTransactionLog(transaction_amount,
|
||||
dest_purpose ? dest_purpose : transaction_purpose, terminal_name, dest_target_name ? dest_target_name : dest_name, FALSE)
|
||||
return 1
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Insufficient funds in account.</span>")
|
||||
return 0
|
||||
|
||||
// phantom_charge is for when you want to charge an account, without making any corresponding log (e.g. you make it yourself with custom date
|
||||
// or there won't be any log for some IC reasons (hacking)
|
||||
/datum/money_account/proc/phantom_charge(transaction_amount = 0, datum/money_account/dest, suspensionbypass = 0)
|
||||
if(suspended && !suspensionbypass)
|
||||
return 0
|
||||
|
||||
if(transaction_amount <= money)
|
||||
//transfer the money
|
||||
money -= transaction_amount
|
||||
if(dest)
|
||||
dest.money += transaction_amount
|
||||
|
||||
//create entries in the two account transaction logs
|
||||
var/datum/transaction/T
|
||||
if(dest)
|
||||
T = new()
|
||||
T.target_name = owner_name
|
||||
if(terminal_name!="")
|
||||
T.target_name += " (via [terminal_name])"
|
||||
T.purpose = transaction_purpose
|
||||
if(transaction_amount > 0)
|
||||
T.amount = "([transaction_amount])"
|
||||
else
|
||||
T.amount = "[transaction_amount]"
|
||||
if(terminal_id)
|
||||
T.source_terminal = terminal_id
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
dest.transaction_log.Add(T)
|
||||
//
|
||||
T = new()
|
||||
T.target_name = (!dest) ? dest_name : dest.owner_name
|
||||
if(terminal_name!="")
|
||||
T.target_name += " (via [terminal_name])"
|
||||
T.purpose = transaction_purpose
|
||||
T.amount = "[transaction_amount]"
|
||||
if(terminal_id)
|
||||
T.source_terminal = terminal_id
|
||||
T.date = current_date_string
|
||||
T.time = station_time_timestamp()
|
||||
transaction_log.Add(T)
|
||||
return 1
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Insufficient funds in account.</span>")
|
||||
return 0
|
||||
return 0
|
||||
|
||||
// Credit is for giving money to an account out of thin air. Suspension does not matter.
|
||||
/datum/money_account/proc/credit(transaction_amount = 0, transaction_purpose,
|
||||
terminal_name = "", dest_name = "UNKNOWN", date = current_date_string, time = "")
|
||||
|
||||
money += transaction_amount
|
||||
makeTransactionLog(transaction_amount, transaction_purpose, terminal_name, dest_name, FALSE, date, time)
|
||||
return 1
|
||||
|
||||
//phantom_credit is like the above without any log
|
||||
/datum/money_account/proc/phantom_credit(transaction_amount = 0)
|
||||
money += transaction_amount
|
||||
return 1
|
||||
|
||||
+15
-17
@@ -1,7 +1,6 @@
|
||||
/datum/event/blob
|
||||
announceWhen = 60
|
||||
endWhen = 120
|
||||
var/obj/structure/blob/core/Blob
|
||||
announceWhen = 120
|
||||
endWhen = 180
|
||||
|
||||
/datum/event/blob/announce()
|
||||
event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
|
||||
@@ -11,18 +10,17 @@
|
||||
if(!T)
|
||||
return kill()
|
||||
var/list/candidates = pollCandidates("Do you want to play as a blob?", ROLE_BLOB, 1)
|
||||
var/mob/C
|
||||
if(candidates.len)
|
||||
C = pick(candidates)
|
||||
Blob = new /obj/structure/blob/core(T, new_overmind=C.client)
|
||||
for(var/i in 1 to 5)
|
||||
Blob.process()
|
||||
else
|
||||
if(!candidates.len)
|
||||
return kill()
|
||||
|
||||
/datum/event/blob/tick()
|
||||
if(!Blob)
|
||||
kill()
|
||||
return
|
||||
if(IsMultiple(activeFor, 3))
|
||||
Blob.process()
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in all_vent_pumps)
|
||||
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
|
||||
if(temp_vent.parent.other_atmosmch.len > 50)
|
||||
vents += temp_vent
|
||||
var/obj/vent = pick(vents)
|
||||
var/mob/living/simple_animal/mouse/blobinfected/B = new(vent.loc)
|
||||
var/mob/M = pick(candidates)
|
||||
B.key = M.key
|
||||
to_chat(B, "<span class='userdanger'>You are now a mouse, infected with blob spores. Find somewhere isolated... before you burst and become the blob! Use ventcrawl (alt-click on vents) to move around.</span>")
|
||||
var/image/alert_overlay = image('icons/mob/blob.dmi', "blank_blob")
|
||||
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B, alert_overlay = alert_overlay)
|
||||
@@ -17,12 +17,12 @@
|
||||
if(announce)
|
||||
event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg')
|
||||
|
||||
var/list/skipped_areas = list(/area/turret_protected/ai, /area/syndicate_depot)
|
||||
var/list/skipped_areas_apc = list(/area/engine/engineering, /area/syndicate_depot)
|
||||
var/list/skipped_areas = list(/area/turret_protected/ai)
|
||||
var/list/skipped_areas_apc = list(/area/engine/engineering)
|
||||
|
||||
for(var/obj/machinery/power/smes/S in machines)
|
||||
var/area/current_area = get_area(S)
|
||||
if(current_area.type in skipped_areas || !is_station_level(S.z))
|
||||
if((current_area.type in skipped_areas) || !is_station_level(S.z))
|
||||
continue
|
||||
S.last_charge = S.charge
|
||||
S.last_output_attempt = S.output_attempt
|
||||
@@ -35,26 +35,26 @@
|
||||
|
||||
for(var/obj/machinery/power/apc/C in apcs)
|
||||
var/area/current_area = get_area(C)
|
||||
if(current_area.type in skipped_areas_apc || !is_station_level(C.z))
|
||||
if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
|
||||
continue
|
||||
if(C.cell)
|
||||
C.cell.charge = 0
|
||||
|
||||
/proc/power_restore(var/announce = 1)
|
||||
var/list/skipped_areas = list(/area/turret_protected/ai, /area/syndicate_depot)
|
||||
var/list/skipped_areas_apc = list(/area/engine/engineering, /area/syndicate_depot)
|
||||
var/list/skipped_areas = list(/area/turret_protected/ai)
|
||||
var/list/skipped_areas_apc = list(/area/engine/engineering)
|
||||
|
||||
if(announce)
|
||||
event_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
|
||||
for(var/obj/machinery/power/apc/C in apcs)
|
||||
var/area/current_area = get_area(C)
|
||||
if(current_area.type in skipped_areas_apc || !is_station_level(C.z))
|
||||
if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
|
||||
continue
|
||||
if(C.cell)
|
||||
C.cell.charge = C.cell.maxcharge
|
||||
for(var/obj/machinery/power/smes/S in machines)
|
||||
var/area/current_area = get_area(S)
|
||||
if(current_area.type in skipped_areas || !is_station_level(S.z))
|
||||
if((current_area.type in skipped_areas) || !is_station_level(S.z))
|
||||
continue
|
||||
S.charge = S.last_charge
|
||||
S.output_attempt = S.last_output_attempt
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#define MINIMUM_PERCENTAGE_LOSS 0.5
|
||||
#define VARIABLE_LOSS 2 // Invariant: 1 - VARIABLE_LOSS/10 >= MINIMUM_PERCENTAGE_LOSS
|
||||
|
||||
/var/global/account_hack_attempted = 0
|
||||
|
||||
/datum/event/money_hacker
|
||||
@@ -16,7 +19,7 @@
|
||||
|
||||
/datum/event/money_hacker/announce()
|
||||
var/message = "A brute force hack has been detected (in progress since [station_time_timestamp()]). The target of the attack is: Financial account #[affected_account.account_number], \
|
||||
without intervention this attack will succeed in approximately 10 minutes. Required intervention: temporary suspension of affected accounts until the attack has ceased. \
|
||||
without intervention this attack will succeed in approximately 10 minutes. Required intervention: temporary suspension of affected account until the attack has ceased. \
|
||||
Notifications will be sent as updates occur.<br>"
|
||||
var/my_department = "[station_name()] firewall subroutines"
|
||||
|
||||
@@ -32,35 +35,38 @@
|
||||
|
||||
/datum/event/money_hacker/end()
|
||||
var/message
|
||||
if(affected_account && !affected_account)
|
||||
//hacker wins
|
||||
if(!isnull(affected_account) && !affected_account.suspended)
|
||||
message = "The hack attempt has succeeded."
|
||||
|
||||
//subtract the money
|
||||
var/lost = affected_account.money * 0.8 + (rand(2,4) - 2) / 10
|
||||
affected_account.money -= lost
|
||||
var/lost = affected_account.money * (MINIMUM_PERCENTAGE_LOSS + rand(0,VARIABLE_LOSS) / 10);
|
||||
|
||||
affected_account.phantom_charge(lost)
|
||||
|
||||
|
||||
//create a taunting log entry
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = pick("","yo brotha from anotha motha","el Presidente","chieF smackDowN")
|
||||
T.purpose = pick("Ne$ ---ount fu%ds init*&lisat@*n","PAY BACK YOUR MUM","Funds withdrawal","pWnAgE","l33t hax","liberationez")
|
||||
T.amount = pick("","([rand(0,99999)])","alla money","9001$","HOLLA HOLLA GET DOLLA","([lost])")
|
||||
var/dest_name = pick("","yo brotha from anotha motha","el Presidente","chieF smackDowN")
|
||||
var/amount = pick("","([rand(0,99999)])","alla money","9001$","HOLLA HOLLA GET DOLLA","([lost])")
|
||||
var/purpose = pick("Ne$ ---ount fu%ds init*&lisat@*n","PAY BACK YOUR MUM","Funds withdrawal","pWnAgE","l33t hax","liberationez")
|
||||
var/date1 = "31 December, 1999"
|
||||
var/date2 = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], [rand(1000,3000)]"
|
||||
T.date = pick("", current_date_string, date1, date2)
|
||||
var/date = pick("", current_date_string, date1, date2)
|
||||
var/time1 = rand(0, 99999999)
|
||||
var/time2 = "[round(time1 / 36000)+12]:[(time1 / 600 % 60) < 10 ? add_zero(time1 / 600 % 60, 1) : time1 / 600 % 60]"
|
||||
T.time = pick("", station_time_timestamp(), time2)
|
||||
T.source_terminal = pick("","[pick("Biesel","New Gibson")] GalaxyNet Terminal #[rand(111,999)]","your mums place","nantrasen high CommanD")
|
||||
var/time = pick("", station_time_timestamp(), time2)
|
||||
var/source_terminal = pick("","[pick("Biesel","New Gibson")] GalaxyNet Terminal #[rand(111,999)]","your mums place","nantrasen high CommanD")
|
||||
|
||||
affected_account.makeTransactionLog(amount, purpose, source_terminal, dest_name, TRUE, date, time)
|
||||
|
||||
affected_account.transaction_log.Add(T)
|
||||
|
||||
else
|
||||
//crew wins
|
||||
message = "The attack has ceased, the affected accounts can now be brought online."
|
||||
message = "The attack has ceased, the affected account can now be brought online."
|
||||
|
||||
var/my_department = "[station_name()] firewall subroutines"
|
||||
|
||||
for(var/obj/machinery/message_server/MS in world)
|
||||
if(!MS.active) continue
|
||||
MS.send_rc_message("Head of Personnel's Desk", my_department, message, "", "", 2)
|
||||
|
||||
#undef MINIMUM_PERCENTAGE_LOSS
|
||||
#undef VARIABLE_LOSS
|
||||
|
||||
@@ -8,19 +8,9 @@
|
||||
if(all_money_accounts.len)
|
||||
var/datum/money_account/D = pick(all_money_accounts)
|
||||
winner_name = D.owner_name
|
||||
if(!D.suspended)
|
||||
D.money += winner_sum
|
||||
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = "Nyx Daily Grand Slam -Stellar- Lottery"
|
||||
T.purpose = "Winner!"
|
||||
T.amount = winner_sum
|
||||
T.date = current_date_string
|
||||
T.time = worldtime2text()
|
||||
T.source_terminal = "Biesel TCD Terminal #[rand(111,333)]"
|
||||
D.transaction_log.Add(T)
|
||||
|
||||
deposit_success = 1
|
||||
D.credit(winner_sum, "Winner!", "Biesel TCD Terminal #[rand(111,333)]", "Nyx Daily Grand Slam -Stellar- Lottery")
|
||||
deposit_success = 1
|
||||
|
||||
/datum/event/money_lotto/announce()
|
||||
var/datum/feed_message/newMsg = new /datum/feed_message
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
nightmare()
|
||||
if(ishuman(src))
|
||||
if(prob(10))
|
||||
emote("writhes in [p_their()] sleep.")
|
||||
custom_emote(1,"writhes in [p_their()] sleep.")
|
||||
dir = pick(cardinal)
|
||||
|
||||
/mob/living/carbon/proc/experience_dream(dream_image, isNightmare)
|
||||
|
||||
@@ -21,7 +21,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
var/image/halbody
|
||||
var/obj/halitem
|
||||
var/hal_screwyhud = SCREWYHUD_NONE
|
||||
var/handling_hal = 0
|
||||
var/handling_hal = FALSE
|
||||
|
||||
/mob/living/carbon/proc/handle_hallucinations()
|
||||
if(handling_hal)
|
||||
@@ -34,9 +34,9 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
//AAAAHg
|
||||
var/list/major = list("fake"=20,"death"=10,"xeno"=10,"singulo"=10,"borer"=10,"delusion"=20,"koolaid"=10)
|
||||
|
||||
handling_hal = 1
|
||||
handling_hal = TRUE
|
||||
while(hallucination > 20)
|
||||
sleep(rand(200, 500) / (hallucination / 25))
|
||||
sleep(rand(200, 500) / (hallucination * 0.04))
|
||||
if(prob(20))
|
||||
continue
|
||||
var/list/current = list()
|
||||
@@ -48,10 +48,8 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
if(86 to 100)
|
||||
current = major
|
||||
|
||||
var/halpick = pickweight(current)
|
||||
|
||||
hallucinate(halpick)
|
||||
handling_hal = 0
|
||||
hallucinate(pickweight(current))
|
||||
handling_hal = FALSE
|
||||
|
||||
|
||||
/obj/effect/hallucination
|
||||
@@ -70,7 +68,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
var/col_mod = null
|
||||
var/image/current_image = null
|
||||
var/image_layer = MOB_LAYER
|
||||
var/active = 1 //qdelery
|
||||
var/active = TRUE //qdelery
|
||||
|
||||
/obj/effect/hallucination/simple/New(loc, mob/living/carbon/T)
|
||||
..()
|
||||
@@ -113,7 +111,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
/obj/effect/hallucination/simple/Destroy()
|
||||
if(target.client)
|
||||
target.client.images.Remove(current_image)
|
||||
active = 0
|
||||
active = FALSE
|
||||
return ..()
|
||||
|
||||
#define FAKE_FLOOD_EXPAND_TIME 20
|
||||
@@ -198,21 +196,17 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
pump = U
|
||||
break
|
||||
if(!pump)
|
||||
return 0
|
||||
return
|
||||
xeno = new(pump.loc,target)
|
||||
sleep(10)
|
||||
if(!xeno)
|
||||
return
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(target,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
if(!xeno)
|
||||
return
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(pump,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
if(!xeno)
|
||||
return
|
||||
for(var/i in 0 to 2)
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(target,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
if(!xeno)
|
||||
return
|
||||
var/xeno_name = xeno.name
|
||||
to_chat(target, "<span class='notice'>[xeno_name] begins climbing into the ventilation system...</span>")
|
||||
sleep(10)
|
||||
@@ -253,7 +247,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
break
|
||||
if(pump)
|
||||
borer = new(pump.loc,target)
|
||||
for(var/i=0, i<11, i++)
|
||||
for(var/i in 0 to 10)
|
||||
walk_to(borer, get_step(borer, get_cardinal_dir(borer, T)))
|
||||
if(borer.Adjacent(T))
|
||||
to_chat(T, "<span class='userdanger'>You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.</span>")
|
||||
@@ -331,10 +325,10 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
target = T
|
||||
var/turf/start = get_turf(T)
|
||||
var/screen_border = pick(cardinal)
|
||||
for(var/i = 0,i<11,i++)
|
||||
for(var/i in 0 to 10)
|
||||
start = get_step(start, screen_border)
|
||||
s = new(start,target)
|
||||
for(var/i = 0,i<11,i++)
|
||||
for(var/i in 0 to 10)
|
||||
sleep(5)
|
||||
s.loc = get_step(get_turf(s), get_dir(s, target))
|
||||
s.Show()
|
||||
@@ -359,10 +353,10 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
|
||||
/obj/effect/hallucination/battle/New(loc, mob/living/carbon/T)
|
||||
target = T
|
||||
var/hits = rand(3,6)
|
||||
var/hits = rand(2,5)
|
||||
switch(rand(1,5))
|
||||
if(1) //Laser fight
|
||||
for(var/i=0,i<hits,i++)
|
||||
for(var/i in 0 to hits)
|
||||
target.playsound_local(null, 'sound/weapons/Laser.ogg', 25, 1)
|
||||
if(prob(75))
|
||||
addtimer(CALLBACK(target, /mob/.proc/playsound_local, null, 'sound/weapons/sear.ogg', 25, 1), rand(10,20))
|
||||
@@ -372,13 +366,13 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
target.playsound_local(null, get_sfx("bodyfall"), 25)
|
||||
if(2) //Esword fight
|
||||
target.playsound_local(null, 'sound/weapons/saberon.ogg', 15, 1)
|
||||
for(var/i=0,i<hits,i++)
|
||||
for(var/i in 0 to hits)
|
||||
target.playsound_local(null, 'sound/weapons/blade1.ogg', 25, 1)
|
||||
sleep(rand(CLICK_CD_MELEE, CLICK_CD_MELEE + 8))
|
||||
target.playsound_local(null, get_sfx("bodyfall"), 25, 1)
|
||||
target.playsound_local(null, 'sound/weapons/saberoff.ogg', 15, 1)
|
||||
if(3) //Gun fight
|
||||
for(var/i=0,i<hits,i++)
|
||||
for(var/i in 0 to hits)
|
||||
target.playsound_local(null, get_sfx("gunshot"), 25)
|
||||
if(prob(75))
|
||||
addtimer(CALLBACK(target, /mob/.proc/playsound_local, null, 'sound/weapons/pierce.ogg', 25, 1), rand(10,20))
|
||||
@@ -392,7 +386,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
sleep(20)
|
||||
target.playsound_local(null, 'sound/weapons/cablecuff.ogg', 15, 1)
|
||||
if(5) // Tick Tock
|
||||
for(var/i=0,i<hits,i++)
|
||||
for(var/i in 0 to hits)
|
||||
target.playsound_local(null, 'sound/items/timer.ogg', 25, 1)
|
||||
sleep(15)
|
||||
qdel(src)
|
||||
@@ -605,27 +599,25 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
/obj/effect/fake_attacker/New(loc, mob/living/carbon/T)
|
||||
..()
|
||||
my_target = T
|
||||
spawn(300)
|
||||
qdel(src)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, src), 300)
|
||||
step_away(src,my_target,2)
|
||||
spawn(0)
|
||||
attack_loop()
|
||||
|
||||
INVOKE_ASYNC(src, .proc/attack_loop)
|
||||
|
||||
/obj/effect/fake_attacker/proc/updateimage()
|
||||
// qdel(src.currentimage)
|
||||
if(dir == NORTH)
|
||||
qdel(src.currentimage)
|
||||
currentimage = new /image(up, src)
|
||||
else if(dir == SOUTH)
|
||||
qdel(src.currentimage)
|
||||
currentimage = new /image(down, src)
|
||||
else if(dir == EAST)
|
||||
qdel(src.currentimage)
|
||||
currentimage = new /image(right, src)
|
||||
else if(dir == WEST)
|
||||
qdel(src.currentimage)
|
||||
currentimage = new /image(left, src)
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
qdel(src.currentimage)
|
||||
currentimage = new /image(up, src)
|
||||
if(SOUTH)
|
||||
qdel(src.currentimage)
|
||||
currentimage = new /image(down, src)
|
||||
if(EAST)
|
||||
qdel(src.currentimage)
|
||||
currentimage = new /image(right, src)
|
||||
if(WEST)
|
||||
qdel(src.currentimage)
|
||||
currentimage = new /image(left, src)
|
||||
my_target << currentimage
|
||||
|
||||
|
||||
@@ -672,8 +664,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
O.name = "blood"
|
||||
var/image/I = image('icons/effects/blood.dmi',O,"floor[rand(1,7)]",O.dir,1)
|
||||
target << I
|
||||
spawn(300)
|
||||
qdel(O)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, O), 300)
|
||||
return
|
||||
|
||||
var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_box/a357,\
|
||||
@@ -815,10 +806,9 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
|
||||
playsound_local(null, pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg'), 50, 1)
|
||||
if(5)
|
||||
playsound_local(null, 'sound/weapons/ring.ogg', 35)
|
||||
sleep(15)
|
||||
playsound_local(null, 'sound/weapons/ring.ogg', 35)
|
||||
sleep(15)
|
||||
playsound_local(null, 'sound/weapons/ring.ogg', 35)
|
||||
for(var/i in 0 to 2)
|
||||
sleep(15)
|
||||
playsound_local(null, 'sound/weapons/ring.ogg', 35)
|
||||
if(6)
|
||||
playsound_local(null, 'sound/magic/Summon_guns.ogg', 50, 1)
|
||||
if(7)
|
||||
@@ -828,19 +818,17 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
|
||||
if(9)
|
||||
//To make it more realistic, I added two gunshots (enough to kill)
|
||||
playsound_local(null, 'sound/weapons/Gunshot.ogg', 25, 1)
|
||||
spawn(rand(10,30))
|
||||
playsound_local(null, 'sound/weapons/Gunshot.ogg', 25, 1)
|
||||
sleep(rand(5,10))
|
||||
playsound_local(null, sound(get_sfx("bodyfall"), 25), 25, 1)
|
||||
var/timer_pause = rand(10,30)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound_local, null, 'sound/weapons/Gunshot.ogg', 25, 1), timer_pause)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound_local, null, sound(get_sfx("bodyfall"), 25), 25, 1), timer_pause+rand(5,10))
|
||||
if(10)
|
||||
playsound_local(null, 'sound/effects/pray_chaplain.ogg', 50)
|
||||
if(11)
|
||||
//Same as above, but with tasers.
|
||||
playsound_local(null, 'sound/weapons/Taser.ogg', 25, 1)
|
||||
spawn(rand(10,30))
|
||||
playsound_local(null, 'sound/weapons/Taser.ogg', 25, 1)
|
||||
sleep(rand(5,10))
|
||||
playsound_local(null, sound(get_sfx("bodyfall"), 25), 25, 1)
|
||||
var/timer_pause = rand(10,30)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound_local, null, 'sound/weapons/Taser.ogg', 25, 1), timer_pause)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound_local, null, sound(get_sfx("bodyfall"), 25), 25, 1), timer_pause+rand(5,10))
|
||||
//Rare audio
|
||||
if(12)
|
||||
//These sounds are (mostly) taken from Hidden: Source
|
||||
@@ -865,7 +853,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
|
||||
if(16)
|
||||
playsound_local(null, 'sound/items/Screwdriver.ogg', 15, 1)
|
||||
sleep(rand(10,30))
|
||||
for(var/i = rand(1,3), i>0, i--)
|
||||
for(var/i in 0 to rand(1,3))
|
||||
playsound_local(null, 'sound/weapons/empty.ogg', 15, 1)
|
||||
sleep(rand(10,30))
|
||||
playsound_local(null, 'sound/machines/airlockforced.ogg', 15, 1)
|
||||
@@ -877,10 +865,9 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
|
||||
playsound_local(null, 'sound/AI/outbreak5.ogg')
|
||||
if(19) //Tesla loose!
|
||||
playsound_local(null, 'sound/magic/lightningbolt.ogg', 35, 1)
|
||||
sleep(20)
|
||||
playsound_local(null, 'sound/magic/lightningbolt.ogg', 65, 1)
|
||||
sleep(20)
|
||||
playsound_local(null, 'sound/magic/lightningbolt.ogg', 100, 1)
|
||||
for(var/i in 0 to 2)
|
||||
sleep(20)
|
||||
playsound_local(null, 'sound/magic/lightningbolt.ogg', 65+(35*(i-1)), 1) //65%, then 100% volume.
|
||||
if(20) //AI is doomsdaying!
|
||||
to_chat(src, "<h1 class='alert'>Anomaly Alert</h1>")
|
||||
to_chat(src, "<br><br><span class='alert'>Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.</span><br><br>")
|
||||
@@ -987,8 +974,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
|
||||
halitem.icon_state = "flashbang1"
|
||||
halitem.name = "Flashbang"
|
||||
if(client) client.screen += halitem
|
||||
spawn(rand(100,250))
|
||||
qdel(halitem)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, halitem), rand(100,250))
|
||||
if("dangerflash")
|
||||
//Flashes of danger
|
||||
if(!halimage)
|
||||
@@ -1007,8 +993,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
|
||||
halimage = image('icons/turf/floors/Chasms.dmi',target,"smooth",TURF_LAYER)
|
||||
if(4)
|
||||
halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01)
|
||||
|
||||
|
||||
|
||||
if(client)
|
||||
client.images += halimage
|
||||
sleep(rand(40,60)) //Only seen for a brief moment.
|
||||
@@ -1054,4 +1039,4 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
|
||||
spawn(rand(30,50)) //Only seen for a brief moment.
|
||||
if(client)
|
||||
client.images -= halbody
|
||||
halbody = null
|
||||
halbody = null
|
||||
@@ -5,7 +5,7 @@
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
icon_state = "candymaker_off"
|
||||
cook_verbs = list("Wonderizing", "Scrumpdiddlyumptiousification", "Miracle-coating", "Flavorifaction")
|
||||
recipe_type = /datum/recipe/candy
|
||||
recipe_type = RECIPE_CANDY
|
||||
off_icon = "candymaker_off"
|
||||
on_icon = "candymaker_on"
|
||||
broken_icon = "candymaker_broke"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
layer = 2.9
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
var/on = 0
|
||||
var/onicon = null
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/stealthmode = FALSE
|
||||
var/list/victims = list()
|
||||
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 500
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
icon_state = "grill_off"
|
||||
cook_verbs = list("Grilling", "Searing", "Frying")
|
||||
recipe_type = /datum/recipe/grill
|
||||
recipe_type = RECIPE_GRILL
|
||||
off_icon = "grill_off"
|
||||
on_icon = "grill_on"
|
||||
broken_icon = "grill_broke"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
anchored = 1
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
icon_state = "icecream_vat"
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 20
|
||||
var/obj/item/reagent_containers/glass/beaker = null
|
||||
var/useramount = 15 //Last used amount
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
layer = 2.9
|
||||
density = 1
|
||||
anchored = 0
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
layer = 2.9
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
flags = OPENCONTAINER
|
||||
@@ -16,10 +16,7 @@
|
||||
var/list/cook_verbs = list("Cooking")
|
||||
//Recipe & Item vars
|
||||
var/recipe_type //Make sure to set this on the machine definition, or else you're gonna runtime on New()
|
||||
var/list/datum/recipe/available_recipes // List of the recipes you can use
|
||||
var/list/acceptable_items // List of the items you can put in
|
||||
var/list/acceptable_reagents // List of the reagents you can put in
|
||||
var/max_n_of_items = 0
|
||||
var/max_n_of_items = 25
|
||||
//Icon states
|
||||
var/off_icon
|
||||
var/on_icon
|
||||
@@ -35,23 +32,28 @@
|
||||
..()
|
||||
create_reagents(100)
|
||||
reagents.set_reacting(FALSE)
|
||||
if(!available_recipes)
|
||||
available_recipes = new
|
||||
acceptable_items = new
|
||||
acceptable_reagents = new
|
||||
for(var/type in subtypesof(recipe_type))
|
||||
init_lists()
|
||||
|
||||
/obj/machinery/kitchen_machine/proc/init_lists()
|
||||
if(!GLOB.cooking_recipes[recipe_type])
|
||||
GLOB.cooking_recipes[recipe_type] = list()
|
||||
GLOB.cooking_ingredients[recipe_type] = list()
|
||||
GLOB.cooking_reagents[recipe_type] = list()
|
||||
if(!length(GLOB.cooking_recipes[recipe_type]))
|
||||
for(var/type in subtypesof(GLOB.cooking_recipe_types[recipe_type]))
|
||||
var/datum/recipe/recipe = new type
|
||||
if(recipe in GLOB.cooking_recipes[recipe_type])
|
||||
qdel(recipe)
|
||||
continue
|
||||
if(recipe.result) // Ignore recipe subtypes that lack a result
|
||||
available_recipes += recipe
|
||||
GLOB.cooking_recipes[recipe_type] += recipe
|
||||
for(var/item in recipe.items)
|
||||
acceptable_items |= item
|
||||
GLOB.cooking_ingredients[recipe_type] |= item
|
||||
for(var/reagent in recipe.reagents)
|
||||
acceptable_reagents |= reagent
|
||||
if(recipe.items)
|
||||
max_n_of_items = max(max_n_of_items,recipe.count_n_items())
|
||||
GLOB.cooking_reagents[recipe_type] |= reagent
|
||||
else
|
||||
qdel(recipe)
|
||||
acceptable_items |= /obj/item/reagent_containers/food/snacks/grown
|
||||
GLOB.cooking_ingredients[recipe_type] |= /obj/item/reagent_containers/food/snacks/grown
|
||||
|
||||
/*******************
|
||||
* Item Adding
|
||||
@@ -80,26 +82,14 @@
|
||||
|
||||
if(broken > 0)
|
||||
if(broken == 2 && istype(O, /obj/item/screwdriver)) // If it's broken and they're using a screwdriver
|
||||
user.visible_message( \
|
||||
"<span class='notice'>[user] starts to fix part of \the [src].</span>", \
|
||||
"<span class='notice'>You start to fix part of \the [src].</span>" \
|
||||
)
|
||||
user.visible_message("<span class='notice'>[user] starts to fix part of [src].</span>", "<span class='notice'>You start to fix part of [src].</span>")
|
||||
if(do_after(user, 20 * O.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>[user] fixes part of \the [src].</span>", \
|
||||
"<span class='notice'>You have fixed part of \the [src].</span>" \
|
||||
)
|
||||
user.visible_message("<span class='notice'>[user] fixes part of [src].</span>", "<span class='notice'>You have fixed part of \the [src].</span>")
|
||||
broken = 1 // Fix it a bit
|
||||
else if(broken == 1 && istype(O, /obj/item/wrench)) // If it's broken and they're doing the wrench
|
||||
user.visible_message( \
|
||||
"<span class='notice'>[user] starts to fix part of \the [src].</span>", \
|
||||
"<span class='notice'>You start to fix part of \the [src].</span>" \
|
||||
)
|
||||
user.visible_message("<span class='notice'>[user] starts to fix part of [src].</span>", "<span class='notice'>You start to fix part of [src].</span>")
|
||||
if(do_after(user, 20 * O.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>[user] fixes \the [src].</span>", \
|
||||
"<span class='notice'>You have fixed \the [src].</span>" \
|
||||
)
|
||||
user.visible_message("<span class='notice'>[user] fixes [src].</span>", "<span class='notice'>You have fixed [src].</span>")
|
||||
icon_state = off_icon
|
||||
broken = 0 // Fix it!
|
||||
dirty = 0 // just to be sure
|
||||
@@ -109,15 +99,9 @@
|
||||
return 1
|
||||
else if(dirty==100) // The machine is all dirty so can't be used!
|
||||
if(istype(O, /obj/item/reagent_containers/spray/cleaner) || istype(O, /obj/item/soap)) // If they're trying to clean it then let them
|
||||
user.visible_message( \
|
||||
"<span class='notice'>[user] starts to clean \the [src].</span>", \
|
||||
"<span class='notice'>You start to clean \the [src].</span>" \
|
||||
)
|
||||
user.visible_message("<span class='notice'>[user] starts to clean [src].</span>", "<span class='notice'>You start to clean [src].</span>")
|
||||
if(do_after(user, 20 * O.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>[user] has cleaned \the [src].</span>", \
|
||||
"<span class='notice'>You have cleaned \the [src].</span>" \
|
||||
)
|
||||
user.visible_message("<span class='notice'>[user] has cleaned [src].</span>", "<span class='notice'>You have cleaned [src].</span>")
|
||||
dirty = 0 // It's clean!
|
||||
broken = 0 // just to be sure
|
||||
icon_state = off_icon
|
||||
@@ -125,33 +109,25 @@
|
||||
else //Otherwise bad luck!!
|
||||
to_chat(user, "<span class='alert'>It's dirty!</span>")
|
||||
return 1
|
||||
else if(is_type_in_list(O,acceptable_items))
|
||||
else if(is_type_in_list(O, GLOB.cooking_ingredients[recipe_type]) || istype(O, /obj/item/mixing_bowl))
|
||||
if(contents.len>=max_n_of_items)
|
||||
to_chat(user, "<span class='alert'>This [src] is full of ingredients, you cannot put more.</span>")
|
||||
return 1
|
||||
if(istype(O,/obj/item/stack) && O:amount>1)
|
||||
new O.type (src)
|
||||
O:use(1)
|
||||
user.visible_message( \
|
||||
"<span class='notice'>[user] has added one of [O] to \the [src].</span>", \
|
||||
"<span class='notice'>You add one of [O] to \the [src].</span>")
|
||||
if(istype(O,/obj/item/stack))
|
||||
var/obj/item/stack/S = O
|
||||
if(S.amount > 1)
|
||||
var/obj/item/stack/to_add = S.split(user, 1)
|
||||
to_add.forceMove(src)
|
||||
user.visible_message("<span class='notice'>[user] adds one of [S] to [src].</span>", "<span class='notice'>You add one of [S] to [src].</span>")
|
||||
else
|
||||
add_item(S, user)
|
||||
else
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "<span class='notice'>\The [O] is stuck to your hand, you cannot put it in \the [src]</span>")
|
||||
return 0
|
||||
|
||||
O.forceMove(src)
|
||||
user.visible_message( \
|
||||
"<span class='notice'>[user] has added \the [O] to \the [src].</span>", \
|
||||
"<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
else if(istype(O,/obj/item/reagent_containers/glass) || \
|
||||
istype(O,/obj/item/reagent_containers/food/drinks) || \
|
||||
istype(O,/obj/item/reagent_containers/food/condiment) \
|
||||
)
|
||||
add_item(O, user)
|
||||
else if(is_type_in_list(O, list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/drinks, /obj/item/reagent_containers/food/condiment)))
|
||||
if(!O.reagents)
|
||||
return 1
|
||||
for(var/datum/reagent/R in O.reagents.reagent_list)
|
||||
if(!(R.id in acceptable_reagents))
|
||||
if(!(R.id in GLOB.cooking_reagents[recipe_type]))
|
||||
to_chat(user, "<span class='alert'>Your [O] contains components unsuitable for cookery.</span>")
|
||||
return 1
|
||||
//G.reagents.trans_to(src,G.amount_per_transfer_from_this)
|
||||
@@ -162,6 +138,14 @@
|
||||
return 1
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/kitchen_machine/proc/add_item(obj/item/I, mob/user)
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "<span class='notice'>\The [I] is stuck to your hand, you cannot put it in [src]</span>")
|
||||
//return 0
|
||||
else
|
||||
I.forceMove(src)
|
||||
user.visible_message("<span class='notice'>[user] adds [I] to [src].</span>", "<span class='notice'>You add [I] to [src].</span>")
|
||||
|
||||
/obj/machinery/kitchen_machine/attack_ai(mob/user)
|
||||
return 0
|
||||
|
||||
@@ -182,11 +166,11 @@
|
||||
return
|
||||
var/dat = ""
|
||||
if(broken > 0)
|
||||
dat = {"<TT>Bzzzzttttt</TT>"}
|
||||
dat = {"<code>Bzzzzttttt</code>"}
|
||||
else if(operating)
|
||||
dat = {"<TT>[pick(cook_verbs)] in progress!<BR>Please wait...!</TT>"}
|
||||
dat = {"<code>[pick(cook_verbs)] in progress!<BR>Please wait...!</code>"}
|
||||
else if(dirty==100)
|
||||
dat = {"<TT>This [src] is dirty!<BR>Please clean it before use!</TT>"}
|
||||
dat = {"<code>This [src] is dirty!<BR>Please clean it before use!</code>"}
|
||||
else
|
||||
var/list/items_counts = new
|
||||
var/list/items_measures = new
|
||||
@@ -260,12 +244,13 @@
|
||||
stop()
|
||||
return
|
||||
|
||||
var/datum/recipe/recipe = select_recipe(available_recipes,src)
|
||||
var/obj/cooked
|
||||
var/obj/byproduct
|
||||
if(!recipe)
|
||||
var/list/recipes_to_make = choose_recipes()
|
||||
|
||||
if(recipes_to_make.len == 1 && recipes_to_make[1][2] == RECIPE_FAIL)
|
||||
//This only runs if there is a single recipe source to be made and it is a failure (the machine was loaded with only 1 mixing bowl that results in failure OR was directly loaded with ingredients that results in failure).
|
||||
//If there are multiple sources, this bit gets skipped.
|
||||
dirty += 1
|
||||
if(prob(max(10,dirty*5)))
|
||||
if(prob(max(10,dirty*5))) //chance to get so dirty we require cleaning before next use
|
||||
if(!wzhzhzh(4))
|
||||
abort()
|
||||
return
|
||||
@@ -274,14 +259,14 @@
|
||||
muck_finish()
|
||||
fail()
|
||||
return
|
||||
else if(has_extra_item())
|
||||
else if(has_extra_item()) //if extra items present, break down and require repair before next use
|
||||
if(!wzhzhzh(4))
|
||||
abort()
|
||||
return
|
||||
broke()
|
||||
fail()
|
||||
return
|
||||
else
|
||||
else //otherwise just stop without requiring cleaning/repair
|
||||
if(!wzhzhzh(10))
|
||||
abort()
|
||||
return
|
||||
@@ -289,24 +274,69 @@
|
||||
fail()
|
||||
return
|
||||
else
|
||||
var/halftime = round(recipe.time/10/2)
|
||||
if(!wzhzhzh(halftime))
|
||||
if(!wzhzhzh(5))
|
||||
abort()
|
||||
return
|
||||
if(!wzhzhzh(halftime))
|
||||
if(!wzhzhzh(5))
|
||||
abort()
|
||||
fail()
|
||||
return
|
||||
cooked = recipe.make_food(src)
|
||||
byproduct = recipe.get_byproduct()
|
||||
stop()
|
||||
if(cooked)
|
||||
cooked.forceMove(loc)
|
||||
for(var/i=1,i<efficiency,i++)
|
||||
cooked = new cooked.type(loc)
|
||||
if(byproduct)
|
||||
new byproduct(loc)
|
||||
make_recipes(recipes_to_make)
|
||||
|
||||
//choose_recipes(): picks out recipes for the machine and any mixing bowls it may contain.
|
||||
//builds a list of the selected recipes to be made in a later proc by associating the "source" of the ingredients (mixing bowl, machine) with the recipe for that source
|
||||
/obj/machinery/kitchen_machine/proc/choose_recipes()
|
||||
var/list/recipes_to_make = list()
|
||||
for(var/obj/item/mixing_bowl/mb in contents) //if we have mixing bowls present, check each one for possible recipes from its respective contents. Mixing bowls act like a wrapper for recipes and ingredients, isolating them from other ingredients and mixing bowls within a machine.
|
||||
var/datum/recipe/recipe = select_recipe(GLOB.cooking_recipes[recipe_type], mb)
|
||||
if(recipe)
|
||||
recipes_to_make.Add(list(list(mb, recipe)))
|
||||
else //if the ingredients of the mixing bowl don't make a valid recipe, we return a fail recipe to generate the burned mess
|
||||
recipes_to_make.Add(list(list(mb, RECIPE_FAIL)))
|
||||
|
||||
var/datum/recipe/recipe_src = select_recipe(GLOB.cooking_recipes[recipe_type], src, ignored_items = list(/obj/item/mixing_bowl)) //check the machine's directly-inserted ingredients for possible recipes as well, ignoring the mixing bowls when selecting recipe
|
||||
if(recipe_src) //if we found a valid recipe for directly-inserted ingredients, add that to our list
|
||||
recipes_to_make.Add(list(list(src, recipe_src)))
|
||||
else if(!recipes_to_make.len) //if the machine has no mixing bowls to make recipes from AND also doesn't have a valid recipe of directly-inserted ingredients, return a failure so we can make a burned mess
|
||||
recipes_to_make.Add(list(list(src, RECIPE_FAIL)))
|
||||
return recipes_to_make
|
||||
|
||||
//make_recipes(recipes_to_make): cycles through the supplied list of recipes and creates each recipe associated with the "source" for that entry
|
||||
/obj/machinery/kitchen_machine/proc/make_recipes(list/recipes_to_make)
|
||||
if(!recipes_to_make)
|
||||
return
|
||||
var/datum/reagents/temp_reagents = new(500)
|
||||
for(var/i=1 to recipes_to_make.len) //cycle through each entry on the recipes_to_make list for processing
|
||||
var/list/L = recipes_to_make[i]
|
||||
var/obj/source = L[1] //this is the source of the recipe entry (mixing bowl or the machine)
|
||||
var/datum/recipe/recipe = L[2] //this is the recipe associated with the source (a valid recipe or null)
|
||||
if(recipe == RECIPE_FAIL) //we have a failure and create a burned mess
|
||||
//failed recipe
|
||||
fail()
|
||||
else //we have a valid recipe to begin making
|
||||
for(var/obj/O in source.contents) //begin processing the ingredients supplied
|
||||
if(istype(O, /obj/item/mixing_bowl)) //ignore mixing bowls present among the ingredients in our source (only really applies to machine sourced recipes)
|
||||
continue
|
||||
if(O.reagents)
|
||||
O.reagents.del_reagent("nutriment")
|
||||
O.reagents.update_total()
|
||||
O.reagents.trans_to(temp_reagents, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
source.reagents.clear_reagents()
|
||||
for(var/e=1 to efficiency) //upgraded machine? make additional servings and split the ingredient reagents among each serving equally.
|
||||
var/obj/cooked = new recipe.result()
|
||||
temp_reagents.trans_to(cooked, temp_reagents.total_volume/efficiency)
|
||||
cooked.forceMove(loc)
|
||||
temp_reagents.clear_reagents()
|
||||
var/obj/byproduct = recipe.get_byproduct() //if the recipe has a byproduct, handle returning that (such as re-usable candy moulds)
|
||||
if(byproduct)
|
||||
new byproduct(loc)
|
||||
if(istype(source, /obj/item/mixing_bowl)) //if the recipe's source was a mixing bowl, make it a little dirtier and return that for re-use.
|
||||
var/obj/item/mixing_bowl/mb = source
|
||||
mb.make_dirty(5 * efficiency)
|
||||
mb.forceMove(loc)
|
||||
stop()
|
||||
return
|
||||
|
||||
/obj/machinery/kitchen_machine/proc/wzhzhzh(seconds)
|
||||
for(var/i=1 to seconds)
|
||||
@@ -318,10 +348,7 @@
|
||||
|
||||
/obj/machinery/kitchen_machine/proc/has_extra_item()
|
||||
for(var/obj/O in contents)
|
||||
if( \
|
||||
!istype(O,/obj/item/reagent_containers/food) && \
|
||||
!istype(O, /obj/item/grown) \
|
||||
)
|
||||
if(!is_type_in_list(O, list(/obj/item/reagent_containers/food, /obj/item/grown, /obj/item/mixing_bowl)))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -376,19 +403,27 @@
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/kitchen_machine/proc/fail()
|
||||
var/obj/item/reagent_containers/food/snacks/badrecipe/ffuu = new(src)
|
||||
var/amount = 0
|
||||
for(var/obj/O in contents-ffuu)
|
||||
for(var/obj/item/mixing_bowl/mb in contents) //fail and remove any mixing bowls present before making the burned mess from the machine itself (to avoid them being destroyed as part of the failure)
|
||||
mb.fail(src)
|
||||
mb.forceMove(get_turf(src))
|
||||
for(var/obj/O in contents)
|
||||
amount++
|
||||
if(O.reagents)
|
||||
if(O.reagents) //this is reagents in inserted objects (like chems in produce)
|
||||
var/id = O.reagents.get_master_reagent_id()
|
||||
if(id)
|
||||
amount+=O.reagents.get_reagent_amount(id)
|
||||
qdel(O)
|
||||
if(reagents && reagents.total_volume) //this is directly-added reagents (like water added directly into the machine)
|
||||
var/id = reagents.get_master_reagent_id()
|
||||
if(id)
|
||||
amount += reagents.get_reagent_amount(id)
|
||||
reagents.clear_reagents()
|
||||
ffuu.reagents.add_reagent("carbon", amount)
|
||||
ffuu.reagents.add_reagent("????", amount/10)
|
||||
ffuu.forceMove(get_turf(src))
|
||||
if(amount)
|
||||
var/obj/item/reagent_containers/food/snacks/badrecipe/ffuu = new(src)
|
||||
ffuu.reagents.add_reagent("carbon", amount)
|
||||
ffuu.reagents.add_reagent("????", amount/10)
|
||||
ffuu.forceMove(get_turf(src))
|
||||
|
||||
/obj/machinery/kitchen_machine/Topic(href, href_list)
|
||||
if(..() || panel_open)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "mw"
|
||||
cook_verbs = list("Microwaving", "Reheating", "Heating")
|
||||
recipe_type = /datum/recipe/microwave
|
||||
recipe_type = RECIPE_MICROWAVE
|
||||
off_icon = "mw"
|
||||
on_icon = "mw1"
|
||||
broken_icon = "mwb"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
layer = 2.9
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 50
|
||||
var/grinded = 0
|
||||
@@ -102,4 +102,4 @@
|
||||
to_chat(user, "<span class='notice'>The machine's display flashes that it has [grinded] monkey\s worth of material left.</span>")
|
||||
else // I'm not sure if the \s macro works with a word in between; I'll play it safe
|
||||
to_chat(user, "<span class='warning'>The machine needs at least [required_grind] monkey\s worth of material to compress [cube_production] monkey\s. It only has [grinded].</span>")
|
||||
return
|
||||
return
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
layer = 2.9
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
var/candy = 0
|
||||
idle_power_usage = 5
|
||||
var/on = FALSE //Is it making food already?
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
icon_state = "oven_off"
|
||||
cook_verbs = list("Baking", "Roasting", "Broiling")
|
||||
recipe_type = /datum/recipe/oven
|
||||
recipe_type = RECIPE_OVEN
|
||||
off_icon = "oven_off"
|
||||
on_icon = "oven_on"
|
||||
broken_icon = "oven_broke"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
var/broken = 0
|
||||
var/processing = 0
|
||||
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 50
|
||||
var/rating_speed = 1
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
layer = 2.9
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
var/max_n_of_items = 1500
|
||||
@@ -226,7 +226,6 @@
|
||||
|
||||
if(load(O, user))
|
||||
user.visible_message("<span class='notice'>[user] has added \the [O] to \the [src].</span>", "<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(istype(O, /obj/item/storage/bag))
|
||||
@@ -242,7 +241,7 @@
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else
|
||||
else if(!istype(O, /obj/item/card/emag))
|
||||
to_chat(user, "<span class='notice'>\The [src] smartly refuses [O].</span>")
|
||||
return 1
|
||||
|
||||
@@ -308,11 +307,6 @@
|
||||
to_chat(user, "<span class='notice'>Some items are refused.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
/obj/machinery/smartfridge/secure/emag_act(mob/user)
|
||||
emagged = 1
|
||||
locked = -1
|
||||
to_chat(user, "You short out the product lock on [src].")
|
||||
|
||||
/*******************
|
||||
* SmartFridge Menu
|
||||
********************/
|
||||
@@ -416,7 +410,7 @@
|
||||
desc = "A wooden contraption, used to dry plant products, food and leather."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "drying_rack_on"
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 200
|
||||
icon_on = "drying_rack_on"
|
||||
@@ -453,13 +447,13 @@
|
||||
return 1
|
||||
if(href_list["dryingOn"])
|
||||
drying = TRUE
|
||||
use_power = 2
|
||||
use_power = ACTIVE_POWER_USE
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
if(href_list["dryingOff"])
|
||||
drying = FALSE
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
update_icon()
|
||||
return 1
|
||||
return 0
|
||||
@@ -503,10 +497,10 @@
|
||||
/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff)
|
||||
if(drying || forceoff)
|
||||
drying = FALSE
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
else
|
||||
drying = TRUE
|
||||
use_power = 2
|
||||
use_power = ACTIVE_POWER_USE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/proc/rack_dry()
|
||||
@@ -539,6 +533,16 @@
|
||||
/************************
|
||||
* Secure SmartFridges
|
||||
*************************/
|
||||
/obj/machinery/smartfridge/secure/emag_act(mob/user)
|
||||
emagged = 1
|
||||
locked = -1
|
||||
to_chat(user, "You short out the product lock on [src].")
|
||||
|
||||
/obj/machinery/smartfridge/secure/emp_act(severity)
|
||||
if(prob(40/severity) && (!emagged) && (locked != -1))
|
||||
playsound(loc, 'sound/effects/sparks4.ogg', 60, 1)
|
||||
emagged = 1
|
||||
locked = -1
|
||||
|
||||
/obj/machinery/smartfridge/secure/Topic(href, href_list)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
@@ -548,4 +552,4 @@
|
||||
to_chat(usr, "<span class='warning'>Access denied.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
return 0
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
/obj/item/deck/examine(mob/user)
|
||||
..()
|
||||
to_chat(user,"<span class='notice'>It contains [cards.len ? cards.len : "no"] cards</span class>")
|
||||
to_chat(user,"<span class='notice'>It contains [cards.len ? cards.len : "no"] cards</span>")
|
||||
|
||||
/obj/item/deck/attack_hand(mob/user as mob)
|
||||
draw_card(user)
|
||||
@@ -221,6 +221,8 @@
|
||||
return
|
||||
|
||||
if(over_object == M)
|
||||
if(!remove_item_from_storage(M))
|
||||
M.unEquip(src)
|
||||
M.put_in_hands(src)
|
||||
|
||||
else if(istype(over_object, /obj/screen))
|
||||
@@ -250,7 +252,7 @@
|
||||
|
||||
/obj/item/pack/attack_self(mob/user as mob)
|
||||
user.visible_message("<span class='notice'>[name] rips open the [src]!</span>", "<span class='notice'>You rips open the [src]!</span>")
|
||||
var/obj/item/cardhand/H = new()
|
||||
var/obj/item/cardhand/H = new(get_turf(user))
|
||||
|
||||
H.cards += cards
|
||||
cards.Cut()
|
||||
@@ -258,7 +260,7 @@
|
||||
qdel(src)
|
||||
|
||||
H.update_icon()
|
||||
user.put_in_active_hand(H)
|
||||
user.put_in_hands(H)
|
||||
|
||||
/obj/item/cardhand
|
||||
name = "hand of cards"
|
||||
@@ -315,9 +317,9 @@
|
||||
/obj/item/cardhand/examine(mob/user)
|
||||
..(user)
|
||||
if((!concealed) && cards.len)
|
||||
to_chat(user,"<span class='notice'>It contains:</span class>")
|
||||
to_chat(user,"<span class='notice'>It contains:</span>")
|
||||
for(var/datum/playingcard/P in cards)
|
||||
to_chat(user,"<span class='notice'>the [P.name].</span class>")
|
||||
to_chat(user,"<span class='notice'>the [P.name].</span>")
|
||||
|
||||
// Datum action here
|
||||
|
||||
@@ -368,16 +370,17 @@
|
||||
var/datum/playingcard/card = pickablecards[pickedcard]
|
||||
|
||||
var/obj/item/cardhand/H = new(get_turf(src))
|
||||
user.put_in_active_hand(H)
|
||||
user.put_in_hands(H)
|
||||
H.cards += card
|
||||
cards -= card
|
||||
H.parentdeck = parentdeck
|
||||
H.concealed = concealed
|
||||
H.update_icon()
|
||||
update_icon()
|
||||
|
||||
if(!cards.len)
|
||||
qdel(src)
|
||||
return
|
||||
update_icon()
|
||||
|
||||
/obj/item/cardhand/verb/discard(var/mob/user as mob)
|
||||
|
||||
@@ -410,7 +413,7 @@
|
||||
if(cards.len)
|
||||
update_icon()
|
||||
if(H.cards.len)
|
||||
usr.visible_message("<span class='notice'>The [user] plays the [discarding].</span>", "<span class='notice'>You play the [discarding].</span>")
|
||||
usr.visible_message("<span class='notice'>The [usr] plays the [discarding].</span>", "<span class='notice'>You play the [discarding].</span>")
|
||||
H.loc = get_step(usr,usr.dir)
|
||||
|
||||
if(!cards.len)
|
||||
@@ -419,7 +422,6 @@
|
||||
/obj/item/cardhand/update_icon(var/direction = 0)
|
||||
|
||||
if(!cards.len)
|
||||
qdel(src)
|
||||
return
|
||||
else if(cards.len > 1)
|
||||
name = "hand of cards"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_state = "biogen-empty"
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 40
|
||||
var/processing = 0
|
||||
var/obj/item/reagent_containers/glass/beaker = null
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
icon_dead = "soybean-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/soya/koi)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
reagents_add = list("soybeanoil" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/soybeans
|
||||
seed = /obj/item/seeds/soya
|
||||
|
||||
@@ -1008,7 +1008,7 @@
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "soil"
|
||||
density = 0
|
||||
use_power = 0
|
||||
use_power = NO_POWER_USE
|
||||
wrenchable = 0
|
||||
|
||||
/obj/machinery/hydroponics/soil/update_icon_hoses()
|
||||
|
||||
@@ -315,12 +315,16 @@
|
||||
/datum/plant_gene/trait/teleport/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C)
|
||||
var/teleport_radius = max(round(G.seed.potency / 10), 1)
|
||||
var/turf/T = get_turf(C)
|
||||
to_chat(C, "<span class='warning'>You slip through spacetime!</span>")
|
||||
do_teleport(C, T, teleport_radius)
|
||||
if(prob(50))
|
||||
do_teleport(G, T, teleport_radius)
|
||||
if(do_teleport(C, T, teleport_radius))
|
||||
to_chat(C, "<span class='warning'>You slip through spacetime!</span>")
|
||||
if(prob(50))
|
||||
do_teleport(G, T, teleport_radius)
|
||||
else
|
||||
new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect...
|
||||
qdel(G)
|
||||
else
|
||||
new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect...
|
||||
to_chat(C, "<span class='warning'>[src] sparks, and burns up!</span>")
|
||||
new /obj/effect/decal/cleanable/molten_object(T)
|
||||
qdel(G)
|
||||
|
||||
|
||||
|
||||
+63
-72
@@ -1,3 +1,7 @@
|
||||
/* KARMA
|
||||
Everything karma related is here.
|
||||
Part of karma purchase is handled in client_procs.dm */
|
||||
|
||||
proc/sql_report_karma(var/mob/spender, var/mob/receiver)
|
||||
var/sqlspendername = sanitizeSQL(spender.name)
|
||||
var/sqlspenderkey = spender.ckey
|
||||
@@ -39,49 +43,49 @@ proc/sql_report_karma(var/mob/spender, var/mob/receiver)
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during karmatotal logging (adding new key). Error : \[[err]\]\n")
|
||||
else
|
||||
karma += 1
|
||||
karma++
|
||||
query = dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karma=[karma] WHERE id=[id]")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during karmatotal logging (updating existing entry). Error : \[[err]\]\n")
|
||||
|
||||
|
||||
var/list/karma_spenders = list()
|
||||
|
||||
// Returns 1 if mob can give karma at all; if not, tells them why
|
||||
// Returns TRUE if mob can give karma at all; if not, tells them why
|
||||
/mob/proc/can_give_karma()
|
||||
if(!client)
|
||||
return 0
|
||||
to_chat(src, "<span class='warning'>You can't award karma without being connected.</span>")
|
||||
return FALSE
|
||||
if(config.disable_karma)
|
||||
to_chat(src, "<span class='warning'>Karma is disabled.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(!ticker || !player_list.len || (ticker.current_state == GAME_STATE_PREGAME))
|
||||
to_chat(src, "<span class='warning'>You can't award karma until the game has started.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(client.karma_spent || (ckey in karma_spenders))
|
||||
to_chat(src, "<span class='warning'>You've already spent your karma for the round.</span>")
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// Returns 1 if mob can give karma to M; if not, tells them why
|
||||
// Returns TRUE if mob can give karma to M; if not, tells them why
|
||||
/mob/proc/can_give_karma_to_mob(mob/M)
|
||||
if(!can_give_karma())
|
||||
return 0
|
||||
return FALSE
|
||||
if(!istype(M))
|
||||
to_chat(src, "<span class='warning'>That's not a mob.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(!M.client)
|
||||
to_chat(src, "<span class='warning'>That mob has no client connected at the moment.</span>")
|
||||
return 0
|
||||
if(ckey == M.ckey)
|
||||
return FALSE
|
||||
if(M.ckey == ckey)
|
||||
to_chat(src, "<span class='warning'>You can't spend karma on yourself!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(client.address == M.client.address)
|
||||
message_admins("<span class='warning'>Illegal karma spending attempt detected from [key] to [M.key]. Using the same IP!</span>")
|
||||
log_game("Illegal karma spending attempt detected from [key] to [M.key]. Using the same IP!")
|
||||
to_chat(src, "<span class='warning'>You can't spend karma on someone connected from the same IP.</span>")
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/verb/spend_karma_list()
|
||||
@@ -129,9 +133,9 @@ var/list/karma_spenders = list()
|
||||
if(!can_give_karma_to_mob(M))
|
||||
return // Check again, just in case things changed while the alert box was up
|
||||
|
||||
M.client.karma += 1
|
||||
M.client.karma++
|
||||
to_chat(usr, "Good karma spent on [M.name].")
|
||||
client.karma_spent = 1
|
||||
client.karma_spent = TRUE
|
||||
karma_spenders += ckey
|
||||
|
||||
var/special_role = "None"
|
||||
@@ -153,14 +157,14 @@ var/list/karma_spenders = list()
|
||||
|
||||
if(config.disable_karma)
|
||||
to_chat(src, "<span class='warning'>Karma is disabled.</span>")
|
||||
return 0
|
||||
return
|
||||
|
||||
var/currentkarma=verify_karma()
|
||||
to_chat(usr, {"<br>You have <b>[currentkarma]</b> available."})
|
||||
return
|
||||
var/currentkarma = verify_karma()
|
||||
if(!isnull(currentkarma))
|
||||
to_chat(usr, {"<br>You have <b>[currentkarma]</b> available."})
|
||||
|
||||
/client/proc/verify_karma()
|
||||
var/currentkarma=0
|
||||
var/currentkarma = 0
|
||||
if(!dbcon.IsConnected())
|
||||
to_chat(usr, "<span class='warning'>Unable to connect to karma database. Please try again later.<br></span>")
|
||||
return
|
||||
@@ -174,24 +178,18 @@ var/list/karma_spenders = list()
|
||||
totalkarma = query.item[1]
|
||||
karmaspent = query.item[2]
|
||||
currentkarma = (text2num(totalkarma) - text2num(karmaspent))
|
||||
/* if(totalkarma)
|
||||
to_chat(usr, {"<br>You have <b>[currentkarma]</b> available.<br>)
|
||||
You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
else
|
||||
to_chat(usr, "<b>Your total karma is:</b> 0<br>")*/
|
||||
|
||||
return currentkarma
|
||||
|
||||
/client/verb/karmashop()
|
||||
set name = "karmashop"
|
||||
set desc = "Spend your hard-earned karma here"
|
||||
set hidden = 1
|
||||
set hidden = TRUE
|
||||
|
||||
if(config.disable_karma)
|
||||
to_chat(src, "<span class='warning'>Karma is disabled.</span>")
|
||||
return 0
|
||||
|
||||
return
|
||||
karmashopmenu()
|
||||
return
|
||||
|
||||
/client/proc/karmashopmenu()
|
||||
var/dat = "<html><body><center>"
|
||||
@@ -267,7 +265,23 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
var/datum/browser/popup = new(usr, "karmashop", "<div align='center'>Karma Shop</div>", 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
return
|
||||
|
||||
//Checks if can afford, what you're purchasing, then purchases. (used in client_procs.dm)
|
||||
/client/proc/karma_purchase(var/karma = 0, var/price = 1, var/category, var/name, var/DBname = null)
|
||||
if(karma < price)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
if(alert("Are you sure you want to unlock [name]?", "Confirmation", "No", "Yes") != "Yes")
|
||||
return
|
||||
if(karma < price) //Check one more time. (definitely not repeated code)
|
||||
to_chat(usr, "You do not have enough karma!")
|
||||
return
|
||||
if(!isnull(DBname)) //In case database uses another name for logging. (Machine, Machine People)
|
||||
name = DBname
|
||||
if(category == "job")
|
||||
DB_job_unlock(name,price)
|
||||
else if(category == "species")
|
||||
DB_species_unlock(name,price)
|
||||
|
||||
/client/proc/DB_job_unlock(var/job,var/cost)
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
|
||||
@@ -281,9 +295,7 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
if(!dbckey)
|
||||
query = dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES ('[usr.ckey]','[job]')")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during whitelist logging (adding new key). Error: \[[err]\]\n")
|
||||
message_admins("SQL ERROR during whitelist logging (adding new key). Error: \[[err]\]\n")
|
||||
queryErrorLog(query.ErrorMsg(),"adding new key")
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have unlocked [job].")
|
||||
@@ -297,9 +309,7 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
var/newjoblist = jointext(joblist,",")
|
||||
query = dbcon.NewQuery("UPDATE [format_table_name("whitelist")] SET job='[newjoblist]' WHERE ckey='[dbckey]'")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during whitelist logging (updating existing entry). Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during whitelist logging (updating existing entry). Error : \[[err]\]\n")
|
||||
queryErrorLog(query.ErrorMsg(),"updating existing entry")
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have unlocked [job].")
|
||||
@@ -321,9 +331,7 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
if(!dbckey)
|
||||
query = dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES ('[usr.ckey]','[species]')")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during whitelist logging (adding new key). Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during whitelist logging (adding new key). Error : \[[err]\]\n")
|
||||
queryErrorLog(query.ErrorMsg(),"adding new key")
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have unlocked [species].")
|
||||
@@ -337,9 +345,7 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
var/newspecieslist = jointext(specieslist,",")
|
||||
query = dbcon.NewQuery("UPDATE [format_table_name("whitelist")] SET species='[newspecieslist]' WHERE ckey='[dbckey]'")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during whitelist logging (updating existing entry). Error: \[[err]\]\n")
|
||||
message_admins("SQL ERROR during whitelist logging (updating existing entry). Error: \[[err]\]\n")
|
||||
queryErrorLog(query.ErrorMsg(),"updating existing entry")
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have unlocked [species].")
|
||||
@@ -349,7 +355,7 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
to_chat(usr, "You already have this species unlocked!")
|
||||
return
|
||||
|
||||
/client/proc/karmacharge(var/cost,var/refund = 0)
|
||||
/client/proc/karmacharge(var/cost,var/refund = FALSE)
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[usr.ckey]'")
|
||||
query.Execute()
|
||||
|
||||
@@ -361,9 +367,7 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
spent += cost
|
||||
query = dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[usr.ckey]'")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during karmaspent updating (updating existing entry). Error: \[[err]\]\n")
|
||||
message_admins("SQL ERROR during karmaspent updating (updating existing entry). Error: \[[err]\]\n")
|
||||
queryErrorLog(query.ErrorMsg(),"updating existing entry")
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have been [refund ? "refunded" : "charged"] [cost] karma.")
|
||||
@@ -372,23 +376,8 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
|
||||
/client/proc/karmarefund(var/type,var/name,var/cost)
|
||||
switch(name)
|
||||
if("Tajaran Ambassador")
|
||||
cost = 30
|
||||
if("Unathi Ambassador")
|
||||
cost = 30
|
||||
if("Skrell Ambassador")
|
||||
cost = 30
|
||||
if("Diona Ambassador")
|
||||
cost = 30
|
||||
if("Kidan Ambassador")
|
||||
cost = 30
|
||||
if("Slime People Ambassador")
|
||||
cost = 30
|
||||
if("Grey Ambassador")
|
||||
cost = 30
|
||||
if("Vox Ambassador")
|
||||
cost = 30
|
||||
if("Customs Officer")
|
||||
if("Tajaran Ambassador","Unathi Ambassador","Skrell Ambassador","Diona Ambassador","Kidan Ambassador",
|
||||
"Slime People Ambassador","Grey Ambassador","Vox Ambassador","Customs Officer")
|
||||
cost = 30
|
||||
if("Nanotrasen Recruiter")
|
||||
cost = 10
|
||||
@@ -422,9 +411,7 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
var/newtypelist = jointext(typelist,",")
|
||||
query = dbcon.NewQuery("UPDATE [format_table_name("whitelist")] SET [type]='[newtypelist]' WHERE ckey='[dbckey]'")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during whitelist logging (updating existing entry). Error: \[[err]\]\n")
|
||||
message_admins("SQL ERROR during whitelist logging (updating existing entry). Error: \[[err]\]\n")
|
||||
queryErrorLog(query.ErrorMsg(),"updating existing entry")
|
||||
return
|
||||
else
|
||||
to_chat(usr, "You have been refunded [cost] karma for [type] [name].")
|
||||
@@ -436,6 +423,10 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Your ckey ([dbckey]) was not found.</span>")
|
||||
|
||||
/client/proc/queryErrorLog(err = null, errType)
|
||||
log_game("SQL ERROR during whitelist logging ([errType]]). Error : \[[err]\]\n")
|
||||
message_admins("SQL ERROR during whitelist logging ([errType]]). Error : \[[err]\]\n")
|
||||
|
||||
/client/proc/checkpurchased(var/name = null) // If the first parameter is null, return a full list of purchases
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
|
||||
query.Execute()
|
||||
@@ -454,10 +445,10 @@ You've gained <b>[totalkarma]</b> total karma in your time here.<br>"}
|
||||
var/list/combinedlist = joblist + specieslist
|
||||
if(name)
|
||||
if(name in combinedlist)
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
return combinedlist
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
@@ -77,7 +77,7 @@
|
||||
health -= O.force * 0.75
|
||||
else
|
||||
if(health <= 0)
|
||||
visible_message("<span class=warning>The bookcase is smashed apart!</span>")
|
||||
visible_message("<span class='warning'>The bookcase is smashed apart!</span>")
|
||||
qdel(src)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/datum/map/delta
|
||||
name = "Delta"
|
||||
full_name = "NSS Kerberos"
|
||||
|
||||
station_name = "NSS Kerberos"
|
||||
station_short = "Kerberos"
|
||||
dock_name = "NAS Trurl"
|
||||
company_name = "Nanotrasen"
|
||||
company_short = "NT"
|
||||
starsys_name = "Epsilon Eridani "
|
||||
@@ -37,8 +37,7 @@
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
D.grabbedby(A,1)
|
||||
var/obj/item/grab/G = A.get_active_hand()
|
||||
var/obj/item/grab/G = D.grabbedby(A,1)
|
||||
if(G)
|
||||
G.state = GRAB_NECK
|
||||
|
||||
|
||||
@@ -53,8 +53,7 @@
|
||||
A.visible_message("<span class='warning'>[A] tries to grab ahold of [D], but fails!</span>", \
|
||||
"<span class='warning'>You fail to grab ahold of [D]!</span>")
|
||||
return 1
|
||||
D.grabbedby(A,1)
|
||||
var/obj/item/grab/G = A.get_active_hand()
|
||||
var/obj/item/grab/G = D.grabbedby(A,1)
|
||||
if(G)
|
||||
D.visible_message("<span class='danger'>[A] grabs ahold of [D] drunkenly!</span>", \
|
||||
"<span class='userdanger'>[A] grabs ahold of [D] drunkenly!</span>")
|
||||
|
||||
@@ -108,8 +108,7 @@
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
D.grabbedby(A,1)
|
||||
var/obj/item/grab/G = A.get_active_hand()
|
||||
var/obj/item/grab/G = D.grabbedby(A,1)
|
||||
if(G)
|
||||
G.state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
|
||||
|
||||
@@ -664,6 +664,9 @@
|
||||
var/turf/T = get_turf(H)
|
||||
T.add_vomit_floor(H)
|
||||
playsound(H, 'sound/effects/splat.ogg', 50, 1)
|
||||
else
|
||||
visible_message("<span class='warning'>[src] flickers and fails, due to bluespace interference!</span>")
|
||||
qdel(src)
|
||||
|
||||
/**********************Resonator**********************/
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/obj/machinery/computer/shuttle/labor/one_way/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
var/obj/docking_port/mobile/M = shuttle_master.getShuttle("laborcamp")
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle("laborcamp")
|
||||
if(!M)
|
||||
to_chat(usr, "<span class='warning'>Cannot locate shuttle!</span>")
|
||||
return 0
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
if(!alone_in_area(get_area(src), usr))
|
||||
to_chat(usr, "<span class='warning'>Prisoners are only allowed to be released while alone.</span>")
|
||||
else
|
||||
switch(shuttle_master.moveShuttle("laborcamp","laborcamp_home"))
|
||||
switch(SSshuttle.moveShuttle("laborcamp","laborcamp_home"))
|
||||
if(1)
|
||||
to_chat(usr, "<span class='notice'>Shuttle not found</span>")
|
||||
if(2)
|
||||
@@ -116,7 +116,7 @@
|
||||
|
||||
if(href_list["choice"] == "release")
|
||||
if(alone_in_area(get_area(loc), usr))
|
||||
var/obj/docking_port/stationary/S = shuttle_master.getDock("laborcamp_home")
|
||||
var/obj/docking_port/stationary/S = SSshuttle.getDock("laborcamp_home")
|
||||
if(S && S.get_docked())
|
||||
if(release_door && release_door.density)
|
||||
release_door.open()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
unacidable = 1
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
pixel_y = -4
|
||||
use_power = 0
|
||||
use_power = NO_POWER_USE
|
||||
var/memory_saved = FALSE
|
||||
var/list/stored_items = list()
|
||||
var/static/list/blacklist = typecacheof(list(/obj/item/spellbook))
|
||||
@@ -97,7 +97,7 @@
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "anomaly_crystal"
|
||||
luminosity = 8
|
||||
use_power = 0
|
||||
use_power = NO_POWER_USE
|
||||
density = 1
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
unacidable = 1
|
||||
|
||||
@@ -207,7 +207,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
for(var/obj/effect/step_trigger/S in locate(x, y, z)) //<-- this is dumb
|
||||
S.Crossed(src)
|
||||
|
||||
var/area/A = get_area_master(src)
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
A.Entered(src)
|
||||
|
||||
|
||||
@@ -24,15 +24,20 @@
|
||||
return target
|
||||
|
||||
// All mobs should have custom emote, really..
|
||||
/mob/proc/custom_emote(var/m_type=1,var/message = null)
|
||||
/mob/proc/custom_emote(var/m_type=EMOTE_VISUAL,var/message = null)
|
||||
|
||||
if(stat || !use_me && usr == src)
|
||||
if(usr)
|
||||
to_chat(usr, "You are unable to emote.")
|
||||
return
|
||||
|
||||
var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
|
||||
if(m_type == 2 && muzzled) return
|
||||
var/muzzled = is_muzzled()
|
||||
if(muzzled)
|
||||
var/obj/item/clothing/mask/muzzle/M = wear_mask
|
||||
if(m_type == EMOTE_SOUND && M.mute >= MUZZLE_MUTE_MUFFLE)
|
||||
return //Not all muzzles block sound
|
||||
if(m_type == EMOTE_SOUND && !can_speak())
|
||||
return
|
||||
|
||||
var/input
|
||||
if(!message)
|
||||
@@ -63,7 +68,7 @@
|
||||
|
||||
|
||||
// Type 1 (Visual) emotes are sent to anyone in view of the item
|
||||
if(m_type & 1)
|
||||
if(m_type & EMOTE_VISUAL)
|
||||
var/list/can_see = get_mobs_in_view(1,src) //Allows silicon & mmi mobs carried around to see the emotes of the person carrying them around.
|
||||
can_see |= viewers(src,null)
|
||||
for(var/mob/O in can_see)
|
||||
@@ -80,7 +85,7 @@
|
||||
|
||||
// Type 2 (Audible) emotes are sent to anyone in hear range
|
||||
// of the *LOCATION* -- this is important for pAIs to be heard
|
||||
else if(m_type & 2)
|
||||
else if(m_type & EMOTE_SOUND)
|
||||
for(var/mob/O in get_mobs_in_view(7,src))
|
||||
|
||||
if(O.status_flags & PASSEMOTES)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// At minimum every mob has a hear_say proc.
|
||||
|
||||
/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
|
||||
/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
|
||||
if(!client)
|
||||
return 0
|
||||
|
||||
@@ -70,12 +70,12 @@
|
||||
if(speaker == src)
|
||||
to_chat(src, "<span class='warning'>You cannot hear yourself speak!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear [speaker.p_them()].")
|
||||
to_chat(src, "<span class='name'>[speaker_name]</span>[speaker.GetAltName()] talks but you cannot hear [speaker.p_them()].")
|
||||
else
|
||||
if(language)
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][language.format_message(message, verb)]</span>")
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[speaker.GetAltName()] [track][language.format_message(message, verb)]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][verb], <span class='message'><span class='body'>\"[message]\"</span></span></span>")
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[speaker.GetAltName()] [track][verb], <span class='message'><span class='body'>\"[message]\"</span></span></span>")
|
||||
if(speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z))
|
||||
var/turf/source = speaker? get_turf(speaker) : get_turf(src)
|
||||
src.playsound_local(source, speech_sound, sound_vol, 1)
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
//This is probably the main one you need to know :)
|
||||
//Just puts stuff on the floor for most mobs, since all mobs have hands but putting stuff in the AI/corgi/ghost hand is VERY BAD.
|
||||
/mob/proc/put_in_hands(obj/item/W)
|
||||
W.forceMove(get_turf(src))
|
||||
W.forceMove(drop_location())
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
W.dropped()
|
||||
@@ -137,7 +137,7 @@
|
||||
if(I)
|
||||
if(client)
|
||||
client.screen -= I
|
||||
I.forceMove(loc)
|
||||
I.forceMove(drop_location())
|
||||
I.dropped(src)
|
||||
if(I)
|
||||
I.layer = initial(I.layer)
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
#define MAX_ALIEN_LEAP_DIST 7
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/leap_at(var/atom/A)
|
||||
if(pounce_cooldown)
|
||||
if(pounce_cooldown > world.time)
|
||||
to_chat(src, "<span class='alertalien'>You are too fatigued to pounce right now!</span>")
|
||||
return
|
||||
|
||||
@@ -114,9 +114,7 @@
|
||||
Weaken(2, 1, 1)
|
||||
|
||||
toggle_leap(0)
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
spawn(pounce_cooldown_time) //3s by default
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
pounce_cooldown = world.time + pounce_cooldown_time
|
||||
else if(A.density && !A.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='alertalien'>[src] smashes into [A]!</span>")
|
||||
Weaken(2, 1, 1)
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
desc = "Enables radio capability on MMIs when either installed directly on the MMI, or through a cyborg's chassis."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "cyborg_upgrade1"
|
||||
origin_tech = "programming=3;biotech=2;engineering=2"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
to_chat(usr, "<span class='warning'>You cannot speak, as your internal speaker is turned off.</span>")
|
||||
. = FALSE
|
||||
|
||||
/mob/living/carbon/brain/handle_message_mode(var/message_mode, var/message, var/verb, var/speaking, var/used_radios, var/alt_name)
|
||||
/mob/living/carbon/brain/handle_message_mode(var/message_mode, var/message, var/verb, var/speaking, var/used_radios)
|
||||
switch(message_mode)
|
||||
if("headset")
|
||||
var/radio_worked = 0 // If any of the radios our brainmob could use functioned, this is set true so that we don't use any others
|
||||
@@ -45,6 +45,6 @@
|
||||
radio_worked = c.radio.talk_into(src, message, message_mode, verb, speaking)
|
||||
return radio_worked
|
||||
if("whisper")
|
||||
whisper_say(message, speaking, alt_name)
|
||||
whisper_say(message, speaking)
|
||||
return 1
|
||||
else return 0
|
||||
|
||||
@@ -78,6 +78,10 @@
|
||||
|
||||
#undef STOMACH_ATTACK_DELAY
|
||||
|
||||
/mob/living/carbon/proc/has_mutated_organs()
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/carbon/proc/vomit(var/lost_nutrition = 10, var/blood = 0, var/stun = 1, var/distance = 0, var/message = 1)
|
||||
if(src.is_muzzled())
|
||||
if(message)
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
var/muzzled = is_muzzled()
|
||||
if(muzzled)
|
||||
var/obj/item/clothing/mask/muzzle/M = wear_mask
|
||||
if(M.mute == MUZZLE_MUTE_NONE)
|
||||
muzzled = 0 //Not all muzzles block sound
|
||||
if(!can_speak())
|
||||
muzzled = 1
|
||||
//var/m_type = 1
|
||||
|
||||
@@ -1390,7 +1390,7 @@
|
||||
dna.species.create_organs(src)
|
||||
|
||||
for(var/thing in kept_items)
|
||||
equip_to_slot_or_del(thing, kept_items[thing])
|
||||
equip_to_slot_if_possible(thing, kept_items[thing], redraw_mob = 0)
|
||||
|
||||
//Handle default hair/head accessories for created mobs.
|
||||
var/obj/item/organ/external/head/H = get_organ("head")
|
||||
@@ -1677,6 +1677,12 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/has_mutated_organs()
|
||||
for(var/obj/item/organ/external/E in bodyparts)
|
||||
if(E.status & ORGAN_MUTATED)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/InCritical()
|
||||
return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
|
||||
|
||||
|
||||
@@ -88,21 +88,21 @@
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/human/adjustBruteLoss(amount, damage_source)
|
||||
/mob/living/carbon/human/adjustBruteLoss(amount, damage_source, robotic=0)
|
||||
if(dna.species)
|
||||
amount = amount * dna.species.brute_mod
|
||||
if(amount > 0)
|
||||
take_overall_damage(amount, 0, used_weapon = damage_source)
|
||||
else
|
||||
heal_overall_damage(-amount, 0)
|
||||
heal_overall_damage(-amount, 0, 0, robotic)
|
||||
|
||||
/mob/living/carbon/human/adjustFireLoss(amount, damage_source)
|
||||
/mob/living/carbon/human/adjustFireLoss(amount, damage_source, robotic=0)
|
||||
if(dna.species)
|
||||
amount = amount * dna.species.burn_mod
|
||||
if(amount > 0)
|
||||
take_overall_damage(0, amount, used_weapon = damage_source)
|
||||
else
|
||||
heal_overall_damage(0, -amount)
|
||||
heal_overall_damage(0, -amount, 0, robotic)
|
||||
|
||||
/mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null)
|
||||
if(dna.species)
|
||||
|
||||
@@ -178,7 +178,7 @@ emp_act
|
||||
/mob/living/carbon/human/grabbedby(mob/living/user)
|
||||
if(w_uniform)
|
||||
w_uniform.add_fingerprint(user)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
//Returns 1 if the attack hit, 0 if it missed.
|
||||
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user, def_zone)
|
||||
|
||||
@@ -630,7 +630,7 @@
|
||||
var/obj/item/reagent_containers/food/snacks/newSnack = new chosenType(get_turf(src))
|
||||
TARGET = newSnack
|
||||
newSnack.reagents.remove_any((newSnack.reagents.total_volume/2)-1)
|
||||
newSnack.name = "Synthetic [newSnack.name]"
|
||||
newSnack.name = "synthetic [newSnack.name]"
|
||||
custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")] as [p_they()] vomit[p_s()] [newSnack] from [p_their()] mouth!")
|
||||
catch(var/exception/e)
|
||||
log_runtime(e, src, "Caught in SNPC cooking module")
|
||||
|
||||
@@ -581,7 +581,7 @@
|
||||
saveVoice()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/interactive/hear_say(message, verb = "says", datum/language/language = null, alt_name = "", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol)
|
||||
/mob/living/carbon/human/interactive/hear_say(message, verb = "says", datum/language/language = null, italics = 0, mob/speaker = null, sound/speech_sound, sound_vol)
|
||||
if(!istype(speaker, /mob/living/carbon/human/interactive))
|
||||
knownStrings |= html_decode(message)
|
||||
..()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/mob/living/carbon/human/say(var/message, var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE)
|
||||
var/alt_name = ""
|
||||
..(message, sanitize = sanitize, ignore_speech_problems = ignore_speech_problems, ignore_atmospherics = ignore_atmospherics) //ohgod we should really be passing a datum here.
|
||||
|
||||
/mob/living/carbon/human/GetAltName()
|
||||
if(name != GetVoice())
|
||||
alt_name = " (as [get_id_name("Unknown")])"
|
||||
|
||||
..(message, alt_name = alt_name, sanitize = sanitize, ignore_speech_problems = ignore_speech_problems, ignore_atmospherics = ignore_atmospherics) //ohgod we should really be passing a datum here.
|
||||
return " (as [get_id_name("Unknown")])"
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/proc/forcesay(list/append)
|
||||
if(stat == CONSCIOUS)
|
||||
@@ -160,7 +160,7 @@
|
||||
returns[3] = speech_problem_flag
|
||||
return returns
|
||||
|
||||
/mob/living/carbon/human/handle_message_mode(var/message_mode, var/message, var/verb, var/speaking, var/used_radios, var/alt_name)
|
||||
/mob/living/carbon/human/handle_message_mode(var/message_mode, var/message, var/verb, var/speaking, var/used_radios)
|
||||
switch(message_mode)
|
||||
if("intercom")
|
||||
for(var/obj/item/radio/intercom/I in view(1, src))
|
||||
@@ -203,7 +203,7 @@
|
||||
R.talk_into(src, message, null, verb, speaking)
|
||||
|
||||
if("whisper")
|
||||
whisper_say(message, speaking, alt_name)
|
||||
whisper_say(message, speaking)
|
||||
return 1
|
||||
else
|
||||
if(message_mode)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user