diff --git a/baystation12.dme b/baystation12.dme index 5a034ff343b..b82ce97a578 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -216,8 +216,6 @@ #include "code\game\gamemodes\setupgame.dm" #include "code\game\gamemodes\autotraitor\autotraitor.dm" #include "code\game\gamemodes\blob\blob.dm" -#include "code\game\gamemodes\blob\blob_finish.dm" -#include "code\game\gamemodes\blob\blob_report.dm" #include "code\game\gamemodes\blob\theblob.dm" #include "code\game\gamemodes\blob\blobs\core.dm" #include "code\game\gamemodes\blob\blobs\factory.dm" @@ -248,6 +246,7 @@ #include "code\game\gamemodes\events\holidays\Holidays.dm" #include "code\game\gamemodes\events\holidays\Other.dm" #include "code\game\gamemodes\extended\extended.dm" +#include "code\game\gamemodes\heist\heist.dm" #include "code\game\gamemodes\malfunction\Malf_Modules.dm" #include "code\game\gamemodes\malfunction\malfunction.dm" #include "code\game\gamemodes\meteor\meteor.dm" @@ -313,6 +312,7 @@ #include "code\game\machinery\newscaster.dm" #include "code\game\machinery\OpTable.dm" #include "code\game\machinery\overview.dm" +#include "code\game\machinery\podmen.dm" #include "code\game\machinery\portable_turret.dm" #include "code\game\machinery\recharger.dm" #include "code\game\machinery\rechargestation.dm" @@ -375,10 +375,12 @@ #include "code\game\machinery\computer\robot.dm" #include "code\game\machinery\computer\security.dm" #include "code\game\machinery\computer\shuttle.dm" +#include "code\game\machinery\computer\skills.dm" #include "code\game\machinery\computer\specops_shuttle.dm" #include "code\game\machinery\computer\station_alert.dm" #include "code\game\machinery\computer\syndicate_shuttle.dm" #include "code\game\machinery\computer\syndicate_specops_shuttle.dm" +#include "code\game\machinery\computer\vox_shuttle.dm" #include "code\game\machinery\doors\airlock.dm" #include "code\game\machinery\doors\airlock_electronics.dm" #include "code\game\machinery\doors\alarmlock.dm" @@ -486,6 +488,7 @@ #include "code\game\objects\items\devices\lightreplacer.dm" #include "code\game\objects\items\devices\multitool.dm" #include "code\game\objects\items\devices\paicard.dm" +#include "code\game\objects\items\devices\pipe_painter.dm" #include "code\game\objects\items\devices\powersink.dm" #include "code\game\objects\items\devices\scanners.dm" #include "code\game\objects\items\devices\taperecorder.dm" @@ -846,6 +849,7 @@ #include "code\modules\mob\death.dm" #include "code\modules\mob\emote.dm" #include "code\modules\mob\inventory.dm" +#include "code\modules\mob\language.dm" #include "code\modules\mob\login.dm" #include "code\modules\mob\logout.dm" #include "code\modules\mob\mob.dm" @@ -876,6 +880,7 @@ #include "code\modules\mob\living\carbon\carbon_defines.dm" #include "code\modules\mob\living\carbon\give.dm" #include "code\modules\mob\living\carbon\shock.dm" +#include "code\modules\mob\living\carbon\species.dm" #include "code\modules\mob\living\carbon\alien\alien.dm" #include "code\modules\mob\living\carbon\alien\death.dm" #include "code\modules\mob\living\carbon\alien\login.dm" @@ -1000,6 +1005,7 @@ #include "code\modules\mob\living\silicon\robot\robot_movement.dm" #include "code\modules\mob\living\silicon\robot\say.dm" #include "code\modules\mob\living\silicon\robot\wires.dm" +#include "code\modules\mob\living\simple_animal\borer.dm" #include "code\modules\mob\living\simple_animal\constructs.dm" #include "code\modules\mob\living\simple_animal\corpse.dm" #include "code\modules\mob\living\simple_animal\parrot.dm" diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index c9e763e8390..5baffbcb615 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -527,7 +527,7 @@ obj/machinery/atmospherics/pipe var/build_killswitch = 1 var/obj/machinery/atmospherics/node1 - New() + New() initialize_directions = dir ..() @@ -722,7 +722,7 @@ obj/machinery/atmospherics/pipe icon_state = "manifold_[connected]_[unconnected]" - if(!connected) + if(!connected) del(src) return @@ -951,7 +951,7 @@ obj/machinery/atmospherics/pipe return initialize() - + for(var/obj/machinery/atmospherics/target in get_step(src,1)) if(target.initialize_directions & 2) node1 = target @@ -1028,7 +1028,7 @@ obj/machinery/atmospherics/pipe manifold4w/general/hidden level = 1 icon_state = "manifold4w-f" - + cap name = "pipe endcap" desc = "An endcap for pipes" @@ -1117,28 +1117,9 @@ obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/u if (istype(src, /obj/machinery/atmospherics/pipe/vent)) return ..() - // ===== Handle paints ===== - if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/red)) - src.color = "red" - user << "\red You paint the pipe red." - update_icon() + if(istype(W,/obj/item/device/pipe_painter)) return 1 - if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/blue)) - src.color = "blue" - user << "\red You paint the pipe blue." - update_icon() - return 1 - if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/green)) - src.color = "green" - user << "\red You paint the pipe green." - update_icon() - return 1 - if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/yellow)) - src.color = "yellow" - user << "\red You paint the pipe yellow." - update_icon() - return 1 - + if (!istype(W, /obj/item/weapon/wrench)) return ..() var/turf/T = src.loc diff --git a/code/WorkInProgress/kilakk/responseteam.dm b/code/WorkInProgress/kilakk/responseteam.dm index 575e5ab6fd0..6faafad342f 100644 --- a/code/WorkInProgress/kilakk/responseteam.dm +++ b/code/WorkInProgress/kilakk/responseteam.dm @@ -2,7 +2,9 @@ // work in progress var/const/members_possible = 5 -var/sent_emergency_team = 0 +var/const/members_required = 1 // We need at least *one* person ;_; +var/global/admin_emergency_team = 0 // Used for admin-spawned response teams +// 'sent_response_team' for automagic response teams /client/proc/response_team() set name = "Dispatch Emergency Response Team" @@ -18,7 +20,7 @@ var/sent_emergency_team = 0 if(ticker.current_state == GAME_STATE_PREGAME) usr << "\red The round hasn't started yet!" return - if(sent_emergency_team == 1) + if(admin_emergency_team || send_emergency_team) usr << "\red Central Command has already dispatched an emergency response team!" return if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes") @@ -35,11 +37,11 @@ var/sent_emergency_team = 0 if(alert("You haven't specified a mission. Exit the setup process?",,"No","Yes")=="Yes") return - if(sent_emergency_team) + if(admin_emergency_team || send_emergency_team) usr << "\red Looks like somebody beat you to it!" return - sent_emergency_team = 1 + admin_emergency_team = 1 message_admins("[key_name_admin(usr)] is dispatching an Emergency Response Team.", 1) log_admin("[key_name(usr)] used Dispatch Response Team.") @@ -87,6 +89,12 @@ var/sent_emergency_team = 0 sleep(300) + if(candidates.len < members_required) + message_admins("Not enough people signed up for [key_name_admin(usr)]'s response team! Aborting.") + log_admin("Response Team aborted: Not Enough Signups.") + admin_emergency_team = 0 + return + for(var/i=members_possible,(i>0&&candidates.len), i--) // The rest of the choosing process is just an input with a list of candidates on it var/chosen = input("Time's up! Choose characters to spawn as reponse team members. This will go on until there are no more ghosts to pick from or until all slots are full.", "Considered Players") as null|anything in candidates candidates -= chosen @@ -111,6 +119,7 @@ var/sent_emergency_team = 0 break spawn(0) + switch(alert(new_member, "You are an Emergency Response Team member! Are you a boy or a girl?",,"Male","Female")) if("Male") new_member.gender = MALE @@ -122,9 +131,12 @@ var/sent_emergency_team = 0 if(!new_name) new_member.real_name = "Agent [pick("Red","Yellow","Orange","Silver","Gold", "Pink", "Purple", "Rainbow")]" // Choose a "random" agent name new_member.name = usr.real_name + new_member.mind.name = usr.real_name + else new_member.real_name = new_name new_member.name = new_name + new_member.mind.name = new_name // -- CHANGE APPEARANCE -- var/new_tone = input(new_member, "Please select your new skin tone: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as num @@ -171,13 +183,16 @@ var/sent_emergency_team = 0 new_member.update_hair(1) new_member.mind_initialize() + new_member.mind.assigned_role = "Emergency Response Team" new_member.mind.special_role = "Emergency Response Team" - ticker.mode.traitors += new_member.mind // ERTs will show up at the end of the round on the "traitor" list + ticker.mode.traitors |= new_member.mind // ERTs will show up at the end of the round on the "traitor" list + // Join message new_member << "\blue You are the Emergency Response Team[!leader_selected?"!":" Leader!"] \nAs a response team [!leader_selected?"member":"leader"] you answer directly to [!leader_selected?"your team leader.":"Central Command."] \nYou have been deployed by NanoTrasen Central Command in Tau Ceti to resolve a Code Red alert aboard [station_name()], and have been provided with the following instructions and information regarding your mission: \red [situation]" new_member.mind.store_memory("Mission Parameters: \red [situation].") + // Leader join message if(leader_selected) new_member << "\red The Nuclear Authentication Code is: [nuke_code]. You are instructed not to detonate the nuclear device aboard [station_name()] unless absolutely necessary." new_member.mind.store_memory("Nuclear Authentication Code: \red [nuke_code]") @@ -213,7 +228,7 @@ var/sent_emergency_team = 0 // Put stuff into their backpacks equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid(src), slot_in_backpack) // Not sure about this + // equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack) // Regular medkit // Loyalty implants var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src) @@ -235,5 +250,7 @@ var/sent_emergency_team = 0 E.registered_name = real_name equip_to_slot_or_del(E, slot_wear_id) + update_icons() + return 1 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index ed740f85d16..956e6be2557 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -17,6 +17,11 @@ var/global/list/landmarks_list = list() //list of all landmarks created var/global/list/surgery_steps = list() //list of all surgery steps |BS12 var/global/list/mechas_list = list() //list of all mechs. Used by hostile mobs target tracking. +//Languages/species/whitelist. +var/global/list/all_species[0] +var/global/list/all_languages[0] +var/global/list/whitelisted_species = list("Human") + //Preferences stuff //Hairstyles var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name @@ -69,6 +74,21 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al var/datum/surgery_step/S = new T surgery_steps += S sort_surgeries() + + //Languages and species. + paths = typesof(/datum/language)-/datum/language + for(var/T in paths) + var/datum/language/L = new T + all_languages[L.name] = L + + paths = typesof(/datum/species)-/datum/species + for(var/T in paths) + var/datum/species/S = new T + all_species[S.name] = S + + if(S.flags & WHITELISTED) + whitelisted_species += S.name + /* // Uncomment to debug chemical reaction list. /client/verb/debug_chemical_list() diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index e6d58ef6386..f92d8b1c7b1 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -45,381 +45,382 @@ datum/shuttle_controller if(istype(A, /area/hallway)) A.readyalert() - proc/shuttlealert(var/X) +datum/shuttle_controller/proc/shuttlealert(var/X) alert = X - proc/recall() - if(direction == 1) - var/timeleft = timeleft() - if(alert == 0) - if(timeleft >= 600) - return - captain_announce("The emergency shuttle has been recalled.") - world << sound('sound/AI/shuttlerecalled.ogg') - setdirection(-1) - online = 1 - for(var/area/A in world) - if(istype(A, /area/hallway)) - A.readyreset() - return - else //makes it possible to send shuttle back. - captain_announce("The shuttle has been recalled.") - setdirection(-1) - online = 1 - alert = 0 // set alert back to 0 after an admin recall +datum/shuttle_controller/proc/recall() + if(direction == 1) + var/timeleft = timeleft() + if(alert == 0) + if(timeleft >= 600) return + captain_announce("The emergency shuttle has been recalled.") + world << sound('sound/AI/shuttlerecalled.ogg') + setdirection(-1) + online = 1 + for(var/area/A in world) + if(istype(A, /area/hallway)) + A.readyreset() + return + else //makes it possible to send shuttle back. + captain_announce("The shuttle has been recalled.") + setdirection(-1) + online = 1 + alert = 0 // set alert back to 0 after an admin recall + return // returns the time (in seconds) before shuttle arrival // note if direction = -1, gives a count-up to SHUTTLEARRIVETIME - proc/timeleft() - if(online) - var/timeleft = round((endtime - world.timeofday)/10 ,1) - if(direction == 1 || direction == 2) - return timeleft - else - return SHUTTLEARRIVETIME-timeleft +datum/shuttle_controller/proc/timeleft() + if(online) + var/timeleft = round((endtime - world.timeofday)/10 ,1) + if(direction == 1 || direction == 2) + return timeleft else - return SHUTTLEARRIVETIME + return SHUTTLEARRIVETIME-timeleft + else + return SHUTTLEARRIVETIME // sets the time left to a given delay (in seconds) - proc/settimeleft(var/delay) - endtime = world.timeofday + delay * 10 - timelimit = delay +datum/shuttle_controller/proc/settimeleft(var/delay) + endtime = world.timeofday + delay * 10 + timelimit = delay // sets the shuttle direction // 1 = towards SS13, -1 = back to centcom - proc/setdirection(var/dirn) - if(direction == dirn) - return - direction = dirn - // if changing direction, flip the timeleft by SHUTTLEARRIVETIME - var/ticksleft = endtime - world.timeofday - endtime = world.timeofday + (SHUTTLEARRIVETIME*10 - ticksleft) +datum/shuttle_controller/proc/setdirection(var/dirn) + if(direction == dirn) return + direction = dirn + // if changing direction, flip the timeleft by SHUTTLEARRIVETIME + var/ticksleft = endtime - world.timeofday + endtime = world.timeofday + (SHUTTLEARRIVETIME*10 - ticksleft) + return - proc/process() +datum/shuttle_controller/proc/process() - emergency_shuttle - process() - if(!online) - return - var/timeleft = timeleft() - if(timeleft > 1e5) // midnight rollover protection - timeleft = 0 - switch(location) - if(0) +datum/shuttle_controller/emergency_shuttle/process() + if(!online) + return + var/timeleft = timeleft() + if(timeleft > 1e5) // midnight rollover protection + timeleft = 0 + switch(location) + if(0) - /* --- Shuttle is in transit to Central Command from SS13 --- */ - if(direction == 2) - if(timeleft>0) - return 0 + /* --- Shuttle is in transit to Central Command from SS13 --- */ + if(direction == 2) + if(timeleft>0) + return 0 - /* --- Shuttle has arrived at Centrcal Command --- */ - else - // turn off the star spawners - /* - for(var/obj/effect/starspawner/S in world) - S.spawning = 0 - */ + /* --- Shuttle has arrived at Centrcal Command --- */ + else + // turn off the star spawners + /* + for(var/obj/effect/starspawner/S in world) + S.spawning = 0 + */ - location = 2 + location = 2 - //main shuttle - var/area/start_location = locate(/area/shuttle/escape/transit) - var/area/end_location = locate(/area/shuttle/escape/centcom) + //main shuttle + var/area/start_location = locate(/area/shuttle/escape/transit) + var/area/end_location = locate(/area/shuttle/escape/centcom) - start_location.move_contents_to(end_location, null, NORTH) + start_location.move_contents_to(end_location, null, NORTH) - for(var/obj/machinery/door/unpowered/D in machines) - if( get_area(D) == end_location ) - spawn(0) - D.locked = 0 - D.open() + for(var/obj/machinery/door/unpowered/shuttle/D in end_location) + spawn(0) + D.locked = 0 + D.open() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) //pods - start_location = locate(/area/shuttle/escape_pod1/transit) - end_location = locate(/area/shuttle/escape_pod1/centcom) - start_location.move_contents_to(end_location, null, NORTH) + start_location = locate(/area/shuttle/escape_pod1/transit) + end_location = locate(/area/shuttle/escape_pod1/centcom) + start_location.move_contents_to(end_location, null, NORTH) - for(var/obj/machinery/door/D in machines) - if( get_area(D) == end_location ) - spawn(0) - D.open() + for(var/obj/machinery/door/D in machines) + if( get_area(D) == end_location ) + spawn(0) + D.open() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - start_location = locate(/area/shuttle/escape_pod2/transit) - end_location = locate(/area/shuttle/escape_pod2/centcom) - start_location.move_contents_to(end_location, null, NORTH) + start_location = locate(/area/shuttle/escape_pod2/transit) + end_location = locate(/area/shuttle/escape_pod2/centcom) + start_location.move_contents_to(end_location, null, NORTH) - for(var/obj/machinery/door/D in machines) - if( get_area(D) == end_location ) - spawn(0) - D.open() + for(var/obj/machinery/door/D in machines) + if( get_area(D) == end_location ) + spawn(0) + D.open() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - start_location = locate(/area/shuttle/escape_pod3/transit) - end_location = locate(/area/shuttle/escape_pod3/centcom) - start_location.move_contents_to(end_location, null, NORTH) + start_location = locate(/area/shuttle/escape_pod3/transit) + end_location = locate(/area/shuttle/escape_pod3/centcom) + start_location.move_contents_to(end_location, null, NORTH) - for(var/obj/machinery/door/D in machines) - if( get_area(D) == end_location ) - spawn(0) - D.open() + for(var/obj/machinery/door/D in machines) + if( get_area(D) == end_location ) + spawn(0) + D.open() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - start_location = locate(/area/shuttle/escape_pod5/transit) - end_location = locate(/area/shuttle/escape_pod5/centcom) - start_location.move_contents_to(end_location, null, EAST) + start_location = locate(/area/shuttle/escape_pod5/transit) + end_location = locate(/area/shuttle/escape_pod5/centcom) + start_location.move_contents_to(end_location, null, EAST) - for(var/obj/machinery/door/D in machines) - if( get_area(D) == end_location ) - spawn(0) - D.open() + for(var/obj/machinery/door/D in machines) + if( get_area(D) == end_location ) + spawn(0) + D.open() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - online = 0 + online = 0 - return 1 + return 1 /* --- Shuttle has docked centcom after being recalled --- */ - if(timeleft>timelimit) - online = 0 - direction = 1 - endtime = null + if(timeleft>timelimit) + online = 0 + direction = 1 + endtime = null - return 0 + return 0 - else if((fake_recall != 0) && (timeleft <= fake_recall)) - recall() - fake_recall = 0 - return 0 + else if((fake_recall != 0) && (timeleft <= fake_recall)) + recall() + fake_recall = 0 + return 0 /* --- Shuttle has docked with the station - begin countdown to transit --- */ - else if(timeleft <= 0) - location = 1 - var/area/start_location = locate(/area/shuttle/escape/centcom) - var/area/end_location = locate(/area/shuttle/escape/station) + else if(timeleft <= 0) + location = 1 + var/area/start_location = locate(/area/shuttle/escape/centcom) + var/area/end_location = locate(/area/shuttle/escape/station) - var/list/dstturfs = list() - var/throwy = world.maxy + var/list/dstturfs = list() + var/throwy = world.maxy - for(var/turf/T in end_location) - dstturfs += T - if(T.y < throwy) - throwy = T.y + for(var/turf/T in end_location) + dstturfs += T + if(T.y < throwy) + throwy = T.y - // hey you, get out of the way! - for(var/turf/T in dstturfs) - // find the turf to move things to - var/turf/D = locate(T.x, throwy - 1, 1) - //var/turf/E = get_step(D, SOUTH) - for(var/atom/movable/AM as mob|obj in T) - AM.Move(D) - // NOTE: Commenting this out to avoid recreating mass driver glitch - /* - spawn(0) - AM.throw_at(E, 1, 1) - return - */ - - if(istype(T, /turf/simulated)) - del(T) - - for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area... - bug.gib() - - for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug... - pest.gib() - - start_location.move_contents_to(end_location) - settimeleft(SHUTTLELEAVETIME) - //send2irc("Server", "The Emergency Shuttle has docked with the station.") - captain_announce("The Emergency Shuttle has docked with the station. You have [round(timeleft()/60,1)] minutes to board the Emergency Shuttle.") - world << sound('sound/AI/shuttledock.ogg') - - return 1 - - if(1) - - // Just before it leaves, close the damn doors! - if(timeleft == 2 || timeleft == 1) - var/area/start_location = locate(/area/shuttle/escape/station) - for(var/obj/machinery/door/unpowered/shuttle/D in start_location) - spawn(0) - D.close() - D.locked = 1 - - if(timeleft>0) - return 0 - - /* --- Shuttle leaves the station, enters transit --- */ - else - - // Turn on the star effects - - /* // kinda buggy atm, i'll fix this later - for(var/obj/effect/starspawner/S in world) - if(!S.spawning) - spawn() S.startspawn() + // hey you, get out of the way! + for(var/turf/T in dstturfs) + // find the turf to move things to + var/turf/D = locate(T.x, throwy - 1, 1) + //var/turf/E = get_step(D, SOUTH) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + // NOTE: Commenting this out to avoid recreating mass driver glitch + /* + spawn(0) + AM.throw_at(E, 1, 1) + return */ - departed = 1 // It's going! - location = 0 // in deep space - direction = 2 // heading to centcom + if(istype(T, /turf/simulated)) + del(T) - //main shuttle - var/area/start_location = locate(/area/shuttle/escape/station) - var/area/end_location = locate(/area/shuttle/escape/transit) + for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area... + bug.gib() - settimeleft(SHUTTLETRANSITTIME) - start_location.move_contents_to(end_location, null, NORTH) + for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug... + pest.gib() + + start_location.move_contents_to(end_location) + settimeleft(SHUTTLELEAVETIME) + //send2irc("Server", "The Emergency Shuttle has docked with the station.") + captain_announce("The Emergency Shuttle has docked with the station. You have [round(timeleft()/60,1)] minutes to board the Emergency Shuttle.") + world << sound('sound/AI/shuttledock.ogg') + + return 1 + + if(1) + + // Just before it leaves, close the damn doors! + if(timeleft == 2 || timeleft == 1) + var/area/start_location = locate(/area/shuttle/escape/station) + for(var/obj/machinery/door/unpowered/shuttle/D in start_location) + spawn(0) + D.close() + D.locked = 1 + + if(timeleft>0) + return 0 + + /* --- Shuttle leaves the station, enters transit --- */ + else + + // Turn on the star effects + + /* // kinda buggy atm, i'll fix this later + for(var/obj/effect/starspawner/S in world) + if(!S.spawning) + spawn() S.startspawn() + */ + + departed = 1 // It's going! + location = 0 // in deep space + direction = 2 // heading to centcom + + //main shuttle + var/area/start_location = locate(/area/shuttle/escape/station) + var/area/end_location = locate(/area/shuttle/escape/transit) + + settimeleft(SHUTTLETRANSITTIME) + start_location.move_contents_to(end_location, null, NORTH) + + // Close shuttle doors, lock + for(var/obj/machinery/door/unpowered/shuttle/D in end_location) + spawn(0) + D.close() + D.locked = 1 - for(var/obj/machinery/door/D in end_location) - spawn(0) - D.close() // Some aesthetic turbulance shaking - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - //pods - start_location = locate(/area/shuttle/escape_pod1/station) - end_location = locate(/area/shuttle/escape_pod1/transit) - start_location.move_contents_to(end_location, null, NORTH) - for(var/obj/machinery/door/D in end_location) - spawn(0) - D.close() + //pods + start_location = locate(/area/shuttle/escape_pod1/station) + end_location = locate(/area/shuttle/escape_pod1/transit) + start_location.move_contents_to(end_location, null, NORTH) + for(var/obj/machinery/door/D in end_location) + spawn(0) + D.close() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - start_location = locate(/area/shuttle/escape_pod2/station) - end_location = locate(/area/shuttle/escape_pod2/transit) - start_location.move_contents_to(end_location, null, NORTH) - for(var/obj/machinery/door/D in end_location) - spawn(0) - D.close() + start_location = locate(/area/shuttle/escape_pod2/station) + end_location = locate(/area/shuttle/escape_pod2/transit) + start_location.move_contents_to(end_location, null, NORTH) + for(var/obj/machinery/door/D in end_location) + spawn(0) + D.close() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - start_location = locate(/area/shuttle/escape_pod3/station) - end_location = locate(/area/shuttle/escape_pod3/transit) - start_location.move_contents_to(end_location, null, NORTH) - for(var/obj/machinery/door/D in end_location) - spawn(0) - D.close() + start_location = locate(/area/shuttle/escape_pod3/station) + end_location = locate(/area/shuttle/escape_pod3/transit) + start_location.move_contents_to(end_location, null, NORTH) + for(var/obj/machinery/door/D in end_location) + spawn(0) + D.close() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - start_location = locate(/area/shuttle/escape_pod5/station) - end_location = locate(/area/shuttle/escape_pod5/transit) - start_location.move_contents_to(end_location, null, EAST) - for(var/obj/machinery/door/D in end_location) - spawn(0) - D.close() + start_location = locate(/area/shuttle/escape_pod5/station) + end_location = locate(/area/shuttle/escape_pod5/transit) + start_location.move_contents_to(end_location, null, EAST) + for(var/obj/machinery/door/D in end_location) + spawn(0) + D.close() - for(var/mob/M in end_location) - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 4, 1) // buckled, not a lot of shaking - else - shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(5) + for(var/mob/M in end_location) + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(5) - captain_announce("The Emergency Shuttle has left the station. Estimate [round(timeleft()/60,1)] minutes until the shuttle docks at Central Command.") + captain_announce("The Emergency Shuttle has left the station. Estimate [round(timeleft()/60,1)] minutes until the shuttle docks at Central Command.") - return 1 + return 1 - else - return 1 + else + return 1 /* @@ -434,23 +435,23 @@ datum/shuttle_controller var/direction = SOUTH layer = 2 // TURF_LAYER - New() - ..() - pixel_x += rand(-2,30) - pixel_y += rand(-2,30) - var/starnum = pick("1", "1", "1", "2", "3", "4") +/obj/effect/bgstar/New() + ..() + pixel_x += rand(-2,30) + pixel_y += rand(-2,30) + var/starnum = pick("1", "1", "1", "2", "3", "4") - icon_state = "star"+starnum + icon_state = "star"+starnum - speed = rand(2, 5) + speed = rand(2, 5) - proc/startmove() +/obj/effect/bgstar/proc/startmove() - while(src) - sleep(speed) - step(src, direction) - for(var/obj/effect/starender/E in loc) - del(src) + while(src) + sleep(speed) + step(src, direction) + for(var/obj/effect/starender/E in loc) + del(src) /obj/effect/starender @@ -461,16 +462,16 @@ datum/shuttle_controller var/spawndir = SOUTH var/spawning = 0 - West - spawndir = WEST +/obj/effect/starspawner/West + spawndir = WEST - proc/startspawn() - spawning = 1 - while(spawning) - sleep(rand(2, 30)) - var/obj/effect/bgstar/S = new/obj/effect/bgstar(locate(x,y,z)) - S.direction = spawndir - spawn() - S.startmove() +/obj/effect/starspawner/proc/startspawn() + spawning = 1 + while(spawning) + sleep(rand(2, 30)) + var/obj/effect/bgstar/S = new/obj/effect/bgstar(locate(x,y,z)) + S.direction = spawndir + spawn() + S.startmove() diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 904761eba83..1a7d97e99cf 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -58,6 +58,10 @@ G.fields["sex"] = H.gender G.fields["species"] = H.get_species() G.fields["photo"] = get_id_photo(H) + if(H.gen_record && !jobban_isbanned(H, "Records")) + G.fields["notes"] = H.gen_record + else + G.fields["notes"] = "No notes found." general += G //Medical Record @@ -119,20 +123,7 @@ proc/get_id_photo(var/mob/living/carbon/human/H) if (H.gender == FEMALE) g = "f" - var/icon/icobase - switch(H.get_species()) - if("Tajaran") - icobase = 'icons/mob/human_races/r_tajaran.dmi' - if("Unathi") - icobase = 'icons/mob/human_races/r_lizard.dmi' - if("Skrell") - icobase = 'icons/mob/human_races/r_skrell.dmi' - - if("Vox") - icobase = 'icons/mob/human_races/r_vox.dmi' - - else - icobase = 'icons/mob/human_races/r_human.dmi' + var/icon/icobase = H.species.icobase preview_icon = new /icon(icobase, "torso_[g]") var/icon/temp @@ -149,15 +140,13 @@ proc/get_id_photo(var/mob/living/carbon/human/H) preview_icon.Blend(temp, ICON_OVERLAY) // Skin tone - if(H.get_species() == "Human") + if(H.species.flags & HAS_SKIN_TONE) if (H.s_tone >= 0) preview_icon.Blend(rgb(H.s_tone, H.s_tone, H.s_tone), ICON_ADD) else preview_icon.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT) - var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes_s") - if(H.get_species()=="Vox") - eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "vox_eyes_s") + var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.species ? H.species.eyes : "eyes_s") eyes_s.Blend(rgb(H.r_eyes, H.g_eyes, H.b_eyes), ICON_ADD) diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 81abf92546a..517c6d0931e 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -256,9 +256,12 @@ client body += "" body += "" + body += "" + body += "" if(ishuman(D)) body += "" body += "" + body += "" body += "" body += "" body += "" @@ -743,6 +746,67 @@ client H.dna.mutantrace = new_mutantrace H.update_mutantrace() + else if(href_list["setspecies"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["setspecies"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + var/new_species = input("Please choose a new species.","Species",null) as null|anything in all_species + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.set_species(new_species)) + usr << "Set species of [H] to [H.species]." + else + usr << "Failed! Something went wrong." + + else if(href_list["addlanguage"]) + if(!check_rights(R_SPAWN)) return + + var/mob/H = locate(href_list["addlanguage"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + + var/new_language = input("Please choose a language to add.","Language",null) as null|anything in all_languages + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.add_language(new_language)) + usr << "Added [new_language] to [H]." + else + usr << "Mob already knows that language." + + else if(href_list["remlanguage"]) + if(!check_rights(R_SPAWN)) return + + var/mob/H = locate(href_list["remlanguage"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + + if(!H.languages.len) + usr << "This mob knows no languages." + return + + var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.remove_language(rem_language.name)) + usr << "Removed [rem_language] from [H]." + else + usr << "Mob doesn't know that language." + else if(href_list["regenerateicons"]) if(!check_rights(0)) return diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 57ddf7817e5..b3b03e6ac26 100755 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -356,10 +356,12 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/storage/firstaid/fire, /obj/item/weapon/storage/firstaid/toxin, /obj/item/weapon/storage/firstaid/o2, + /obj/item/weapon/storage/firstaid/adv, /obj/item/weapon/reagent_containers/glass/bottle/antitoxin, /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline, /obj/item/weapon/reagent_containers/glass/bottle/stoxin, - /obj/item/weapon/storage/box/syringes) + /obj/item/weapon/storage/box/syringes, + /obj/item/weapon/storage/box/autoinjectors) cost = 10 containertype = /obj/structure/closet/crate/medical containername = "Medical crate" diff --git a/code/defines/obj/hydro.dm b/code/defines/obj/hydro.dm index 9e26cb48fdb..bfea9a3b22b 100644 --- a/code/defines/obj/hydro.dm +++ b/code/defines/obj/hydro.dm @@ -81,30 +81,6 @@ plant_type = 2 growthstages = 3 -/obj/item/seeds/replicapod - name = "pack of replica pod seeds" - desc = "These seeds grow into replica pods. They say these are used to harvest humans." - icon_state = "seed-replicapod" - mypath = "/obj/item/seeds/replicapod" - species = "replicapod" - plantname = "Replica Pod" - productname = "/mob/living/carbon/human" //verrry special -- Urist - lifespan = 50 //no idea what those do - endurance = 8 - maturation = 10 - production = 10 - yield = 1 //seeds if there isn't a dna inside - oneharvest = 1 - potency = 30 - plant_type = 0 - growthstages = 6 - var/ui = null //for storing the guy - var/se = null - var/ckey = null - var/realName = null - var/datum/mind/mind = null - gender = MALE - /obj/item/seeds/grapeseed name = "pack of grape seeds" desc = "These seeds grow into grape vines." diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index bd57ca478c4..5064113e153 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -557,6 +557,13 @@ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) return ..() +/obj/item/weapon/hatchet/unathiknife + name = "duelling knife" + desc = "A length of leather-bound wood studded with razor-sharp teeth. How crude." + icon = 'icons/obj/weapons.dmi' + icon_state = "unathiknife" + attack_verb = list("ripped", "torn", "cut") + /obj/item/weapon/scythe icon_state = "scythe0" name = "scythe" diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 049d7f0cd70..fd034fbf5ae 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -309,6 +309,11 @@ proc/process_ghost_teleport_locs() /area/shuttle/research/outpost icon_state = "shuttle" +/area/shuttle/vox/station + name = "\improper Vox Skipjack" + icon_state = "yellow" + requires_power = 0 + /area/airtunnel1/ // referenced in airtunnel.dm:759 /area/dummy/ // Referenced in engine.dm:261 @@ -489,10 +494,29 @@ proc/process_ghost_teleport_locs() icon_state = "yellow" requires_power = 0 +/area/vox_station/transit + name = "\improper hyperspace" + icon_state = "shuttle" +/area/vox_station/southwest_solars + name = "\improper aft port solars" + icon_state = "southwest" +/area/vox_station/northwest_solars + name = "\improper fore port solars" + icon_state = "northwest" +/area/vox_station/northeast_solars + name = "\improper fore starboard solars" + icon_state = "northeast" +/area/vox_station/southeast_solars + name = "\improper aft starboard solars" + icon_state = "southeast" + +/area/vox_station/mining + name = "\improper nearby mining asteroid" + icon_state = "north" //PRISON /area/prison diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index c0921cd54a1..6695fe44027 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -45,8 +45,13 @@ poweralm = state if(istype(source)) //Only report power alarms on the z-level where the source is located. var/list/cameras = list() - for (var/obj/machinery/camera/C in src) - cameras += C + for (var/area/RA in related) + for (var/obj/machinery/camera/C in RA) + cameras += C + if(state == 1) + C.network.Remove("Power Alarms") + else + C.network.Add("Power Alarms") for (var/mob/living/silicon/aiPlayer in player_list) if(aiPlayer.z == source.z) if (state == 1) @@ -73,11 +78,15 @@ //updateicon() for(var/obj/machinery/camera/C in RA) cameras += C + C.network.Add("Atmosphere Alarms") for(var/mob/living/silicon/aiPlayer in player_list) aiPlayer.triggerAlarm("Atmosphere", src, cameras, src) for(var/obj/machinery/computer/station_alert/a in machines) a.triggerAlarm("Atmosphere", src, cameras, src) else if (atmosalm == 2) + for(var/area/RA in related) + for(var/obj/machinery/camera/C in RA) + C.network.Remove("Atmosphere Alarms") for(var/mob/living/silicon/aiPlayer in player_list) aiPlayer.cancelAlarm("Atmosphere", src, src) for(var/obj/machinery/computer/station_alert/a in machines) @@ -101,8 +110,10 @@ spawn() D.close() var/list/cameras = list() - for (var/obj/machinery/camera/C in src) - cameras += C + for(var/area/RA in related) + for (var/obj/machinery/camera/C in RA) + cameras.Add(C) + C.network.Add("Fire Alarms") for (var/mob/living/silicon/ai/aiPlayer in player_list) aiPlayer.triggerAlarm("Fire", src, cameras, src) for (var/obj/machinery/computer/station_alert/a in machines) @@ -120,6 +131,9 @@ else if(D.density) spawn(0) D.open() + for(var/area/RA in related) + for (var/obj/machinery/camera/C in RA) + C.network.Remove("Fire Alarms") for (var/mob/living/silicon/ai/aiPlayer in player_list) aiPlayer.cancelAlarm("Fire", src, src) for (var/obj/machinery/computer/station_alert/a in machines) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 784ba44c188..d160e662e84 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -490,7 +490,7 @@ its easier to just keep the beam vertical. var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblClickNew() proc is being tested) -/atom/proc/DblClickNew() +/*/atom/proc/DblClickNew() if(!usr) return // TODO DOOHL: Intergrate params to new proc. Saved for another time because var/valid_place is a fucking brainfuck @@ -792,7 +792,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl if (in_range) if ( !animal.restrained() ) - attack_animal(animal) + attack_animal(animal)*/ /atom/DblClick(location, control, params) //TODO: DEFERRED: REWRITE if(!usr) return @@ -943,9 +943,9 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl // ------- ( CAN USE ITEM OR HAS 1 SECOND USE DELAY ) AND NOT CLICKING ON SCREEN ------- - if (usr.next_move < world.time) - usr.prev_move = usr.next_move - usr.next_move = world.time + 10 + if (usr.last_click + usr.click_delay < world.time) + usr.last_click = world.time + usr.click_delay = 0 else // ------- ALREADY USED ONE ITEM WITH USE DELAY IN THE PREVIOUS SECOND ------- return @@ -1109,10 +1109,9 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl // ------- ITEM INACESSIBLE OR CLICKING ON SCREEN ------- if (istype(src, /obj/screen)) // ------- IT'S THE HUD YOU'RE CLICKING ON ------- - usr.prev_move = usr.next_move - usr:lastDblClick = world.time + 2 - if (usr.next_move < world.time) - usr.next_move = world.time + 2 + usr.delay_click(2) + if (usr.last_click + usr.click_delay < world.time) + usr.last_click = world.time else return @@ -1144,7 +1143,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl src.hand_al(usr, usr.hand) else // ------- YOU ARE CLICKING ON AN OBJECT THAT'S INACCESSIBLE TO YOU AND IS NOT YOUR HUD ------- - if((LASER in usr:mutations) && usr:a_intent == "hurt" && world.time >= usr.next_move) + if((LASER in usr:mutations) && usr:a_intent == "hurt" && usr.last_click + usr.click_delay < world.time) // ------- YOU HAVE THE LASER MUTATION, YOUR INTENT SET TO HURT AND IT'S BEEN MORE THAN A DECISECOND SINCE YOU LAS TATTACKED ------- var/turf/T = get_turf(usr) @@ -1169,7 +1168,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl spawn( 1 ) A.process() - usr.next_move = world.time + 6 + usr.delay_click(6) return /atom/proc/ShiftClick(var/mob/M as mob) diff --git a/code/game/communications.dm b/code/game/communications.dm index 94d53f6bf52..32d8ca69348 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -74,7 +74,6 @@ Radio: 1359 - Security 1441 - death squad 1443 - Confession Intercom -1349 - Miners 1347 - Cargo techs Devices: @@ -110,10 +109,21 @@ var/list/radiochannels = list( "Supply" = 1347, ) //depenging helpers -var/list/DEPT_FREQS = list(1351,1355,1357,1359,1213, 1443, 1441,1347) +var/list/DEPT_FREQS = list(1351, 1355, 1357, 1359, 1213, 1443, 1441, 1347) + +// central command channels, i.e deathsquid & response teams +var/list/CENT_FREQS = list(1441, 1443) + var/const/COMM_FREQ = 1353 //command, colored gold in chat window var/const/SYND_FREQ = 1213 +// department channels +var/const/SEC_FREQ = 1359 +var/const/ENG_FREQ = 1357 +var/const/SCI_FREQ = 1351 +var/const/MED_FREQ = 1355 +var/const/SUP_FREQ = 1347 + #define TRANSMISSION_WIRE 0 #define TRANSMISSION_RADIO 1 diff --git a/code/game/dna.dm b/code/game/dna.dm index cb58013e016..13f90e7d506 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -550,15 +550,11 @@ var/mob/living/carbon/monkey/O = null - switch(M.dna.mutantrace) - if("tajaran") - O = new /mob/living/carbon/monkey/tajara(src) - if("lizard") - O = new /mob/living/carbon/monkey/unathi(src) - if("skrell") - O = new /mob/living/carbon/monkey/skrell(src) - else - O = new /mob/living/carbon/monkey(src) + if(H.species.primitive) + O = new H.species.primitive(src) + else + H.gib() //Trying to change the species of a creature with no primitive var set is messy. + return if(M) if (M.dna) @@ -626,6 +622,9 @@ del(animation) var/mob/living/carbon/human/O = new( src ) + if(Mo.greaterform) + O.set_species(Mo.greaterform) + if (isblockon(getblock(M.dna.uni_identity, 11,3),11)) O.gender = FEMALE else diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 7cca20dfac0..e53053764b2 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -6,7 +6,7 @@ var/list/blob_cores = list() var/list/blob_nodes = list() -/datum/game_mode/blob +/*/datum/game_mode/blob name = "blob" config_tag = "blob" required_players = 0 @@ -130,3 +130,4 @@ var/list/blob_nodes = list() stage = 3 return +*/ \ No newline at end of file diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 904e7570e4b..a78e8dd8ae0 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -278,6 +278,7 @@ Implants; if(BE_REV) roletext="revolutionary" if(BE_CULTIST) roletext="cultist" if(BE_NINJA) roletext="ninja" + if(BE_RAIDER) roletext="raider" // Assemble a list of active players without jobbans. for(var/mob/new_player/player in player_list) diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm new file mode 100644 index 00000000000..5a1e12a191b --- /dev/null +++ b/code/game/gamemodes/heist/heist.dm @@ -0,0 +1,257 @@ +/* +VOX HEIST ROUNDTYPE +*/ + +#define MAX_VOX_KILLS 10 //Number of kills during the round before the Inviolate is broken. + //Would be nice to use vox-specific kills but is currently not feasible. + +var/global/vox_kills = 0 //Used to check the Inviolate. + +/datum/game_mode/ + var/list/datum/mind/raiders = list() //Antags. + +/datum/game_mode/heist + name = "heist" + config_tag = "heist" + required_players = 15 + required_players_secret = 25 + required_enemies = 4 + recommended_enemies = 6 + + var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) + var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) + + var/list/raid_objectives = list() //Raid objectives. + var/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective. + +/datum/game_mode/heist/announce() + world << "The current game mode is - Heist!" + world << "An unidentified bluespace signature has slipped past the Icarus and is approaching [station_name()]!" + world << "Whoever they are, they're likely up to no good. Protect the crew and station resources against this dastardly threat!" + world << "Raiders: Loot [station_name()] for anything and everything you need." + world << "Personnel: Repel the raiders and their low, low prices and/or crossbows." + +/datum/game_mode/heist/can_start() + + if(!..()) + return 0 + + var/list/candidates = get_players_for_role(BE_RAIDER) + var/raider_num = 0 + + //Check that we have enough vox. + if(candidates.len < required_enemies) + return 0 + else if(candidates.len < recommended_enemies) + raider_num = candidates.len + else + raider_num = recommended_enemies + + //Grab candidates randomly until we have enough. + while(raider_num > 0) + var/datum/mind/new_raider = pick(candidates) + raiders += new_raider + candidates -= new_raider + raider_num-- + + for(var/datum/mind/raider in raiders) + raider.assigned_role = "MODE" + raider.special_role = "Vox Raider" + return 1 + +/datum/game_mode/heist/pre_setup() + return 1 + +/datum/game_mode/heist/post_setup() + + //Build a list of spawn points. + var/list/turf/raider_spawn = list() + + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == "voxstart") + raider_spawn += get_turf(L) + del(L) + continue + + //Generate objectives for the group. + raid_objectives = forge_vox_objectives() + + var/index = 1 + + //Spawn the vox! + for(var/datum/mind/raider in raiders) + + if(index > raider_spawn.len) + index = 1 + + raider.current.loc = raider_spawn[index] + index++ + + var/sounds = rand(2,8) + var/i = 0 + var/newname = "" + + while(i<=sounds) + i++ + newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah")) + + var/mob/living/carbon/human/vox = raider.current + + vox.real_name = capitalize(newname) + vox.name = vox.real_name + vox.age = rand(12,20) + vox.dna.mutantrace = "vox" + vox.set_species("Vox") + vox.add_language("Vox-pidgin") + vox.h_style = "Short Vox Quills" + vox.flavor_text = "" + for(var/datum/organ/external/limb in vox.organs) + limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) + vox.equip_vox_raider() + vox.regenerate_icons() + + raider.objectives = raid_objectives + greet_vox(raider) + + spawn (rand(waittime_l, waittime_h)) + send_intercept() + +/datum/game_mode/heist/proc/is_raider_crew_safe() + + if(cortical_stacks.len == 0) + return 0 + + for(var/obj/stack in cortical_stacks) + if (get_area(stack) != locate(/area/shuttle/vox/station)) + return 0 + return 1 + +/datum/game_mode/heist/proc/is_raider_crew_alive() + + for(var/datum/mind/raider in raiders) + if(raider.current) + if(istype(raider.current,/mob/living/carbon/human) && raider.current.stat != 2) + return 1 + return 0 + +/datum/game_mode/heist/proc/forge_vox_objectives() + + + //Commented out for testing. + /* var/i = 1 + var/max_objectives = pick(2,2,2,3,3) + var/list/objs = list() + while(i<= max_objectives) + var/list/goals = list("kidnap","loot","salvage") + var/goal = pick(goals) + var/datum/objective/heist/O + + if(goal == "kidnap") + goals -= "kidnap" + O = new /datum/objective/heist/kidnap() + else if(goal == "loot") + O = new /datum/objective/heist/loot() + else + O = new /datum/objective/heist/salvage() + O.choose_target() + objs += O + + i++ + + //-All- vox raids have these two objectives. Failing them loses the game. + objs += new /datum/objective/heist/inviolate_crew + objs += new /datum/objective/heist/inviolate_death */ + + raid_objectives += new /datum/objective/heist/kidnap + raid_objectives += new /datum/objective/heist/loot + raid_objectives += new /datum/objective/heist/salvage + raid_objectives += new /datum/objective/heist/inviolate_crew + raid_objectives += new /datum/objective/heist/inviolate_death + + for(var/datum/objective/heist/O in raid_objectives) + O.choose_target() + + return raid_objectives + +/datum/game_mode/heist/proc/greet_vox(var/datum/mind/raider) + raider.current << "\blue You are a Vox Raider, fresh from the Shoal!" + raider.current << "\blue The Vox are a race of cunning, sharp-eyed nomadic raiders and traders endemic to Tau Ceti and much of the unexplored galaxy. You and the crew have come to the Exodus for plunder, trade or both." + raider.current << "\blue Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious." + raider.current << "\blue Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!" + var/obj_count = 1 + for(var/datum/objective/objective in raider.objectives) + raider.current << "Objective #[obj_count]: [objective.explanation_text]" + obj_count++ + + +/datum/game_mode/heist/declare_completion() + + //No objectives, go straight to the feedback. + if(!(raid_objectives.len)) return ..() + + var/win_type = "Major" + var/win_group = "Crew" + var/win_msg = "" + + var/success = raid_objectives.len + + //Decrease success for failed objectives. + for(var/datum/objective/O in raid_objectives) + if(!(O.check_completion())) success-- + + //Set result by objectives. + if(success == raid_objectives.len) + win_type = "Major" + win_group = "Vox" + else if(success > 2) + win_type = "Minor" + win_group = "Vox" + else + win_type = "Minor" + win_group = "Crew" + + //Now we modify that result by the state of the vox crew. + if(!is_raider_crew_alive()) + + win_type = "Major" + win_group = "Crew" + win_msg += "The Vox Raiders have been wiped out!" + + else if(!is_raider_crew_safe()) + + if(win_group == "Crew" && win_type == "Minor") + win_type = "Major" + + win_group = "Crew" + win_msg += "The Vox Raiders have left someone behind!" + + else + + if(win_group == "Vox") + if(win_type == "Minor") + + win_type = "Major" + win_msg += "The Vox Raiders escaped the station!" + else + win_msg += "The Vox Raiders were repelled!" + + world << "\red [win_type] [win_group] victory!" + world << "[win_msg]" + feedback_set_details("round_end_result","heist - [win_type] [win_group]") + + var/count = 1 + for(var/datum/objective/objective in raid_objectives) + if(objective.check_completion()) + world << "
Objective #[count]: [objective.explanation_text] Success!" + feedback_add_details("traitor_objective","[objective.type]|SUCCESS") + else + world << "
Objective #[count]: [objective.explanation_text] Fail." + feedback_add_details("traitor_objective","[objective.type]|FAIL") + count++ + + ..() + +/datum/game_mode/heist/check_finished() + if (!(is_raider_crew_alive()) || (vox_shuttle_location && (vox_shuttle_location == "start"))) + return 1 + return ..() \ No newline at end of file diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 1b3552408c5..3d154485133 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -742,3 +742,173 @@ datum/objective/absorb /*-------ENDOF CULTIST------*/ */ + +//Vox heist objectives. + +datum/objective/heist + proc/choose_target() + return + +datum/objective/heist/kidnap + choose_target() + var/list/roles = list("Chief Engineer","Research Director","Roboticist","Chemist","Station Engineer") + var/list/possible_targets = list() + var/list/priority_targets = list() + + for(var/datum/mind/possible_target in ticker.minds) + if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && (possible_target.assigned_role != "MODE")) + possible_targets += possible_target + for(var/role in roles) + if(possible_target.assigned_role == role) + priority_targets += possible_target + continue + + if(priority_targets.len > 0) + target = pick(priority_targets) + else if(possible_targets.len > 0) + target = pick(possible_targets) + + if(target && target.current) + explanation_text = "The Shoal has a need for [target.current.real_name], the [target.assigned_role]. Take them alive." + else + explanation_text = "Free Objective" + return target + + check_completion() + if(target && target.current) + if (target.current.stat == 2) + return 0 // They're dead. Fail. + //if (!target.current.restrained()) + // return 0 // They're loose. Close but no cigar. + + var/area/shuttle/vox/station/A = locate() + for(var/mob/living/carbon/human/M in A) + if(target.current == M) + return 1 //They're restrained on the shuttle. Success. + else + return 0 + +datum/objective/heist/loot + + choose_target() + var/loot = "an object" + switch(rand(1,8)) + if(1) + target = /obj/structure/particle_accelerator + target_amount = 6 + loot = "a complete particle accelerator" + if(2) + target = /obj/machinery/the_singularitygen + target_amount = 1 + loot = "a gravitational generator" + if(3) + target = /obj/machinery/power/emitter + target_amount = 4 + loot = "four emitters" + if(4) + target = /obj/machinery/nuclearbomb + target_amount = 1 + loot = "a nuclear bomb" + if(5) + target = /obj/item/weapon/gun + target_amount = 6 + loot = "six guns" + if(6) + target = /obj/item/weapon/gun/energy + target_amount = 4 + loot = "four energy guns" + if(7) + target = /obj/item/weapon/gun/energy/laser + target_amount = 2 + loot = "two laser guns" + if(8) + target = /obj/item/weapon/gun/energy/ionrifle + target_amount = 1 + loot = "an ion gun" + + explanation_text = "We are lacking in hardware. Steal [loot]." + + check_completion() + + var/total_amount = 0 + + for(var/obj/O in locate(/area/shuttle/vox/station)) + if(istype(O,target)) total_amount++ + if(total_amount >= target_amount) return 1 + + var/datum/game_mode/heist/H = ticker.mode + for(var/datum/mind/raider in H.raiders) + if(raider.current) + for(var/obj/O in raider.current.get_contents()) + if(istype(O,target)) total_amount++ + if(total_amount >= target_amount) return 1 + + return 0 + +datum/objective/heist/salvage + + choose_target() + switch(rand(1,8)) + if(1) + target = "metal" + target_amount = 300 + if(2) + target = "glass" + target_amount = 200 + if(3) + target = "plasteel" + target_amount = 100 + if(4) + target = "plasma" + target_amount = 100 + if(5) + target = "silver" + target_amount = 50 + if(6) + target = "gold" + target_amount = 20 + if(7) + target = "uranium" + target_amount = 20 + if(8) + target = "diamond" + target_amount = 20 + + explanation_text = "Ransack the station and escape with [target_amount] [target]." + + check_completion() + + var/total_amount = 0 + + for(var/obj/item/O in locate(/area/shuttle/vox/station)) + if(istype(O,/obj/item/stack/sheet)) + if(O.name == target) + var/obj/item/stack/sheet/S = O + total_amount += S.amount + + var/datum/game_mode/heist/H = ticker.mode + for(var/datum/mind/raider in H.raiders) + if(raider.current) + for(var/obj/item/O in raider.current.get_contents()) + if(istype(O,/obj/item/stack/sheet)) + if(O.name == target) + var/obj/item/stack/sheet/S = O + total_amount += S.amount + + if(total_amount >= target_amount) return 1 + return 0 + + +datum/objective/heist/inviolate_crew + explanation_text = "Do not leave any Vox behind, alive or dead." + + check_completion() + var/datum/game_mode/heist/H = ticker.mode + if(H.is_raider_crew_safe()) return 1 + return 0 + +datum/objective/heist/inviolate_death + explanation_text = "Follow the Inviolate. Minimise death and loss of resources." + check_completion() + if(vox_kills>5) return 0 + return 1 \ No newline at end of file diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index cacd825d017..22dd096bcca 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -28,7 +28,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/heads/cmo(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/cmo(H), slot_wear_suit) - H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(H), slot_l_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand) H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store) if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) @@ -88,7 +88,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/medical(H), slot_belt) - H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(H), slot_l_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand) H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store) if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 9f9ff56f780..a4158218a1e 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -70,12 +70,14 @@ dat += text("[]\t-Burn Severity %: []
", (occupant.getFireLoss() < 60 ? "" : ""), occupant.getFireLoss()) dat += text("
Paralysis Summary %: [] ([] seconds left!)
", occupant.paralysis, round(occupant.paralysis / 4)) if(occupant.reagents) - dat += text("Inaprovaline units: [] units
", occupant.reagents.get_reagent_amount("inaprovaline")) - dat += text("Soporific: [] units
", occupant.reagents.get_reagent_amount("stoxin")) - dat += text("Dermaline: [] units
", occupant.reagents.get_reagent_amount("dermaline")) - dat += text("Bicaridine: [] units
", occupant.reagents.get_reagent_amount("bicaridine")) - dat += text("Dexalin: [] units
", occupant.reagents.get_reagent_amount("dexalin")) - dat += text("
Refresh meter readings each second
Inject Inaprovaline
Inject Soporific
Inject Dermaline
Inject Bicaridine
Inject Dexalin", src, src, src, src, src, src) + for(var/chemical in connected.available_chemicals) + dat += "[connected.available_chemicals[chemical]]: [occupant.reagents.get_reagent_amount(chemical)] units
" + dat += "
Refresh meter readings each second
" + for(var/chemical in connected.available_chemicals) + dat += "Inject [connected.available_chemicals[chemical]]: " + for(var/amount in connected.amounts) + dat += "[amount] units " + dat += "
" else dat += "The sleeper is empty." dat += text("

