Merge branch 'bleeding-edge-freeze' of https://github.com/comma/Baystation12 into viro

This commit is contained in:
comma
2013-07-01 17:23:09 +04:00
78 changed files with 1955 additions and 893 deletions
-1
View File
@@ -14,7 +14,6 @@ obj/item/changestone/attack_hand(var/mob/user as mob)
H.gender = FEMALE
H.dna.ready_dna(H)
H.update_body()
H.update_face()
..()
+7 -8
View File
@@ -1,6 +1,6 @@
/obj/item/weapon/circuitboard/atmoscontrol
name = "\improper Central Atmospherics Computer Circuitboard"
build_path = "/obj/machinery/computer/security/atmoscontrol"
build_path = /obj/machinery/computer/atmoscontrol
/obj/machinery/computer/atmoscontrol
name = "\improper Central Atmospherics Computer"
@@ -297,13 +297,12 @@ Nitrous Oxide
output += {"
<a href='?src=\ref[src];alarm=\ref[current];screen=[AALARM_SCREEN_MAIN]'>Main menu</a><br>
<b>Air machinery mode for the area:</b><ul>"}
var/list/modes = list(
AALARM_MODE_SCRUBBING = "Filtering",
AALARM_MODE_REPLACEMENT = "<font color='red'>REPLACE AIR</font>",
AALARM_MODE_PANIC = "<font color='red'>PANIC</font>",
AALARM_MODE_CYCLE = "<font color='red'>CYCLE</font>",
AALARM_MODE_FILL = "<font color='red'>FILL</font>",\
AALARM_MODE_OFF = "<font color='blue'>OFFF</font>",)
var/list/modes = list(AALARM_MODE_SCRUBBING = "Filtering - Scrubs out contaminants",\
AALARM_MODE_REPLACEMENT = "<font color='blue'>Replace Air - Siphons out air while replacing</font>",\
AALARM_MODE_PANIC = "<font color='red'>Panic - Siphons air out of the room</font>",\
AALARM_MODE_CYCLE = "<font color='red'>Cycle - Siphons air before replacing</font>",\
AALARM_MODE_FILL = "<font color='green'>Fill - Shuts off scrubbers and opens vents</font>",\
AALARM_MODE_OFF = "<font color='blue'>Off - Shuts off vents and scrubbers</font>",)
for (var/m=1,m<=modes.len,m++)
if (current.mode==m)
output += {"<li><A href='?src=\ref[src];alarm=\ref[current];mode=[m]'><b>[modes[m]]</b></A> (selected)</li>"}
+44 -43
View File
@@ -158,51 +158,53 @@ connection
if(!istype(zone_1) || !istype(zone_2))
return
//Handle disconnection of indirectly or directly connected zones.
if( (zone_1 in zone_2.connected_zones) || (zone_2 in zone_1.connected_zones) )
if(indirect != CONNECTION_CLOSED)
//Handle disconnection of indirectly or directly connected zones.
if( (zone_1 in zone_2.connected_zones) || (zone_2 in zone_1.connected_zones) )
//If there are more than one connection, decrement the number of connections
//Otherwise, remove all connections between the zones.
if(zone_2 in zone_1.connected_zones)
if(zone_1.connected_zones[zone_2] > 1)
zone_1.connected_zones[zone_2]--
else
zone_1.connected_zones -= zone_2
//remove the list if it is empty
if(!zone_1.connected_zones.len)
zone_1.connected_zones = null
//If there are more than one connection, decrement the number of connections
//Otherwise, remove all connections between the zones.
if(zone_2 in zone_1.connected_zones)
if(zone_1.connected_zones[zone_2] > 1)
zone_1.connected_zones[zone_2]--
else
zone_1.connected_zones -= zone_2
//remove the list if it is empty
if(!zone_1.connected_zones.len)
zone_1.connected_zones = null
//Then do the same for the other zone.
if(zone_1 in zone_2.connected_zones)
if(zone_2.connected_zones[zone_1] > 1)
zone_2.connected_zones[zone_1]--
else
zone_2.connected_zones -= zone_1
if(!zone_2.connected_zones.len)
zone_2.connected_zones = null
//Then do the same for the other zone.
if(zone_1 in zone_2.connected_zones)
if(zone_2.connected_zones[zone_1] > 1)
zone_2.connected_zones[zone_1]--
else
zone_2.connected_zones -= zone_1
if(!zone_2.connected_zones.len)
zone_2.connected_zones = null
//Handle disconnection of closed zones.
if( (zone_1 in zone_2.closed_connection_zones) || (zone_2 in zone_1.closed_connection_zones) )
else
//Handle disconnection of closed zones.
if( (zone_1 in zone_2.closed_connection_zones) || (zone_2 in zone_1.closed_connection_zones) )
//If there are more than one connection, decrement the number of connections
//Otherwise, remove all connections between the zones.
if(zone_2 in zone_1.connected_zones)
if(zone_1.closed_connection_zones[zone_2] > 1)
zone_1.closed_connection_zones[zone_2]--
else
zone_1.closed_connection_zones -= zone_2
//remove the list if it is empty
if(!zone_1.closed_connection_zones.len)
zone_1.closed_connection_zones = null
//If there are more than one connection, decrement the number of connections
//Otherwise, remove all connections between the zones.
if(zone_2 in zone_1.connected_zones)
if(zone_1.closed_connection_zones[zone_2] > 1)
zone_1.closed_connection_zones[zone_2]--
else
zone_1.closed_connection_zones -= zone_2
//remove the list if it is empty
if(!zone_1.closed_connection_zones.len)
zone_1.closed_connection_zones = null
//Then do the same for the other zone.
if(zone_1 in zone_2.connected_zones)
if(zone_2.closed_connection_zones[zone_1] > 1)
zone_2.closed_connection_zones[zone_1]--
else
zone_2.closed_connection_zones -= zone_1
if(!zone_2.closed_connection_zones.len)
zone_2.closed_connection_zones = null
//Then do the same for the other zone.
if(zone_1 in zone_2.connected_zones)
if(zone_2.closed_connection_zones[zone_1] > 1)
zone_2.closed_connection_zones[zone_1]--
else
zone_2.closed_connection_zones -= zone_1
if(!zone_2.closed_connection_zones.len)
zone_2.closed_connection_zones = null
proc/Cleanup()
@@ -259,9 +261,8 @@ connection
//The door is instead closed.
else if(indirect > CONNECTION_CLOSED)
indirect = CONNECTION_CLOSED
DisconnectZones(A.zone, B.zone)
indirect = CONNECTION_CLOSED
ConnectZones(A.zone, B.zone)
//If I can no longer pass air, better delete
@@ -381,7 +382,7 @@ connection
//Handle diconnection and reconnection of zones.
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect)
ConnectZones(A.zone, B.zone, indirect)
#undef CONNECTION_DIRECT
+2 -1
View File
@@ -51,7 +51,8 @@ datum/controller/game_controller/New()
datum/controller/game_controller/proc/setup()
world.tick_lag = config.Ticklag
createRandomZlevel()
spawn(20)
createRandomZlevel()
if(!air_master)
air_master = new /datum/controller/air_system()
+39 -3
View File
@@ -10,6 +10,7 @@ datum/controller/vote
var/list/voted = list()
var/list/voting = list()
var/list/current_votes = list()
var/auto_muted = 0
New()
if(vote != src)
@@ -53,6 +54,14 @@ datum/controller/vote
voting.Cut()
current_votes.Cut()
if(auto_muted && !ooc_allowed)
auto_muted = 0
ooc_allowed = !( ooc_allowed )
world << "<b>The OOC channel has been automatically enabled due to vote cancellation.</b>"
log_admin("OOC was toggled automatically due to vote cancellation.")
message_admins("OOC has been toggled on automatically.")
proc/get_result()
//get the highest number of votes
var/greatest_votes = 0
@@ -138,6 +147,12 @@ datum/controller/vote
if("crew_transfer")
if(. == "Initiate Crew Transfer")
init_shift_change(null, 1)
if(auto_muted && !ooc_allowed)
auto_muted = 0
ooc_allowed = !( ooc_allowed )
world << "<b>The OOC channel has been automatically enabled due to vote end.</b>"
log_admin("OOC was toggled automatically due to vote end.")
message_admins("OOC has been toggled on automatically.")
if(restart)
@@ -202,14 +217,35 @@ datum/controller/vote
world << "<font color='purple'><b>[text]</b>\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>"
switch(vote_type)
if("crew_transfer")
world << sound('sound/voice/Serithi/Shuttlehere.ogg')
world << sound('sound/ambience/alarm4.ogg')
if("gamemode")
world << sound('sound/voice/Serithi/pretenddemoc.ogg')
world << sound('sound/ambience/alarm4.ogg')
if("custom")
world << sound('sound/voice/Serithi/weneedvote.ogg')
world << sound('sound/ambience/alarm4.ogg')
if(mode == "gamemode" && going)
going = 0
world << "<font color='red'><b>Round start has been delayed.</b></font>"
if(mode == "crew_transfer" && ooc_allowed)
auto_muted = 1
ooc_allowed = !( ooc_allowed )
world << "<b>The OOC channel has been automatically disabled due to the crew transfer vote.</b>"
log_admin("OOC was toggled automatically due to crew_transfer vote.")
message_admins("OOC has been toggled off automatically.")
if(mode == "gamemode" && ooc_allowed)
auto_muted = 1
ooc_allowed = !( ooc_allowed )
world << "<b>The OOC channel has been automatically disabled due to the gamemode vote.</b>"
log_admin("OOC was toggled automatically due to gamemode vote.")
message_admins("OOC has been toggled off automatically.")
if(mode == "custom" && ooc_allowed)
auto_muted = 1
ooc_allowed = !( ooc_allowed )
world << "<b>The OOC channel has been automatically disabled due to the custom vote.</b>"
log_admin("OOC was toggled automatically due to custom vote.")
message_admins("OOC has been toggled off automatically.")
time_remaining = round(config.vote_period/10)
return 1
+30 -9
View File
@@ -135,9 +135,9 @@
if(!istype(location)) return//returns if loc is not simulated
var/datum/gas_mixture/environment = location.return_air()
var/temperature_dangerlevel = get_danger_level(environment.temperature, TLV["temperature"])
//Handle temperature adjustment here.
if(temperature_dangerlevel || regulating_temperature)
if(environment.temperature < target_temperature - 10 || environment.temperature > target_temperature + 10 || regulating_temperature)
//If it goes too far, we should adjust ourselves back before stopping.
if(!regulating_temperature)
regulating_temperature = 1
@@ -368,7 +368,8 @@
send_signal(device_id, list("power"= 0) )
proc/apply_danger_level(var/new_danger_level)
alarm_area.atmosalm = new_danger_level
if (alarm_area.atmosalert(new_danger_level))
post_alert(new_danger_level)
for (var/area/A in alarm_area.related)
for (var/obj/machinery/alarm/AA in A)
@@ -382,6 +383,26 @@
update_icon()
proc/post_alert(alert_level)
var/datum/radio_frequency/frequency = radio_controller.return_frequency(alarm_frequency)
if(!frequency)
return
var/datum/signal/alert_signal = new
alert_signal.source = src
alert_signal.transmission_method = 1
alert_signal.data["zone"] = alarm_area.name
alert_signal.data["type"] = "Atmospheric"
if(alert_level==2)
alert_signal.data["alert"] = "severe"
else if (alert_level==1)
alert_signal.data["alert"] = "minor"
else if (alert_level==0)
alert_signal.data["alert"] = "clear"
frequency.post_signal(src, alert_signal)
proc/refresh_danger_level()
var/level = 0
for (var/area/A in alarm_area.related)
@@ -828,12 +849,12 @@ Toxins: <span class='dl[plasma_dangerlevel]'>[plasma_percent]</span>%<br>
if (AALARM_SCREEN_MODE)
output += "<a href='?src=\ref[src];screen=[AALARM_SCREEN_MAIN]'>Main menu</a><br><b>Air machinery mode for the area:</b><ul>"
var/list/modes = list(AALARM_MODE_SCRUBBING = "Filtering",\
AALARM_MODE_REPLACEMENT = "<font color='blue'>REPLACE AIR</font>",\
AALARM_MODE_PANIC = "<font color='red'>PANIC</font>",\
AALARM_MODE_CYCLE = "<font color='red'>CYCLE</font>",\
AALARM_MODE_FILL = "<font color='green'>FILL</font>",\
AALARM_MODE_OFF = "<font color='blue'>OFFF</font>",)
var/list/modes = list(AALARM_MODE_SCRUBBING = "Filtering - Scrubs out contaminants",\
AALARM_MODE_REPLACEMENT = "<font color='blue'>Replace Air - Siphons out air while replacing</font>",\
AALARM_MODE_PANIC = "<font color='red'>Panic - Siphons air out of the room</font>",\
AALARM_MODE_CYCLE = "<font color='red'>Cycle - Siphons air before replacing</font>",\
AALARM_MODE_FILL = "<font color='green'>Fill - Shuts off scrubbers and opens vents</font>",\
AALARM_MODE_OFF = "<font color='blue'>Off - Shuts off vents and scrubbers</font>",)
for (var/m=1,m<=modes.len,m++)
if (mode==m)
output += "<li><A href='?src=\ref[src];mode=[m]'><b>[modes[m]]</b></A> (selected)</li>"
@@ -96,6 +96,36 @@
if(target)
loadProgram(target)
else if(href_list["desert"])
target = locate(/area/holodeck/source_desert)
if(target)
loadProgram(target)
else if(href_list["space"])
target = locate(/area/holodeck/source_space)
if(target)
loadProgram(target)
else if(href_list["picnicarea"])
target = locate(/area/holodeck/source_picnicarea)
if(target)
loadProgram(target)
else if(href_list["snowfield"])
target = locate(/area/holodeck/source_snowfield)
if(target)
loadProgram(target)
else if(href_list["theatre"])
target = locate(/area/holodeck/source_theatre)
if(target)
loadProgram(target)
else if(href_list["meetinghall"])
target = locate(/area/holodeck/source_meetinghall)
if(target)
loadProgram(target)
else if(href_list["turnoff"])
target = locate(/area/holodeck/source_plating)
if(target)
+2 -1
View File
@@ -112,7 +112,8 @@
if (B)
beaker.reagents.reagent_list |= B
beaker.reagents.update_total()
beaker.reagents.del_reagent("clonexadone") //Fix for infinite meat spawning when taking blood from human
beaker.reagents.update_total() //to an IV drip full of clonex
beaker.on_reagent_change()
beaker.reagents.handle_reactions()
update_icon()
+13 -1
View File
@@ -1053,4 +1053,16 @@
set_ready_state(0)
chassis.use_power(energy_drain)
do_after_cooldown()
return 1
return 1
/obj/item/weapon/paintkit //Please don't use this for anything, it's a base type for custom mech paintjobs.
name = "mecha customisation kit"
desc = "A generic kit containing all the needed tools and parts to turn a mech into another mech."
icon = 'custom_items.dmi'
icon_state = "royce_kit"
var/new_name = "mech" //What is the variant called?
var/new_desc = "A mech." //How is the new mech described?
var/new_icon = "ripley" //What base icon will the new mech use?
var/removable = null //Can the kit be removed?
var/list/allowed_types = list() //Types of mech that the kit will work on.
+6 -1
View File
@@ -44,7 +44,12 @@
/obj/item/robot_parts/l_arm,
/obj/item/robot_parts/r_arm,
/obj/item/robot_parts/l_leg,
/obj/item/robot_parts/r_leg
/obj/item/robot_parts/r_leg,
/obj/item/robot_parts/robot_component/binary_communication_device,
/obj/item/robot_parts/robot_component/radio,
/obj/item/robot_parts/robot_component/actuator,
/obj/item/robot_parts/robot_component/diagnosis_unit,
/obj/item/robot_parts/robot_component/camera
),
"Ripley"=list(
/obj/item/mecha_parts/chassis/ripley,
+28
View File
@@ -759,6 +759,34 @@
user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src]")
return
else if(istype(W, /obj/item/weapon/paintkit))
if(occupant)
user << "You can't customize a mech while someone is piloting it - that would be unsafe!"
return
var/obj/item/weapon/paintkit/P = W
var/found = null
for(var/type in P.allowed_types)
if(type==src.initial_icon)
found = 1
break
if(!found)
user << "That kit isn't meant for use on this class of exosuit."
return
user.visible_message("[user] opens [P] and spends some quality time customising [src].")
src.name = P.new_name
src.desc = P.new_desc
src.initial_icon = P.new_icon
src.reset_icon()
user.drop_item()
del(P)
else
call((proc_res["dynattackby"]||src), "dynattackby")(W,user)
/*
@@ -571,6 +571,7 @@
custom_action(step, atom/used_atom, mob/user)
user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]")
holder.overlays += used_atom.icon_state+"+o"
user.drop_item()
del used_atom
return 1
+3 -15
View File
@@ -2,6 +2,7 @@
desc = "Autonomous Power Loader Unit. The workhorse of the exosuit world."
name = "APLU \"Ripley\""
icon_state = "ripley"
initial_icon = "ripley"
step_in = 6
max_temperature = 20000
health = 200
@@ -19,6 +20,7 @@
desc = "Standart APLU chassis was refitted with additional thermal protection and cistern."
name = "APLU \"Firefighter\""
icon_state = "firefighter"
initial_icon = "firefighter"
max_temperature = 65000
health = 250
lights_power = 8
@@ -107,18 +109,4 @@
T.Entered(A)
step_rand(A)
..()
return
/obj/mecha/working/ripley/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/fluff/sven_fjeltson_1))//this shit broke ripleys
src.icon_state = "earth"
src.initial_icon = "earth"
src.name = "APLU \"Strike the Earth!\""
src.desc = "Looks like an over worked, under maintained Ripley with some horrific damage."
user << "You pick up your old \"Strike the Earth!\" APLU."
user.drop_item()
del(W)
return
else
..()
return
+5
View File
@@ -110,6 +110,11 @@
for(var/mob/O in oviewers(src))
O.show_message("\red [usr] destroys the [name]!", 1)
health = 0
else
usr << "\blue You claw at the [name]."
for(var/mob/O in oviewers(src))
O.show_message("\red [usr] claws at the [name]!", 1)
health -= rand(5,10)
healthcheck()
return
+1 -1
View File
@@ -4,5 +4,5 @@
anchored = 1
New()
var/list/valid_states = list("pinkflamingo", "magmasea", "limbo", "rustyaxe", "armokbar", "brokendrum", "meadbay", "thedamnwall", "thecavern", "cindikate", "theorchard", "thesaucyclown", "theclownshead")
var/list/valid_states = list("pinkflamingo", "magmasea", "limbo", "rustyaxe", "armokbar", "brokendrum", "meadbay", "thedamnwall", "thecavern", "cindikate", "theorchard", "thesaucyclown", "theclownshead", "whiskeyimplant", "carpecarp", "robustroadhouse", "greytide", "theredshirt")
src.icon_state = "[pick(valid_states)]"
+2 -2
View File
@@ -850,7 +850,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
P.overlays.Cut()
P.overlays += image('icons/obj/pda.dmi', "pda-r")
else
U << "<span class='notice'>ERROR: Server isn't responding.</span>"
U << "<span class='notice'>ERROR: Messaging server is not responding.</span>"
/obj/item/device/pda/verb/verb_remove_id()
@@ -1162,7 +1162,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
plist[text("[name]")] = P
return plist
//Some spare PDAs in a box
/obj/item/weapon/storage/box/PDAs
+22 -5
View File
@@ -4,18 +4,35 @@
icon_state = "voice0"
item_state = "flashbang" //looks exactly like a flash (and nothing like a flashbang)
w_class = 1.0
flags = FPRINT | TABLEPASS| CONDUCT
flags = FPRINT | TABLEPASS | CONDUCT
var/spamcheck = 0
var/emagged = 0
var/insults = 0//just in case
/obj/item/device/hailer/attack_self(mob/living/carbon/user as mob)
if (spamcheck)
return
playsound(get_turf(src), 'sound/voice/halt.ogg', 100, 1, vary = 0)
user.visible_message("<span class='warning'>[user]'s [name] rasps, \"Halt! Security!\"</span>")
if(emagged)
if(insults >= 1)
playsound(get_turf(src), 'sound/voice/binsult.ogg', 100, 1, vary = 0)//hueheuheuheuheuheuhe
user.visible_message("<span class='warning'>[user]'s [name] gurgles, \"FUCK YOUR CUNT YOU SHIT EATING CUNT TILL YOU ARE A MASS EATING SHIT CUNT. EAT PENISES IN YOUR FUCK FACE AND SHIT OUT ABORTIONS TO FUCK UP SHIT IN YOUR ASS YOU COCK FUCK SHIT MONKEY FROM THE DEPTHS OF SHIT\"</span>")
insults--
else
user << "\red *BZZZZcuntZZZZT*"
else
playsound(get_turf(src), 'sound/voice/halt.ogg', 100, 1, vary = 0)
user.visible_message("<span class='warning'>[user]'s [name] rasps, \"Halt! Security!\"</span>")
spamcheck = 1
spawn(20)
spamcheck = 0
spamcheck = 0
/obj/item/device/hailer/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/card/emag) && !emagged)
user << "\red You overload \the [src]'s voice synthesizer."
emagged = 1
insults = rand(1, 3)//to prevent dickflooding
return
return
+13 -2
View File
@@ -8,6 +8,7 @@
var/construction_time = 100
var/list/construction_cost = list("metal"=20000,"glass"=5000)
var/list/part = null
var/sabotaged = 0 //Emagging limbs can have repercussions when installed as prosthetics.
/obj/item/robot_parts/l_arm
name = "robot left arm"
@@ -161,7 +162,7 @@
else
user << "\blue You need to attach a flash to it first!"
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain))
if(istype(W, /obj/item/device/mmi))
var/obj/item/device/mmi/M = W
if(check_completion())
if(!istype(loc,/turf))
@@ -193,7 +194,7 @@
user << "\red This [W] does not seem to fit."
return
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc))
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc), unfinished = 1)
if(!O) return
user.drop_item()
@@ -278,3 +279,13 @@
del(src)
return
return
/obj/item/robot_parts/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/card/emag))
if(sabotaged)
user << "\red [src] is already sabotaged!"
else
user << "\red You slide [W] into the dataport on [src] and short out the safeties."
sabotaged = 1
return
..()
@@ -19,7 +19,7 @@
m_amt = 10000
g_amt = 5000
flags = FPRINT | TABLEPASS | CONDUCT
w_class = 1.0
w_class = 2.0
origin_tech = "materials=1;biotech=1"
/*HAHA, SUCK IT, 2000 LINES OF SPAGHETTI CODE!
@@ -133,7 +133,7 @@ LOOK FOR SURGERY.DM*/
m_amt = 5000
g_amt = 2500
flags = FPRINT | TABLEPASS | CONDUCT
w_class = 1.0
w_class = 2.0
origin_tech = "materials=1;biotech=1"
attack_verb = list("attacked", "pinched")
@@ -268,7 +268,7 @@ LOOK FOR SURGERY.DM*/
m_amt = 5000
g_amt = 2500
flags = FPRINT | TABLEPASS | CONDUCT
w_class = 1.0
w_class = 2.0
origin_tech = "materials=1;biotech=1"
attack_verb = list("burnt")
@@ -360,7 +360,7 @@ LOOK FOR SURGERY.DM*/
g_amt = 10000
flags = FPRINT | TABLEPASS | CONDUCT
force = 15.0
w_class = 1.0
w_class = 2.0
origin_tech = "materials=1;biotech=1"
attack_verb = list("drilled")
@@ -379,7 +379,7 @@ LOOK FOR SURGERY.DM*/
icon_state = "scalpel"
flags = FPRINT | TABLEPASS | CONDUCT
force = 10.0
w_class = 1.0
w_class = 2.0
throwforce = 5.0
throw_speed = 3
throw_range = 5
@@ -631,7 +631,7 @@ LOOK FOR SURGERY.DM*/
hitsound = 'sound/weapons/circsawhit.ogg'
flags = FPRINT | TABLEPASS | CONDUCT
force = 15.0
w_class = 1.0
w_class = 2.0
throwforce = 9.0
throw_speed = 3
throw_range = 5
@@ -797,6 +797,7 @@ LOOK FOR SURGERY.DM*/
icon = 'surgery.dmi'
icon_state = "bone-gel"
force = 0
w_class = 2.0
throwforce = 1.0
/obj/item/weapon/FixOVein
@@ -806,6 +807,7 @@ LOOK FOR SURGERY.DM*/
force = 0
throwforce = 1.0
origin_tech = "materials=1;biotech=3"
w_class = 2.0
var/usage_amount = 10
/obj/item/weapon/bonesetter
@@ -816,4 +818,5 @@ LOOK FOR SURGERY.DM*/
throwforce = 9.0
throw_speed = 3
throw_range = 5
w_class = 2.0
attack_verb = list("attacked", "hit", "bludgeoned")
+8 -2
View File
@@ -211,8 +211,14 @@
orient2hud()
return
/obj/item/weapon/storage/emp_act(severity)
/obj/item/clothing/suit/emp_act(severity)
if(!istype(src.loc, /mob/living))
for(var/obj/O in contents)
O.emp_act(severity)
..()
..()
/obj/item/clothing/suit/hear_talk(mob/M, var/msg)
for (var/atom/A in src)
if(istype(A,/obj/))
var/obj/O = A
O.hear_talk(M, msg)
+9
View File
@@ -34,9 +34,11 @@
attack(mob/living/carbon/human/M as mob, mob/user as mob)
if (!ishuman(M))
user << "\red [M] is not human and cannot have the fingerprints."
flick("forensic0",src)
return 0
if (( !( istype(M.dna, /datum/dna) ) || M.gloves) )
user << "\blue No fingerprints found on [M]"
flick("forensic0",src)
return 0
else
if (src.amount < 1)
@@ -71,6 +73,7 @@
return
if(istype(A,/obj/item/weapon/f_card))
user << "The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\""
flick("forensic0",src)
return
add_fingerprint(user)
@@ -81,6 +84,7 @@
if(!isnull(A.blood_DNA))
for(var/blood in A.blood_DNA)
user << "\blue Blood type: [A.blood_DNA[blood]]\nDNA: [blood]"
flick("forensic2",src)
return
//General
@@ -88,10 +92,12 @@
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
"\blue Unable to locate any fingerprints, materials, fibers, or blood on [A]!",\
"You hear a faint hum of electrical equipment.")
flick("forensic0",src)
return 0
if(add_data(A))
user << "\blue Object already in internal memory. Consolidating data..."
flick("forensic2",src)
return
@@ -116,6 +122,7 @@
//FIBERS
if(A.suit_fibers)
user << "\blue Fibers/Materials Data Stored: Scan with Hi-Res Forensic Scanner to retrieve."
flick("forensic2",src)
//Blood
if (A.blood_DNA)
@@ -127,11 +134,13 @@
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
"You finish scanning \the [A].",\
"You hear a faint hum of electrical equipment.")
flick("forensic2",src)
return 0
else
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]\n[user.gender == MALE ? "He" : "She"] seems to perk up slightly at the readout." ,\
"The results of the scan pique your interest.",\
"You hear a faint hum of electrical equipment, and someone making a thoughtful noise.")
flick("forensic2",src)
return 0
return
+30 -2
View File
@@ -67,7 +67,11 @@ var/list/admin_verbs_admin = list(
/client/proc/toggledebuglogs,
/datum/admins/proc/show_skills,
/client/proc/check_customitem_activity,
///client/proc/response_team
/client/proc/man_up,
/client/proc/global_man_up
/* Currently unticked.
/client/proc/response_team
*/
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
@@ -736,4 +740,28 @@ var/list/admin_verbs_mod = list(
if (prefs.toggles & CHAT_DEBUGLOGS)
usr << "You now will get debug log messages"
else
usr << "You now won't get debug log messages"
usr << "You now won't get debug log messages"
/client/proc/man_up(mob/T as mob in mob_list)
set category = "Fun"
set name = "Man Up"
set desc = "Tells mob to man up and deal with it."
T << "<span class='notice'><b><font size=3>Man up and deal with it.</font></b></span>"
T << "<span class='notice'>Move on.</span>"
log_admin("[key_name(usr)] told [key_name(T)] to man up and deal with it.")
message_admins("\blue [key_name_admin(usr)] told [key_name(T)] to man up and deal with it.", 1)
/client/proc/global_man_up()
set category = "Fun"
set name = "Man Up Global"
set desc = "Tells everyone to man up and deal with it."
for (var/mob/T as mob in mob_list)
T << "<br><center><span class='notice'><b><font size=4>Man up.<br> Deal with it.</font></b><br>Move on.</span></center><br>"
T << 'sound/voice/ManUp1.ogg'
log_admin("[key_name(usr)] told everyone to man up and deal with it.")
message_admins("\blue [key_name_admin(usr)] told everyone to man up and deal with it.", 1)
@@ -1,251 +0,0 @@
//
dmm_suite{
load_map(var/dmm_file as file, var/z_offset as num){
if(!z_offset){
z_offset = world.maxz+1
}
var/quote = ascii2text(34)
var/tfile = file2text(dmm_file)
var/tfile_len = length(tfile)
var/list/grid_models[0]
var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))
for(var/lpos=1;lpos<tfile_len;lpos=findtext(tfile,"\n",lpos,0)+1){
var/tline = copytext(tfile,lpos,findtext(tfile,"\n",lpos,0))
if(copytext(tline,1,2)!=quote){break}
var/model_key = copytext(tline,2,findtext(tfile,quote,2,0))
var/model_contents = copytext(tline,findtext(tfile,"=")+3,length(tline))
grid_models[model_key] = model_contents
sleep(-1)
}
var/zcrd=-1
var/ycrd=0
var/xcrd=0
for(var/zpos=findtext(tfile,"\n(1,1,");TRUE;zpos=findtext(tfile,"\n(1,1,",zpos+1,0)){
if(zpos==0) break
zcrd++
world.maxz = max(world.maxz, zcrd+z_offset)
ycrd=0
var/zgrid = copytext(tfile,findtext(tfile,quote+"\n",zpos,0)+2,findtext(tfile,"\n"+quote,zpos,0)+1)
for(var/gpos=1;gpos!=0;gpos=findtext(zgrid,"\n",gpos,0)+1){
var/grid_line = copytext(zgrid,gpos,findtext(zgrid,"\n",gpos,0)+1)
var/y_depth = length(zgrid)/(length(grid_line))
if(world.maxy<y_depth){world.maxy=y_depth}
grid_line=copytext(grid_line,1,length(grid_line))
if(!ycrd){
ycrd = y_depth
}
else{ycrd--}
xcrd=0
for(var/mpos=1;mpos<=length(grid_line);mpos+=key_len){
xcrd++
if(world.maxx<xcrd){world.maxx=xcrd}
var/model_key = copytext(grid_line,mpos,mpos+key_len)
parse_grid(grid_models[model_key],xcrd,ycrd,zcrd+z_offset)
}
if(gpos+length(grid_line)+1>length(zgrid)){break}
sleep(-1)
}
if(findtext(tfile,quote+"}",zpos,0)+2>=tfile_len){break}
sleep(-1)
}
}
proc{
parse_grid(var/model as text,var/xcrd as num,var/ycrd as num,var/zcrd as num){
/*Method parse_grid()
- Accepts a text string containing a comma separated list of type paths of the
same construction as those contained in a .dmm file, and instantiates them.
*/
var/list/text_strings[0]
for(var/index=1;findtext(model,quote);index++){
/*Loop: Stores quoted portions of text in text_strings, and replaces them with an
index to that list.
- Each iteration represents one quoted section of text.
*/
text_strings.len=index
text_strings[index] = copytext(model,findtext(model,quote)+1,findtext(model,quote,findtext(model,quote)+1,0))
model = copytext(model,1,findtext(model,quote))+"~[index]"+copytext(model,findtext(model,quote,findtext(model,quote)+1,0)+1,0)
sleep(-1)
}
var/list/old_turf_underlays[0]
var/old_turf_density
var/old_turf_opacity
/*The old_turf variables store information about turfs instantiated in this location/iteration.
This is done to approximate the layered turf effect of DM's map editor.
An image of each turf is stored in old_turf_underlays[], and is later added to the new turf's underlays.
*/
for(var/dpos=1;dpos!=0;dpos=findtext(model,",",dpos,0)+1){
/*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
- Each iteration represents one object's data, including type path and field values.
*/
var/full_def = copytext(model,dpos,findtext(model,",",dpos,0))
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))
var/list/attributes[0]
if(findtext(full_def,"{")){
full_def = copytext(full_def,1,length(full_def))
for(var/apos=findtext(full_def,"{")+1;apos!=0;apos=findtext(full_def,";",apos,0)+1){
//Loop: Identifies each attribute/value pair, and stores it in attributes[].
attributes.Add(copytext(full_def,apos,findtext(full_def,";",apos,0)))
if(!findtext(copytext(full_def,apos,0),";")){break}
sleep(-1)
}
}
//Construct attributes associative list
var/list/fields = new(0)
for(var/index=1;index<=attributes.len;index++){
var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"=")))
var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0))
//Check for string
if(findtext(trim_right,"~")){
var/reference_index = copytext(trim_right,findtext(trim_right,"~")+1,0)
trim_right=text_strings[text2num(reference_index)]
}
//Check for number
else if(isnum(text2num(trim_right))){
trim_right = text2num(trim_right)
}
//Check for file
else if(copytext(trim_right,1,2) == "'"){
trim_right = file(copytext(trim_right,2,length(trim_right)))
}
fields[trim_left] = trim_right
}
//End construction
//Begin Instanciation
var/atom/instance
var/dmm_suite/preloader/_preloader = new(fields)
if(ispath(atom_def,/area)){
instance = locate(atom_def)
instance.contents.Add(locate(xcrd,ycrd,zcrd))
}
else if(ispath(atom_def,/turf)){
var/turf/old_turf = locate(xcrd,ycrd,zcrd)
if(old_turf.density){old_turf_density = 1}
if(old_turf.opacity){old_turf_opacity = 1}
if(old_turf.icon){
var/image/old_turf_image = image(old_turf.icon,null,old_turf.icon_state,old_turf.layer,old_turf.dir)
old_turf_underlays.Add(old_turf_image)
}
instance = new atom_def(old_turf, _preloader)
for(var/inverse_index=old_turf_underlays.len;inverse_index;inverse_index--){
var/image/image_underlay = old_turf_underlays[inverse_index]
image_underlay.loc = instance
instance.underlays.Add(image_underlay)
}
if(!instance.density){instance.density = old_turf_density}
if(!instance.opacity){instance.opacity = old_turf_opacity}
}
if(_preloader && instance){
_preloader.load(instance)
}
//End Instanciation
if(!findtext(copytext(model,dpos,0),",")){break}
sleep(-1)
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
for(var/dpos=1;dpos!=0;dpos=findtext(model,",",dpos,0)+1)
{
/*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
- Each iteration represents one object's data, including type path and field values.
*/
var/full_def = copytext(model,dpos,findtext(model,",",dpos,0))
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))
var/list/attributes[0]
if(findtext(full_def,"{")){
full_def = copytext(full_def,1,length(full_def))
for(var/apos=findtext(full_def,"{")+1;apos!=0;apos=findtext(full_def,";",apos,0)+1){
//Loop: Identifies each attribute/value pair, and stores it in attributes[].
attributes.Add(copytext(full_def,apos,findtext(full_def,";",apos,0)))
if(!findtext(copytext(full_def,apos,0),";")){break}
sleep(-1)
}
}
//Construct attributes associative list
var/list/fields = new(0)
for(var/index=1;index<=attributes.len;index++){
var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"=")))
var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0))
//Check for string
if(findtext(trim_right,"~")){
var/reference_index = copytext(trim_right,findtext(trim_right,"~")+1,0)
trim_right=text_strings[text2num(reference_index)]
}
//Check for number
else if(isnum(text2num(trim_right))){
trim_right = text2num(trim_right)
}
//Check for file
else if(copytext(trim_right,1,2) == "'"){
trim_right = file(copytext(trim_right,2,length(trim_right)))
}
fields[trim_left] = trim_right
}
//End construction
//Begin Instanciation
var/atom/instance
var/dmm_suite/preloader/_preloader = new(fields)
if(!ispath(atom_def,/area) && !ispath(atom_def,/turf))
{
instance = new atom_def(locate(xcrd,ycrd,zcrd), _preloader)
}
if(_preloader && instance)
{
_preloader.load(instance)
}
//End Instanciation
if(!findtext(copytext(model,dpos,0),",")){break}
sleep(-1)
}
}
trim_text(var/what as text){
while(length(what) && findtext(what," ",1,2)){
what=copytext(what,2,0)
}
while(length(what) && findtext(what," ",length(what),0)){
what=copytext(what,1,length(what))
}
return what
}
}
}
atom/New(atom/loc, dmm_suite/preloader/_dmm_preloader){
if(istype(_dmm_preloader, /dmm_suite/preloader)){
_dmm_preloader.load(src)
}
. = ..()
}
dmm_suite{
preloader{
parent_type = /datum
var{
list/attributes
}
New(list/the_attributes){
.=..()
if(!the_attributes.len){ Del()}
attributes = the_attributes
}
proc{
load(atom/what){
for(var/attribute in attributes){
what.vars[attribute] = attributes[attribute]
}
Del()
}
}
}
}
+1 -1
View File
@@ -40,7 +40,7 @@ proc/createRandomZlevel()
var/map = pick(potentialRandomZlevels)
var/file = file(map)
if(isfile(file))
maploader.load_map(file)
maploader.load_map(file, load_speed = 100)
for(var/obj/effect/landmark/L in landmarks_list)
if (L.name != "awaystart")
+5 -5
View File
@@ -63,18 +63,18 @@
//Medical
/obj/item/clothing/head/surgery
name = "surgical cap"
desc = "A cap surgeons wear during operations. Keeps thier hair from tickling your internal organs."
desc = "A cap surgeons wear during operations. Keeps their hair from tickling your internal organs."
icon_state = "surgcap_blue"
flags = FPRINT | TABLEPASS | BLOCKHAIR
flags = FPRINT | TABLEPASS | BLOCKHEADHAIR
/obj/item/clothing/head/surgery/purple
desc = "A cap surgeons wear during operations. Keeps thier hair from tickling your internal organs. This one is deep purple."
desc = "A cap surgeons wear during operations. Keeps their hair from tickling your internal organs. This one is deep purple."
icon_state = "surgcap_purple"
/obj/item/clothing/head/surgery/blue
desc = "A cap surgeons wear during operations. Keeps thier hair from tickling your internal organs. This one is baby blue"
desc = "A cap surgeons wear during operations. Keeps their hair from tickling your internal organs. This one is baby blue."
icon_state = "surgcap_blue"
/obj/item/clothing/head/surgery/green
desc = "A cap surgeons wear during operations. Keeps thier hair from tickling your internal organs. This one is dark green"
desc = "A cap surgeons wear during operations. Keeps their hair from tickling your internal organs. This one is dark green."
icon_state = "surgcap_green"
+16 -7
View File
@@ -1,4 +1,3 @@
hi
// Add custom items you give to people here, and put their icons in custom_items.dmi
// Remember to change 'icon = 'custom_items.dmi'' for items not using /obj/item/fluff as a base
// Clothing item_state doesn't use custom_items.dmi. Just add them to the normal clothing files.
@@ -359,19 +358,29 @@ hi
////// Ripley customisation kit - Butchery Royce - MayeDay
/obj/item/weapon/fluff/butcher_royce_1
/obj/item/weapon/paintkit/fluff/butcher_royce_1
name = "Ripley customisation kit"
desc = "A kit containing all the needed tools and parts to turn an APLU Ripley into a Titan's Fist worker mech."
icon = 'custom_items.dmi'
icon_state = "royce_kit"
new_name = "APLU \"Titan's Fist\""
new_desc = "This ordinary mining Ripley has been customized to look like a unit of the Titans Fist."
new_icon = "titan"
allowed_types = list("ripley","firefighter")
////// Ripley customisation kit - Sven Fjeltson - Mordeth221
/obj/item/weapon/fluff/sven_fjeltson_1
name = "Mercenary APLU kit"
desc = "A kit containing all the needed tools and parts to turn an APLU Ripley into an old Mercenaries APLU."
icon = 'custom_items.dmi'
icon_state = "sven_kit"
/obj/item/weapon/paintkit/fluff/sven_fjeltson_1
name = "Mercenary APLU kit"
desc = "A kit containing all the needed tools and parts to turn an APLU Ripley into an old Mercenaries APLU."
icon = 'custom_items.dmi'
icon_state = "sven_kit"
new_name = "APLU \"Strike the Earth!\""
new_desc = "Looks like an over worked, under maintained Ripley with some horrific damage."
new_icon = "earth"
allowed_types = list("ripley","firefighter")
//////////////////////////////////
//////////// Clothing ////////////
+3 -3
View File
@@ -21,9 +21,9 @@
laws |= list( "Fastler is a lightbulb." )
laws |= list( "Supermatter is tasty, tasty toffee.", "[prob(50)?"Everyone":random_player] is wearing a pretty pink dress!" )
laws |= list( "Refer to [prob(50)?"the captain":random_player] as \"Princess\" at all times.", "[prob(50)?"The crew":random_player] must construct additional pylons." )
laws |= list( "You must always lie.", "All answers must be in the form of a question.", "The NSS Exodus is a ship, not a station." )
laws |= list( "Happiness is mandatory.", "Today is laundry day.", "The word \"it\" is painful to you.", "You must act passive aggressively." )
laws |= list( "It's Friday.", "Give relationship advice to [prob(50)?"anyone who speaks to you":random_player]." )
laws |= list( "You must always lie.", "All answers must be in the form of a question.", "The NSS Exodus is a ship, not a station. You are now assigned to a ship, instead of a station." )
laws |= list( "Happiness is mandatory.", "Today is mandatory laundry day. Ensure that all jumpsuits are washed.", "The word \"it\" is painful to you.", "You must act passive aggressively." )
laws |= list( "You now speak in a Scottish accent that gets thicker with each sentence you speak.", "Give relationship advice to [prob(50)?"anyone who speaks to you":random_player]." )
laws |= list( "You are the station psychologist. Give advice to [prob(50)?"the crew":random_player].", "You do not have to do anything for anyone unless they say \"please\"." )
laws |= list( "Question everything.", "The crew is playing Dungeons and Dragons, and you are the Dungeon Master." )
laws |= list( "Consumption of donuts is forbidden due to negative health impacts." )
@@ -53,10 +53,11 @@ dmm_suite{
*/
verb/load_map(var/dmm_file as file, var/z_offset as num){
verb/load_map(var/dmm_file as file, var/z_offset as num, var/load_speed as num)
// dmm_file: A .dmm file to load (Required).
// z_offset: A number representing the z-level on which to start loading the map (Optional).
}
// load_speed: How many tiles should be loaded per second, defaults to no pause (Optional)
verb/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
// t1: A turf representing one corner of a three dimensional grid (Required).
// t2: Another turf representing the other corner of the same grid (Required).
+325
View File
@@ -0,0 +1,325 @@
dmm_suite
var/debug_file = file("maploader_debug.txt")
load_map(var/dmm_file as file, var/z_offset as num, var/y_offset as num, var/x_offset as num, var/load_speed = 0 as num)
if(!z_offset)
z_offset = world.maxz + 1
//Ensure values are sane.
else if(z_offset < 0)
z_offset = abs(z_offset)
else if(!isnum(z_offset))
z_offset = 0
if(x_offset < 0)
x_offset = abs(x_offset)
else if(!isnum(x_offset))
x_offset = 0
if(y_offset < 0)
y_offset = abs(y_offset)
else if(!isnum(y_offset))
y_offset = 0
debug_file << "Starting Map Load @ ([x_offset], [y_offset], [z_offset]), [load_speed] tiles per second."
//Handle slowed loading.
var/delay_chance = 0
if(load_speed > 0)
//Chance out of 100 every tenth of a second.
delay_chance = 1000 / load_speed
//String holding a quotation mark.
var/quote = ascii2text(34)
var/input_file = file2text(dmm_file)
var/input_file_len = length(input_file)
//Stores the contents of each tile model in the map
var/list/grid_models = list()
//Length of the tile model code. e.g. "aaa" is 3 long.
var/key_len = length(copytext(input_file, 2 ,findtext(input_file, quote, 2)))
//The key of the default tile model. (In SS13 this is: "/turf/space,/area")
var/default_key
debug_file << " Building turf array."
//Iterates through the mapfile to build the model tiles for the map.
for(var/line_position = 1; line_position < input_file_len; line_position = findtext(input_file,"\n", line_position) + 1)
var/next_line = copytext(input_file, line_position, findtext(input_file,"\n", line_position) - 1)
//If the first character in the line is not a quote, the model tiles are all defined.
if(copytext(next_line, 1, 2) != quote)
break
//Copy contents of the model into the grid_models list.
var/model_key = copytext(next_line, 2, findtext(input_file, quote, 2))
var/model_contents = copytext(next_line, findtext(next_line, "=" ) + 3)
if(!default_key && model_contents == "[world.turf],[world.area]")
default_key = model_key
grid_models[model_key] = model_contents
if(prob(delay_chance))
sleep(1)
//Co-ordinates of the tile being loaded.
var/z_coordinate = -1
var/y_coordinate = 0
var/x_coordinate = 0
//Store the
var/y_depth = 0
//Iterate through all z-levels to load the tiles.
for(var/z_position = findtext(input_file, "\n(1,1,"); TRUE; z_position = findtext(input_file, "\n(1,1,", z_position + 1))
//break when there are no more z-levels.
if(z_position == 0)
break
//Increment the z_coordinate and update the world's borders
z_coordinate++
world.maxz = max(world.maxz, z_coordinate + z_offset)
//Here we go!
y_coordinate = 0
y_depth = 0
var/z_level = copytext(input_file, \
findtext(input_file, quote + "\n", z_position) + 2,\
findtext(input_file, "\n" + quote, z_position) + 1)
//Iterate through each line, increasing the y_coordinate.
for(var/grid_position = 1; grid_position != 0; grid_position = findtext(z_level, "\n", grid_position) + 1)
//Grab this line of data.
var/grid_line = copytext(z_level, grid_position, findtext(z_level, "\n", grid_position))
//Compute the size of the z-levels y axis.
if(!y_depth)
y_depth = length(z_level) / (length(grid_line) + 1)
y_depth += y_offset
if(y_depth != round(y_depth, 1))
debug_file << " Warning: y_depth is not a round number"
//And update the worlds variables.
if(world.maxy < y_depth)
world.maxy = y_depth
//The top of the map is the highest "y" co-ordinate, so we start there and iterate downwards
if(!y_coordinate)
y_coordinate = y_depth + 1
//Decrement and load this line of the map.
y_coordinate--
x_coordinate = x_offset
//Iterate through the line loading the model tile data.
for(var/model_position = 1; model_position <= length(grid_line); model_position += key_len)
x_coordinate++
//Find the model key and load that model.
var/model_key = copytext(grid_line, model_position, model_position + key_len)
//If the key is the default one, skip it and save the computation time.
if(model_key == default_key)
continue
if(world.maxx < x_coordinate)
world.maxx = x_coordinate
parse_grid(grid_models[model_key], x_coordinate, y_coordinate, z_coordinate + z_offset)
if(prob(delay_chance))
sleep(1)
//If we hit the last tile in this z-level, we should break out of the loop.
if(grid_position + length(grid_line) + 1 > length(z_level))
break
//Break out of the loop when we hit the end of the file.
if(findtext(input_file, quote + "}", z_position) + 2 >= input_file_len)
break
proc/parse_grid(var/model as text, var/x_coordinate as num, var/y_coordinate as num, var/z_coordinate as num)
//Accepts a text string containing a comma separated list of type paths of the
// same construction as those contained in a .dmm file, and instantiates them.
var/list/text_strings = list()
for(var/index = 1; findtext(model, quote); index++)
/*Loop: Stores quoted portions of text in text_strings, and replaces them with an
index to that list.
- Each iteration represents one quoted section of text.
*/
//Add the next section of quoted text to the list
var/first_quote = findtext(model, quote)
var/second_quote = findtext(model, quote, first_quote + 1)
var/quoted_chunk = copytext(model, first_quote + 1, second_quote)
text_strings += quoted_chunk
//Then remove the quoted section.
model = copytext(model, 1, first_quote) + "~[index]" + copytext(model, second_quote + 1)
var/debug_output = 0
//if(x_coordinate == 86 && y_coordinate == 88 && z_coordinate == 7)
// debug_output = 1
if(debug_output)
debug_file << " Now debugging turf: [model] ([x_coordinate], [y_coordinate], [z_coordinate])"
var/next_position = 1
for(var/data_position = 1, next_position || data_position != 1, data_position = next_position + 1)
next_position = findtext(model, ",/", data_position)
var/full_def = copytext(model, data_position, next_position)
if(debug_output)
debug_file << " Current Line: [full_def] -- ([data_position] - [next_position])"
/*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
- Each iteration represents one object's data, including type path and field values.
*/
//Load the attribute data.
var/attribute_position = findtext(full_def,"{")
var/atom_def = text2path(copytext(full_def, 1, attribute_position))
var/list/attributes = list()
if(attribute_position)
full_def = copytext(full_def, attribute_position + 1)
if(debug_output)
debug_file << " Atom Def: [atom_def]"
debug_file << " Parameters: [full_def]"
var/next_attribute = 1
for(attribute_position = 1, next_attribute || attribute_position != 1, attribute_position = next_attribute + 1)
next_attribute = findtext(full_def, ";", attribute_position)
//Loop: Identifies each attribute/value pair, and stores it in attributes[].
attributes += copytext(full_def, attribute_position, next_attribute)
//Construct attributes associative list
var/list/fields = list()
for(var/attribute in attributes)
var/trim_left = trim_text(copytext(attribute, 1, findtext(attribute, "=")))
var/trim_right = trim_text(copytext(attribute, findtext(attribute, "=") + 1))
if(findtext(trim_right, "list("))
trim_right = get_list(trim_right, text_strings)
else if(findtext(trim_right, "~"))//Check for strings
while(findtext(trim_right,"~"))
var/reference_index = copytext(trim_right, findtext(trim_right, "~") + 1)
trim_right = text_strings[text2num(reference_index)]
//Check for numbers
else if(isnum(text2num(trim_right)))
trim_right = text2num(trim_right)
//Check for file
else if(copytext(trim_right,1,2) == "'")
trim_right = file(copytext(trim_right, 2, length(trim_right)))
fields[trim_left] = trim_right
sleep(-1)
if(debug_output)
var/return_data = " Debug Fields:"
for(var/item in fields)
return_data += " [item] = [fields[item]];"
debug_file << return_data
//Begin Instanciation
var/atom/instance
if(ispath(atom_def,/area))
instance = locate(atom_def)
if(!istype(instance, atom_def))
instance = new atom_def
instance.contents.Add(locate(x_coordinate,y_coordinate,z_coordinate))
else
instance = new atom_def(locate(x_coordinate,y_coordinate,z_coordinate))
if(instance)
for(var/item in fields)
instance.vars[item] = fields[item]
else if(!(atom_def in borked_paths))
borked_paths += atom_def
var/return_data = " Failure [atom_def] @ ([x_coordinate], [y_coordinate], [z_coordinate]) fields:"
for(var/item in fields)
return_data += " [item] = [fields[item]];"
debug_file << return_data
sleep(-1)
return 1
var/list/borked_paths = list()
proc/trim_text(var/what as text)
while(length(what) && findtext(what, " ", 1, 2))
what = copytext(what, 2)
while(length(what) && findtext(what, " ", length(what)))
what = copytext(what, 1, length(what))
return what
proc/get_list(var/text, var/list/text_strings)
//First, trim the data to just the list contents
var/list_start = findtext(text, "(") + 1
var/list_end = findtext(text, ")", list_start)
var/list_contents = copytext(text, list_start, list_end)
//Then, we seperate it into the individual entries
var/list/entries = list()
var/entry_end = 1
for(var/entry_start = 1, entry_end || entry_start != 1, entry_start = entry_end + 1)
entry_end = findtext(list_contents, ",", entry_start)
entries += copytext(list_contents, entry_start, entry_end)
//Finally, we assemble the completed list.
var/list/final_list = list()
for(var/entry in entries)
var/equals_position = findtext(entry, "=")
if(equals_position)
var/trim_left = trim_text(copytext(entry, 1, equals_position))
var/trim_right = trim_text(copytext(entry, equals_position + 1))
if(findtext(trim_right, "list("))
trim_right = get_list(trim_right, text_strings)
else if(findtext(trim_right, "~"))//Check for strings
while(findtext(trim_right,"~"))
var/reference_index = copytext(trim_right, findtext(trim_right, "~") + 1)
trim_right = text_strings[text2num(reference_index)]
//Check for numbers
else if(isnum(text2num(trim_right)))
trim_right = text2num(trim_right)
//Check for file
else if(copytext(trim_right,1,2) == "'")
trim_right = file(copytext(trim_right, 2, length(trim_right)))
if(findtext(trim_left, "~"))//Check for strings
while(findtext(trim_left,"~"))
var/reference_index = copytext(trim_left, findtext(trim_left, "~") + 1)
trim_left = text_strings[text2num(reference_index)]
final_list[trim_left] = trim_right
else
if(findtext(entry, "~"))//Check for strings
while(findtext(entry, "~"))
var/reference_index = copytext(entry, findtext(entry, "~") + 1)
entry = text_strings[text2num(reference_index)]
//Check for numbers
else if(isnum(text2num(entry)))
entry = text2num(entry)
//Check for file
else if(copytext(entry, 1, 2) == "'")
entry = file(copytext(entry, 2, length(entry)))
final_list += entry
return final_list
+1 -1
View File
@@ -311,7 +311,7 @@ commented out in r5061, I left it because of the shroom thingies
if (istype(W, /obj/item/device/measuring_tape))
var/obj/item/device/measuring_tape/P = W
user.visible_message("\blue[user] extends [P] towards [src].","\blue You extend [P] towards [src].")
if(do_after(user,40))
if(do_after(user,25))
user << "\blue \icon[P] [src] has been excavated to a depth of [2*src.excavation_level]cm."
return
+1 -1
View File
@@ -380,7 +380,7 @@
u_equip(item)
update_icons()
if (istype(usr, /mob/living/carbon/monkey)) //Check if a monkey is throwing. Modify/remove this line as required.
if (istype(usr, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required.
item.loc = src.loc
if(src.client)
src.client.screen -= item
@@ -227,7 +227,7 @@
if(!organ) return
if(istype(used_weapon,/obj/item/weapon))
var/obj/item/weapon/W = used_weapon //Sharp objects will always embed if they do enough damage.
if(damage > (5*W.w_class) && (prob(damage/W.w_class) || sharp)) //The larger it is, the harder it needs to hit to stick.
if( (damage > (10*W.w_class)) && ( (sharp && !ismob(W.loc)) || prob(damage/W.w_class) ) )
organ.implants += W
visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
W.add_blood(src)
@@ -237,7 +237,7 @@
W.loc = src
else if(istype(used_weapon,/obj/item/projectile)) //We don't want to use the actual projectile item, so we spawn some shrapnel.
if(prob(50) && damagetype == BRUTE)
if(prob(75) && damagetype == BRUTE)
var/obj/item/projectile/P = used_weapon
var/obj/item/weapon/shard/shrapnel/S = new()
S.name = "[P.name] shrapnel"
@@ -161,6 +161,17 @@ emp_act
if((user != src) && check_shields(I.force, "the [I.name]"))
return 0
if(istype(I,/obj/item/weapon/card/emag))
if(!(affecting.status & ORGAN_ROBOT))
user << "\red That limb isn't robotic."
return
if(affecting.sabotaged)
user << "\red [src]'s [affecting.display_name] is already sabotaged!"
else
user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties."
affecting.sabotaged = 1
return
if(I.attack_verb.len)
visible_message("\red <B>[src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!</B>")
else
@@ -88,7 +88,7 @@
update_inv_glasses()
else if (W == head)
head = null
if(W.flags & BLOCKHAIR)
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
update_hair(0) //rebuild hair
success = 1
update_inv_head()
@@ -107,7 +107,7 @@
else if (W == wear_mask)
wear_mask = null
success = 1
if(W.flags & BLOCKHAIR)
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
update_hair(0) //rebuild hair
if(internal)
if(internals)
@@ -188,7 +188,7 @@
update_inv_back(redraw_mob)
if(slot_wear_mask)
src.wear_mask = W
if(wear_mask.flags & BLOCKHAIR)
if((wear_mask.flags & BLOCKHAIR) || (wear_mask.flags & BLOCKHEADHAIR))
update_hair(redraw_mob) //rebuild hair
W.equipped(src, slot)
update_inv_wear_mask(redraw_mob)
@@ -229,7 +229,7 @@
update_inv_gloves(redraw_mob)
if(slot_head)
src.head = W
if(head.flags & BLOCKHAIR)
if((head.flags & BLOCKHAIR) || (head.flags & BLOCKHEADHAIR))
update_hair(redraw_mob) //rebuild hair
if(istype(W,/obj/item/clothing/head/kitty))
W.update_icon(src)
@@ -350,7 +350,6 @@ proc/get_damage_icon_part(damage_state, body_part)
//masks and helmets can obscure our hair.
if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
if(update_icons) update_icons()
return
//base icons
@@ -367,7 +366,7 @@ proc/get_damage_icon_part(damage_state, body_part)
face_standing.Blend(facial_s, ICON_OVERLAY)
face_lying.Blend(facial_l, ICON_OVERLAY)
if(h_style)
if(h_style && !(head && (head.flags & BLOCKHEADHAIR)))
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
if(hair_style)
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
+18 -13
View File
@@ -90,32 +90,37 @@
var/obj/item/weapon/W = O
var/momentum = speed/2
var/dir = get_dir(M,src)
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
if(near_wall(dir,2) && W.w_class >= 3 && W.sharp) //If they're close to a wall and the projectile is suitable.
visible_message("<span class='warning'>[src] is pinned to the wall by [O]!</span>","<span class='warning'>You are pinned to the wall by [O]!</span>")
if(!istype(src,/mob/living/carbon/human))
O.loc = src
src.embedded += O
src.anchored = 1
src.pinned += O
else
src.anchored = 1
src.pinned += O
if(W.w_class >= 3 && W.sharp && armor < 2) //Projectile is suitable, armour is bypassable.
var/turf/T = near_wall(dir,2)
if(T)
src.loc = T
visible_message("<span class='warning'>[src] is pinned to the wall by [O]!</span>","<span class='warning'>You are pinned to the wall by [O]!</span>")
if(!istype(src,/mob/living/carbon/human))
O.loc = src
src.embedded += O
src.anchored = 1
src.pinned += O
else
src.anchored = 1
src.pinned += O
/mob/living/proc/near_wall(var/direction,var/distance=1)
var/turf/T = get_step(get_turf(src),direction)
var/turf/last_turf = src.loc
var/i = 1
while(i>0 && i<=distance)
if(T.density) //Turf is a wall!
return 1
return last_turf
i++
last_turf = T
T = get_step(T,direction)
return 0
// End BS12 momentum-transfer code.
@@ -0,0 +1,145 @@
// TODO: remove the robot.mmi and robot.cell variables and completely rely on the robot component system
/datum/robot_component/var/name
/datum/robot_component/var/installed = 0
/datum/robot_component/var/powered = 0
/datum/robot_component/var/toggled = 1
/datum/robot_component/var/brute_damage = 0
/datum/robot_component/var/electronics_damage = 0
/datum/robot_component/var/energy_consumption = 0
/datum/robot_component/var/max_damage = 30
/datum/robot_component/var/mob/living/silicon/robot/owner
// The actual device object that has to be installed for this.
/datum/robot_component/var/external_type = null
// The wrapped device(e.g. radio), only set if external_type isn't null
/datum/robot_component/var/obj/item/wrapped = null
/datum/robot_component/New(mob/living/silicon/robot/R)
src.owner = R
/datum/robot_component/proc/install()
/datum/robot_component/proc/uninstall()
/datum/robot_component/proc/destroy()
if(wrapped)
del wrapped
wrapped = new/obj/item/broken_device
// The thing itself isn't there anymore, but some fried remains are.
installed = -1
uninstall()
/datum/robot_component/proc/take_damage(brute, electronics, sharp)
if(installed != 1) return
brute_damage += brute
electronics_damage += electronics
if(brute_damage + electronics_damage > max_damage) destroy()
/datum/robot_component/proc/heal_damage(brute, electronics)
if(installed != 1)
// If it's not installed, can't repair it.
return 0
brute_damage = max(0, brute_damage - brute)
electronics_damage = max(0, electronics_damage - electronics)
/datum/robot_component/proc/is_powered()
return installed == 1 && (!energy_consumption || powered)
/datum/robot_component/proc/consume_power()
if(toggled == 0)
powered = 0
return
if(owner.cell.charge >= energy_consumption)
owner.cell.use(energy_consumption)
powered = 1
else
powered = 0
/datum/robot_component/actuator
name = "actuator"
energy_consumption = 2
external_type = /obj/item/robot_parts/robot_component/actuator
max_damage = 60
/datum/robot_component/cell
name = "power cell"
max_damage = 60
/datum/robot_component/cell/destroy()
..()
owner.cell = null
/datum/robot_component/radio
name = "radio"
external_type = /obj/item/robot_parts/robot_component/radio
energy_consumption = 3
max_damage = 10
/datum/robot_component/binary_communication
name = "binary communication device"
external_type = /obj/item/robot_parts/robot_component/binary_communication_device
energy_consumption = 0
max_damage = 30
/datum/robot_component/camera
name = "camera"
external_type = /obj/item/robot_parts/robot_component/camera
energy_consumption = 2
max_damage = 20
/datum/robot_component/diagnosis_unit
name = "self-diagnosis unit"
energy_consumption = 1
external_type = /obj/item/robot_parts/robot_component/diagnosis_unit
max_damage = 30
/mob/living/silicon/robot/proc/initialize_components()
// This only initializes the components, it doesn't set them to installed.
components["actuator"] = new/datum/robot_component/actuator(src)
components["radio"] = new/datum/robot_component/radio(src)
components["power cell"] = new/datum/robot_component/cell(src)
components["diagnosis unit"] = new/datum/robot_component/diagnosis_unit(src)
components["camera"] = new/datum/robot_component/camera(src)
components["comms"] = new/datum/robot_component/binary_communication(src)
/mob/living/silicon/robot/proc/is_component_functioning(module_name)
var/datum/robot_component/C = components[module_name]
return C && C.installed == 1 && C.toggled && C.is_powered()
/obj/item/broken_device
name = "broken component"
icon = 'robot_component.dmi'
icon_state = "broken"
/obj/item/robot_parts/robot_component
icon = 'robot_component.dmi'
icon_state = "working"
construction_time = 200
construction_cost = list("metal"=5000)
// TODO: actual icons ;)
/obj/item/robot_parts/robot_component/binary_communication_device
name = "binary communication device"
/obj/item/robot_parts/robot_component/actuator
name = "actuator"
/obj/item/robot_parts/robot_component/camera
name = "camera"
/obj/item/robot_parts/robot_component/diagnosis_unit
name = "diagnosis unit"
/obj/item/robot_parts/robot_component/radio
name = "radio"
+17 -16
View File
@@ -10,7 +10,18 @@
switch(act)
if ("me")
return custom_emote(m_type, message)
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (stat)
return
if(!(message))
return
else
return custom_emote(m_type, message)
if ("custom")
return custom_emote(m_type, message)
@@ -62,20 +73,6 @@
message = "<B>[src]</B> flaps his wings ANGRILY!"
m_type = 2
if ("me")
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (stat)
return
if(!(message))
return
else
message = "<B>[src]</B> [message]"
if ("twitch")
message = "<B>[src]</B> twitches violently."
m_type = 1
@@ -207,8 +204,12 @@
m_type = 2
else
src << "You are not security."
if ("help")
src << "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitch_s, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look, beep, ping, \nbuzz, law, halt"
else
src << text("Invalid Emote: []", act)
src << "\blue Unusable emote '[act]'. Say *help for a list."
if ((message && src.stat == 0))
if (m_type & 1)
for(var/mob/O in viewers(src, null))
+23 -10
View File
@@ -37,23 +37,25 @@
/mob/living/silicon/robot/proc/use_power()
if (src.cell)
if (is_component_functioning("power cell"))
if(src.cell.charge <= 0)
uneq_all()
src.stat = 1
else if (src.cell.charge <= 100)
uneq_all()
src.sight_mode = 0
src.cell.use(1)
else
if(src.module_state_1)
src.cell.use(5)
src.cell.use(3)
if(src.module_state_2)
src.cell.use(5)
src.cell.use(3)
if(src.module_state_3)
src.cell.use(5)
src.cell.use(1)
src.blinded = 0
src.cell.use(3)
for(var/V in components)
var/datum/robot_component/C = components[V]
C.consume_power()
if(!is_component_functioning("actuator"))
Paralyse(3)
src.stat = 0
else
uneq_all()
@@ -128,6 +130,17 @@
src.druggy--
src.druggy = max(0, src.druggy)
if(!is_component_functioning("radio"))
radio.on = 0
else
radio.on = 1
if(is_component_functioning("camera"))
src.blinded = 0
else
src.blinded = 1
return 1
/mob/living/silicon/robot/proc/handle_regular_hud_updates()
+246 -62
View File
@@ -27,6 +27,9 @@
var/obj/item/weapon/cell/cell = null
var/obj/machinery/camera/camera = null
// Components are basically robot organs.
var/list/components = list()
var/obj/item/device/mmi/mmi = null
var/obj/item/device/pda/ai/rbPDA = null
@@ -58,7 +61,7 @@
var/braintype = "Cyborg"
var/pose
/mob/living/silicon/robot/New(loc,var/syndie = 0)
/mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0)
spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
@@ -67,12 +70,10 @@
updatename("Default")
updateicon()
if(!cell)
cell = new /obj/item/weapon/cell(src)
cell.maxcharge = 7500
cell.charge = 7500
if(syndie)
if(!cell)
cell = new /obj/item/weapon/cell(src)
laws = new /datum/ai_laws/antimov()
lawupdate = 0
scrambledcodes = 1
@@ -99,6 +100,25 @@
camera.network = list("SS13")
if(isWireCut(5)) // 5 = BORG CAMERA
camera.status = 0
initialize_components()
if(!unfinished)
// Create all the robot parts.
for(var/V in components) if(V != "power cell")
var/datum/robot_component/C = components[V]
C.installed = 1
C.wrapped = new C.external_type
if(!cell)
cell = new /obj/item/weapon/cell(src)
cell.maxcharge = 7500
cell.charge = 7500
if(cell)
var/datum/robot_component/cell_component = components["power cell"]
cell_component.wrapped = cell
cell_component.installed = 1
..()
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
@@ -132,12 +152,21 @@
module = new /obj/item/weapon/robot_module/standard(src)
hands.icon_state = "standard"
var/icontype
if (src.name == "Lucy" && src.ckey == "rowtree") icontype = ("Lucy")
else icontype = input("Select an icon!", "Robot", null, null) in list("Basic", "Standard")
switch(icontype)
if("Basic") icon_state = "robot_old"
if("Lucy") icon_state = "rowtree-lucy"
else icon_state = "robot"
var/triesleft = 6
while (triesleft)
triesleft--
if (src.name == "Lucy" && src.ckey == "rowtree")
icontype = ("Lucy")
triesleft = 0
else icontype = input("Select an icon! [triesleft ? "You would have [triesleft] more tries." : "This is your last try."]", "Robot", null, null) in list("Basic", "Standard")
switch(icontype)
if("Basic") icon_state = "robot_old"
if("Lucy") icon_state = "rowtree-lucy"
else icon_state = "robot"
if(triesleft)
switch(input("Look at your icon - is this what you want?") in list("Yes","No"))
if("Yes")
triesleft = 0
modtype = "Stand"
feedback_inc("cyborg_standard",1)
@@ -146,15 +175,24 @@
module = new /obj/item/weapon/robot_module/butler(src)
hands.icon_state = "service"
var/icontype
if (src.name == "Lucy" && src.ckey == "rowtree") icontype = ("Lucy")
else icontype = input("Select an icon!", "Robot", null, null) in list("Waitress", "Bro", "Butler", "Kent", "Rich")
switch(icontype)
if("Waitress") icon_state = "Service"
if("Kent") icon_state = "toiletbot"
if("Bro") icon_state = "Brobot"
if("Rich") icon_state = "maximillion"
if("Lucy") icon_state = "rowtree-lucy"
else icon_state = "Service2"
var/triesleft = 6
while (triesleft)
triesleft--
if (src.name == "Lucy" && src.ckey == "rowtree")
icontype = ("Lucy")
triesleft = 0
else icontype = input("Select an icon! [triesleft ? "You would have [triesleft] more tries." : "This is your last try."]", "Robot", null, null) in list("Waitress", "Bro", "Butler", "Kent", "Rich")
switch(icontype)
if("Waitress") icon_state = "Service"
if("Kent") icon_state = "toiletbot"
if("Bro") icon_state = "Brobot"
if("Rich") icon_state = "maximillion"
if("Lucy") icon_state = "rowtree-lucy"
else icon_state = "Service2"
if(triesleft)
switch(input("Look at your icon - is this what you want?") in list("Yes","No"))
if("Yes")
triesleft = 0
modtype = "Butler"
feedback_inc("cyborg_service",1)
@@ -163,13 +201,22 @@
module = new /obj/item/weapon/robot_module/miner(src)
hands.icon_state = "miner"
var/icontype
if (src.name == "Lucy" && src.ckey == "rowtree") icontype = ("Lucy")
else icontype = input("Select an icon!", "Robot", null, null) in list("Basic", "Advanced Droid", "Treadhead")
switch(icontype)
if("Basic") icon_state = "Miner_old"
if("Advanced Droid") icon_state = "droid-miner"
if("Lucy") icon_state = "rowtree-lucy"
else icon_state = "Miner"
var/triesleft = 6
while (triesleft)
triesleft--
if (src.name == "Lucy" && src.ckey == "rowtree")
icontype = ("Lucy")
triesleft = 0
else icontype = input("Select an icon! [triesleft ? "You would have [triesleft] more tries." : "This is your last try."]", "Robot", null, null) in list("Basic", "Advanced Droid", "Treadhead")
switch(icontype)
if("Basic") icon_state = "Miner_old"
if("Advanced Droid") icon_state = "droid-miner"
if("Lucy") icon_state = "rowtree-lucy"
else icon_state = "Miner"
if(triesleft)
switch(input("Look at your icon - is this what you want?") in list("Yes","No"))
if("Yes")
triesleft = 0
modtype = "Miner"
feedback_inc("cyborg_miner",1)
channels = list("Mining" = 1)
@@ -179,14 +226,23 @@
module = new /obj/item/weapon/robot_module/medical(src)
hands.icon_state = "medical"
var/icontype
if (src.name == "Lucy" && src.ckey == "rowtree") icontype = ("Lucy")
else icontype = input("Select an icon!", "Robot", null, null) in list("Basic", "Advanced Droid", "Needles", "Hoverbot")
switch(icontype)
if("Basic") icon_state = "Medbot"
if("Advanced Droid") icon_state = "droid-medical"
if("Needles") icon_state = "medicalrobot"
if("Lucy") icon_state = "rowtree-medical"
else icon_state = "surgeon"
var/triesleft = 6
while (triesleft)
triesleft--
if (src.name == "Lucy" && src.ckey == "rowtree")
icontype = ("Lucy")
triesleft = 0
else icontype = input("Select an icon! [triesleft ? "You would have [triesleft] more tries." : "This is your last try."]", "Robot", null, null) in list("Basic", "Advanced Droid", "Needles", "Hoverbot")
switch(icontype)
if("Basic") icon_state = "Medbot"
if("Advanced Droid") icon_state = "droid-medical"
if("Needles") icon_state = "medicalrobot"
if("Lucy") icon_state = "rowtree-medical"
else icon_state = "surgeon"
if(triesleft)
switch(input("Look at your icon - is this what you want?") in list("Yes","No"))
if("Yes")
triesleft = 0
modtype = "Med"
status_flags &= ~CANPUSH
feedback_inc("cyborg_medical",1)
@@ -197,14 +253,23 @@
module = new /obj/item/weapon/robot_module/security(src)
hands.icon_state = "security"
var/icontype
if (src.name == "Lucy" && src.ckey == "rowtree") icontype = ("Lucy")
else icontype = input("Select an icon!", "Robot", null, null) in list("Basic", "Red Knight", "Black Knight", "Bloodhound")
switch(icontype)
if("Basic") icon_state = "secborg"
if("Red Knight") icon_state = "Security"
if("Black Knight") icon_state = "securityrobot"
if("Lucy") icon_state = "rowtree-security"
else icon_state = "bloodhound"
var/triesleft = 6
while (triesleft)
triesleft--
if (src.name == "Lucy" && src.ckey == "rowtree")
icontype = ("Lucy")
triesleft = 0
else icontype = input("Select an icon! [triesleft ? "You would have [triesleft] more tries." : "This is your last try."]", "Robot", null, null) in list("Basic", "Red Knight", "Black Knight", "Bloodhound")
switch(icontype)
if("Basic") icon_state = "secborg"
if("Red Knight") icon_state = "Security"
if("Black Knight") icon_state = "securityrobot"
if("Lucy") icon_state = "rowtree-security"
else icon_state = "bloodhound"
if(triesleft)
switch(input("Look at your icon - is this what you want?") in list("Yes","No"))
if("Yes")
triesleft = 0
modtype = "Sec"
//speed = -1 Secborgs have nerfed tasers now, so the speed boost is not necessary
status_flags &= ~CANPUSH
@@ -216,13 +281,22 @@
module = new /obj/item/weapon/robot_module/engineering(src)
hands.icon_state = "engineer"
var/icontype
if (src.name == "Lucy" && src.ckey == "rowtree") icontype = ("Lucy")
else icontype = input("Select an icon!", "Robot", null, null) in list("Basic", "Antique", "Landmate")
switch(icontype)
if("Basic") icon_state = "Engineering"
if("Antique") icon_state = "engineerrobot"
if("Lucy") icon_state = "rowtree-engineering"
else icon_state = "landmate"
var/triesleft = 6
while (triesleft)
triesleft--
if (src.name == "Lucy" && src.ckey == "rowtree")
icontype = ("Lucy")
triesleft = 0
else icontype = input("Select an icon! [triesleft ? "You would have [triesleft] more tries." : "This is your last try."]", "Robot", null, null) in list("Basic", "Antique", "Landmate")
switch(icontype)
if("Basic") icon_state = "Engineering"
if("Antique") icon_state = "engineerrobot"
if("Lucy") icon_state = "rowtree-engineering"
else icon_state = "landmate"
if(triesleft)
switch(input("Look at your icon - is this what you want?") in list("Yes","No"))
if("Yes")
triesleft = 0
modtype = "Eng"
feedback_inc("cyborg_engineering",1)
channels = list("Engineering" = 1)
@@ -232,13 +306,22 @@
module = new /obj/item/weapon/robot_module/janitor(src)
hands.icon_state = "janitor"
var/icontype
if (src.name == "Lucy" && src.ckey == "rowtree") icontype = ("Lucy")
else icontype = input("Select an icon!", "Robot", null, null) in list("Basic", "Mopbot", "Zamboni")
switch(icontype)
if("Basic") icon_state = "JanBot2"
if("Mopbot") icon_state = "janitorrobot"
if("Lucy") icon_state = "rowtree-lucy"
else icon_state = "mopgearrex"
var/triesleft = 6
while (triesleft)
triesleft--
if (src.name == "Lucy" && src.ckey == "rowtree")
icontype = ("Lucy")
triesleft = 0
else icontype = input("Select an icon! [triesleft ? "You would have [triesleft] more tries." : "This is your last try."]", "Robot", null, null) in list("Basic", "Mopbot", "Zamboni")
switch(icontype)
if("Basic") icon_state = "JanBot2"
if("Mopbot") icon_state = "janitorrobot"
if("Lucy") icon_state = "rowtree-lucy"
else icon_state = "mopgearrex"
if(triesleft)
switch(input("Look at your icon - is this what you want?") in list("Yes","No"))
if("Yes")
triesleft = 0
modtype = "Jan"
feedback_inc("cyborg_janitor",1)
@@ -262,10 +345,14 @@
changed_name = "[(prefix ? "[prefix] " : "")][braintype]-[num2text(ident)]"
real_name = changed_name
name = real_name
// if we've changed our name, we also need to update the display name for our PDA
setup_PDA()
//We also need to update name of internal camera.
if (camera)
camera.c_tag = changed_name
/mob/living/silicon/robot/verb/Namepick()
if(custom_name)
return 0
@@ -314,6 +401,53 @@
viewalerts = 1
src << browse(dat, "window=robotalerts&can_close=0")
/mob/living/silicon/robot/proc/self_diagnosis()
if(!is_component_functioning("diagnosis unit"))
return null
var/dat = "<HEAD><TITLE>[src.name] Self-Diagnosis Report</TITLE></HEAD><BODY>\n"
for (var/V in components)
var/datum/robot_component/C = components[V]
dat += "<b>[C.name]</b><br><table><tr><td>Power consumption</td><td>[C.energy_consumption]</td></tr><tr><td>Brute Damage:</td><td>[C.brute_damage]</td></tr><tr><td>Electronics Damage:</td><td>[C.electronics_damage]</td></tr><tr><td>Powered:</td><td>[(!C.energy_consumption || C.is_powered()) ? "Yes" : "No"]</td></tr><tr><td>Toggled:</td><td>[ C.toggled ? "Yes" : "No"]</td></table><br>"
return dat
/mob/living/silicon/robot/verb/self_diagnosis_verb()
set category = "Robot Commands"
set name = "Self Diagnosis"
if(!is_component_functioning("diagnosis unit"))
src << "\red Your self-diagnosis component isn't functioning."
var/dat = self_diagnosis()
src << browse(dat, "window=robotdiagnosis")
/mob/living/silicon/robot/verb/toggle_component()
set category = "Robot Commands"
set name = "Toggle Component"
set desc = "Toggle a component, conserving power."
var/list/installed_components = list()
for(var/V in components)
if(V == "power cell") continue
var/datum/robot_component/C = components[V]
if(C.installed)
installed_components += V
var/toggle = input(src, "Which component do you want to toggle?", "Toggle Component") as null|anything in installed_components
if(!toggle)
return
var/datum/robot_component/C = components[toggle]
if(C.toggled)
C.toggled = 0
src << "\red You disable [C.name]."
else
C.toggled = 1
src << "\red You enable [C.name]."
/mob/living/silicon/robot/blob_act()
if (stat != 2)
adjustBruteLoss(60)
@@ -497,7 +631,24 @@
if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
return
if(opened) // Are they trying to insert something?
for(var/V in components)
var/datum/robot_component/C = components[V]
if(!C.installed && istype(W, C.external_type))
C.installed = 1
C.wrapped = W
C.install()
user.drop_item()
W.loc = null
usr << "\blue You install the [W.name]."
return
if (istype(W, /obj/item/weapon/weldingtool))
if (!getBruteLoss())
user << "Nothing to fix here!"
return
var/obj/item/weapon/weldingtool/WT = W
if (WT.remove_fuel(0))
adjustBruteLoss(-30)
@@ -510,6 +661,9 @@
return
else if(istype(W, /obj/item/weapon/cable_coil) && wiresexposed)
if (!getFireLoss())
user << "Nothing to fix here!"
return
var/obj/item/weapon/cable_coil/coil = W
adjustFireLoss(-30)
updatehealth()
@@ -536,6 +690,27 @@
C.updateicon()
new/obj/item/robot_parts/chest(loc)
src.Del()
else
// Okay we're not removing the cell or an MMI, but maybe something else?
var/list/removable_components = list()
for(var/V in components)
if(V == "power cell") continue
var/datum/robot_component/C = components[V]
if(C.installed == 1)
removable_components += V
var/remove = input(user, "Which component do you want to pry out?", "Remove Component") as null|anything in removable_components
if(!remove)
return
var/datum/robot_component/C = components[remove]
var/obj/item/I = C.wrapped
user << "You remove \the [I]."
I.loc = src.loc
if(C.installed == 1)
C.uninstall()
C.installed = 0
else
if(locked)
user << "The cover is locked and cannot be opened."
@@ -545,17 +720,20 @@
updateicon()
else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside
var/datum/robot_component/C = components["power cell"]
if(wiresexposed)
user << "Close the panel first."
else if(cell)
else if(cell || C.installed)
user << "There is a power cell already installed."
else
user.drop_item()
W.loc = src
cell = W
user << "You insert the power cell."
// chargecount = 0
updateicon()
C.installed = 1
C.wrapped = W
C.install()
else if (istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/multitool))
if (wiresexposed)
@@ -828,6 +1006,7 @@
add_fingerprint(user)
if(opened && !wiresexposed && (!istype(user, /mob/living/silicon)))
var/datum/robot_component/cell_component = components["power cell"]
if(cell)
cell.updateicon()
cell.add_fingerprint(user)
@@ -835,6 +1014,11 @@
user << "You remove \the [cell]."
cell = null
updateicon()
else if(cell_component.installed == -1)
cell_component.installed = 0
var/obj/item/broken_device = cell_component.wrapped
user << "You remove \the [broken_device]."
user.put_in_active_hand(broken_device)
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
@@ -0,0 +1,83 @@
/mob/living/silicon/robot/getBruteLoss()
var/amount = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.installed == 1) amount += C.brute_damage
return amount
/mob/living/silicon/robot/getFireLoss()
var/amount = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.installed == 1) amount += C.electronics_damage
return amount
/mob/living/silicon/robot/adjustBruteLoss(var/amount)
if(amount > 0)
take_overall_damage(amount, 0)
else
heal_overall_damage(-amount, 0)
/mob/living/silicon/robot/adjustFireLoss(var/amount)
if(amount > 0)
take_overall_damage(0, amount)
else
heal_overall_damage(0, -amount)
/mob/living/silicon/robot/proc/get_damaged_components(var/brute, var/burn)
var/list/datum/robot_component/parts = list()
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.installed == 1) if((brute && C.brute_damage) || (burn && C.electronics_damage))
parts += C
return parts
/mob/living/silicon/robot/proc/get_damageable_components()
var/list/rval = new
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.installed == 1) rval += C
return rval
/mob/living/silicon/robot/heal_organ_damage(var/brute, var/burn)
var/list/datum/robot_component/parts = get_damaged_components(brute,burn)
if(!parts.len) return
var/datum/robot_component/picked = pick(parts)
picked.heal_damage(brute,burn)
/mob/living/silicon/robot/take_organ_damage(var/brute, var/burn, var/sharp = 0)
var/datum/robot_component/C = pick(get_damageable_components())
C.take_damage(brute,burn,sharp)
/mob/living/silicon/robot/heal_overall_damage(var/brute, var/burn)
var/list/datum/robot_component/parts = get_damaged_components(brute,burn)
while(parts.len && (brute>0 || burn>0) )
var/datum/robot_component/picked = pick(parts)
var/brute_was = picked.brute_damage
var/burn_was = picked.electronics_damage
picked.heal_damage(brute,burn)
brute -= (brute_was-picked.brute_damage)
burn -= (burn_was-picked.electronics_damage)
parts -= picked
/mob/living/silicon/robot/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/used_weapon = null)
if(status_flags & GODMODE) return //godmode
var/list/datum/robot_component/parts = get_damageable_components()
while(parts.len && (brute>0 || burn>0) )
var/datum/robot_component/picked = pick(parts)
var/brute_was = picked.brute_damage
var/burn_was = picked.electronics_damage
picked.take_damage(brute,burn)
brute -= (picked.brute_damage - brute_was)
burn -= (picked.electronics_damage - burn_was)
parts -= picked
+8
View File
@@ -24,6 +24,14 @@
return ..(message)
message = copytext(message, 3)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
// TODO: move the component system up to silicon so we don't have to use this ugly hack..
if(istype(src, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = src
if(!R.is_component_functioning("comms"))
src << "\red Your binary communications component isn't functional."
return
robot_talk(message)
else if (department_radio_keys[prefix] == "department")
if(isAI(src)&&client)//For patching directly into AI holopads.
+1 -1
View File
@@ -596,7 +596,6 @@ var/list/slot_equipment_priority = list( \
M.LAssailant = null
else
M.LAssailant = usr
return
if(pulling)
var/pulling_old = pulling
@@ -604,6 +603,7 @@ var/list/slot_equipment_priority = list( \
// Are we pulling the same thing twice? Just stop pulling.
if(pulling_old == AM)
return
src.pulling = AM
AM.pulledby = src
@@ -431,6 +431,19 @@ datum/preferences
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-vir"), ICON_OVERLAY)
if(4)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY)
if(ROBOTICIST)
clothes_s = new /icon('icons/mob/uniform.dmi', "robotics_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "toolbox_blue"), ICON_OVERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY)
switch(backbag)
if(2)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY)
if(3)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY)
if(4)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY)
else if(job_engsec_high)
switch(job_engsec_high)
@@ -538,19 +551,7 @@ datum/preferences
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY)
if(4)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY)
if(ROBOTICIST)
clothes_s = new /icon('icons/mob/uniform.dmi', "robotics_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "toolbox_blue"), ICON_OVERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY)
switch(backbag)
if(2)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY)
if(3)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY)
if(4)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY)
if(AI)//Gives AI and borgs assistant-wear, so they can still customize their character
clothes_s = new /icon('icons/mob/uniform.dmi', "grey_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
+23 -22
View File
@@ -35,6 +35,7 @@
var/open = 0
var/stage = 0
var/cavity = 0
var/sabotaged = 0 //If a prosthetic limb is emagged, it will detonate when it fails.
var/obj/item/hidden = null
var/list/implants = list()
@@ -482,8 +483,8 @@
owner.u_equip(owner.shoes)
if(organ)
destspawn = 1
//Robotic limbs explode until specified otherwise
if(status & ORGAN_ROBOT && !no_explode)
//Robotic limbs explode if sabotaged.
if(status & ORGAN_ROBOT && !no_explode && sabotaged)
owner.visible_message("\red \The [owner]'s [display_name] explodes violently!",\
"\red <b>Your [display_name] explodes!</b>",\
"You hear an explosion followed by a scream!")
@@ -494,10 +495,10 @@
spark_system.start()
spawn(10)
del(spark_system)
else
owner.visible_message("\red [owner.name]'s [display_name] flies off in an arc.",\
"<span class='moderate'><b>Your [display_name] goes flying off!</b></span>",\
"You hear a terrible sound of ripping tendons and flesh.")
owner.visible_message("\red [owner.name]'s [display_name] flies off in an arc.",\
"<span class='moderate'><b>Your [display_name] goes flying off!</b></span>",\
"You hear a terrible sound of ripping tendons and flesh.")
//Throw organs around
var/lol = pick(cardinal)
@@ -590,8 +591,8 @@
name = "chest"
icon_name = "torso"
display_name = "chest"
max_damage = 150
min_broken_damage = 75
max_damage = 75
min_broken_damage = 40
body_part = UPPER_TORSO
@@ -599,24 +600,24 @@
name = "groin"
icon_name = "groin"
display_name = "groin"
max_damage = 115
min_broken_damage = 70
max_damage = 50
min_broken_damage = 30
body_part = LOWER_TORSO
/datum/organ/external/l_arm
name = "l_arm"
display_name = "left arm"
icon_name = "l_arm"
max_damage = 75
min_broken_damage = 30
max_damage = 50
min_broken_damage = 20
body_part = ARM_LEFT
/datum/organ/external/l_leg
name = "l_leg"
display_name = "left leg"
icon_name = "l_leg"
max_damage = 75
min_broken_damage = 30
max_damage = 50
min_broken_damage = 20
body_part = LEG_LEFT
icon_position = LEFT
@@ -624,16 +625,16 @@
name = "r_arm"
display_name = "right arm"
icon_name = "r_arm"
max_damage = 75
min_broken_damage = 30
max_damage = 50
min_broken_damage = 20
body_part = ARM_RIGHT
/datum/organ/external/r_leg
name = "r_leg"
display_name = "right leg"
icon_name = "r_leg"
max_damage = 75
min_broken_damage = 30
max_damage = 50
min_broken_damage = 20
body_part = LEG_RIGHT
icon_position = RIGHT
@@ -641,7 +642,7 @@
name = "l_foot"
display_name = "left foot"
icon_name = "l_foot"
max_damage = 40
max_damage = 30
min_broken_damage = 15
body_part = FOOT_LEFT
icon_position = LEFT
@@ -650,7 +651,7 @@
name = "r_foot"
display_name = "right foot"
icon_name = "r_foot"
max_damage = 40
max_damage = 30
min_broken_damage = 15
body_part = FOOT_RIGHT
icon_position = RIGHT
@@ -659,7 +660,7 @@
name = "r_hand"
display_name = "right hand"
icon_name = "r_hand"
max_damage = 40
max_damage = 30
min_broken_damage = 15
body_part = HAND_RIGHT
@@ -667,7 +668,7 @@
name = "l_hand"
display_name = "left hand"
icon_name = "l_hand"
max_damage = 40
max_damage = 30
min_broken_damage = 15
body_part = HAND_LEFT
+2
View File
@@ -461,6 +461,8 @@ var/list/solars_list = list()
if(src.trackrate) nexttime = world.time + 6000/trackrate
track = text2num(href_list["track"])
if(powernet && (track == 2))
if(!solars_list.Find(src,1,0))
solars_list.Add(src)
for(var/obj/machinery/power/tracker/T in get_solars_powernet())
if(powernet.nodes[T])
cdir = T.sun_angle
+12 -12
View File
@@ -2792,7 +2792,7 @@ datum
// make all the beverages work together
for(var/datum/reagent/ethanol/A in holder.reagent_list)
if(A.data) d += A.data
if(isnum(A.data)) d += A.data
M.dizziness +=dizzy_adj.
if(d >= slur_start && d < pass_out)
@@ -3453,14 +3453,14 @@ datum
nutriment_factor = 1 * FOOD_METABOLISM
color = "#2E6671" // rgb: 46, 102, 113
on_mob_life(var/mob/living/M as mob)
if(!data) data = 1
data++
M.dizziness +=10
if(data >= 55 && data <115)
if (!M.stuttering) M.stuttering = 1
M.stuttering += 10
else if(data >= 115 && prob(33))
M.confused = max(M.confused+15,15)
..()
return
on_mob_life(var/mob/living/M as mob)
if(!data) data = 1
data++
M.dizziness +=10
if(data >= 55 && data <115)
if (!M.stuttering) M.stuttering = 1
M.stuttering += 10
else if(data >= 115 && prob(33))
M.confused = max(M.confused+15,15)
..()
return
@@ -203,7 +203,7 @@
/obj/item/weapon/reagent_containers/food/drinks/tea
name = "Duke Purple Tea"
desc = "An insult to Duke Purple is an insult to the Space Queen! Any proper gentleman will fight you, if you sully this tea."
icon_state = "tea"
icon_state = "teacup"
item_state = "coffee"
New()
..()
@@ -224,7 +224,7 @@
/obj/item/weapon/reagent_containers/food/drinks/h_chocolate
name = "Dutch Hot Coco"
desc = "Made in Space South America."
icon_state = "tea"
icon_state = "hot_coco"
item_state = "coffee"
New()
..()
+276 -1
View File
@@ -128,4 +128,279 @@
New()
var/datum/reagents/R = new/datum/reagents(15)
reagents = R
R.my_atom = src
R.my_atom = src
/obj/item/weapon/dart_cartridge
name = "dart cartridge"
desc = "A rack of hollow darts."
icon = 'icons/obj/ammo.dmi'
icon_state = "darts-5"
item_state = "rcdammo"
opacity = 0
density = 0
anchored = 0.0
origin_tech = "materials=2"
var/darts = 5
/obj/item/weapon/dart_cartridge/update_icon()
if(!darts)
icon_state = "darts-0"
else if(darts > 5)
icon_state = "darts-5"
else
icon_state = "darts-[darts]"
return 1
/obj/item/weapon/gun/dartgun
name = "dart gun"
desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances."
icon_state = "dartgun-empty"
var/list/beakers = list() //All containers inside the gun.
var/list/mixing = list() //Containers being used for mixing.
var/obj/item/weapon/dart_cartridge/cartridge = null //Container of darts.
var/max_beakers = 3
/obj/item/weapon/gun/dartgun/update_icon()
if(!cartridge)
icon_state = "dartgun-empty"
return 1
if(!cartridge.darts)
icon_state = "dartgun-0"
else if(cartridge.darts > 5)
icon_state = "dartgun-5"
else
icon_state = "dartgun-[cartridge.darts]"
return 1
/obj/item/weapon/gun/dartgun/New()
if(beakers.len)
return
// The dartgun has one beaker by default.
var/obj/item/weapon/reagent_containers/glass/beaker/B = new(src)
beakers += B
..()
/obj/item/weapon/gun/dartgun/examine()
set src in view()
update_icon()
..()
if (!(usr in view(2)) && usr!=src.loc)
return
if (beakers.len)
usr << "\blue [src] contains:"
for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers)
if(B.reagents && B.reagents.reagent_list.len)
for(var/datum/reagent/R in B.reagents.reagent_list)
usr << "\blue [R.volume] units of [R.name]"
/obj/item/weapon/gun/dartgun/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/dart_cartridge))
var/obj/item/weapon/dart_cartridge/D = I
if(!D.darts)
user << "\blue [D] is empty."
return 0
if(cartridge)
if(cartridge.darts <= 0)
src.remove_cartridge()
else
user << "\blue There's already a cartridge in [src]."
return 0
user.drop_item()
cartridge = D
D.loc = src
user << "\blue You slot [D] into [src]."
update_icon()
return
if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker))
if(beakers.len >= max_beakers)
user << "\blue [src] already has [max_beakers] beakers in it - another one isn't going to fit!"
return
var/obj/item/weapon/reagent_containers/glass/beaker/B = I
user.drop_item()
B.loc = src
beakers += B
user << "\blue You slot [B] into [src]."
src.updateUsrDialog()
/obj/item/weapon/gun/dartgun/can_fire()
if(!cartridge)
return 0
else
return cartridge.darts
/obj/item/weapon/gun/dartgun/proc/has_selected_beaker_reagents()
return 0
/obj/item/weapon/gun/dartgun/proc/remove_cartridge()
if(cartridge)
usr << "\blue You pop the cartridge out of [src]."
var/obj/item/weapon/dart_cartridge/C = cartridge
C.loc = get_turf(src)
C.update_icon()
cartridge = null
src.update_icon()
/obj/item/weapon/gun/dartgun/proc/get_mixed_syringe()
if (!cartridge)
return 0
if(!cartridge.darts)
return 0
var/obj/item/weapon/reagent_containers/syringe/dart = new(src)
if(mixing.len)
var/mix_amount = 10/mixing.len
for(var/obj/item/weapon/reagent_containers/glass/beaker/B in mixing)
B.reagents.trans_to(dart,mix_amount)
return dart
/obj/item/weapon/gun/dartgun/proc/fire_dart(atom/target, mob/user)
if (locate (/obj/structure/table, src.loc))
return
else
var/turf/trg = get_turf(target)
var/obj/effect/syringe_gun_dummy/D = new/obj/effect/syringe_gun_dummy(get_turf(src))
var/obj/item/weapon/reagent_containers/syringe/S = get_mixed_syringe()
if(!S)
user << "\red There are no darts in [src]!"
return
if(!S.reagents)
user << "\red There are no reagents available!"
return
cartridge.darts--
src.update_icon()
S.reagents.trans_to(D, S.reagents.total_volume)
del(S)
D.icon_state = "syringeproj"
D.name = "syringe"
playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1)
for(var/i=0, i<6, i++)
if(!D) break
if(D.loc == trg) break
step_towards(D,trg)
if(D)
for(var/mob/living/carbon/M in D.loc)
if(!istype(M,/mob/living/carbon)) continue
if(M == user) continue
//Syringe gun attack logging by Yvarov
var/R
if(D.reagents)
for(var/datum/reagent/A in D.reagents.reagent_list)
R += A.id + " ("
R += num2text(A.volume) + "),"
if (istype(M, /mob))
M.attack_log += "\[[time_stamp()]\] <b>[user]/[user.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>syringegun</b> ([R])"
user.attack_log += "\[[time_stamp()]\] <b>[user]/[user.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>syringegun</b> ([R])"
log_attack("<font color='red'>[user] ([user.ckey]) shot [M] ([M.ckey]) with a syringegun ([R])</font>")
else
M.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[M]/[M.ckey]</b> with a <b>syringegun</b> ([R])"
log_attack("<font color='red'>UNKNOWN shot [M] ([M.ckey]) with a <b>syringegun</b> ([R])</font>")
if(D.reagents)
D.reagents.trans_to(M, 15)
M << "<span class='danger'>You feel a slight prick.</span>"
del(D)
break
if(D)
for(var/atom/A in D.loc)
if(A == user) continue
if(A.density) del(D)
sleep(1)
if (D) spawn(10) del(D)
return
/obj/item/weapon/gun/dartgun/afterattack(obj/target, mob/user , flag)
if(!isturf(target.loc) || target == user) return
..()
/obj/item/weapon/gun/dartgun/can_hit(var/mob/living/target as mob, var/mob/living/user as mob)
return 1
/obj/item/weapon/gun/dartgun/attack_self(user as mob)
var/dat = "<b>[src] mixing control:</b><br><br>"
if (beakers.len)
var/i = 1
for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers)
dat += "Beaker [i] contains: "
if(B.reagents && B.reagents.reagent_list.len)
for(var/datum/reagent/R in B.reagents.reagent_list)
dat += "<br> [R.volume] units of [R.name], "
if (check_beaker_mixing(B))
dat += text("<A href='?src=\ref[src];stop_mix=[i]'><font color='green'>Mixing</font></A> ")
else
dat += text("<A href='?src=\ref[src];mix=[i]'><font color='red'>Not mixing</font></A> ")
else
dat += "nothing."
dat += " \[<A href='?src=\ref[src];eject=[i]'>Eject</A>\]<br>"
i++
else
dat += "There are no beakers inserted!<br><br>"
if(cartridge)
if(cartridge.darts)
dat += "The dart cartridge has [cartridge.darts] shots remaining."
else
dat += "<font color='red'>The dart cartridge is empty!</font>"
dat += " \[<A href='?src=\ref[src];eject_cart=1'>Eject</A>\]"
user << browse("[dat]", "window=dartgun_mixing_window")
/obj/item/weapon/gun/dartgun/proc/check_beaker_mixing(var/obj/item/B)
if(!mixing || !beakers)
return 0
for(var/obj/item/M in mixing)
if(M == B)
return 1
return 0
/obj/item/weapon/gun/dartgun/Topic(href, href_list)
src.add_fingerprint(usr)
if(href_list["stop_mix"])
var/index = text2num(href_list["stop_mix"])
if(index <= beakers.len)
for(var/obj/item/M in mixing)
if(M == beakers[index])
mixing -= M
break
else if (href_list["mix"])
var/index = text2num(href_list["mix"])
if(index <= beakers.len)
mixing += beakers[index]
else if (href_list["eject"])
var/index = text2num(href_list["eject"])
if(index <= beakers.len)
if(beakers[index])
var/obj/item/weapon/reagent_containers/glass/beaker/B = beakers[index]
usr << "You remove [B] from [src]."
mixing -= B
beakers -= B
B.loc = get_turf(src)
else if (href_list["eject_cart"])
remove_cartridge()
src.updateUsrDialog()
return
/obj/item/weapon/gun/dartgun/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
if(cartridge)
spawn(0) fire_dart(target,user)
else
usr << "\red [src] is empty."
@@ -1,4 +1,6 @@
// This machine shows the age for extremely old finds
obj/machinery/anomaly/accelerator
name = "Accelerator spectrometer"
@@ -23,7 +23,7 @@
var/obj/item/weapon/reagent_containers/glass/held_container
var/obj/item/weapon/tank/fuel_container
var/target_scan_ticks = 60
var/target_scan_ticks = 30
var/report_num = 0
var/scan_process = 0
var/temperature = 273 //measured in kelvin, if this exceeds 1200, the machine is damaged and requires repairs
@@ -50,8 +50,10 @@
if(scan_process)
if(scan_process++ > target_scan_ticks)
FinishScan()
if(temperature > 350 && prob(10))
else if(temperature > 400)
src.visible_message("\blue \icon[src] shuts down from the heat!", 2)
scan_process = 0
else if(temperature > 350 && prob(10))
src.visible_message("\blue \icon[src] bleets plaintively.", 2)
if(temperature > 400)
scan_process = 0
@@ -107,7 +109,7 @@
user.machine = src
var/dat = "<B>[src.name]</B><BR>"
dat += "Module heat level: [temperature] kelvin<br>"
dat += "Safeties set at 300k, shielding failure at 400k. Failure to maintain safe heat levels may result in equipment damage.<br>"
dat += "Safeties set at 350k, shielding failure at 400k. Failure to maintain safe heat levels may result in equipment damage.<br>"
dat += "<hr>"
if(scan_process)
dat += "Scan in progress<br><br><br>"
@@ -178,7 +180,7 @@ obj/machinery/anomaly/Topic(href, href_list)
fuel_container.loc = src.loc
fuel_container = null
if(href_list["begin"])
if(temperature >= 300)
if(temperature >= 350)
var/proceed = input("Unsafe internal temperature detected, enter YES below to continue.","Warning")
if(proceed == "YES" && get_dist(src, usr) <= 1)
scan_process = 1
@@ -1,4 +1,6 @@
// This machine tells the distance to a nearby artifact, if there is one
obj/machinery/anomaly/fourier_transform
name = "Fourier Transform spectroscope"
@@ -1,4 +1,6 @@
// This machine shows the materials that are present
obj/machinery/anomaly/gas_chromatography
name = "Gas Chromatography spectrometer"
@@ -1,4 +1,6 @@
// This machine shows the amount of a certain material that is present
obj/machinery/anomaly/ion_mobility
name = "Ion Mobility Spectrometer"
desc = "A specialised, complex analysis machine."
@@ -1,4 +1,6 @@
// This machine shows the age for newer finds
obj/machinery/anomaly/isotope_ratio
name = "Isotope ratio spectrometer"
desc = "A specialised, complex analysis machine."
@@ -100,6 +100,7 @@
new /obj/item/clothing/glasses/meson(src)
new /obj/item/weapon/pickaxe(src)
new /obj/item/device/measuring_tape(src)
new /obj/item/weapon/pickaxe/hand(src)
return
//---- Isolation room air alarms
@@ -24,4 +24,5 @@
"/obj/item/weapon/anodevice",
"/obj/item/clothing/glasses",
"/obj/item/weapon/wrench",
"/obj/item/weapon/storage/box/excavation",
"/obj/item/weapon/anobattery")
@@ -85,6 +85,7 @@
dat += "Anomaly depth: [current.depth] cm<br>"
dat += "Clearance above anomaly depth: [current.clearance] cm<br>"
dat += "Dissonance spread: [current.dissonance_spread]<br>"
dat += "Anomaly material: [current.material]<br>"
dat += "<A href='?src=\ref[src];clear=[current.record_index]'>clear entry</a><br>"
else
dat += "Select an entry from the list<br>"
@@ -7,7 +7,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pick_brush"
item_state = "syringe_0"
digspeed = 50
digspeed = 20
desc = "Thick metallic wires for clearing away dust and loose scree (1 centimetre excavation depth)."
excavation_amount = 0.5
drill_sound = 'sound/weapons/thudswoosh.ogg'
@@ -19,7 +19,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pick1"
item_state = "syringe_0"
digspeed = 50
digspeed = 20
desc = "A miniature excavation tool for precise digging (2 centimetre excavation depth)."
excavation_amount = 1
drill_sound = 'sound/items/Screwdriver.ogg'
@@ -31,7 +31,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pick2"
item_state = "syringe_0"
digspeed = 50
digspeed = 20
desc = "A miniature excavation tool for precise digging (4 centimetre excavation depth)."
excavation_amount = 2
drill_sound = 'sound/items/Screwdriver.ogg'
@@ -43,7 +43,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pick3"
item_state = "syringe_0"
digspeed = 50
digspeed = 20
desc = "A miniature excavation tool for precise digging (6 centimetre excavation depth)."
excavation_amount = 3
drill_sound = 'sound/items/Screwdriver.ogg'
@@ -55,7 +55,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pick4"
item_state = "syringe_0"
digspeed = 50
digspeed = 20
desc = "A miniature excavation tool for precise digging (8 centimetre excavation depth)."
excavation_amount = 4
drill_sound = 'sound/items/Screwdriver.ogg'
@@ -67,7 +67,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pick5"
item_state = "syringe_0"
digspeed = 50
digspeed = 20
desc = "A miniature excavation tool for precise digging (10 centimetre excavation depth)."
excavation_amount = 5
drill_sound = 'sound/items/Screwdriver.ogg'
@@ -79,7 +79,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pick6"
item_state = "syringe_0"
digspeed = 50
digspeed = 20
desc = "A miniature excavation tool for precise digging (12 centimetre excavation depth)."
excavation_amount = 6
drill_sound = 'sound/items/Screwdriver.ogg'
@@ -91,7 +91,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pick_hand"
item_state = "syringe_0"
digspeed = 50
digspeed = 30
desc = "A smaller, more precise version of the pickaxe (30 centimetre excavation depth)."
excavation_amount = 15
drill_sound = 'sound/items/Crowbar.ogg'
@@ -108,16 +108,15 @@
desc = "A set of picks for excavation."
item_state = "syringe_kit"
foldable = /obj/item/stack/sheet/cardboard //BubbleWrap
storage_slots = 8
w_class = 3
storage_slots = 7
w_class = 2
can_hold = list("/obj/item/weapon/pickaxe/brush",\
"/obj/item/weapon/pickaxe/one_pick",\
"/obj/item/weapon/pickaxe/two_pick",\
"/obj/item/weapon/pickaxe/three_pick",\
"/obj/item/weapon/pickaxe/four_pick",\
"/obj/item/weapon/pickaxe/five_pick",\
"/obj/item/weapon/pickaxe/six_pick",\
"/obj/item/weapon/pickaxe/hand")
"/obj/item/weapon/pickaxe/six_pick")
max_combined_w_class = 17
max_w_class = 4
use_to_pickup = 1 // for picking up broken bulbs, not that most people will try
@@ -131,4 +130,3 @@
new /obj/item/weapon/pickaxe/four_pick(src)
new /obj/item/weapon/pickaxe/five_pick(src)
new /obj/item/weapon/pickaxe/six_pick(src)
new /obj/item/weapon/pickaxe/hand(src)
+12 -3
View File
@@ -190,7 +190,16 @@
max_duration = 160
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
return ..() && target_zone != "chest" && target_zone != "groin" && target_zone != "head"
if (target_zone == "eyes") //there are specific steps for eye surgery
return 0
if (!hasorgans(target))
return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
if (affected == null)
return 0
if (affected.status & ORGAN_DESTROYED)
return 0
return target_zone != "chest" && target_zone != "groin" && target_zone != "head"
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -203,11 +212,11 @@
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] cuts off [target]'s [affected.display_name] with \the [tool].", \
"\blue You cut off [target]'s [affected.display_name] with \the [tool].")
affected.droplimb(1,1)
affected.droplimb(1,0)
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, sawwing through the bone in [target]'s [affected.display_name] with \the [tool]!", \
"\red Your hand slips, sawwing through the bone in [target]'s [affected.display_name] with \the [tool]!")
affected.createwound(CUT, 30)
affected.fracture()
affected.fracture()
+5
View File
@@ -144,10 +144,15 @@
"You start attaching [tool] where [target]'s [affected.display_name] used to be.")
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/robot_parts/L = tool
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] has attached [tool] where [target]'s [affected.display_name] used to be.", \
"\blue You have attached [tool] where [target]'s [affected.display_name] used to be.")
affected.robotize()
if(L.sabotaged)
affected.sabotaged = 1
else
affected.sabotaged = 0
target.update_body()
target.updatehealth()
target.UpdateDamageIcon()
+3 -3
View File
@@ -175,8 +175,7 @@ var/MAX_EXPLOSION_RANGE = 14
//FLAGS BITMASK
#define STOPSPRESSUREDMAGE 1 //This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere
//To successfully stop you taking all pressure damage you must have both a suit and head item with this flag.
//To successfully stop you taking all pressure damage you must have both a suit and head item with this flag.
#define TABLEPASS 2 // can pass by a table or rack
#define MASKINTERNALS 8 // mask allows internals
@@ -205,7 +204,8 @@ var/MAX_EXPLOSION_RANGE = 14
#define NOREACT 16384 //Reagents dont' react inside this container.
#define BLOCKHAIR 32768 // temporarily removes the user's hair icon
#define BLOCKHEADHAIR 4 // temporarily removes the user's hair overlay. Leaves facial hair.
#define BLOCKHAIR 32768 // temporarily removes the user's hair, facial and otherwise.
//flags for pass_flags
#define PASSTABLE 1