Merge branch 'master' of https://github.com/ParadiseSS13/Paradise into FlagBearerFluff

This commit is contained in:
Aurorablade
2018-09-29 23:30:04 -04:00
407 changed files with 4479 additions and 3624 deletions
+3 -3
View File
@@ -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!
+6 -6
View File
@@ -44,14 +44,14 @@
return dat
/datum/adminTicketHolder/proc/showUI(var/client/user, var/tab)
/datum/adminTicketHolder/proc/showUI(mob/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)
/datum/adminTicketHolder/proc/showDetailUI(mob/user, var/ticketID)
var/datum/admin_ticket/T = globAdminTicketHolder.allTickets[ticketID]
var/status = "[T.state2text()]"
@@ -91,9 +91,9 @@
popup.set_content(dat)
popup.open()
/datum/adminTicketHolder/proc/userDetailUI(var/client/user)
/datum/adminTicketHolder/proc/userDetailUI(mob/user)
//dat
var/tickets = checkForTicket(user)
var/tickets = checkForTicket(user.client)
var/dat
dat += "<h1>Your open tickets</h1>"
dat += "<table>"
@@ -130,7 +130,7 @@
if(href_list["details"])
var/indexNum = text2num(href_list["details"])
showDetailUI(usr.client, indexNum)
showDetailUI(usr, indexNum)
return
if(href_list["resolve"])
@@ -169,4 +169,4 @@
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)
showDetailUI(usr, indexNum)
@@ -48,4 +48,4 @@
if(!holder && !check_rights(R_ADMIN))
return
globAdminTicketHolder.userDetailUI(usr.client)
globAdminTicketHolder.userDetailUI(usr)
+1 -2
View File
@@ -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)
+7 -1
View File
@@ -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)
+1 -1
View File
@@ -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)))
+1 -1
View File
@@ -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))
+2
View File
@@ -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.
@@ -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 = "")
+3 -24
View File
@@ -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 ..()
+2 -2
View File
@@ -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
+54 -33
View File
@@ -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>")
+29 -14
View File
@@ -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)
+2 -1
View File
@@ -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)
+18 -112
View File
@@ -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"
+1
View File
@@ -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
+50 -186
View File
@@ -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 ineterest.",
"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
+1 -1
View File
@@ -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(
+3 -2
View File
@@ -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
+13 -5
View File
@@ -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
+88
View File
@@ -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
@@ -1228,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."
@@ -1396,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
+1 -1
View File
@@ -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()
+4 -32
View File
@@ -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")
+23 -233
View File
@@ -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
+23 -59
View File
@@ -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)
+31 -60
View File
@@ -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?
+56 -34
View File
@@ -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
View File
@@ -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)
+8 -8
View File
@@ -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
+21 -15
View File
@@ -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
+2 -12
View File
@@ -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
+1 -1
View File
@@ -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)
+54 -69
View File
@@ -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 ..()
+11 -9
View File
@@ -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"
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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()
+9 -5
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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 ..()
+1 -2
View File
@@ -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
+1 -2
View File
@@ -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>")
+1 -2
View File
@@ -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
+3
View File
@@ -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**********************/
@@ -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
+10 -5
View File
@@ -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)
+4 -4
View File
@@ -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)
+2 -2
View File
@@ -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"
+2 -2
View File
@@ -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
+4
View File
@@ -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
@@ -1328,7 +1328,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")
@@ -1615,6 +1615,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)
..()
+6 -6
View File
@@ -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)
@@ -253,8 +253,8 @@
if(H.status_flags & GOTTAGOFAST)
. -= 1
if(H.status_flags & GOTTAGOREALLYFAST)
. -= 2
if(H.status_flags & GOTTAGOFAST_METH)
. -= 1
return .
/datum/species/proc/on_species_gain(mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
@@ -127,9 +127,26 @@
if((head_organ.dna.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use.
hair += i
var/file = file2text("config/custom_sprites.txt") //Pulls up the custom_sprites list
var/lines = splittext(file, "\n")
for(var/line in lines) // Looks for lines set up as screen:ckey:screen_name
var/list/Entry = splittext(line, ":") // split lines
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i]) // Cleans up lines
if(Entry.len != 3 || Entry[1] != "screen") // Ignore entries that aren't for screens
continue
if(Entry[2] == H.ckey) // They're in the list? Custom sprite time, var and icon change required
hair += Entry[3] // Adds custom screen to list
var/new_style = input(H, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair
var/new_color = input("Please select hair color.", "Monitor Color", head_organ.hair_colour) as null|color
if(H.incapacitated())
to_chat(src, "<span class='warning'>You were interrupted while changing your monitor display.</span>")
to_chat(H, "<span class='warning'>You were interrupted while changing your monitor display.</span>")
return
if(new_style)
H.change_hair(new_style)
H.change_hair(new_style, 1) // The 1 is to enable custom sprites
if(new_color)
H.change_hair_color(new_color)
@@ -83,7 +83,6 @@
if("Warden","Security Officer","Security Pod Pilot")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security
H.equip_or_collect(new /obj/item/gun/energy/gun/advtaser(H), slot_in_backpack)
if("Internal Affairs Agent")
suit=/obj/item/clothing/suit/space/eva/plasmaman/lawyer
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/lawyer
@@ -93,7 +92,6 @@
if("Head of Security")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security/hos
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hos
H.equip_or_collect(new /obj/item/gun/energy/gun(H), slot_in_backpack)
if("Captain", "Blueshield")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security/captain
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/captain
@@ -106,7 +104,6 @@
if("Medical Doctor","Brig Physician","Virologist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical
H.equip_or_collect(new /obj/item/flashlight/pen(H), slot_in_backpack)
if("Paramedic")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/paramedic
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/paramedic
@@ -84,16 +84,21 @@
/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H)
if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime")
H.unEquip(H.wear_mask)
H.unEquip(H.l_hand)
H.equip_or_collect(new /obj/item/clothing/mask/breath/vox(H), slot_wear_mask)
var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null
var/obj/item/tank/internal_tank
if(tank_pref)//Diseasel, here you go
H.equip_or_collect(new /obj/item/tank/nitrogen(H), slot_l_hand)
internal_tank = new /obj/item/tank/nitrogen(H)
else
H.equip_or_collect(new /obj/item/tank/emergency_oxygen/vox(H), slot_l_hand)
to_chat(H, "<span class='notice'>You are now running on nitrogen internals from the [H.l_hand] in your hand. Your species finds oxygen toxic, so you must breathe nitrogen only.</span>")
H.internal = H.l_hand
internal_tank = new /obj/item/tank/emergency_oxygen/vox(H)
if(!H.equip_to_appropriate_slot(internal_tank))
if(!H.put_in_any_hand_if_possible(internal_tank))
H.unEquip(H.l_hand)
H.equip_or_collect(internal_tank, slot_l_hand)
to_chat(H, "<span class='boldannounce'>Could not find an empty slot for internals! Please report this as a bug</span>")
H.internal = internal_tank
to_chat(H, "<span class='notice'>You are now running on nitrogen internals from the [internal_tank]. Your species finds oxygen toxic, so you must breathe nitrogen only.</span>")
H.update_action_buttons_icon()
/datum/species/vox/on_species_gain(mob/living/carbon/human/H)
@@ -1,10 +1,5 @@
//Lallander was here
/mob/living/carbon/human/whisper(message as text)
var/alt_name = ""
if(name != GetVoice())
alt_name = "(as [get_id_name("Unknown")])"
message = trim_strip_html_properly(message) //bit of duplicate code, acceptable because the workaround would be annoying
//parse the language code and consume it
@@ -23,4 +18,4 @@
message = trim_left(message)
message = handle_autohiss(message, speaking)
whisper_say(message, speaking, alt_name)
whisper_say(message, speaking)
+1 -1
View File
@@ -14,7 +14,7 @@
return 1
return ..()
/mob/living/carbon/slime/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/living/carbon/slime/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(speaker in Friends)
speech_buffer = list()
speech_buffer.Add(speaker)
+11 -9
View File
@@ -95,10 +95,10 @@ proc/get_radio_key_from_channel(var/channel)
returns[3] = speech_problem_flag
return returns
/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios)
switch(message_mode)
if("whisper") //all mobs can whisper by default
whisper_say(message, speaking, alt_name)
whisper_say(message, speaking)
return 1
return 0
@@ -109,7 +109,7 @@ proc/get_radio_key_from_channel(var/channel)
return returns
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb = "says", var/alt_name = "", var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE)
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb = "says", var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE)
if(client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "<span class='danger'>You cannot speak in IC (Muted).</span>")
@@ -184,7 +184,7 @@ proc/get_radio_key_from_channel(var/channel)
return 0
var/list/used_radios = list()
if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name))
if(handle_message_mode(message_mode, message, verb, speaking, used_radios))
return 1
var/list/handle_v = handle_speech_sound()
@@ -268,7 +268,7 @@ proc/get_radio_key_from_channel(var/channel)
var/speech_bubble_test = say_test(message)
for(var/mob/M in listening)
M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol)
M.hear_say(message, verb, speaking, italics, src, speech_sound, sound_vol)
if(M.client)
speech_bubble_recipients.Add(M.client)
spawn(0)
@@ -359,7 +359,7 @@ proc/get_radio_key_from_channel(var/channel)
/mob/living/proc/get_whisper_loc()
return src
/mob/living/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
/mob/living/proc/whisper_say(var/message, var/datum/language/speaking = null, var/verb="whispers")
if(client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "<span class='danger'>You cannot speak in IC (Muted).</span>")
@@ -381,6 +381,7 @@ proc/get_radio_key_from_channel(var/channel)
var/eavesdropping_range = 2
var/watching_range = 5
var/italics = 1
var/adverb_added = FALSE
var/not_heard //the message displayed to people who could not hear the whispering
if(speaking)
@@ -389,6 +390,7 @@ proc/get_radio_key_from_channel(var/channel)
not_heard = "[verb] something"
else
var/adverb = pick("quietly", "softly")
adverb_added = TRUE
verb = "[speaking.speech_verb] [adverb]"
not_heard = "[speaking.speech_verb] something [adverb]"
else
@@ -404,7 +406,7 @@ proc/get_radio_key_from_channel(var/channel)
if(verb == "yells loudly")
verb = "slurs emphatically"
else if(speech_problem_flag)
else if(speech_problem_flag && !adverb_added)
var/adverb = pick("quietly", "softly")
verb = "[verb] [adverb]"
@@ -464,14 +466,14 @@ proc/get_radio_key_from_channel(var/channel)
var/speech_bubble_test = say_test(message)
for(var/mob/M in listening)
M.hear_say(message, verb, speaking, alt_name, italics, src)
M.hear_say(message, verb, speaking, italics, src)
if(M.client)
speech_bubble_recipients.Add(M.client)
if(eavesdropping.len)
var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
for(var/mob/M in eavesdropping)
M.hear_say(new_message, verb, speaking, alt_name, italics, src)
M.hear_say(new_message, verb, speaking, italics, src)
if(M.client)
speech_bubble_recipients.Add(M.client)
+5 -5
View File
@@ -69,7 +69,7 @@ var/list/ai_verbs_default = list(
var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click() -- TLE
var/malfhacking = 0 // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite
var/malf_cooldown = 0 //Cooldown var for malf modules
var/malf_cooldown = 0 //Cooldown var for malf modules, stores a worldtime + cooldown
var/obj/machinery/power/apc/malfhack = null
var/explosive = 0 //does the AI explode when it dies?
@@ -281,7 +281,7 @@ var/list/ai_verbs_default = list(
/obj/machinery/ai_powersupply
name="\improper AI power supply"
active_power_usage=1000
use_power = 2
use_power = ACTIVE_POWER_USE
power_channel = EQUIP
var/mob/living/silicon/ai/powered_ai = null
invisibility = 100
@@ -303,9 +303,9 @@ var/list/ai_verbs_default = list(
return
if(!powered_ai.anchored)
loc = powered_ai.loc
use_power = 0
use_power = NO_POWER_USE
if(powered_ai.anchored)
use_power = 2
use_power = ACTIVE_POWER_USE
/mob/living/silicon/ai/proc/pick_icon()
set category = "AI Commands"
@@ -1250,7 +1250,7 @@ var/list/ai_verbs_default = list(
else
to_chat(src, "<span class='warning'>Target is not on or near any active cameras on the station.</span>")
/mob/living/silicon/ai/handle_fire()
return
@@ -137,6 +137,6 @@
acceleration = !acceleration
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
/mob/camera/aiEye/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/camera/aiEye/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(relay_speech)
ai.relay_speech(speaker, message, verb, language)
+1 -1
View File
@@ -7,7 +7,7 @@
var/turf/T = get_turf_or_move(loc)
for(var/mob/M in viewers(T))
M.show_message("<span class=warning>[src] emits a dull beep before it loses power and collapses.</span>", 3, "<span class=warning>You hear a dull beep followed by the sound of glass crunching.</span>", 2)
M.show_message("<span class='warning'>[src] emits a dull beep before it loses power and collapses.</span>", 3, "<span class='warning'>You hear a dull beep followed by the sound of glass crunching.</span>", 2)
name = "pAI debris"
desc = "The unfortunate remains of some poor personal AI device."
icon_state = "[chassis]_dead"
+6 -6
View File
@@ -324,11 +324,11 @@
return
if(loc != card)
to_chat(src, "<span class=warning>You are already in your mobile form!</span>")
to_chat(src, "<span class='warning'>You are already in your mobile form!</span>")
return
if(world.time <= last_special)
to_chat(src, "<span class=warning>You must wait before folding your chassis out again!</span>")
to_chat(src, "<span class='warning'>You must wait before folding your chassis out again!</span>")
return
last_special = world.time + 200
@@ -336,7 +336,7 @@
//I'm not sure how much of this is necessary, but I would rather avoid issues.
force_fold_out()
visible_message("<span class=notice>[src] folds outwards, expanding into a mobile form.</span>", "<span class=notice>You fold outwards, expanding into a mobile form.</span>")
visible_message("<span class='notice'>[src] folds outwards, expanding into a mobile form.</span>", "<span class='notice'>You fold outwards, expanding into a mobile form.</span>")
/mob/living/silicon/pai/proc/force_fold_out()
if(istype(card.loc, /mob))
@@ -359,11 +359,11 @@
return
if(loc == card)
to_chat(src, "<span class=warning>You are already in your card form!</span>")
to_chat(src, "<span class='warning'>You are already in your card form!</span>")
return
if(world.time <= last_special)
to_chat(src, "<span class=warning>You must wait before returning to your card form!</span>")
to_chat(src, "<span class='warning'>You must wait before returning to your card form!</span>")
return
close_up()
@@ -494,7 +494,7 @@
if(loc == card)
return
visible_message("<span class=notice>[src] neatly folds inwards, compacting down to a rectangular card.</span>", "<span class=notice>You neatly fold inwards, compacting down to a rectangular card.</span>")
visible_message("<span class='notice'>[src] neatly folds inwards, compacting down to a rectangular card.</span>", "<span class='notice'>You neatly fold inwards, compacting down to a rectangular card.</span>")
stop_pulling()
reset_perspective(card)
@@ -65,7 +65,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
if("name")
t = input("Enter a name for your pAI", "pAI Name", candidate.name) as text
if(t)
candidate.name = sanitize(copytext(t,1,MAX_NAME_LEN))
candidate.name = reject_bad_name(sanitize(copytext(t,1,MAX_NAME_LEN)))
if("desc")
t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message
if(t)
@@ -84,7 +84,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
candidate.savefile_load(usr)
//In case people have saved unsanitized stuff.
if(candidate.name)
candidate.name = sanitize(copytext(candidate.name,1,MAX_NAME_LEN))
candidate.name = reject_bad_name(sanitize(copytext(candidate.name,1,MAX_NAME_LEN)))
if(candidate.description)
candidate.description = sanitize(copytext(candidate.description,1,MAX_MESSAGE_LEN))
if(candidate.role)
@@ -163,7 +163,7 @@
icon_state = "radio"
//
//Robotic Component Analyser, basically a health analyser for robots
//Robotic Component Analyzer, basically a health analyzer for robots
//
/obj/item/robotanalyzer
name = "cyborg analyzer"
@@ -281,7 +281,7 @@
grabbed_something = 1
if(grabbed_something)
to_chat(user, "<span class='notice'>You deploy your decompiler and clear out the contents of \the [T].<span>")
to_chat(user, "<span class='notice'>You deploy your decompiler and clear out the contents of \the [T].</span>")
else
to_chat(user, "<span class='warning'>Nothing on \the [T] is useful to you.</span>")
return
@@ -4,7 +4,7 @@
density = 1
anchored = 1
use_power = 1
use_power = IDLE_POWER_USE
idle_power_usage = 20
active_power_usage = 5000
@@ -1,7 +1,7 @@
/mob/living/silicon/robot/drone/say(var/message, var/datum/language/speaking = null)
if(copytext(message, 1, 2) == "*")
return emote(copytext(message, 2))
if(!speaking)
speaking = parse_language(message)
if(!speaking)
@@ -10,6 +10,6 @@
if(speaking)
return ..()
/mob/living/silicon/robot/drone/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
/mob/living/silicon/robot/drone/whisper_say(var/message, var/datum/language/speaking = null, var/verb="whispers")
say(message) //drones do not get to whisper, only speak normally
return 1
@@ -20,6 +20,9 @@
contents -= O
if(module)
O.loc = module //Return item to module so it appears in its contents, so it can be taken out again.
for(var/X in O.actions) // Remove assocated actions
var/datum/action/A = X
A.Remove(src)
if(module_active == O)
module_active = null
@@ -56,6 +59,7 @@
O.plane = HUD_PLANE
O.screen_loc = inv1.screen_loc
contents += O
set_actions(O)
else if(!module_state_2)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_2 = O
@@ -63,6 +67,7 @@
O.plane = HUD_PLANE
O.screen_loc = inv2.screen_loc
contents += O
set_actions(O)
else if(!module_state_3)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_3 = O
@@ -70,10 +75,16 @@
O.plane = HUD_PLANE
O.screen_loc = inv3.screen_loc
contents += O
set_actions(O)
else
to_chat(src, "You need to disable a module first!")
update_icons()
/mob/living/silicon/robot/proc/set_actions(obj/item/I)
for(var/X in I.actions)
var/datum/action/A = X
A.Grant(src)
/mob/living/silicon/robot/proc/uneq_active()
uneq_module(module_active)

Some files were not shown because too many files have changed in this diff Show More