Close", user) @@ -88,27 +90,15 @@ return if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) usr.set_machine(src) - if (src.connected) - if (src.connected.occupant) - if(src.connected.occupant.health > 0) - if (href_list["inap"]) - src.connected.inject_inap(usr) - if (href_list["stox"]) - src.connected.inject_stox(usr) - if (href_list["derm"]) - src.connected.inject_dermaline(usr) - if (href_list["bic"]) - src.connected.inject_bicaridine(usr) - if (href_list["dex"]) - src.connected.inject_dexalin(usr) - else - if(src.connected.occupant.health > -100) - if (href_list["inap"]) - src.connected.inject_inap(usr) - if (href_list["stox"] || href_list["derm"] || href_list["bic"] || href_list["dex"]) - usr << "\red \b this person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!" - else + if (href_list["chemical"]) + if (src.connected) + if (src.connected.occupant) + if (src.connected.occupant.stat == DEAD) usr << "\red \b This person has no life for to preserve anymore. Take them to a department capable of reanimating them." + else if(src.connected.occupant.health > 0 || href_list["chemical"] == "inaprovaline") + src.connected.inject_chemical(usr,href_list["chemical"],text2num(href_list["amount"])) + else + usr << "\red \b This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!" if (href_list["refresh"]) src.updateUsrDialog() src.add_fingerprint(usr) @@ -142,6 +132,8 @@ anchored = 1 var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r" var/mob/living/occupant = null + var/available_chemicals = list("inaprovaline" = "Inaprovaline", "stoxin" = "Soporific", "dermaline" = "Dermaline", "bicaridine" = "Bicaridine", "dexalin" = "Dexalin") + var/amounts = list(10, 20) New() @@ -275,53 +267,13 @@ return - proc/inject_inap(mob/living/user as mob) + proc/inject_chemical(mob/living/user as mob, chemical, amount) if(src.occupant && src.occupant.reagents) - if(src.occupant.reagents.get_reagent_amount("inaprovaline") + 30 <= 60) - src.occupant.reagents.add_reagent("inaprovaline", 30) - user << text("Occupant now has [] units of Inaprovaline in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("inaprovaline")) - else - user << "There's no occupant in the sleeper or the subject rejects the chemicals!" - return - - - proc/inject_stox(mob/living/user as mob) - if(src.occupant && src.occupant.reagents) - if(src.occupant.reagents.get_reagent_amount("stoxin") + 20 <= 40) - src.occupant.reagents.add_reagent("stoxin", 20) - user << text("Occupant now has [] units of soporifics in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("stoxin")) - else - user << "There's no occupant in the sleeper or the subject rejects the chemicals!" - return - - - proc/inject_dermaline(mob/living/user as mob) - if(src.occupant && src.occupant.reagents) - if(src.occupant.reagents.get_reagent_amount("dermaline") + 20 <= 40) - src.occupant.reagents.add_reagent("dermaline", 20) - user << text("Occupant now has [] units of Dermaline in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("dermaline")) - else - user << "There's no occupant in the sleeper or the subject rejects the chemicals!" - return - - - proc/inject_bicaridine(mob/living/user as mob) - if(src.occupant && src.occupant.reagents) - if(src.occupant.reagents.get_reagent_amount("bicaridine") + 10 <= 20) - src.occupant.reagents.add_reagent("bicaridine", 10) - user << text("Occupant now has [] units of Bicaridine in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("bicaridine")) - else - user << "There's no occupant in the sleeper or the subject rejects the chemicals!" - return - - - proc/inject_dexalin(mob/living/user as mob) - if(src.occupant && src.occupant.reagents) - if(src.occupant.reagents.get_reagent_amount("dexalin") + 20 <= 40) - src.occupant.reagents.add_reagent("dexalin", 20) - user << text("Occupant now has [] units of Dexalin in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("dexalin")) - else - user << "There's no occupant in the sleeper or the subject rejects the chemicals!" + if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= 40) + src.occupant.reagents.add_reagent(chemical, amount) + user << "Occupant now has [src.occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in his/her bloodstream." + return + user << "There's no occupant in the sleeper or the subject rejects the chemicals!" return @@ -398,4 +350,4 @@ del(O) src.add_fingerprint(usr) return - return + return \ No newline at end of file diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index ec48cf76cc4..ea2456cf977 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -1479,8 +1479,7 @@ FIRE ALARM A = A.loc if (!( istype(A, /area) )) return - for(var/area/RA in A.related) - RA.firereset() + A.firereset() update_icon() return @@ -1491,8 +1490,7 @@ FIRE ALARM A = A.loc if (!( istype(A, /area) )) return - for(var/area/RA in A.related) - RA.firealert() + A.firealert() update_icon() //playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0) return diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index 47b27ac54bd..d0345f60905 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -233,7 +233,8 @@ text("[src.oddbutton ? "Yes" : "No" if(target && path.len == 0) spawn(0) if(!src || !target) return - src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, 0, 30) + src.path = AStar(src.loc, src.target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id=botcard) + if (!path) path = list() if(src.path.len == 0) src.oldtarget = src.target src.target = null diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 5e5ae744068..d71a43c083e 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -615,6 +615,7 @@ Auto Patrol: []"}, // given an optional turf to avoid /obj/machinery/bot/ed209/proc/calc_path(var/turf/avoid = null) src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid) + if (!src.path) src.path = list() // look for a criminal in view of the bot diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm index bb984a1787b..69fc5afd3f3 100644 --- a/code/game/machinery/bots/floorbot.dm +++ b/code/game/machinery/bots/floorbot.dm @@ -241,9 +241,10 @@ if(src.target && (src.target != null) && src.path.len == 0) spawn(0) if(!istype(src.target, /turf/)) - src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30) + src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30, id=botcard) else - src.path = AStar(src.loc, src.target, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30) + src.path = AStar(src.loc, src.target, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30, id=botcard) + if (!src.path) src.path = list() if(src.path.len == 0) src.oldtarget = src.target src.target = null diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index c67a5a77b19..d5408d33308 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -87,6 +87,9 @@ usr << "No network found please hang up and try your call again." return + var/temptag = "[get_area(src)] ([rand(1, 999)])" + input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag)) + state = 4 var/obj/machinery/camera/C = new(src.loc) src.loc = C @@ -94,9 +97,12 @@ C.auto_turn() - C.network = tempnetwork + C.network = uniquelist(tempnetwork) + tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS) + if(!tempnetwork.len)//Camera isn't on any open network - remove its chunk from AI visibility. + cameranet.removeCamera(C) - C.c_tag = "[get_area_name(src)] ([rand(1, 999)]" + C.c_tag = input for(var/i = 5; i >= 0; i -= 1) var/direct = input(user, "Direction?", "Assembling Camera", null) in list("LEAVE IT", "NORTH", "EAST", "SOUTH", "WEST" ) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 124239dc82b..fd66d0c2c32 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -116,7 +116,7 @@ //Clonepod //Start growing a human clone in the pod! -/obj/machinery/clonepod/proc/growclone(var/ckey, var/clonename, var/ui, var/se, var/mindref, var/mrace) +/obj/machinery/clonepod/proc/growclone(var/ckey, var/clonename, var/ui, var/se, var/mindref, var/datum/species/mrace) if(mess || attempting) return 0 var/datum/mind/clonemind = locate(mindref) @@ -191,13 +191,11 @@ randmutb(H) //Sometimes the clones come out wrong. H.f_style = "Shaved" - if(mrace == "none") //no more xenos losing ears/tentacles + if(mrace.name == "Human") //no more xenos losing ears/tentacles H.h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") - if(H.dna) - H.dna.mutantrace = mrace - H.update_mutantrace() - H.update_mutantrace_languages() + H.species = mrace + H.update_mutantrace() H.suiciding = 0 src.attempting = 0 return 1 diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 2081a640d8e..7dca0ae01fb 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -37,6 +37,10 @@ /obj/item/weapon/circuitboard/security name = "Circuit board (Security)" build_path = "/obj/machinery/computer/security" + var/network = list("SS13") + req_access = list(access_security) + var/locked = 1 + var/emagged = 0 /obj/item/weapon/circuitboard/aicore name = "Circuit board (AI core)" origin_tech = "programming=4;biotech=2" @@ -80,6 +84,9 @@ /obj/item/weapon/circuitboard/secure_data name = "Circuit board (Security Records)" build_path = "/obj/machinery/computer/secure_data" +/obj/item/weapon/circuitboard/skills + name = "Circuit board (Employment Records)" + build_path = "/obj/machinery/computer/skills" /obj/item/weapon/circuitboard/stationalert name = "Circuit board (Station Alerts)" build_path = "/obj/machinery/computer/station_alert" @@ -166,10 +173,6 @@ name = "Circuit board (Operating Computer)" build_path = "/obj/machinery/computer/operating" origin_tech = "programming=2;biotech=2" -/obj/item/weapon/circuitboard/mining - name = "Circuit board (Outpost Status Display)" - build_path = "/obj/machinery/computer/security/mining" - origin_tech = "programming=2" /obj/item/weapon/circuitboard/comm_monitor name = "Circuit board (Telecommunications Monitor)" build_path = "/obj/machinery/computer/telecomms/monitor" @@ -238,6 +241,40 @@ user << "DERP! BUG! Report this (And what you were doing to cause it) to Agouri" return +/obj/item/weapon/circuitboard/security/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I,/obj/item/weapon/card/emag)) + if(emagged) + user << "Circuit lock is already removed." + return + user << "\blue You override the circuit lock and open controls." + emagged = 1 + locked = 0 + else if(istype(I,/obj/item/weapon/card/id)) + if(emagged) + user << "\red Circuit lock does not respond." + return + if(check_access(I)) + locked = !locked + user << "\blue You [locked ? "" : "un"]lock the circuit controls." + else + user << "\red Access denied." + else if(istype(I,/obj/item/device/multitool)) + if(locked) + user << "\red Circuit controls are locked." + return + var/existing_networks = dd_list2text(network,",") + var/input = strip_html(input(usr, "Which networks would you like to connect this camera console circuit to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Multitool-Circuitboard interface", existing_networks)) + if(!input) + usr << "No input found please hang up and try your call again." + return + var/list/tempnetwork = text2list(input, ",") + tempnetwork = difflist(tempnetwork,RESTRICTED_CAMERA_NETWORKS,1) + if(tempnetwork.len < 1) + usr << "No network found please hang up and try your call again." + return + network = tempnetwork + return + /obj/item/weapon/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob) if(istype(I,/obj/item/weapon/screwdriver)) if(src.build_path == "/obj/machinery/computer/rdconsole/core") @@ -353,4 +390,8 @@ var/obj/machinery/computer/supplycomp/SC = B var/obj/item/weapon/circuitboard/supplycomp/C = circuit SC.can_order_contraband = C.contraband_enabled - del(src) + if(istype(circuit,/obj/item/weapon/circuitboard/security)) + var/obj/machinery/computer/security/C = B + var/obj/item/weapon/circuitboard/security/CB = circuit + C.network = CB.network + del(src) \ No newline at end of file diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 0e4caf97c3f..857d4169ea1 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -5,7 +5,6 @@ name = "Security Cameras" desc = "Used to access the various cameras on the station." icon_state = "cameras" - circuit = "/obj/item/weapon/circuitboard/security" var/obj/machinery/camera/current = null var/last_pic = 1.0 var/list/network = list("SS13") @@ -45,8 +44,7 @@ var/list/D = list() D["Cancel"] = "Cancel" for(var/obj/machinery/camera/C in L) - var/list/tempnetwork = C.network&network - if(tempnetwork.len) + if(can_access_camera(C)) D[text("[][]", C.c_tag, (C.status ? null : " (Deactivated)"))] = C var/t = input(user, "Which camera should you change to?") as null|anything in D @@ -61,24 +59,110 @@ return 0 if(C) - if ((get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) || !( C.can_use() )) && (!istype(user, /mob/living/silicon/ai))) - if(!C.can_use() && !isAI(user)) - src.current = null - return 0 - else - if(isAI(user)) - var/mob/living/silicon/ai/A = user - A.eyeobj.setLoc(get_turf(C)) - A.client.eye = A.eyeobj - else - src.current = C - use_power(50) - - spawn(5) - attack_hand(user) + switch_to_camera(user, C) + spawn(5) + attack_hand(user) return + proc/can_access_camera(var/obj/machinery/camera/C) + var/list/shared_networks = src.network & C.network + if(shared_networks.len) + return 1 + return 0 + proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C) + if ((get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) || !( C.can_use() )) && (!istype(user, /mob/living/silicon/ai))) + if(!C.can_use() && !isAI(user)) + src.current = null + return 0 + else + if(isAI(user)) + var/mob/living/silicon/ai/A = user + A.eyeobj.setLoc(get_turf(C)) + A.client.eye = A.eyeobj + else + src.current = C + use_power(50) + return 1 + + attackby(I as obj, user as mob) + if(istype(I, /obj/item/weapon/screwdriver)) + playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) + if(do_after(user, 20)) + if (stat & BROKEN) + user << "\blue The broken glass falls out." + var/obj/structure/computerframe/CF = new /obj/structure/computerframe(loc) + new /obj/item/weapon/shard(loc) + var/obj/item/weapon/circuitboard/security/CB = new /obj/item/weapon/circuitboard/security(CF) + CB.network = network + for (var/obj/C in src) + C.loc = loc + CF.circuit = CB + CF.state = 3 + CF.icon_state = "3" + CF.anchored = 1 + del(src) + else + user << "\blue You disconnect the monitor." + var/obj/structure/computerframe/CF = new /obj/structure/computerframe( loc ) + var/obj/item/weapon/circuitboard/security/CB = new /obj/item/weapon/circuitboard/security(CF) + CB.network = network + for (var/obj/C in src) + C.loc = loc + CF.circuit = CB + CF.state = 4 + CF.icon_state = "4" + CF.anchored = 1 + del(src) + else + attack_hand(user) + return + +//Camera control: moving. + proc/jump_on_click(var/mob/user,var/A) + if(user.machine != src) + return + var/obj/machinery/camera/jump_to + if(istype(A,/obj/machinery/camera)) + jump_to = A + else if(ismob(A)) + if(ishuman(A)) + jump_to = locate() in A:head + else if(isrobot(A)) + jump_to = A:camera + else if(isobj(A)) + jump_to = locate() in A + else if(isturf(A)) + var/best_dist = INFINITY + for(var/obj/machinery/camera/camera in get_area(A)) + if(!camera.can_use()) + continue + if(!can_access_camera(camera)) + continue + var/dist = get_dist(camera,A) + if(dist < best_dist) + best_dist = dist + jump_to = camera + if(isnull(jump_to)) + return + if(can_access_camera(jump_to)) + switch_to_camera(user,jump_to) +//Camera control: mouse. +/atom/DblClick() + ..() + if(istype(usr.machine,/obj/machinery/computer/security)) + var/obj/machinery/computer/security/console = usr.machine + console.jump_on_click(usr,src) +//Camera control: arrow keys. +/mob/Move(n,direct) + if(istype(machine,/obj/machinery/computer/security)) + var/obj/machinery/computer/security/console = machine + var/turf/T = get_turf(console.current) + for(var/i;i<10;i++) + T = get_step(T,direct) + console.jump_on_click(src,T) + return + ..(n,direct) /obj/machinery/computer/security/telescreen name = "Telescreen" @@ -87,7 +171,6 @@ icon_state = "telescreen" network = list("thunder") density = 0 - circuit = null /obj/machinery/computer/security/telescreen/update_icon() icon_state = initial(icon_state) @@ -100,10 +183,6 @@ desc = "Damn, they better have /tg/thechannel on these things." icon = 'icons/obj/status_display.dmi' icon_state = "entertainment" - network = list("thunder") - density = 0 - circuit = null - /obj/machinery/computer/security/wooden_tv name = "Security Cameras" @@ -116,4 +195,9 @@ desc = "Used to access the various cameras on the outpost." icon_state = "miningcameras" network = list("MINE") - circuit = "/obj/item/weapon/circuitboard/mining" + +/obj/machinery/computer/security/engineering + name = "Engineering Cameras" + desc = "Used to monitor fires and breaches." + icon_state = "engineeringcameras" + network = list("Power Alarms","Atmosphere Alarms","Fire Alarms") \ No newline at end of file diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index edb4882cd2b..e29097a0308 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -443,10 +443,7 @@ subject.dna.check_integrity() var/datum/data/record/R = new /datum/data/record( ) - if(subject.dna) - R.fields["mrace"] = subject.dna.mutantrace - else - R.fields["mrace"] = null + R.fields["mrace"] = subject.species R.fields["ckey"] = subject.ckey R.fields["name"] = subject.real_name R.fields["id"] = copytext(md5(subject.real_name), 2, 6) diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm new file mode 100644 index 00000000000..7613d711ce6 --- /dev/null +++ b/code/game/machinery/computer/skills.dm @@ -0,0 +1,419 @@ +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 + +/obj/machinery/computer/skills//TODO:SANITY + name = "Employment Records" + desc = "Used to view personnel's employment records" + icon_state = "medlaptop" + req_one_access = list(access_heads) + circuit = "/obj/item/weapon/circuitboard/skills" + var/obj/item/weapon/card/id/scan = null + var/authenticated = null + var/rank = null + var/screen = null + var/datum/data/record/active1 = null + var/a_id = null + var/temp = null + var/printing = null + var/can_change_id = 0 + var/list/Perp + var/tempname = null + //Sorting Variables + var/sortBy = "name" + var/order = 1 // -1 = Descending - 1 = Ascending + + +/obj/machinery/computer/skills/attackby(obj/item/O as obj, user as mob) + if(istype(O, /obj/item/weapon/card/id) && !scan) + usr.drop_item() + O.loc = src + scan = O + user << "You insert [O]." + ..() + +/obj/machinery/computer/skills/attack_ai(mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer/skills/attack_paw(mob/user as mob) + return attack_hand(user) + +//Someone needs to break down the dat += into chunks instead of long ass lines. +/obj/machinery/computer/skills/attack_hand(mob/user as mob) + if(..()) + return + if (src.z > 6) + user << "\red Unable to establish a connection: \black You're too far away from the station!" + return + var/dat + + if (temp) + dat = text("[]

Clear Screen", temp, src) + else + dat = text("Confirm Identity: []
", src, (scan ? text("[]", scan.name) : "----------")) + if (authenticated) + switch(screen) + if(1.0) + dat += {" +

"} + dat += text("Search Records
", src) + dat += text("New Record
", src) + dat += {" +

+ + + + +
Records:
+ + + + + + +"} + if(!isnull(data_core.general)) + for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order)) + for(var/datum/data/record/E in data_core.security) + var/background + dat += text("", background, src, R, R.fields["name"]) + dat += text("", R.fields["id"]) + dat += text("", R.fields["rank"]) + dat += text("", R.fields["fingerprint"]) + dat += "
NameIDRankFingerprints
[][][][]

" + dat += text("Record Maintenance

", src) + dat += text("{Log Out}",src) + if(2.0) + dat += "Records Maintenance
" + dat += "
Delete All Records

Back" + if(3.0) + dat += "
Employment Record

" + if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) + var/icon/front = new(active1.fields["photo"], dir = SOUTH) + var/icon/side = new(active1.fields["photo"], dir = WEST) + user << browse_rsc(front, "front.png") + user << browse_rsc(side, "side.png") + dat += text(" \ +
\ + Name: [active1.fields["name"]]
\ + ID: [active1.fields["id"]]
\n \ + Sex: [active1.fields["sex"]]
\n \ + Age: [active1.fields["age"]]
\n \ + Rank: [active1.fields["rank"]]
\n \ + Fingerprint: [active1.fields["fingerprint"]]
\n \ + Physical Status: [active1.fields["p_stat"]]
\n \ + Mental Status: [active1.fields["m_stat"]]

\n \ + Employment/skills summary:
[active1.fields["notes"]]
Photo:
\ +
") + else + dat += "General Record Lost!
" + dat += text("\nDelete Record (ALL)

\nPrint Record
\nBack
", src, src, src) + if(4.0) + if(!Perp.len) + dat += text("ERROR. String could not be located.

Back", src) + else + dat += {" + + "} + dat += text("", tempname) + dat += {" + +
Search Results for '[]':
+ + + + + + + "} + for(var/i=1, i<=Perp.len, i += 2) + var/crimstat = "" + var/datum/data/record/R = Perp[i] + if(istype(Perp[i+1],/datum/data/record/)) + var/datum/data/record/E = Perp[i+1] + crimstat = E.fields["criminal"] + var/background + background = "'background-color:#00FF7F;'" + dat += text("", background, src, R, R.fields["name"]) + dat += text("", R.fields["id"]) + dat += text("", R.fields["rank"]) + dat += text("", R.fields["fingerprint"]) + dat += text("", crimstat) + dat += "
NameIDRankFingerprints
[][][][][]

" + dat += text("
Return to index.", src) + else + else + dat += text("{Log In}", src) + user << browse(text("Employment Records[]", dat), "window=secure_rec;size=600x400") + onclose(user, "secure_rec") + return + +/*Revised /N +I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. +What a mess.*/ +/obj/machinery/computer/skills/Topic(href, href_list) + if(..()) + return + if (!( data_core.general.Find(active1) )) + active1 = null + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.set_machine(src) + switch(href_list["choice"]) +// SORTING! + if("Sorting") + // Reverse the order if clicked twice + if(sortBy == href_list["sort"]) + if(order == 1) + order = -1 + else + order = 1 + else + // New sorting order! + sortBy = href_list["sort"] + order = initial(order) +//BASIC FUNCTIONS + if("Clear Screen") + temp = null + + if ("Return") + screen = 1 + active1 = null + + if("Confirm Identity") + if (scan) + if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand()) + usr.put_in_hands(scan) + else + scan.loc = get_turf(src) + scan = null + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/weapon/card/id)) + usr.drop_item() + I.loc = src + scan = I + + if("Log Out") + authenticated = null + screen = null + active1 = null + + if("Log In") + if (istype(usr, /mob/living/silicon/ai)) + src.active1 = null + src.authenticated = usr.name + src.rank = "AI" + src.screen = 1 + else if (istype(usr, /mob/living/silicon/robot)) + src.active1 = null + src.authenticated = usr.name + var/mob/living/silicon/robot/R = usr + src.rank = R.braintype + src.screen = 1 + else if (istype(scan, /obj/item/weapon/card/id)) + active1 = null + if(check_access(scan)) + authenticated = scan.registered_name + rank = scan.assignment + screen = 1 +//RECORD FUNCTIONS + if("Search Records") + var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text + if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !in_range(src, usr))) + return + Perp = new/list() + t1 = lowertext(t1) + var/list/components = text2list(t1, " ") + if(components.len > 5) + return //Lets not let them search too greedily. + for(var/datum/data/record/R in data_core.general) + var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"] + for(var/i = 1, i<=components.len, i++) + if(findtext(temptext,components[i])) + var/prelist = new/list(2) + prelist[1] = R + Perp += prelist + for(var/i = 1, i<=Perp.len, i+=2) + for(var/datum/data/record/E in data_core.security) + var/datum/data/record/R = Perp[i] + if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) + Perp[i+1] = E + tempname = t1 + screen = 4 + + if("Record Maintenance") + screen = 2 + active1 = null + + if ("Browse Record") + var/datum/data/record/R = locate(href_list["d_rec"]) + if (!( data_core.general.Find(R) )) + temp = "Record Not Found!" + else + for(var/datum/data/record/E in data_core.security) + active1 = R + screen = 3 + +/* if ("Search Fingerprints") + var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text + if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!in_range(src, usr)) && (!istype(usr, /mob/living/silicon)))) + return + active1 = null + t1 = lowertext(t1) + for(var/datum/data/record/R in data_core.general) + if (lowertext(R.fields["fingerprint"]) == t1) + active1 = R + if (!( active1 )) + temp = text("Could not locate record [].", t1) + else + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"])) + screen = 3 */ + + if ("Print Record") + if (!( printing )) + printing = 1 + sleep(50) + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc ) + P.info = "
Employment Record

" + if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) + P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
\nEmployment/Skills Summary:[]
", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"], active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"], active1.fields["notes"]) + else + P.info += "General Record Lost!
" + P.info += "" + P.name = "paper - 'Employment Record'" + printing = null +//RECORD DELETE + if ("Delete All Records") + temp = "" + temp += "Are you sure you wish to delete all Employment records?
" + temp += "Yes
" + temp += "No" + + if ("Purge All Records") + for(var/datum/data/record/R in data_core.security) + del(R) + temp = "All Employment records deleted." + + if ("Delete Record (ALL)") + if (active1) + temp = "
Are you sure you wish to delete the record (ALL)?
" + temp += "Yes
" + temp += "No" +//RECORD CREATE + if ("New Record (General)") + var/datum/data/record/G = new /datum/data/record() + G.fields["name"] = "New Record" + G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6)) + G.fields["rank"] = "Unassigned" + G.fields["real_rank"] = "Unassigned" + G.fields["sex"] = "Male" + G.fields["age"] = "Unknown" + G.fields["fingerprint"] = "Unknown" + G.fields["p_stat"] = "Active" + G.fields["m_stat"] = "Stable" + G.fields["species"] = "Human" + data_core.general += G + active1 = G + +//FIELD FUNCTIONS + if ("Edit Field") + var/a1 = active1 + switch(href_list["field"]) + if("name") + if (istype(active1, /datum/data/record)) + var/t1 = input("Please input name:", "Secure. records", active1.fields["name"], null) as text + if ((!( t1 ) || !length(trim(t1)) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon)))) || active1 != a1) + return + active1.fields["name"] = t1 + if("id") + if (istype(active1, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) + return + active1.fields["id"] = t1 + if("fingerprint") + if (istype(active1, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) + return + active1.fields["fingerprint"] = t1 + if("sex") + if (istype(active1, /datum/data/record)) + if (active1.fields["sex"] == "Male") + active1.fields["sex"] = "Female" + else + active1.fields["sex"] = "Male" + if("age") + if (istype(active1, /datum/data/record)) + var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) + return + active1.fields["age"] = t1 + if("rank") + var/list/L = list( "Head of Personnel", "Captain", "AI" ) + //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N + if ((istype(active1, /datum/data/record) && L.Find(rank))) + temp = "
Rank:
" + temp += "" + else + alert(usr, "You do not have the required rank to do this!") + if("species") + if (istype(active1, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) + return + active1.fields["species"] = t1 + +//TEMPORARY MENU FUNCTIONS + else//To properly clear as per clear screen. + temp=null + switch(href_list["choice"]) + if ("Change Rank") + if (active1) + active1.fields["rank"] = href_list["rank"] + if(href_list["rank"] in get_all_jobs()) + active1.fields["real_rank"] = href_list["real_rank"] + + if ("Delete Record (ALL) Execute") + if (active1) + for(var/datum/data/record/R in data_core.medical) + if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) + del(R) + else + del(active1) + else + temp = "This function does not appear to be working at the moment. Our apologies." + + add_fingerprint(usr) + updateUsrDialog() + return + +/obj/machinery/computer/skills/emp_act(severity) + if(stat & (BROKEN|NOPOWER)) + ..(severity) + return + + for(var/datum/data/record/R in data_core.security) + if(prob(10/severity)) + switch(rand(1,6)) + if(1) + R.fields["name"] = "[pick(pick(first_names_male), pick(first_names_female))] [pick(last_names)]" + if(2) + R.fields["sex"] = pick("Male", "Female") + if(3) + R.fields["age"] = rand(5, 85) + if(4) + R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Parolled", "Released") + if(5) + R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit") + if(6) + R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") + continue + + else if(prob(1)) + del(R) + continue + + ..(severity) \ No newline at end of file diff --git a/code/game/machinery/computer/vox_shuttle.dm b/code/game/machinery/computer/vox_shuttle.dm new file mode 100644 index 00000000000..fa9d05d7b90 --- /dev/null +++ b/code/game/machinery/computer/vox_shuttle.dm @@ -0,0 +1,106 @@ +#define VOX_SHUTTLE_MOVE_TIME 260 +#define VOX_SHUTTLE_COOLDOWN 460 + +//Copied from Syndicate shuttle. +var/global/vox_shuttle_location + +/obj/machinery/computer/vox_station + name = "vox skipjack terminal" + icon = 'icons/obj/computer.dmi' + icon_state = "syndishuttle" + req_access = list(access_syndicate) + var/area/curr_location + var/moving = 0 + var/lastMove = 0 + var/warning //Warning about the end of the round. + +/obj/machinery/computer/vox_station/New() + curr_location= locate(/area/shuttle/vox/station) + + +/obj/machinery/computer/vox_station/proc/vox_move_to(area/destination as area) + if(moving) return + if(lastMove + VOX_SHUTTLE_COOLDOWN > world.time) return + var/area/dest_location = locate(destination) + if(curr_location == dest_location) return + + moving = 1 + lastMove = world.time + + if(curr_location.z != dest_location.z) + var/area/transit_location = locate(/area/vox_station/transit) + curr_location.move_contents_to(transit_location) + curr_location = transit_location + sleep(VOX_SHUTTLE_MOVE_TIME) + + curr_location.move_contents_to(dest_location) + curr_location = dest_location + moving = 0 + + return 1 + + +/obj/machinery/computer/vox_station/attackby(obj/item/I as obj, mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer/vox_station/attack_ai(mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer/vox_station/attack_paw(mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer/vox_station/attack_hand(mob/user as mob) + if(!allowed(user)) + user << "\red Access Denied" + return + + user.set_machine(src) + + var/dat = {"Location: [curr_location]
+ Ready to move[max(lastMove + VOX_SHUTTLE_COOLDOWN - world.time, 0) ? " in [max(round((lastMove + VOX_SHUTTLE_COOLDOWN - world.time) * 0.1), 0)] seconds" : ": now"]
+ Return to dark space
+ Fore port solar | + Aft port solar | + Fore starboard solar
+ Aft starboard solar | + Mining Asteroid
+ Close"} + + user << browse(dat, "window=computer;size=575x450") + onclose(user, "computer") + return + + +/obj/machinery/computer/vox_station/Topic(href, href_list) + if(!isliving(usr)) return + var/mob/living/user = usr + + if(in_range(src, user) || istype(user, /mob/living/silicon)) + user.set_machine(src) + + vox_shuttle_location = "station" + if(href_list["start"]) + if(ticker && (istype(ticker.mode,/datum/game_mode/heist))) + if(!warning) + user << "\red Returning to dark space will end your raid and report your success or failure. If you are sure, press the button again." + warning = 1 + return + vox_move_to(/area/shuttle/vox/station) + vox_shuttle_location = "start" + else if(href_list["solars_fore_starboard"]) + vox_move_to(/area/vox_station/northeast_solars) + else if(href_list["solars_fore_port"]) + vox_move_to(/area/vox_station/northwest_solars) + else if(href_list["solars_aft_starboard"]) + vox_move_to(/area/vox_station/southeast_solars) + else if(href_list["solars_aft_port"]) + vox_move_to(/area/vox_station/southwest_solars) + else if(href_list["mining"]) + vox_move_to(/area/vox_station/mining) + + add_fingerprint(usr) + updateUsrDialog() + return + +/obj/machinery/computer/vox_station/bullet_act(var/obj/item/projectile/Proj) + visible_message("[Proj] ricochets off [src]!") \ No newline at end of file diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 4d634d45895..a5eb560e3c1 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -17,222 +17,287 @@ anchored = 1.0 // can't pick it up density = 0 // can walk through it. var/id = null // id of door it controls. - var/releasetime = 0 // when world.time reaches it - release the prisoneer + var/releasetime = 0 // when world.timeofday reaches it - release the prisoner var/timing = 1 // boolean, true/1 timer is on, false/0 means it's not timing var/picture_state // icon_state of alert picture, if not displaying text/numbers var/list/obj/machinery/targets = list() + var/timetoset = 0 // Used to set releasetime upon starting the timer - New() - ..() +/obj/machinery/door_timer/New() + ..() - pixel_x = ((src.dir & 3)? (0) : (src.dir == 4 ? 32 : -32)) - pixel_y = ((src.dir & 3)? (src.dir ==1 ? 24 : -32) : (0)) + pixel_x = ((src.dir & 3)? (0) : (src.dir == 4 ? 32 : -32)) + pixel_y = ((src.dir & 3)? (src.dir ==1 ? 24 : -32) : (0)) - spawn(20) - for(var/obj/machinery/door/window/brigdoor/M in world) - if (M.id == src.id) - targets += M + spawn(20) + for(var/obj/machinery/door/window/brigdoor/M in world) + if (M.id == src.id) + targets += M - for(var/obj/machinery/flasher/F in world) - if(F.id == src.id) - targets += F + for(var/obj/machinery/flasher/F in world) + if(F.id == src.id) + targets += F - for(var/obj/structure/closet/secure_closet/brig/C in world) - if(C.id == src.id) - targets += C + for(var/obj/structure/closet/secure_closet/brig/C in world) + if(C.id == src.id) + targets += C - if(targets.len==0) - stat |= BROKEN - update_icon() - return + if(targets.len==0) + stat |= BROKEN + update_icon() return + return //Main door timer loop, if it's timing and time is >0 reduce time by 1. // if it's less than 0, open door, reset timer // update the door_timer window and the icon - process() - if(stat & (NOPOWER|BROKEN)) return - if(src.timing) - if(world.time > src.releasetime) - src.timer_end() // open doors, reset timer, clear status screen - src.timing = 0 - src.updateUsrDialog() - src.update_icon() - else - timer_end() - return +/obj/machinery/door_timer/process() + + if(stat & (NOPOWER|BROKEN)) return + if(src.timing) + + // poorly done midnight rollover + // (no seriously there's gotta be a better way to do this) + var/timeleft = timeleft() + if(timeleft > 1e5) + src.releasetime = 0 -// has the door power sitatuation changed, if so update icon. - power_change() - ..() - update_icon() - return + if(world.timeofday > src.releasetime) + src.timer_end() // open doors, reset timer, clear status screen + src.timing = 0 + + src.updateUsrDialog() + src.update_icon() + + else + timer_end() + + return + + +// has the door power situation changed, if so update icon. +/obj/machinery/door_timer/power_change() + ..() + update_icon() + return // open/closedoor checks if door_timer has power, if so it checks if the // linked door is open/closed (by density) then opens it/closes it. - proc/timer_start() - if(stat & (NOPOWER|BROKEN)) return 0 - for(var/obj/machinery/door/window/brigdoor/door in targets) - if(door.density) continue - spawn(0) - door.close() +// Closes and locks doors, power check +/obj/machinery/door_timer/proc/timer_start() + if(stat & (NOPOWER|BROKEN)) return 0 - for(var/obj/structure/closet/secure_closet/brig/C in targets) - if(C.broken) continue - if(C.opened && !C.close()) continue - C.locked = 1 - C.icon_state = C.icon_locked - return 1 + // Set releasetime + releasetime = world.timeofday + timetoset + + for(var/obj/machinery/door/window/brigdoor/door in targets) + if(door.density) continue + spawn(0) + door.close() + + for(var/obj/structure/closet/secure_closet/brig/C in targets) + if(C.broken) continue + if(C.opened && !C.close()) continue + C.locked = 1 + C.icon_state = C.icon_locked + return 1 - proc/timer_end() - if(stat & (NOPOWER|BROKEN)) return 0 +// Opens and unlocks doors, power check +/obj/machinery/door_timer/proc/timer_end() + if(stat & (NOPOWER|BROKEN)) return 0 - for(var/obj/machinery/door/window/brigdoor/door in targets) - if(!door.density) continue - spawn(0) - door.open() + // Reset releasetime + releasetime = 0 - for(var/obj/structure/closet/secure_closet/brig/C in targets) - if(C.broken) continue - if(C.opened) continue - C.locked = 0 - C.icon_state = C.icon_closed + for(var/obj/machinery/door/window/brigdoor/door in targets) + if(!door.density) continue + spawn(0) + door.open() - return 1 + for(var/obj/structure/closet/secure_closet/brig/C in targets) + if(C.broken) continue + if(C.opened) continue + C.locked = 0 + C.icon_state = C.icon_closed + + return 1 - proc/timeleft() - . = (releasetime-world.time)/10 - if(. < 0) - . = 0 +// Check for releasetime timeleft +/obj/machinery/door_timer/proc/timeleft() + . = (releasetime - world.timeofday)/10 + if(. < 0) + . = 0 +// Set timetoset +/obj/machinery/door_timer/proc/timeset(var/seconds) + timetoset = seconds * 10 - proc/timeset(var/seconds) - releasetime=world.time+seconds*10 - return + if(timetoset <= 0) + timetoset = 0 + return //Allows AIs to use door_timer, see human attack_hand function below - attack_ai(var/mob/user as mob) - return src.attack_hand(user) +/obj/machinery/door_timer/attack_ai(var/mob/user as mob) + return src.attack_hand(user) //Allows humans to use door_timer //Opens dialog window when someone clicks on door timer // Allows altering timer and the timing boolean. // Flasher activation limited to 150 seconds - attack_hand(var/mob/user as mob) - if(..()) - return - var/second = round(timeleft() % 60) - var/minute = round((timeleft() - second) / 60) - user.set_machine(src) - var/dat = "" - dat += "
Timer System:" - dat += "Door [src.id] controls
" - if (src.timing) - dat += "Stop Timer and open door
" - else - dat += "Activate Timer and close door
" - - dat += "Time Left: [(minute ? text("[minute]:") : null)][second]
" - dat += "- - + +
" - - for(var/obj/machinery/flasher/F in targets) - if(F.last_flash && (F.last_flash + 150) > world.time) - dat += "
Flash Charging" - else - dat += "
Activate Flash" - - dat += "

Close" - dat += "
" - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") +/obj/machinery/door_timer/attack_hand(var/mob/user as mob) + if(..()) return + // Used for the 'time left' display + var/second = round(timeleft() % 60) + var/minute = round((timeleft() - second) / 60) + + // Used for 'set timer' + var/setsecond = round((timetoset / 10) % 60) + var/setminute = round(((timetoset / 10) - setsecond) / 60) + + user.set_machine(src) + + // dat + var/dat = "" + + dat += "
Timer System:" + dat += " Door [src.id] controls
" + + // Start/Stop timer + if (src.timing) + dat += "Stop Timer and open door
" + else + dat += "Activate Timer and close door
" + + // Time Left display (uses releasetime) + dat += "Time Left: [(minute ? text("[minute]:") : null)][second]
" + dat += "
" + + // Set Timer display (uses timetoset) + if(src.timing) + dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond] Set
" + else + dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond]
" + + // Controls + dat += "- - + +
" + + // Mounted flash controls + for(var/obj/machinery/flasher/F in targets) + if(F.last_flash && (F.last_flash + 150) > world.time) + dat += "
Flash Charging" + else + dat += "
Activate Flash" + + dat += "

Close" + dat += "
" + + user << browse(dat, "window=computer;size=400x500") + onclose(user, "computer") + return + //Function for using door_timer dialog input, checks if user has permission // href_list to // "timing" turns on timer // "tp" value to modify timer // "fc" activates flasher +// "change" resets the timer to the timetoset amount while the timer is counting down // Also updates dialog window and timer icon - Topic(href, href_list) - if(..()) - return - if(!src.allowed(usr)) - return +/obj/machinery/door_timer/Topic(href, href_list) + if(..()) + return + if(!src.allowed(usr)) + return + + usr.set_machine(src) + + if(href_list["timing"]) + src.timing = text2num(href_list["timing"]) - usr.set_machine(src) - if(href_list["timing"]) - src.timing = text2num(href_list["timing"]) - else - if(href_list["tp"]) //adjust timer, close door if not already closed - var/tp = text2num(href_list["tp"]) - var/timeleft = timeleft() - timeleft += tp - timeleft = min(max(round(timeleft), 0), 3600) - timeset(timeleft) - //src.timing = 1 - //src.closedoor() - if(href_list["fc"]) - for(var/obj/machinery/flasher/F in targets) - F.flash() - src.add_fingerprint(usr) - src.updateUsrDialog() - src.update_icon() if(src.timing) src.timer_start() else src.timer_end() - return + + else + if(href_list["tp"]) //adjust timer, close door if not already closed + var/tp = text2num(href_list["tp"]) + var/addtime = (timetoset / 10) + addtime += tp + addtime = min(max(round(addtime), 0), 3600) + + timeset(addtime) + + if(href_list["fc"]) + for(var/obj/machinery/flasher/F in targets) + F.flash() + + if(href_list["change"]) + src.timer_start() + + src.add_fingerprint(usr) + src.updateUsrDialog() + src.update_icon() + + /* if(src.timing) + src.timer_start() + + else + src.timer_end() */ + + return //icon update function // if NOPOWER, display blank // if BROKEN, display blue screen of death icon AI uses // if timing=true, run update display function - update_icon() - if(stat & (NOPOWER)) - icon_state = "frame" - return - if(stat & (BROKEN)) - set_picture("ai_bsod") - return - if(src.timing) - var/disp1 = uppertext(id) - var/timeleft = timeleft() - var/disp2 = "[add_zero(num2text((timeleft / 60) % 60),2)]~[add_zero(num2text(timeleft % 60), 2)]" - spawn( 5 ) - update_display(disp1, disp2) - else - update_display("SET","TIME") +/obj/machinery/door_timer/update_icon() + if(stat & (NOPOWER)) + icon_state = "frame" return + if(stat & (BROKEN)) + set_picture("ai_bsod") + return + if(src.timing) + var/disp1 = uppertext(id) + var/timeleft = timeleft() + var/disp2 = "[add_zero(num2text((timeleft / 60) % 60),2)]~[add_zero(num2text(timeleft % 60), 2)]" + spawn( 5 ) + update_display(disp1, disp2) + else + update_display("SET","TIME") + return // Adds an icon in case the screen is broken/off, stolen from status_display.dm - proc/set_picture(var/state) - picture_state = state - overlays.Cut() - overlays += image('icons/obj/status_display.dmi', icon_state=picture_state) +/obj/machinery/door_timer/proc/set_picture(var/state) + picture_state = state + overlays.Cut() + overlays += image('icons/obj/status_display.dmi', icon_state=picture_state) //Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display // Stolen from status_display - proc/update_display(var/line1, var/line2) - if(line2 == null) // single line display - overlays.Cut() - overlays += texticon(line1, 23, -13) - else // dual line display - overlays.Cut() - overlays += texticon(line1, 23, -9) - overlays += texticon(line2, 23, -17) +/obj/machinery/door_timer/proc/update_display(var/line1, var/line2) + if(line2 == null) // single line display + overlays.Cut() + overlays += texticon(line1, 23, -13) + else // dual line display + overlays.Cut() + overlays += texticon(line1, 23, -9) + overlays += texticon(line2, 23, -17) // return an icon of a time text string (tn) // valid characters are 0-9 and : // px, py are pixel offsets @@ -240,19 +305,19 @@ //Actual string input to icon display for loop, with 5 pixel x offsets for each letter. //Stolen from status_display - proc/texticon(var/tn, var/px = 0, var/py = 0) - var/image/I = image('icons/obj/status_display.dmi', "blank") - var/len = lentext(tn) +/obj/machinery/door_timer/proc/texticon(var/tn, var/px = 0, var/py = 0) + var/image/I = image('icons/obj/status_display.dmi', "blank") + var/len = lentext(tn) - for(var/d = 1 to len) - var/char = copytext(tn, len-d+1, len-d+2) - if(char == " ") - continue - var/image/ID = image('icons/obj/status_display.dmi', icon_state=char) - ID.pixel_x = -(d-1)*5 + px - ID.pixel_y = py - I.overlays += ID - return I + for(var/d = 1 to len) + var/char = copytext(tn, len-d+1, len-d+2) + if(char == " ") + continue + var/image/ID = image('icons/obj/status_display.dmi', icon_state=char) + ID.pixel_x = -(d-1)*5 + px + ID.pixel_y = py + I.overlays += ID + return I /obj/machinery/door_timer/cell_1 diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm index 5d187b337c7..a0f8c371e41 100644 --- a/code/game/machinery/hydroponics.dm +++ b/code/game/machinery/hydroponics.dm @@ -915,115 +915,13 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) parent.update_tray() -/obj/item/seeds/replicapod/harvest(mob/user = usr) //now that one is fun -- Urist - var/obj/machinery/hydroponics/parent = loc - var/make_podman = 0 - var/mob/ghost - if(ckey && config.revival_pod_plants) - ghost = find_dead_player("[ckey]") - if(ismob(ghost)) - if(istype(ghost,/mob/dead/observer)) - var/mob/dead/observer/O = ghost - if(istype(mind,/datum/mind)) - if(O.can_reenter_corpse) - make_podman = 1 - else - make_podman = 1 - - if(make_podman) //all conditions met! - var/mob/living/carbon/human/podman = new /mob/living/carbon/human(parent.loc) - if(realName) - podman.real_name = realName - else - podman.real_name = "Pod Person [rand(0,999)]" - var/oldactive = mind.active - mind.active = 1 - mind.transfer_to(podman) - mind.active = oldactive - // -- Mode/mind specific stuff goes here. TODO! Broken :( Should be merged into mob/living/Login - switch(ticker.mode.name) - if ("revolution") - if (podman.mind in ticker.mode:revolutionaries) - ticker.mode:add_revolutionary(podman.mind) - ticker.mode:update_all_rev_icons() //So the icon actually appears - if (podman.mind in ticker.mode:head_revolutionaries) - ticker.mode:update_all_rev_icons() - if ("nuclear emergency") - if (podman.mind in ticker.mode:syndicates) - ticker.mode:update_all_synd_icons() - if ("cult") - if (podman.mind in ticker.mode:cult) - ticker.mode:add_cultist(podman.mind) - ticker.mode:update_all_cult_icons() //So the icon actually appears - - // -- End mode specific stuff - - podman.gender = ghost.gender - if(podman.gender in list(NEUTER, PLURAL)) //Sanity check, which should never actually happen. - podman.gender = pick(MALE,FEMALE) - - if(!podman.dna) - podman.dna = new /datum/dna() - podman.dna.real_name = podman.real_name - if(ui) - podman.dna.uni_identity = ui - updateappearance(podman, ui) - if(se) - podman.dna.struc_enzymes = se - if(!prob(potency)) //if it fails, plantman! - if(podman) -// podman.dna.mutantrace = "plant" - podman.mutations.Add(PLANT) - podman.update_mutantrace() - - else //else, one packet of seeds. maybe two - var/seed_count = 1 - if(prob(yield * parent.yieldmod * 20)) - seed_count++ - for(var/i=0,iYour blood has been placed into a replica pod seed. Return to your body if you want to be returned to life as a pod person! (Verbs -> Ghost -> Re-enter corpse)" + break + else + user << "Nothing happens." + return + + if (!istype(source)) + return + + if(source.ckey) + realName = source.real_name + ckey = source.ckey + + W:reagents.clear_reagents() + return + + return ..() + +/obj/item/seeds/replicapod/harvest(mob/user = usr) + + var/obj/machinery/hydroponics/parent = loc + var/mob/ghost + var/list/candidates = list() + + user.visible_message("\blue You carefully begin to open the pod...","[user] carefully begins to open the pod...") + + //If a sample is injected (and revival is allowed) the plant will be controlled by the original donor. + if(source && source.mind && source.ckey && config.revival_pod_plants) + ghost = source + else // If no sample was injected or revival is not allowed, we grab an interested observer. + for(var/mob/dead/observer/O in player_list) + if(O.client) + var/response = alert(O, "Someone is harvesting a replica pod. Would you like to play as a Dionaea?", "Replica pod harvest", "Yes", "No") + if(response == "Yes") + candidates += O + + if(!do_after(user, 100)) + return + + if(!src || !user) + return + + if(candidates.len) + ghost = pick(candidates) + + //If we don't have a ghost or the ghost is now unplayed, we just give the harvester some seeds. + if(!ghost || !(ghost.ckey)) + user << "The pod has formed badly, and all you can do is salvage some of the seeds." + var/seed_count = 1 + + if(prob(yield * parent.yieldmod * 20)) + seed_count++ + + for(var/i=0,iYou awaken slowly, feeling your sap stir into sluggish motion as the warm air caresses your bark." + if(source && ckey && podman.ckey == ckey) + podman << "Memories of a life as [source] drift oddly through a mind unsuited for them, like a skin of oil over a fathomless lake." + podman << "You are now one of the Dionaea, a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders." + podman << "Too much darkness will send you into shock and starve you, but light will help you heal." + + if(!realName) + var/newname = input(podman,"Enter a name, or leave blank for the default name.", "Name change","") as text + if (newname != "") + podman.real_name = newname + parent.update_tray() \ No newline at end of file diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 4ab483076b7..7302ed81b6c 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -341,12 +341,10 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept freq_text = "Engineering" if(1359) freq_text = "Security" -// if(1349) -// freq_text = "Mining" if(1347) freq_text = "Supply" if(1441) - freq_text = "Death Squad" + freq_text = "Special Ops" if(1443) freq_text = "Response Team" //There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO @@ -365,10 +363,35 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/part_b = " \icon[radio]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE var/part_c = "" - if (display_freq==SYND_FREQ) + // syndies! + if (display_freq == SYND_FREQ) part_a = "" - else if (display_freq==COMM_FREQ) + + // centcomm channels (deathsquid and ert) + else if (display_freq in CENT_FREQS) + part_a = "" + + // command channel + else if (display_freq == COMM_FREQ) part_a = "" + + // department radio formatting (poorly optimized, ugh) + else if (display_freq == SEC_FREQ) + part_a = "" + + else if (display_freq == ENG_FREQ) + part_a = "" + + else if (display_freq == SCI_FREQ) + part_a = "" + + else if (display_freq == MED_FREQ) + part_a = "" + + else if (display_freq == SUP_FREQ) // cargo + part_a = "" + + // If all else fails and it's a dept_freq, color me purple! else if (display_freq in DEPT_FREQS) part_a = "" @@ -406,8 +429,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept blackbox.msg_deathsquad += blackbox_msg if(1213) blackbox.msg_syndicate += blackbox_msg -// if(1349) -// blackbox.msg_mining += blackbox_msg if(1347) blackbox.msg_cargo += blackbox_msg else @@ -629,8 +650,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept freq_text = "Engineering" if(1359) freq_text = "Security" -// if(1349) -// freq_text = "Mining" if(1347) freq_text = "Supply" //There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO @@ -685,8 +704,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept blackbox.msg_deathsquad += blackbox_msg if(1213) blackbox.msg_syndicate += blackbox_msg -// if(1349) -// blackbox.msg_mining += blackbox_msg if(1347) blackbox.msg_cargo += blackbox_msg else diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm index 2b708ded291..914bd8c9016 100644 --- a/code/game/machinery/telecomms/presets.dm +++ b/code/game/machinery/telecomms/presets.dm @@ -142,12 +142,7 @@ id = "Supply Server" freq_listening = list(1347) autolinkers = list("supply") -/* -/obj/machinery/telecomms/server/presets/mining - id = "Mining Server" - freq_listening = list(1349) - autolinkers = list("mining") -*/ + /obj/machinery/telecomms/server/presets/common id = "Common Server" freq_listening = list() diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 80703f4916e..9439757282a 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1,860 +1,861 @@ -/datum/data/vending_product - var/product_name = "generic" - var/product_path = null - var/amount = 0 - var/price = 0 - var/display_color = "blue" - - - -/obj/machinery/vending - name = "Vendomat" - desc = "A generic vending machine." - icon = 'icons/obj/vending.dmi' - icon_state = "generic" - layer = 2.9 - anchored = 1 - density = 1 - var/active = 1 //No sales pitches if off! - var/vend_ready = 1 //Are we ready to vend?? Is it time?? - var/vend_delay = 10 //How long does it take to vend? - var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now. - - // To be filled out at compile time - var/list/products = list() // For each, use the following pattern: - var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2) - var/list/premium = list() // No specified amount = only one in stock - var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price. - - var/product_slogans = "" //String of slogans separated by semicolons, optional - var/product_ads = "" //String of small ad messages in the vending screen - random chance - var/list/product_records = list() - var/list/hidden_records = list() - var/list/coin_records = list() - var/list/slogan_list = list() - var/list/small_ads = list() // small ad messages in the vending screen - random chance of popping up whenever you open it - var/vend_reply //Thank you for shopping! - var/last_reply = 0 - var/last_slogan = 0 //When did we last pitch? - var/slogan_delay = 6000 //How long until we can pitch again? - var/icon_vend //Icon_state when vending! - var/icon_deny //Icon_state when vending! - //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine. - var/seconds_electrified = 0 //Shock customers like an airlock. - var/shoot_inventory = 0 //Fire items at customers! We're broken! - var/shut_up = 1 //Stop spouting those godawful pitches! - var/extended_inventory = 0 //can we access the hidden inventory? - var/panel_open = 0 //Hacking that vending machine. Gonna get a free candy bar. - var/wires = 15 - var/obj/item/weapon/coin/coin - var/const/WIRE_EXTEND = 1 - var/const/WIRE_SCANID = 2 - var/const/WIRE_SHOCK = 3 - var/const/WIRE_SHOOTINV = 4 - - var/obj/machinery/account_database/linked_db - var/datum/money_account/linked_account - -/obj/machinery/vending/New() - ..() - spawn(4) - src.slogan_list = text2list(src.product_slogans, ";") - - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - src.last_slogan = world.time + rand(0, slogan_delay) - - src.build_inventory(products) - //Add hidden inventory - src.build_inventory(contraband, 1) - src.build_inventory(premium, 0, 1) - power_change() - - reconnect_database() - linked_account = vendor_account - - return - - return - -/obj/machinery/vending/proc/reconnect_database() - for(var/obj/machinery/account_database/DB in world) - if(DB.z == src.z) - linked_db = DB - break - -/obj/machinery/vending/ex_act(severity) - switch(severity) - if(1.0) - del(src) - return - if(2.0) - if (prob(50)) - del(src) - return - if(3.0) - if (prob(25)) - spawn(0) - src.malfunction() - return - return - else - return - -/obj/machinery/vending/blob_act() - if (prob(50)) - spawn(0) - src.malfunction() - del(src) - return - - return - -/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0) - for(var/typepath in productlist) - var/amount = productlist[typepath] - var/price = prices[typepath] - if(isnull(amount)) amount = 1 - - var/atom/temp = new typepath(null) - var/datum/data/vending_product/R = new /datum/data/vending_product() - R.product_name = temp.name - R.product_path = typepath - R.amount = amount - R.price = price - R.display_color = pick("red","blue","green") - - if(hidden) - hidden_records += R - else if(req_coin) - coin_records += R - else - product_records += R -// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]" - return - -/obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/emag)) - src.emagged = 1 - user << "You short out the product lock on [src]" - return - else if(istype(W, /obj/item/weapon/screwdriver)) - src.panel_open = !src.panel_open - user << "You [src.panel_open ? "open" : "close"] the maintenance panel." - src.overlays.Cut() - if(src.panel_open) - src.overlays += image(src.icon, "[initial(icon_state)]-panel") - src.updateUsrDialog() - return - else if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters)) - if(src.panel_open) - attack_hand(user) - return - else if(istype(W, /obj/item/weapon/coin) && premium.len > 0) - user.drop_item() - W.loc = src - coin = W - user << "\blue You insert the [W] into the [src]" - return - else if(istype(W, /obj/item/weapon/card) && currently_vending) - //attempt to connect to a new db, and if that doesn't work then fail - if(!linked_db) - reconnect_database() - if(linked_db) - if(linked_account) - var/obj/item/weapon/card/I = W - scan_card(I) - else - usr << "\icon[src]Unable to connect to linked account." - else - usr << "\icon[src]Unable to connect to accounts database." - else - ..() - -/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I) - if(!currently_vending) return - if (istype(I, /obj/item/weapon/card/id)) - var/obj/item/weapon/card/id/C = I - visible_message("[usr] swipes a card through [src].") - if(linked_account) - var/attempt_pin = input("Enter pin code", "Vendor transaction") as num - var/datum/money_account/D = linked_db.attempt_account_access(C.associated_account_number, attempt_pin, 2) - if(D) - var/transaction_amount = currently_vending.price - if(transaction_amount <= D.money) - - //transfer the money - D.money -= transaction_amount - linked_account.money += transaction_amount - - //create entries in the two account transaction logs - var/datum/transaction/T = new() - T.target_name = "[linked_account.owner_name] (via [src.name])" - T.purpose = "Purchase of [currently_vending.product_name]" - if(transaction_amount > 0) - T.amount = "([transaction_amount])" - else - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - D.transaction_log.Add(T) - // - T = new() - T.target_name = D.owner_name - T.purpose = "Purchase of [currently_vending.product_name]" - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - linked_account.transaction_log.Add(T) - - // Vend the item - src.vend(src.currently_vending, usr) - currently_vending = null - else - usr << "\icon[src]You don't have that much money!" - else - usr << "\icon[src]Unable to access account. Check security settings and try again." - else - usr << "\icon[src]EFTPOS is not connected to an account." - -/obj/machinery/vending/attack_paw(mob/user as mob) - return attack_hand(user) - -/obj/machinery/vending/attack_ai(mob/user as mob) - return attack_hand(user) - -/obj/machinery/vending/attack_hand(mob/user as mob) - if(stat & (BROKEN|NOPOWER)) - return - user.set_machine(src) - - if(src.seconds_electrified != 0) - if(src.shock(user, 100)) - return - - var/vendorname = (src.name) //import the machine's name - - if(src.currently_vending) - var/dat = "
[vendorname]


" //display the name, and added a horizontal rule - dat += "You have selected [currently_vending.product_name].
Please swipe your ID to pay for the article.

" - dat += "Cancel" - user << browse(dat, "window=vending") - onclose(user, "") - return - - var/dat = "
[vendorname]


" //display the name, and added a horizontal rule - dat += "Select an item:

" //the rest is just general spacing and bolding - - if (premium.len > 0) - dat += "Coin slot: [coin ? coin : "No coin inserted"] (Remove)

" - - if (src.product_records.len == 0) - dat += "No product loaded!" - else - var/list/display_records = src.product_records - if(src.extended_inventory) - display_records = src.product_records + src.hidden_records - if(src.coin) - display_records = src.product_records + src.coin_records - if(src.coin && src.extended_inventory) - display_records = src.product_records + src.hidden_records + src.coin_records - - for (var/datum/data/vending_product/R in display_records) - dat += "[R.product_name]:" - dat += " [R.amount] " - if(R.price) - dat += " (Price: [R.price])" - if (R.amount > 0) - dat += " (Vend)" - else - dat += " SOLD OUT" - dat += "
" - - dat += "
" - - if(panel_open) - var/list/vendwires = list( - "Violet" = 1, - "Orange" = 2, - "Goldenrod" = 3, - "Green" = 4, - ) - dat += "


Access Panel
" - for(var/wiredesc in vendwires) - var/is_uncut = src.wires & APCWireColorToFlag[vendwires[wiredesc]] - dat += "[wiredesc] wire: " - if(!is_uncut) - dat += "Mend" - else - dat += "Cut " - dat += "Pulse " - dat += "
" - - dat += "
" - dat += "The orange light is [(src.seconds_electrified == 0) ? "off" : "on"].
" - dat += "The red light is [src.shoot_inventory ? "off" : "blinking"].
" - dat += "The green light is [src.extended_inventory ? "on" : "off"].
" - dat += "The [(src.wires & WIRE_SCANID) ? "purple" : "yellow"] light is on.
" - - if (product_slogans != "") - dat += "The speaker switch is [src.shut_up ? "off" : "on"]. Toggle" - - user << browse(dat, "window=vending") - onclose(user, "") - return - -/obj/machinery/vending/Topic(href, href_list) - if(stat & (BROKEN|NOPOWER)) - return - if(usr.stat || usr.restrained()) - return - - if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon)) - if(!coin) - usr << "There is no coin in this machine." - return - - coin.loc = src.loc - if(!usr.get_active_hand()) - usr.put_in_hands(coin) - usr << "\blue You remove the [coin] from the [src]" - coin = null - - - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) - usr.set_machine(src) - if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending)) - - if(istype(usr,/mob/living/silicon)) - if(istype(usr,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = usr - if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) )) - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - else - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - - if ((!src.allowed(usr)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH - usr << "\red Access denied." //Unless emagged of course - flick(src.icon_deny,src) - return - - var/datum/data/vending_product/R = locate(href_list["vend"]) - if (!R || !istype(R) || !R.product_path || R.amount <= 0) - return - - if(R.price == null) - src.vend(R, usr) - else - src.currently_vending = R - src.updateUsrDialog() - - return - - else if (href_list["cancel_buying"]) - src.currently_vending = null - src.updateUsrDialog() - return - - else if ((href_list["cutwire"]) && (src.panel_open)) - var/twire = text2num(href_list["cutwire"]) - if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) )) - usr << "You need wirecutters!" - return - if (src.isWireColorCut(twire)) - src.mend(twire) - else - src.cut(twire) - - else if ((href_list["pulsewire"]) && (src.panel_open)) - var/twire = text2num(href_list["pulsewire"]) - if (!istype(usr.get_active_hand(), /obj/item/device/multitool)) - usr << "You need a multitool!" - return - if (src.isWireColorCut(twire)) - usr << "You can't pulse a cut wire." - return - else - src.pulse(twire) - - else if ((href_list["togglevoice"]) && (src.panel_open)) - src.shut_up = !src.shut_up - - src.add_fingerprint(usr) - src.updateUsrDialog() - else - usr << browse(null, "window=vending") - return - return - -/obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user) - if ((!src.allowed(user)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH - user << "\red Access denied." //Unless emagged of course - flick(src.icon_deny,src) - return - src.vend_ready = 0 //One thing at a time!! - - if (R in coin_records) - if(!coin) - user << "\blue You need to insert a coin to get this item." - return - if(coin.string_attached) - if(prob(50)) - user << "\blue You successfully pull the coin out before the [src] could swallow it." - else - user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all." - del(coin) - else - del(coin) - - R.amount-- - - if(((src.last_reply + (src.vend_delay + 200)) <= world.time) && src.vend_reply) - spawn(0) - src.speak(src.vend_reply) - src.last_reply = world.time - - use_power(5) - if (src.icon_vend) //Show the vending animation if needed - flick(src.icon_vend,src) - spawn(src.vend_delay) - new R.product_path(get_turf(src)) - src.vend_ready = 1 - return - - src.updateUsrDialog() - -/obj/machinery/vending/process() - if(stat & (BROKEN|NOPOWER)) - return - - if(!src.active) - return - - if(src.seconds_electrified > 0) - src.seconds_electrified-- - - //Pitch to the people! Really sell it! - if(((src.last_slogan + src.slogan_delay) <= world.time) && (src.slogan_list.len > 0) && (!src.shut_up) && prob(5)) - var/slogan = pick(src.slogan_list) - src.speak(slogan) - src.last_slogan = world.time - - if(src.shoot_inventory && prob(2)) - src.throw_item() - - return - -/obj/machinery/vending/proc/speak(var/message) - if(stat & NOPOWER) - return - - if (!message) - return - - for(var/mob/O in hearers(src, null)) - O.show_message("[src] beeps, \"[message]\"",2) - return - -/obj/machinery/vending/power_change() - if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" - else - if( powered() ) - icon_state = initial(icon_state) - stat &= ~NOPOWER - else - spawn(rand(0, 15)) - src.icon_state = "[initial(icon_state)]-off" - stat |= NOPOWER - -//Oh no we're malfunctioning! Dump out some product and break. -/obj/machinery/vending/proc/malfunction() - for(var/datum/data/vending_product/R in src.product_records) - if (R.amount <= 0) //Try to use a record that actually has something to dump. - continue - var/dump_path = R.product_path - if (!dump_path) - continue - - while(R.amount>0) - new dump_path(src.loc) - R.amount-- - break - - stat |= BROKEN - src.icon_state = "[initial(icon_state)]-broken" - return - -//Somebody cut an important wire and now we're following a new definition of "pitch." -/obj/machinery/vending/proc/throw_item() - var/obj/throw_item = null - var/mob/living/target = locate() in view(7,src) - if(!target) - return 0 - - for(var/datum/data/vending_product/R in src.product_records) - if (R.amount <= 0) //Try to use a record that actually has something to dump. - continue - var/dump_path = R.product_path - if (!dump_path) - continue - - R.amount-- - throw_item = new dump_path(src.loc) - break - if (!throw_item) - return 0 - spawn(0) - throw_item.throw_at(target, 16, 3) - src.visible_message("\red [src] launches [throw_item.name] at [target.name]!") - return 1 - -/obj/machinery/vending/proc/isWireColorCut(var/wireColor) - var/wireFlag = APCWireColorToFlag[wireColor] - return ((src.wires & wireFlag) == 0) - -/obj/machinery/vending/proc/isWireCut(var/wireIndex) - var/wireFlag = APCIndexToFlag[wireIndex] - return ((src.wires & wireFlag) == 0) - -/obj/machinery/vending/proc/cut(var/wireColor) - var/wireFlag = APCWireColorToFlag[wireColor] - var/wireIndex = APCWireColorToIndex[wireColor] - src.wires &= ~wireFlag - switch(wireIndex) - if(WIRE_EXTEND) - src.extended_inventory = 0 - if(WIRE_SHOCK) - src.seconds_electrified = -1 - if (WIRE_SHOOTINV) - if(!src.shoot_inventory) - src.shoot_inventory = 1 - - -/obj/machinery/vending/proc/mend(var/wireColor) - var/wireFlag = APCWireColorToFlag[wireColor] - var/wireIndex = APCWireColorToIndex[wireColor] //not used in this function - src.wires |= wireFlag - switch(wireIndex) -// if(WIRE_SCANID) - if(WIRE_SHOCK) - src.seconds_electrified = 0 - if (WIRE_SHOOTINV) - src.shoot_inventory = 0 - -/obj/machinery/vending/proc/pulse(var/wireColor) - var/wireIndex = APCWireColorToIndex[wireColor] - switch(wireIndex) - if(WIRE_EXTEND) - src.extended_inventory = !src.extended_inventory -// if (WIRE_SCANID) - if (WIRE_SHOCK) - src.seconds_electrified = 30 - if (WIRE_SHOOTINV) - src.shoot_inventory = !src.shoot_inventory - - -/obj/machinery/vending/proc/shock(mob/user, prb) - if(stat & (BROKEN|NOPOWER)) // unpowered, no shock - return 0 - if(!prob(prb)) - return 0 - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - if (electrocute_mob(user, get_area(src), src, 0.7)) - return 1 - else - return 0 - -/* - * Vending machine types - */ - -/* - -/obj/machinery/vending/[vendors name here] // --vending machine template :) - name = "" - desc = "" - icon = '' - icon_state = "" - vend_delay = 15 - products = list() - contraband = list() - premium = list() - -*/ - -/* -/obj/machinery/vending/atmospherics //Commenting this out until someone ponies up some actual working, broken, and unpowered sprites - Quarxink - name = "Tank Vendor" - desc = "A vendor with a wide variety of masks and gas tanks." - icon = 'icons/obj/objects.dmi' - icon_state = "dispenser" - product_paths = "/obj/item/weapon/tank/oxygen;/obj/item/weapon/tank/plasma;/obj/item/weapon/tank/emergency_oxygen;/obj/item/weapon/tank/emergency_oxygen/engi;/obj/item/clothing/mask/breath" - product_amounts = "10;10;10;5;25" - vend_delay = 0 -*/ - -/obj/machinery/vending/boozeomat - name = "Booze-O-Mat" - desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." - icon_state = "boozeomat" //////////////18 drink entities below, plus the glasses, in case someone wants to edit the number of bottles - icon_deny = "boozeomat-deny" - products = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/rum = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 5,/obj/item/weapon/reagent_containers/food/drinks/beer = 6, - /obj/item/weapon/reagent_containers/food/drinks/ale = 6,/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 4, - /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 4,/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 4, - /obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 4,/obj/item/weapon/reagent_containers/food/drinks/tonic = 8, - /obj/item/weapon/reagent_containers/food/drinks/cola = 8, /obj/item/weapon/reagent_containers/food/drinks/sodawater = 15, - /obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 9) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/tea = 10) - vend_delay = 15 - product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" - product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" - req_access_txt = "25" - -/obj/machinery/vending/assist - products = list( /obj/item/device/assembly/prox_sensor = 5,/obj/item/device/assembly/igniter = 3,/obj/item/device/assembly/signaler = 4, - /obj/item/weapon/wirecutters = 1, /obj/item/weapon/cartridge/signal = 4) - contraband = list(/obj/item/device/flashlight = 5,/obj/item/device/assembly/timer = 2) - product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!" - -/obj/machinery/vending/coffee - name = "Hot Drinks machine" - desc = "A vending machine which dispenses hot drinks." - product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies" - icon_state = "coffee" - icon_vend = "coffee-vend" - vend_delay = 34 - products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10) - prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25, /obj/item/weapon/reagent_containers/food/drinks/tea = 25, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25) - - - - -/obj/machinery/vending/snack - name = "Getmore Chocolate Corp" - desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars" - product_slogans = "Try our new nougat bar!;Twice the calories for half the price!" - product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!" - icon_state = "snack" - products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 6,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 6,/obj/item/weapon/reagent_containers/food/snacks/chips =6, - /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6, - /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6) - contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6) - prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 20,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 30,/obj/item/weapon/reagent_containers/food/snacks/chips =25, - /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 30,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 20,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 30, - /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 25) - - - -/obj/machinery/vending/cola - name = "Robust Softdrinks" - desc = "A softdrink vendor provided by Robust Industries, LLC." - icon_state = "Cola_Machine" - product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!" - product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space." - products = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 10, - /obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/starkist = 10, - /obj/item/weapon/reagent_containers/food/drinks/space_up = 10) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/thirteenloko = 5) - prices = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 20,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 20, - /obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 20,/obj/item/weapon/reagent_containers/food/drinks/starkist = 20, - /obj/item/weapon/reagent_containers/food/drinks/space_up = 20) - -//This one's from bay12 -/obj/machinery/vending/cart - name = "PTech" - desc = "Cartridges for PDAs" - product_slogans = "Carts to go!" - icon_state = "cart" - icon_deny = "cart-deny" - products = list(/obj/item/weapon/cartridge/medical = 10,/obj/item/weapon/cartridge/engineering = 10,/obj/item/weapon/cartridge/security = 10, - /obj/item/weapon/cartridge/janitor = 10,/obj/item/weapon/cartridge/signal/toxins = 10,/obj/item/device/pda/heads = 10, - /obj/item/weapon/cartridge/captain = 3,/obj/item/weapon/cartridge/quartermaster = 10) - - -/obj/machinery/vending/cigarette - name = "Cigarette machine" //OCD had to be uppercase to look nice with the new formating - desc = "If you want to get cancer, might as well do it in style" - product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!" - product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs." - vend_delay = 34 - icon_state = "cigs" - products = list(/obj/item/weapon/storage/fancy/cigarettes = 10,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 4) - contraband = list(/obj/item/weapon/lighter/zippo = 4) - premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2) - prices = list(/obj/item/weapon/storage/fancy/cigarettes = 60,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 60) - - -/obj/machinery/vending/medical - name = "NanoMed Plus" - desc = "Medical drug dispenser." - icon_state = "med" - icon_deny = "med-deny" - product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" - req_access_txt = "5" - products = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline = 4, - /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, - /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, - /obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2) - contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6) - - -//This one's from bay12 -/obj/machinery/vending/plasmaresearch - name = "Toximate 3000" - desc = "All the fine parts you need in one vending machine!" - products = list(/obj/item/clothing/under/rank/scientist = 6,/obj/item/clothing/suit/bio_suit = 6,/obj/item/clothing/head/bio_hood = 6, - /obj/item/device/transfer_valve = 6,/obj/item/device/assembly/timer = 6,/obj/item/device/assembly/signaler = 6, - /obj/item/device/assembly/prox_sensor = 6,/obj/item/device/assembly/igniter = 6) - -/obj/machinery/vending/wallmed1 - name = "NanoMed" - desc = "Wall-mounted Medical Equipment dispenser." - product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?" - icon_state = "wallmed" - icon_deny = "wallmed-deny" - req_access_txt = "5" - density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude - products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/weapon/reagent_containers/syringe/inaprovaline = 4,/obj/item/device/healthanalyzer = 1) - contraband = list(/obj/item/weapon/reagent_containers/syringe/antitoxin = 4,/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/pill/tox = 1) - -/obj/machinery/vending/wallmed2 - name = "NanoMed" - desc = "Wall-mounted Medical Equipment dispenser." - icon_state = "wallmed" - icon_deny = "wallmed-deny" - req_access_txt = "5" - density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude - products = list(/obj/item/weapon/reagent_containers/syringe/inaprovaline = 5,/obj/item/weapon/reagent_containers/syringe/antitoxin = 3,/obj/item/stack/medical/bruise_pack = 3, - /obj/item/stack/medical/ointment =3,/obj/item/device/healthanalyzer = 3) - contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3) - -/obj/machinery/vending/security - name = "SecTech" - desc = "A security equipment vendor" - product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" - icon_state = "sec" - icon_deny = "sec-deny" - req_access_txt = "1" - products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, - /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6) - contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2) - -/obj/machinery/vending/hydronutrients - name = "NutriMax" - desc = "A plant nutrients vendor" - product_slogans = "Aren't you glad you don't have to fertilize the natural way?;Now with 50% less stink!;Plants are people too!" - product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..." - icon_state = "nutri" - icon_deny = "nutri-deny" - products = list(/obj/item/beezeez = 45,/obj/item/nutrient/ez = 35,/obj/item/nutrient/l4z = 25,/obj/item/nutrient/rh = 15,/obj/item/weapon/pestspray = 20, - /obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5) - contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) - -/obj/machinery/vending/hydroseeds - name = "MegaSeed Servitor" - desc = "When you need seeds fast!" - product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" - product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" - icon_state = "seeds" - products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, - /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, - /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3, - /obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3, - /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3, - /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3) - contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2, - /obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2) - premium = list(/obj/item/toy/waterflower = 1) - - -/obj/machinery/vending/magivend - name = "MagiVend" - desc = "A magic vending machine." - icon_state = "MagiVend" - product_slogans = "Sling spells the proper way with MagiVend!;Be your own Houdini! Use MagiVend!" - vend_delay = 15 - vend_reply = "Have an enchanted evening!" - product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!" - products = list(/obj/item/clothing/head/wizard = 1,/obj/item/clothing/suit/wizrobe = 1,/obj/item/clothing/head/wizard/red = 1,/obj/item/clothing/suit/wizrobe/red = 1,/obj/item/clothing/shoes/sandal = 1,/obj/item/weapon/staff = 2) - contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave - -/obj/machinery/vending/dinnerware - name = "Dinnerware" - desc = "A kitchen and restaurant equipment vendor" - product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..." - icon_state = "dinnerware" - products = list(/obj/item/weapon/tray = 8,/obj/item/weapon/kitchen/utensil/fork = 6,/obj/item/weapon/kitchenknife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2) - contraband = list(/obj/item/weapon/kitchen/utensil/spoon = 2,/obj/item/weapon/kitchen/utensil/knife = 2,/obj/item/weapon/kitchen/rollingpin = 2, /obj/item/weapon/butch = 2) - -/obj/machinery/vending/sovietsoda - name = "BODA" - desc = "Old sweet water vending machine" - icon_state = "sovietsoda" - product_ads = "For Tsar and Country.;Have you fulfilled your nutrition quota today?;Very nice!;We are simple people, for this is all we eat.;If there is a person, there is a problem. If there is no person, then there is no problem." - products = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/soda = 30) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/cola = 20) - -/obj/machinery/vending/tool - name = "YouTool" - desc = "Tools for tools." - icon_state = "tool" - icon_deny = "tool-deny" - //req_access_txt = "12" //Maintenance access - products = list(/obj/item/weapon/cable_coil/random = 10,/obj/item/weapon/crowbar = 5,/obj/item/weapon/weldingtool = 3,/obj/item/weapon/wirecutters = 5, - /obj/item/weapon/wrench = 5,/obj/item/device/analyzer = 5,/obj/item/device/t_scanner = 5,/obj/item/weapon/screwdriver = 5) - contraband = list(/obj/item/weapon/weldingtool/hugetank = 2,/obj/item/clothing/gloves/fyellow = 2) - premium = list(/obj/item/clothing/gloves/yellow = 1) - -/obj/machinery/vending/engivend - name = "Engi-Vend" - desc = "Spare tool vending. What? Did you expect some witty description?" - icon_state = "engivend" - icon_deny = "engivend-deny" - req_access_txt = "11" //Engineering Equipment access - products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/cell/high = 10) - contraband = list(/obj/item/weapon/cell/potato = 3) - premium = list(/obj/item/weapon/storage/belt/utility = 3) - -//This one's from bay12 -/obj/machinery/vending/engineering - name = "Robco Tool Maker" - desc = "Everything you need for do-it-yourself station repair." - icon_state = "engi" - icon_deny = "engi-deny" - req_access_txt = "11" - products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4, - /obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/yellow = 4, /obj/item/weapon/screwdriver = 12, - /obj/item/weapon/crowbar = 12,/obj/item/weapon/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/wrench = 12,/obj/item/device/t_scanner = 12, - /obj/item/weapon/cable_coil/heavyduty = 8, /obj/item/weapon/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8, - /obj/item/weapon/light/tube = 10,/obj/item/clothing/suit/fire = 4, /obj/item/weapon/stock_parts/scanning_module = 5,/obj/item/weapon/stock_parts/micro_laser = 5, - /obj/item/weapon/stock_parts/matter_bin = 5,/obj/item/weapon/stock_parts/manipulator = 5,/obj/item/weapon/stock_parts/console_screen = 5) - // There was an incorrect entry (cablecoil/power). I improvised to cablecoil/heavyduty. - // Another invalid entry, /obj/item/weapon/circuitry. I don't even know what that would translate to, removed it. - // The original products list wasn't finished. The ones without given quantities became quantity 5. -Sayu - -//This one's from bay12 -/obj/machinery/vending/robotics - name = "Robotech Deluxe" - desc = "All the tools you need to create your own robot army." - icon_state = "robotics" - icon_deny = "robotics-deny" - req_access_txt = "29" - products = list(/obj/item/clothing/suit/storage/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/weapon/cable_coil = 4,/obj/item/device/flash = 4, - /obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, - /obj/item/weapon/scalpel = 2,/obj/item/weapon/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, - /obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5) - //everything after the power cell had no amounts, I improvised. -Sayu - +/datum/data/vending_product + var/product_name = "generic" + var/product_path = null + var/amount = 0 + var/price = 0 + var/display_color = "blue" + + + +/obj/machinery/vending + name = "Vendomat" + desc = "A generic vending machine." + icon = 'icons/obj/vending.dmi' + icon_state = "generic" + layer = 2.9 + anchored = 1 + density = 1 + var/active = 1 //No sales pitches if off! + var/vend_ready = 1 //Are we ready to vend?? Is it time?? + var/vend_delay = 10 //How long does it take to vend? + var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now. + + // To be filled out at compile time + var/list/products = list() // For each, use the following pattern: + var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2) + var/list/premium = list() // No specified amount = only one in stock + var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price. + + var/product_slogans = "" //String of slogans separated by semicolons, optional + var/product_ads = "" //String of small ad messages in the vending screen - random chance + var/list/product_records = list() + var/list/hidden_records = list() + var/list/coin_records = list() + var/list/slogan_list = list() + var/list/small_ads = list() // small ad messages in the vending screen - random chance of popping up whenever you open it + var/vend_reply //Thank you for shopping! + var/last_reply = 0 + var/last_slogan = 0 //When did we last pitch? + var/slogan_delay = 6000 //How long until we can pitch again? + var/icon_vend //Icon_state when vending! + var/icon_deny //Icon_state when vending! + //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine. + var/seconds_electrified = 0 //Shock customers like an airlock. + var/shoot_inventory = 0 //Fire items at customers! We're broken! + var/shut_up = 1 //Stop spouting those godawful pitches! + var/extended_inventory = 0 //can we access the hidden inventory? + var/panel_open = 0 //Hacking that vending machine. Gonna get a free candy bar. + var/wires = 15 + var/obj/item/weapon/coin/coin + var/const/WIRE_EXTEND = 1 + var/const/WIRE_SCANID = 2 + var/const/WIRE_SHOCK = 3 + var/const/WIRE_SHOOTINV = 4 + + var/obj/machinery/account_database/linked_db + var/datum/money_account/linked_account + +/obj/machinery/vending/New() + ..() + spawn(4) + src.slogan_list = text2list(src.product_slogans, ";") + + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + src.last_slogan = world.time + rand(0, slogan_delay) + + src.build_inventory(products) + //Add hidden inventory + src.build_inventory(contraband, 1) + src.build_inventory(premium, 0, 1) + power_change() + + reconnect_database() + linked_account = vendor_account + + return + + return + +/obj/machinery/vending/proc/reconnect_database() + for(var/obj/machinery/account_database/DB in world) + if(DB.z == src.z) + linked_db = DB + break + +/obj/machinery/vending/ex_act(severity) + switch(severity) + if(1.0) + del(src) + return + if(2.0) + if (prob(50)) + del(src) + return + if(3.0) + if (prob(25)) + spawn(0) + src.malfunction() + return + return + else + return + +/obj/machinery/vending/blob_act() + if (prob(50)) + spawn(0) + src.malfunction() + del(src) + return + + return + +/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0) + for(var/typepath in productlist) + var/amount = productlist[typepath] + var/price = prices[typepath] + if(isnull(amount)) amount = 1 + + var/atom/temp = new typepath(null) + var/datum/data/vending_product/R = new /datum/data/vending_product() + R.product_name = temp.name + R.product_path = typepath + R.amount = amount + R.price = price + R.display_color = pick("red","blue","green") + + if(hidden) + hidden_records += R + else if(req_coin) + coin_records += R + else + product_records += R +// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]" + return + +/obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/card/emag)) + src.emagged = 1 + user << "You short out the product lock on [src]" + return + else if(istype(W, /obj/item/weapon/screwdriver)) + src.panel_open = !src.panel_open + user << "You [src.panel_open ? "open" : "close"] the maintenance panel." + src.overlays.Cut() + if(src.panel_open) + src.overlays += image(src.icon, "[initial(icon_state)]-panel") + src.updateUsrDialog() + return + else if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters)) + if(src.panel_open) + attack_hand(user) + return + else if(istype(W, /obj/item/weapon/coin) && premium.len > 0) + user.drop_item() + W.loc = src + coin = W + user << "\blue You insert the [W] into the [src]" + return + else if(istype(W, /obj/item/weapon/card) && currently_vending) + //attempt to connect to a new db, and if that doesn't work then fail + if(!linked_db) + reconnect_database() + if(linked_db) + if(linked_account) + var/obj/item/weapon/card/I = W + scan_card(I) + else + usr << "\icon[src]Unable to connect to linked account." + else + usr << "\icon[src]Unable to connect to accounts database." + else + ..() + +/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I) + if(!currently_vending) return + if (istype(I, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/C = I + visible_message("[usr] swipes a card through [src].") + if(linked_account) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + var/datum/money_account/D = linked_db.attempt_account_access(C.associated_account_number, attempt_pin, 2) + if(D) + var/transaction_amount = currently_vending.price + if(transaction_amount <= D.money) + + //transfer the money + D.money -= transaction_amount + linked_account.money += transaction_amount + + //create entries in the two account transaction logs + var/datum/transaction/T = new() + T.target_name = "[linked_account.owner_name] (via [src.name])" + T.purpose = "Purchase of [currently_vending.product_name]" + if(transaction_amount > 0) + T.amount = "([transaction_amount])" + else + T.amount = "[transaction_amount]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + D.transaction_log.Add(T) + // + T = new() + T.target_name = D.owner_name + T.purpose = "Purchase of [currently_vending.product_name]" + T.amount = "[transaction_amount]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + linked_account.transaction_log.Add(T) + + // Vend the item + src.vend(src.currently_vending, usr) + currently_vending = null + else + usr << "\icon[src]You don't have that much money!" + else + usr << "\icon[src]Unable to access account. Check security settings and try again." + else + usr << "\icon[src]EFTPOS is not connected to an account." + +/obj/machinery/vending/attack_paw(mob/user as mob) + return attack_hand(user) + +/obj/machinery/vending/attack_ai(mob/user as mob) + return attack_hand(user) + +/obj/machinery/vending/attack_hand(mob/user as mob) + if(stat & (BROKEN|NOPOWER)) + return + user.set_machine(src) + + if(src.seconds_electrified != 0) + if(src.shock(user, 100)) + return + + var/vendorname = (src.name) //import the machine's name + + if(src.currently_vending) + var/dat = "
[vendorname]


" //display the name, and added a horizontal rule + dat += "You have selected [currently_vending.product_name].
Please swipe your ID to pay for the article.

" + dat += "Cancel" + user << browse(dat, "window=vending") + onclose(user, "") + return + + var/dat = "
[vendorname]


" //display the name, and added a horizontal rule + dat += "Select an item:

" //the rest is just general spacing and bolding + + if (premium.len > 0) + dat += "Coin slot: [coin ? coin : "No coin inserted"] (Remove)

" + + if (src.product_records.len == 0) + dat += "No product loaded!" + else + var/list/display_records = src.product_records + if(src.extended_inventory) + display_records = src.product_records + src.hidden_records + if(src.coin) + display_records = src.product_records + src.coin_records + if(src.coin && src.extended_inventory) + display_records = src.product_records + src.hidden_records + src.coin_records + + for (var/datum/data/vending_product/R in display_records) + dat += "[R.product_name]:" + dat += " [R.amount] " + if(R.price) + dat += " (Price: [R.price])" + if (R.amount > 0) + dat += " (Vend)" + else + dat += " SOLD OUT" + dat += "
" + + dat += "
" + + if(panel_open) + var/list/vendwires = list( + "Violet" = 1, + "Orange" = 2, + "Goldenrod" = 3, + "Green" = 4, + ) + dat += "


Access Panel
" + for(var/wiredesc in vendwires) + var/is_uncut = src.wires & APCWireColorToFlag[vendwires[wiredesc]] + dat += "[wiredesc] wire: " + if(!is_uncut) + dat += "Mend" + else + dat += "Cut " + dat += "Pulse " + dat += "
" + + dat += "
" + dat += "The orange light is [(src.seconds_electrified == 0) ? "off" : "on"].
" + dat += "The red light is [src.shoot_inventory ? "off" : "blinking"].
" + dat += "The green light is [src.extended_inventory ? "on" : "off"].
" + dat += "The [(src.wires & WIRE_SCANID) ? "purple" : "yellow"] light is on.
" + + if (product_slogans != "") + dat += "The speaker switch is [src.shut_up ? "off" : "on"]. Toggle" + + user << browse(dat, "window=vending") + onclose(user, "") + return + +/obj/machinery/vending/Topic(href, href_list) + if(stat & (BROKEN|NOPOWER)) + return + if(usr.stat || usr.restrained()) + return + + if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon)) + if(!coin) + usr << "There is no coin in this machine." + return + + coin.loc = src.loc + if(!usr.get_active_hand()) + usr.put_in_hands(coin) + usr << "\blue You remove the [coin] from the [src]" + coin = null + + + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) + usr.set_machine(src) + if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending)) + + if(istype(usr,/mob/living/silicon)) + if(istype(usr,/mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = usr + if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) )) + usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" + return + else + usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" + return + + if ((!src.allowed(usr)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH + usr << "\red Access denied." //Unless emagged of course + flick(src.icon_deny,src) + return + + var/datum/data/vending_product/R = locate(href_list["vend"]) + if (!R || !istype(R) || !R.product_path || R.amount <= 0) + return + + if(R.price == null) + src.vend(R, usr) + else + src.currently_vending = R + src.updateUsrDialog() + + return + + else if (href_list["cancel_buying"]) + src.currently_vending = null + src.updateUsrDialog() + return + + else if ((href_list["cutwire"]) && (src.panel_open)) + var/twire = text2num(href_list["cutwire"]) + if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) )) + usr << "You need wirecutters!" + return + if (src.isWireColorCut(twire)) + src.mend(twire) + else + src.cut(twire) + + else if ((href_list["pulsewire"]) && (src.panel_open)) + var/twire = text2num(href_list["pulsewire"]) + if (!istype(usr.get_active_hand(), /obj/item/device/multitool)) + usr << "You need a multitool!" + return + if (src.isWireColorCut(twire)) + usr << "You can't pulse a cut wire." + return + else + src.pulse(twire) + + else if ((href_list["togglevoice"]) && (src.panel_open)) + src.shut_up = !src.shut_up + + src.add_fingerprint(usr) + src.updateUsrDialog() + else + usr << browse(null, "window=vending") + return + return + +/obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user) + if ((!src.allowed(user)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH + user << "\red Access denied." //Unless emagged of course + flick(src.icon_deny,src) + return + src.vend_ready = 0 //One thing at a time!! + + if (R in coin_records) + if(!coin) + user << "\blue You need to insert a coin to get this item." + return + if(coin.string_attached) + if(prob(50)) + user << "\blue You successfully pull the coin out before the [src] could swallow it." + else + user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all." + del(coin) + else + del(coin) + + R.amount-- + + if(((src.last_reply + (src.vend_delay + 200)) <= world.time) && src.vend_reply) + spawn(0) + src.speak(src.vend_reply) + src.last_reply = world.time + + use_power(5) + if (src.icon_vend) //Show the vending animation if needed + flick(src.icon_vend,src) + spawn(src.vend_delay) + new R.product_path(get_turf(src)) + src.vend_ready = 1 + return + + src.updateUsrDialog() + +/obj/machinery/vending/process() + if(stat & (BROKEN|NOPOWER)) + return + + if(!src.active) + return + + if(src.seconds_electrified > 0) + src.seconds_electrified-- + + //Pitch to the people! Really sell it! + if(((src.last_slogan + src.slogan_delay) <= world.time) && (src.slogan_list.len > 0) && (!src.shut_up) && prob(5)) + var/slogan = pick(src.slogan_list) + src.speak(slogan) + src.last_slogan = world.time + + if(src.shoot_inventory && prob(2)) + src.throw_item() + + return + +/obj/machinery/vending/proc/speak(var/message) + if(stat & NOPOWER) + return + + if (!message) + return + + for(var/mob/O in hearers(src, null)) + O.show_message("[src] beeps, \"[message]\"",2) + return + +/obj/machinery/vending/power_change() + if(stat & BROKEN) + icon_state = "[initial(icon_state)]-broken" + else + if( powered() ) + icon_state = initial(icon_state) + stat &= ~NOPOWER + else + spawn(rand(0, 15)) + src.icon_state = "[initial(icon_state)]-off" + stat |= NOPOWER + +//Oh no we're malfunctioning! Dump out some product and break. +/obj/machinery/vending/proc/malfunction() + for(var/datum/data/vending_product/R in src.product_records) + if (R.amount <= 0) //Try to use a record that actually has something to dump. + continue + var/dump_path = R.product_path + if (!dump_path) + continue + + while(R.amount>0) + new dump_path(src.loc) + R.amount-- + break + + stat |= BROKEN + src.icon_state = "[initial(icon_state)]-broken" + return + +//Somebody cut an important wire and now we're following a new definition of "pitch." +/obj/machinery/vending/proc/throw_item() + var/obj/throw_item = null + var/mob/living/target = locate() in view(7,src) + if(!target) + return 0 + + for(var/datum/data/vending_product/R in src.product_records) + if (R.amount <= 0) //Try to use a record that actually has something to dump. + continue + var/dump_path = R.product_path + if (!dump_path) + continue + + R.amount-- + throw_item = new dump_path(src.loc) + break + if (!throw_item) + return 0 + spawn(0) + throw_item.throw_at(target, 16, 3) + src.visible_message("\red [src] launches [throw_item.name] at [target.name]!") + return 1 + +/obj/machinery/vending/proc/isWireColorCut(var/wireColor) + var/wireFlag = APCWireColorToFlag[wireColor] + return ((src.wires & wireFlag) == 0) + +/obj/machinery/vending/proc/isWireCut(var/wireIndex) + var/wireFlag = APCIndexToFlag[wireIndex] + return ((src.wires & wireFlag) == 0) + +/obj/machinery/vending/proc/cut(var/wireColor) + var/wireFlag = APCWireColorToFlag[wireColor] + var/wireIndex = APCWireColorToIndex[wireColor] + src.wires &= ~wireFlag + switch(wireIndex) + if(WIRE_EXTEND) + src.extended_inventory = 0 + if(WIRE_SHOCK) + src.seconds_electrified = -1 + if (WIRE_SHOOTINV) + if(!src.shoot_inventory) + src.shoot_inventory = 1 + + +/obj/machinery/vending/proc/mend(var/wireColor) + var/wireFlag = APCWireColorToFlag[wireColor] + var/wireIndex = APCWireColorToIndex[wireColor] //not used in this function + src.wires |= wireFlag + switch(wireIndex) +// if(WIRE_SCANID) + if(WIRE_SHOCK) + src.seconds_electrified = 0 + if (WIRE_SHOOTINV) + src.shoot_inventory = 0 + +/obj/machinery/vending/proc/pulse(var/wireColor) + var/wireIndex = APCWireColorToIndex[wireColor] + switch(wireIndex) + if(WIRE_EXTEND) + src.extended_inventory = !src.extended_inventory +// if (WIRE_SCANID) + if (WIRE_SHOCK) + src.seconds_electrified = 30 + if (WIRE_SHOOTINV) + src.shoot_inventory = !src.shoot_inventory + + +/obj/machinery/vending/proc/shock(mob/user, prb) + if(stat & (BROKEN|NOPOWER)) // unpowered, no shock + return 0 + if(!prob(prb)) + return 0 + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + if (electrocute_mob(user, get_area(src), src, 0.7)) + return 1 + else + return 0 + +/* + * Vending machine types + */ + +/* + +/obj/machinery/vending/[vendors name here] // --vending machine template :) + name = "" + desc = "" + icon = '' + icon_state = "" + vend_delay = 15 + products = list() + contraband = list() + premium = list() + +*/ + +/* +/obj/machinery/vending/atmospherics //Commenting this out until someone ponies up some actual working, broken, and unpowered sprites - Quarxink + name = "Tank Vendor" + desc = "A vendor with a wide variety of masks and gas tanks." + icon = 'icons/obj/objects.dmi' + icon_state = "dispenser" + product_paths = "/obj/item/weapon/tank/oxygen;/obj/item/weapon/tank/plasma;/obj/item/weapon/tank/emergency_oxygen;/obj/item/weapon/tank/emergency_oxygen/engi;/obj/item/clothing/mask/breath" + product_amounts = "10;10;10;5;25" + vend_delay = 0 +*/ + +/obj/machinery/vending/boozeomat + name = "Booze-O-Mat" + desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." + icon_state = "boozeomat" //////////////18 drink entities below, plus the glasses, in case someone wants to edit the number of bottles + icon_deny = "boozeomat-deny" + products = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/rum = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 5,/obj/item/weapon/reagent_containers/food/drinks/beer = 6, + /obj/item/weapon/reagent_containers/food/drinks/ale = 6,/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 4, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 4,/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 4, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 4,/obj/item/weapon/reagent_containers/food/drinks/tonic = 8, + /obj/item/weapon/reagent_containers/food/drinks/cola = 8, /obj/item/weapon/reagent_containers/food/drinks/sodawater = 15, + /obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 9) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/tea = 10) + vend_delay = 15 + product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" + product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" + req_access_txt = "25" + +/obj/machinery/vending/assist + products = list( /obj/item/device/assembly/prox_sensor = 5,/obj/item/device/assembly/igniter = 3,/obj/item/device/assembly/signaler = 4, + /obj/item/weapon/wirecutters = 1, /obj/item/weapon/cartridge/signal = 4) + contraband = list(/obj/item/device/flashlight = 5,/obj/item/device/assembly/timer = 2) + product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!" + +/obj/machinery/vending/coffee + name = "Hot Drinks machine" + desc = "A vending machine which dispenses hot drinks." + product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies" + icon_state = "coffee" + icon_vend = "coffee-vend" + vend_delay = 34 + products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10) + prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25, /obj/item/weapon/reagent_containers/food/drinks/tea = 25, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25) + + + + +/obj/machinery/vending/snack + name = "Getmore Chocolate Corp" + desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars" + product_slogans = "Try our new nougat bar!;Twice the calories for half the price!" + product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!" + icon_state = "snack" + products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 6,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 6,/obj/item/weapon/reagent_containers/food/snacks/chips =6, + /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6, + /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6) + contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6) + prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 20,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 30,/obj/item/weapon/reagent_containers/food/snacks/chips =25, + /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 30,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 20,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 30, + /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 25) + + + +/obj/machinery/vending/cola + name = "Robust Softdrinks" + desc = "A softdrink vendor provided by Robust Industries, LLC." + icon_state = "Cola_Machine" + product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!" + product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space." + products = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 10, + /obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/starkist = 10, + /obj/item/weapon/reagent_containers/food/drinks/space_up = 10) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/thirteenloko = 5) + prices = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 20,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 20, + /obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 20,/obj/item/weapon/reagent_containers/food/drinks/starkist = 20, + /obj/item/weapon/reagent_containers/food/drinks/space_up = 20) + +//This one's from bay12 +/obj/machinery/vending/cart + name = "PTech" + desc = "Cartridges for PDAs" + product_slogans = "Carts to go!" + icon_state = "cart" + icon_deny = "cart-deny" + products = list(/obj/item/weapon/cartridge/medical = 10,/obj/item/weapon/cartridge/engineering = 10,/obj/item/weapon/cartridge/security = 10, + /obj/item/weapon/cartridge/janitor = 10,/obj/item/weapon/cartridge/signal/toxins = 10,/obj/item/device/pda/heads = 10, + /obj/item/weapon/cartridge/captain = 3,/obj/item/weapon/cartridge/quartermaster = 10) + + +/obj/machinery/vending/cigarette + name = "Cigarette machine" //OCD had to be uppercase to look nice with the new formating + desc = "If you want to get cancer, might as well do it in style" + product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!" + product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs." + vend_delay = 34 + icon_state = "cigs" + products = list(/obj/item/weapon/storage/fancy/cigarettes = 10,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 4) + contraband = list(/obj/item/weapon/lighter/zippo = 4) + premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2) + prices = list(/obj/item/weapon/storage/fancy/cigarettes = 60,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 60) + + +/obj/machinery/vending/medical + name = "NanoMed Plus" + desc = "Medical drug dispenser." + icon_state = "med" + icon_deny = "med-deny" + product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" + req_access_txt = "5" + products = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline = 4, + /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, + /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, + /obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2, + /obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2) + contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6) + + +//This one's from bay12 +/obj/machinery/vending/plasmaresearch + name = "Toximate 3000" + desc = "All the fine parts you need in one vending machine!" + products = list(/obj/item/clothing/under/rank/scientist = 6,/obj/item/clothing/suit/bio_suit = 6,/obj/item/clothing/head/bio_hood = 6, + /obj/item/device/transfer_valve = 6,/obj/item/device/assembly/timer = 6,/obj/item/device/assembly/signaler = 6, + /obj/item/device/assembly/prox_sensor = 6,/obj/item/device/assembly/igniter = 6) + +/obj/machinery/vending/wallmed1 + name = "NanoMed" + desc = "Wall-mounted Medical Equipment dispenser." + product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?" + icon_state = "wallmed" + icon_deny = "wallmed-deny" + req_access_txt = "5" + density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude + products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/weapon/reagent_containers/hypospray/autoinjector = 4,/obj/item/device/healthanalyzer = 1) + contraband = list(/obj/item/weapon/reagent_containers/syringe/antitoxin = 4,/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/pill/tox = 1) + +/obj/machinery/vending/wallmed2 + name = "NanoMed" + desc = "Wall-mounted Medical Equipment dispenser." + icon_state = "wallmed" + icon_deny = "wallmed-deny" + req_access_txt = "5" + density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude + products = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector = 5,/obj/item/weapon/reagent_containers/syringe/antitoxin = 3,/obj/item/stack/medical/bruise_pack = 3, + /obj/item/stack/medical/ointment =3,/obj/item/device/healthanalyzer = 3) + contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3) + +/obj/machinery/vending/security + name = "SecTech" + desc = "A security equipment vendor" + product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" + icon_state = "sec" + icon_deny = "sec-deny" + req_access_txt = "1" + products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, + /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6) + contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2) + +/obj/machinery/vending/hydronutrients + name = "NutriMax" + desc = "A plant nutrients vendor" + product_slogans = "Aren't you glad you don't have to fertilize the natural way?;Now with 50% less stink!;Plants are people too!" + product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..." + icon_state = "nutri" + icon_deny = "nutri-deny" + products = list(/obj/item/beezeez = 45,/obj/item/nutrient/ez = 35,/obj/item/nutrient/l4z = 25,/obj/item/nutrient/rh = 15,/obj/item/weapon/pestspray = 20, + /obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5) + contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) + +/obj/machinery/vending/hydroseeds + name = "MegaSeed Servitor" + desc = "When you need seeds fast!" + product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" + product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" + icon_state = "seeds" + products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, + /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, + /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3, + /obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3, + /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3, + /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3) + contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2, + /obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2) + premium = list(/obj/item/toy/waterflower = 1) + + +/obj/machinery/vending/magivend + name = "MagiVend" + desc = "A magic vending machine." + icon_state = "MagiVend" + product_slogans = "Sling spells the proper way with MagiVend!;Be your own Houdini! Use MagiVend!" + vend_delay = 15 + vend_reply = "Have an enchanted evening!" + product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!" + products = list(/obj/item/clothing/head/wizard = 1,/obj/item/clothing/suit/wizrobe = 1,/obj/item/clothing/head/wizard/red = 1,/obj/item/clothing/suit/wizrobe/red = 1,/obj/item/clothing/shoes/sandal = 1,/obj/item/weapon/staff = 2) + contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave + +/obj/machinery/vending/dinnerware + name = "Dinnerware" + desc = "A kitchen and restaurant equipment vendor" + product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..." + icon_state = "dinnerware" + products = list(/obj/item/weapon/tray = 8,/obj/item/weapon/kitchen/utensil/fork = 6,/obj/item/weapon/kitchenknife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2) + contraband = list(/obj/item/weapon/kitchen/utensil/spoon = 2,/obj/item/weapon/kitchen/utensil/knife = 2,/obj/item/weapon/kitchen/rollingpin = 2, /obj/item/weapon/butch = 2) + +/obj/machinery/vending/sovietsoda + name = "BODA" + desc = "Old sweet water vending machine" + icon_state = "sovietsoda" + product_ads = "For Tsar and Country.;Have you fulfilled your nutrition quota today?;Very nice!;We are simple people, for this is all we eat.;If there is a person, there is a problem. If there is no person, then there is no problem." + products = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/soda = 30) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/cola = 20) + +/obj/machinery/vending/tool + name = "YouTool" + desc = "Tools for tools." + icon_state = "tool" + icon_deny = "tool-deny" + //req_access_txt = "12" //Maintenance access + products = list(/obj/item/weapon/cable_coil/random = 10,/obj/item/weapon/crowbar = 5,/obj/item/weapon/weldingtool = 3,/obj/item/weapon/wirecutters = 5, + /obj/item/weapon/wrench = 5,/obj/item/device/analyzer = 5,/obj/item/device/t_scanner = 5,/obj/item/weapon/screwdriver = 5) + contraband = list(/obj/item/weapon/weldingtool/hugetank = 2,/obj/item/clothing/gloves/fyellow = 2) + premium = list(/obj/item/clothing/gloves/yellow = 1) + +/obj/machinery/vending/engivend + name = "Engi-Vend" + desc = "Spare tool vending. What? Did you expect some witty description?" + icon_state = "engivend" + icon_deny = "engivend-deny" + req_access_txt = "11" //Engineering Equipment access + products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/cell/high = 10) + contraband = list(/obj/item/weapon/cell/potato = 3) + premium = list(/obj/item/weapon/storage/belt/utility = 3) + +//This one's from bay12 +/obj/machinery/vending/engineering + name = "Robco Tool Maker" + desc = "Everything you need for do-it-yourself station repair." + icon_state = "engi" + icon_deny = "engi-deny" + req_access_txt = "11" + products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4, + /obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/yellow = 4, /obj/item/weapon/screwdriver = 12, + /obj/item/weapon/crowbar = 12,/obj/item/weapon/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/wrench = 12,/obj/item/device/t_scanner = 12, + /obj/item/weapon/cable_coil/heavyduty = 8, /obj/item/weapon/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8, + /obj/item/weapon/light/tube = 10,/obj/item/clothing/suit/fire = 4, /obj/item/weapon/stock_parts/scanning_module = 5,/obj/item/weapon/stock_parts/micro_laser = 5, + /obj/item/weapon/stock_parts/matter_bin = 5,/obj/item/weapon/stock_parts/manipulator = 5,/obj/item/weapon/stock_parts/console_screen = 5) + // There was an incorrect entry (cablecoil/power). I improvised to cablecoil/heavyduty. + // Another invalid entry, /obj/item/weapon/circuitry. I don't even know what that would translate to, removed it. + // The original products list wasn't finished. The ones without given quantities became quantity 5. -Sayu + +//This one's from bay12 +/obj/machinery/vending/robotics + name = "Robotech Deluxe" + desc = "All the tools you need to create your own robot army." + icon_state = "robotics" + icon_deny = "robotics-deny" + req_access_txt = "29" + products = list(/obj/item/clothing/suit/storage/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/weapon/cable_coil = 4,/obj/item/device/flash = 4, + /obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, + /obj/item/weapon/scalpel = 2,/obj/item/weapon/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, + /obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5) + //everything after the power cell had no amounts, I improvised. -Sayu + diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index c55684eb197..281c23f0fd0 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -131,8 +131,7 @@ else if(isliving(src.loc)) return - user.lastDblClick = world.time + 2 - user.next_move = world.time + 2 + user.delay_click(2) src.pickup(user) add_fingerprint(user) user.put_in_active_hand(src) @@ -166,8 +165,7 @@ if(istype(src.loc, /mob/living)) return src.pickup(user) - user.lastDblClick = world.time + 2 - user.next_move = world.time + 2 + user.delay_click(2) user.put_in_active_hand(src) return @@ -229,6 +227,8 @@ log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)])" ) msg_admin_attack("ATTACK: [user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") //BS12 EDIT ALG + user.delay_click(10) + //spawn(1800) // this wont work right // M.lastattacker = null ///////////////////////// diff --git a/code/game/objects/items/devices/pipe_painter.dm b/code/game/objects/items/devices/pipe_painter.dm new file mode 100644 index 00000000000..da297fbb55b --- /dev/null +++ b/code/game/objects/items/devices/pipe_painter.dm @@ -0,0 +1,22 @@ +/obj/item/device/pipe_painter + name = "pipe painter" + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "labeler1" + item_state = "flight" + var/list/modes = list("grey","red","blue","cyan","green","yellow","purple") + var/mode = "grey" + +/obj/item/device/pipe_painter/afterattack(atom/A, mob/user as mob) + if(!istype(A,/obj/machinery/atmospherics/pipe) || istype(A,/obj/machinery/atmospherics/pipe/tank) || istype(A,/obj/machinery/atmospherics/pipe/vent) || istype(A,/obj/machinery/atmospherics/pipe/simple/heat_exchanging) || istype(A,/obj/machinery/atmospherics/pipe/simple/insulated)) + return + var/obj/machinery/atmospherics/pipe/P = A + P.color = mode + user.visible_message("[user] paints \the [P] [mode].","You paint \the [P] [mode].") + P.update_icon() + +/obj/item/device/pipe_painter/attack_self(mob/user as mob) + mode = input("Which colour do you want to use?","Pipe painter") in modes + +/obj/item/device/pipe_painter/examine() + ..() + usr << "It is in [mode] mode." \ No newline at end of file diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index 165f6748ec5..d2d5417d6c3 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -121,7 +121,8 @@ desc = "An encyption key for a radio headset. Contains cypherkeys." icon_state = "cargo_cypherkey" channels = list("Supply" = 1) + /obj/item/device/encryptionkey/ert name = "NanoTrasen ERT Radio Encryption Key" desc = "An encyption key for a radio headset. Contains cypherkeys." - channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Mining" = 1, "Cargo" = 1,) + channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 0081954da84..422a27897c0 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -499,8 +499,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use freq_text = "Engineering" if(1359) freq_text = "Security" -// if(1349) -// freq_text = "Mining" if(1347) freq_text = "Supply" //There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 9fccf2e0604..5011f5346ee 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -33,6 +33,7 @@ R.base_icon = "robot" del(R.module) R.module = null + R.camera.network.Remove(list("Medical","MINE")) R.updatename("Default") R.status_flags |= CANPUSH R.updateicon() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index ca538c254e2..4721bcc8fe6 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -11,15 +11,6 @@ var/heal_burn = 0 /obj/item/stack/medical/attack(mob/living/carbon/M as mob, mob/user as mob) - if (M.stat == 2) - var/t_him = "it" - if (M.gender == MALE) - t_him = "him" - else if (M.gender == FEMALE) - t_him = "her" - user << "\red \The [M] is dead, you cannot help [t_him]!" - return 1 - if (!istype(M)) user << "\red \The [src] cannot be applied to [M]!" return 1 @@ -47,42 +38,16 @@ user << "\red This isn't useful at all on a robotic limb.." return 1 - if(src.heal_brute) - if(!affecting.bandage()) - user << "\red The wounds on [M]'s [affecting.display_name] have already been bandaged." - return 1 - else - for (var/datum/wound/W in affecting.wounds) - if (W.internal) - continue - if (W.current_stage <= W.max_bleeding_stage) - user.visible_message( "\blue [user] bandages [W.desc] on [M]'s [affecting.display_name].", \ - "\blue You bandage [W.desc] on [M]'s [affecting.display_name]." ) - //H.add_side_effect("Itch") - else if (istype(W,/datum/wound/bruise)) - user.visible_message( "\blue [user] places bruise patch over [W.desc] on [M]'s [affecting.display_name].", \ - "\blue You place bruise patch over [W.desc] on [M]'s [affecting.display_name]." ) - else - user.visible_message( "\blue [user] places bandaid over [W.desc] on [M]'s [affecting.display_name].", \ - "\blue You place bandaid over [W.desc] on [M]'s [affecting.display_name]." ) - - else if(src.heal_burn) - if(!affecting.salve()) - user << "\red The wounds on [M]'s [affecting.display_name] have already been salved." - return 1 - else - user.visible_message( "\blue [user] salves wounds on [M]'s [affecting.display_name].", \ - "\blue You salve wounds on [M]'s [affecting.display_name]." ) - H.UpdateDamageIcon() + else + M.heal_organ_damage((src.heal_brute/2), (src.heal_burn/2)) user.visible_message( \ "\blue [M] has been applied with [src] by [user].", \ "\blue You apply \the [src] to [M]." \ ) - - use(1) + use(1) M.updatehealth() /obj/item/stack/medical/bruise_pack @@ -90,18 +55,60 @@ singular_name = "gauze length" desc = "Some sterile gauze to wrap around bloody stumps." icon_state = "brutepack" - heal_brute = 60 origin_tech = "biotech=1" +/obj/item/stack/medical/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob) + if(..()) + return 1 + + if (istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + + if(!affecting.bandage()) + user << "\red The wounds on [M]'s [affecting.display_name] have already been bandaged." + return 1 + else + for (var/datum/wound/W in affecting.wounds) + if (W.internal) + continue + if (W.current_stage <= W.max_bleeding_stage) + user.visible_message( "\blue [user] bandages [W.desc] on [M]'s [affecting.display_name].", \ + "\blue You bandage [W.desc] on [M]'s [affecting.display_name]." ) + //H.add_side_effect("Itch") + else if (istype(W,/datum/wound/bruise)) + user.visible_message( "\blue [user] places bruise patch over [W.desc] on [M]'s [affecting.display_name].", \ + "\blue You place bruise patch over [W.desc] on [M]'s [affecting.display_name]." ) + else + user.visible_message( "\blue [user] places bandaid over [W.desc] on [M]'s [affecting.display_name].", \ + "\blue You place bandaid over [W.desc] on [M]'s [affecting.display_name]." ) + use(1) + /obj/item/stack/medical/ointment name = "ointment" desc = "Used to treat those nasty burns." gender = PLURAL singular_name = "ointment" icon_state = "ointment" - heal_burn = 40 + heal_burn = 1 origin_tech = "biotech=1" +/obj/item/stack/medical/ointment/attack(mob/living/carbon/M as mob, mob/user as mob) + if(..()) + return 1 + + if (istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + + if(!affecting.salve()) + user << "\red The wounds on [M]'s [affecting.display_name] have already been salved." + return 1 + else + user.visible_message( "\blue [user] salves wounds on [M]'s [affecting.display_name].", \ + "\blue You salve wounds on [M]'s [affecting.display_name]." ) + use(1) + /obj/item/stack/medical/bruise_pack/tajaran name = "\improper S'rendarr's Hand leaf" singular_name = "S'rendarr's Hand leaf" @@ -126,6 +133,34 @@ heal_brute = 12 origin_tech = "biotech=1" +/obj/item/stack/medical/advanced/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob) + if(..()) + return 1 + + if (istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + + if(!affecting.bandage()) + user << "\red The wounds on [M]'s [affecting.display_name] have already been treated." + return 1 + else + for (var/datum/wound/W in affecting.wounds) + if (W.internal) + continue + if (W.current_stage <= W.max_bleeding_stage) + user.visible_message( "\blue [user] cleans [W.desc] on [M]'s [affecting.display_name] and seals edges with bioglue.", \ + "\blue You clean and seal [W.desc] on [M]'s [affecting.display_name]." ) + //H.add_side_effect("Itch") + else if (istype(W,/datum/wound/bruise)) + user.visible_message( "\blue [user] places medicine patch over [W.desc] on [M]'s [affecting.display_name].", \ + "\blue You place medicine patch over [W.desc] on [M]'s [affecting.display_name]." ) + else + user.visible_message( "\blue [user] smears some bioglue over [W.desc] on [M]'s [affecting.display_name].", \ + "\blue You smear some bioglue over [W.desc] on [M]'s [affecting.display_name]." ) + affecting.heal_damage(heal_brute,0) + use(1) + /obj/item/stack/medical/advanced/ointment name = "advanced burn kit" singular_name = "advanced burn kit" @@ -134,8 +169,26 @@ heal_burn = 12 origin_tech = "biotech=1" + +/obj/item/stack/medical/advanced/ointment/attack(mob/living/carbon/M as mob, mob/user as mob) + if(..()) + return 1 + + if (istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + + if(!affecting.salve()) + user << "\red The wounds on [M]'s [affecting.display_name] have already been salved." + return 1 + else + user.visible_message( "\blue [user] covers wounds on [M]'s [affecting.display_name] with regenerative membrane.", \ + "\blue You cover wounds on [M]'s [affecting.display_name] with regenerative membrane." ) + affecting.heal_damage(0,heal_burn) + use(1) + /obj/item/stack/medical/splint - name = "medical splint" + name = "medical splints" singular_name = "medical splint" icon_state = "splint" amount = 5 @@ -143,3 +196,38 @@ /obj/item/stack/medical/splint/single amount = 1 + + +/obj/item/stack/medical/splint/attack(mob/living/carbon/M as mob, mob/user as mob) + if(..()) + return 1 + + if (istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + var/limb = affecting.display_name + if(!((affecting.name == "l_arm") || (affecting.name == "r_arm") || (affecting.name == "l_leg") || (affecting.name == "r_leg"))) + user << "\red You can't apply a splint there!" + return + if(affecting.status & ORGAN_SPLINTED) + user << "\red [M]'s [limb] is already splinted!" + return + if (M != user) + user.visible_message("\red [user] starts to apply \the [src] to [M]'s [limb].", "\red You start to apply \the [src] to [M]'s [limb].", "\red You hear something being wrapped.") + else + if((!user.hand && affecting.name == "r_arm") || (user.hand && affecting.name == "l_arm")) + user << "\red You can't apply a splint to the arm you're using!" + return + user.visible_message("\red [user] starts to apply \the [src] to their [limb].", "\red You start to apply \the [src] to your [limb].", "\red You hear something being wrapped.") + if(do_after(user, 50)) + if (M != user) + user.visible_message("\red [user] finishes applying \the [src] to [M]'s [limb].", "\red You finish applying \the [src] to [M]'s [limb].", "\red You hear something being wrapped.") + else + if(prob(25)) + user.visible_message("\red [user] successfully applies \the [src] to their [limb].", "\red You successfully apply \the [src] to your [limb].", "\red You hear something being wrapped.") + else + user.visible_message("\red [user] fumbles \the [src].", "\red You fumble \the [src].", "\red You hear something being wrapped.") + return + affecting.status |= ORGAN_SPLINTED + use(1) + return \ No newline at end of file diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index 77cf343de21..6a26f70e1f5 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -14,7 +14,6 @@ m_amt = 90 attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed") var/max_water = 50 - var/last_use = 1.0 var/safety = 1 var/sprite_name = "fire_extinguisher" @@ -67,11 +66,6 @@ usr << "\red \The [src] is empty." return - if (world.time < src.last_use + 20) - return - - src.last_use = world.time - playsound(src.loc, 'sound/effects/extinguish.ogg', 75, 1, -3) var/direction = get_dir(src,target) diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 494e5c6552a..38d07024feb 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -461,3 +461,7 @@ the implant may become unstable and either pre-maturely inject the subject or si islegal() return 0 + +/obj/item/weapon/implant/cortical + name = "cortical stack" + desc = "A fist-sized mass of biocircuits and chips." diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index f4b2a147620..cc2c284adce 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -12,7 +12,7 @@ icon_state ="bookEngineering" author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Station Repairs and Construction" - dat = {" + /*dat = {" @@ -23,7 +23,7 @@ - "} + "}*/ /obj/item/weapon/book/manual/engineering_particle_accelerator name = "Particle Accelerator User's Guide" @@ -32,7 +32,7 @@ title = "Particle Accelerator User's Guide" //big pile of shit below. - dat = {" + /*dat = {"