Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into 7/26/2015_bay_merge_2

Conflicts:
	.travis.yml
	polaris.dme
This commit is contained in:
Neerti
2015-07-26 16:01:27 -04:00
70 changed files with 4690 additions and 4624 deletions
+1 -1
View File
@@ -23,7 +23,7 @@
/proc/ToRban_update()
spawn(0)
log_misc("Downloading updated ToR data...")
var/http[] = world.Export("http://exitlist.torproject.org/exit-addresses")
var/http[] = world.Export("https://check.torproject.org/exit-addresses")
var/list/rawlist = file2list(http["CONTENT"])
if(rawlist.len)
+1 -1
View File
@@ -1334,7 +1334,7 @@
src.owner << "You sent [input] to [L] via a secure channel."
log_admin("[src.owner] replied to [key_name(L)]'s Centcomm message with the message [input].")
message_admins("[src.owner] replied to [key_name(L)]'s Centcom message with: \"[input]\"")
if(!L.isAI())
if(!L.isMobAI())
L << "<span class='info'>You hear something crackle in your headset for a moment before a voice speaks.</span>"
L << "<span class='info'>Please stand by for a message from Central Command.</span>"
L << "<span class='info'>Message as follows.</span>"
@@ -260,7 +260,6 @@
return 0
/stat_rig_module/Click()
..()
if(CanUse())
var/list/href_list = list(
"interact_module" = module.holder.installed_modules.Find(module),
@@ -269,6 +268,9 @@
AddHref(href_list)
module.holder.Topic(usr, href_list)
/stat_rig_module/DblClick()
return Click()
/stat_rig_module/activate/New(var/obj/item/rig_module/module)
..()
name = module.activate_string
+1 -1
View File
@@ -107,7 +107,7 @@ proc/populate_ghost_traps()
ghost_trap_role = "Plant"
/datum/ghosttrap/plant/welcome_candidate(var/mob/target)
target << "<span class='alium><B>You awaken slowly, stirring into sluggish motion as the air caresses you.</B></span>"
target << "<span class='alium'><B>You awaken slowly, stirring into sluggish motion as the air caresses you.</B></span>"
// This is a hack, replace with some kind of species blurb proc.
if(istype(target,/mob/living/carbon/alien/diona))
target << "<B>You are \a [target], one of a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders.</B>"
+85 -24
View File
@@ -11,13 +11,16 @@
var/lum_g
var/lum_b
var/list/effect_r
var/list/effect_g
var/list/effect_b
var/tmp/old_lum_r
var/tmp/old_lum_g
var/tmp/old_lum_b
var/list/effect_str
var/list/effect_turf
var/applied
var/vis_update //Whetever we should smartly recalculate visibility. and then only update tiles that became (in) visible to us
var/needs_update
var/destroyed
var/force_update
@@ -38,9 +41,7 @@
parse_light_color()
effect_r = list()
effect_g = list()
effect_b = list()
effect_str = list()
effect_turf = list()
update()
@@ -67,9 +68,16 @@
/datum/light_source/proc/force_update()
force_update = 1
if(!needs_update)
lighting_update_lights += src
if(!needs_update) //Incase we're already updating either way.
needs_update = 1
lighting_update_lights += src
/datum/light_source/proc/vis_update()
if(!needs_update)
needs_update = 1
lighting_update_lights += src
vis_update = 1
/datum/light_source/proc/check()
if(!source_atom || !light_range || !light_power)
@@ -96,14 +104,19 @@
light_range = source_atom.light_range
. = 1
if(light_range && light_power && !applied)
. = 1
if(. || source_atom.light_color != light_color)//Save the old lumcounts if we need to update, if the colour changed DO IT BEFORE we parse the colour and LOSE the old lumcounts!
old_lum_r = lum_r
old_lum_g = lum_g
old_lum_b = lum_b
if(source_atom.light_color != light_color)
light_color = source_atom.light_color
parse_light_color()
. = 1
if(light_range && light_power && !applied)
. = 1
/datum/light_source/proc/parse_light_color()
if(light_color)
lum_r = GetRedPart(light_color) / 255
@@ -143,19 +156,18 @@
if(!strength) //Don't add turfs that aren't affected to the affected turfs.
continue
effect_r += round(lum_r * strength, LIGHTING_ROUND_VALUE)
effect_g += round(lum_g * strength, LIGHTING_ROUND_VALUE)
effect_b += round(lum_b * strength, LIGHTING_ROUND_VALUE)
strength = round(strength, LIGHTING_ROUND_VALUE) //Screw sinking points.
effect_str += strength
T.lighting_overlay.update_lumcount(
round(lum_r * strength, LIGHTING_ROUND_VALUE),
round(lum_g * strength, LIGHTING_ROUND_VALUE),
round(lum_b * strength, LIGHTING_ROUND_VALUE)
lum_r * strength,
lum_g * strength,
lum_b * strength
)
else
effect_r += 0
effect_g += 0
effect_b += 0
effect_str += 0
if(!T.affecting_lights)
T.affecting_lights = list()
@@ -171,11 +183,60 @@
T.affecting_lights -= src
if(T.lighting_overlay)
T.lighting_overlay.update_lumcount(-effect_r[i], -effect_g[i], -effect_b[i])
var/str = effect_str[i]
T.lighting_overlay.update_lumcount(-str * old_lum_r, -str * old_lum_g, -str * old_lum_b)
i++
effect_r.Cut()
effect_g.Cut()
effect_b.Cut()
effect_str.Cut()
effect_turf.Cut()
//Smartly updates the lighting, only removes lum from and adds lum to turfs that actually got changed.
//This is for lights that need to reconsider due to nearby opacity changes.
//Stupid dumb copy pasta because BYOND and speed.
/datum/light_source/proc/smart_vis_update()
var/list/view[0]
for(var/turf/T in dview(light_range, source_turf, INVISIBILITY_LIGHTING))
view += T //Filter out turfs.
//This is the part where we calculate new turfs (if any)
var/list/new_turfs = view - effect_turf //This will result with all the tiles that are added.
for(var/turf/T in new_turfs)
//Big huge copy paste from apply_lum() incoming because screw unreadable defines and screw proc call overhead.
if(T.lighting_overlay)
. = light_power * falloff(T.lighting_overlay)
if(!.) //Don't add turfs that aren't affected to the affected turfs.
continue
. = round(., LIGHTING_ROUND_VALUE)
effect_str += .
T.lighting_overlay.update_lumcount(
lum_r * .,
lum_g * .,
lum_b * .
)
else
effect_str += 0
if(!T.affecting_lights)
T.affecting_lights = list()
T.affecting_lights += src
effect_turf += T
var/list/old_turfs = effect_turf - view
for(var/turf/T in old_turfs)
//Insert not-so-huge copy paste from remove_lum().
var/idx = effect_turf.Find(T) //Get the index, luckily Find() is cheap in small lists like this. (with small I mean under a couple thousand len)
if(T.affecting_lights)
T.affecting_lights -= src
if(T.lighting_overlay)
var/str = effect_str[idx]
T.lighting_overlay.update_lumcount(-str * lum_r, -str * lum_g, -str * lum_b)
effect_turf.Cut(idx, idx + 1)
effect_str.Cut(idx, idx + 1)
@@ -98,8 +98,3 @@
var/turf/T = loc
if(istype(T))
T.lighting_overlay = null
for(var/datum/light_source/D in T.affecting_lights) //Remove references to us on the light sources affecting us.
D.effect_r -= src
D.effect_g -= src
D.effect_b -= src
+13 -9
View File
@@ -10,12 +10,17 @@
lighting_update_lights = list()
for(var/datum/light_source/L in lighting_update_lights_old)
if(L.needs_update)
if(L.destroyed || L.check() || L.force_update)
L.remove_lum()
if(!L.destroyed) L.apply_lum()
L.force_update = 0
L.needs_update = 0
if(L.destroyed || L.check() || L.force_update)
L.remove_lum()
if(!L.destroyed)
L.apply_lum()
else if(L.vis_update) //We smartly update only tiles that became (in) visible to use.
L.smart_vis_update()
L.vis_update = 0
L.force_update = 0
L.needs_update = 0
scheck()
@@ -24,8 +29,7 @@
lighting_update_overlays = list()
for(var/atom/movable/lighting_overlay/O in lighting_update_overlays_old)
if(O.needs_update)
O.update_overlay()
O.needs_update = 0
O.update_overlay()
O.needs_update = 0
scheck()
+1 -1
View File
@@ -4,7 +4,7 @@
/turf/proc/reconsider_lights()
for(var/datum/light_source/L in affecting_lights)
L.force_update()
L.vis_update()
/turf/proc/lighting_clear_overlays()
if(lighting_overlay)
-16
View File
@@ -316,22 +316,6 @@
//Throwing stuff
/mob/living/carbon/proc/toggle_throw_mode()
if (src.in_throw_mode)
throw_mode_off()
else
throw_mode_on()
/mob/living/carbon/proc/throw_mode_off()
src.in_throw_mode = 0
if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
src.throw_icon.icon_state = "act_throw_off"
/mob/living/carbon/proc/throw_mode_on()
src.in_throw_mode = 1
if(src.throw_icon)
src.throw_icon.icon_state = "act_throw_on"
/mob/proc/throw_item(atom/target)
return
+39 -22
View File
@@ -25,32 +25,45 @@
skipface |= wear_mask.flags_inv & HIDEFACE
// crappy hacks because you can't do \his[src] etc. I'm sorry this proc is so unreadable, blame the text macros :<
var/t_He = "It" //capitalised for use at the start of each line.
var/t_his = "its"
var/t_him = "it"
var/t_has = "has"
var/t_is = "is"
var/t_He = "They" //capitalised for use at the start of each line.
var/t_he = "they"
var/t_his = "their"
var/t_him = "them"
var/t_has = "have"
var/t_is = "are"
var/t_does = "do"
var/msg = "<span class='info'>*---------*\nThis is "
if( skipjumpsuit && skipface ) //big suits/masks/helmets make it hard to tell their gender
t_He = "They"
t_his = "their"
t_him = "them"
t_has = "have"
t_is = "are"
else
//big suits/masks/helmets make it hard to tell their gender
if(!skipjumpsuit || !skipface)
if(icon)
msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
switch(gender)
if(MALE)
t_He = "He"
t_he = "he"
t_his = "his"
t_him = "him"
t_has = "has"
t_is = "is"
t_does = "does"
if(FEMALE)
t_He = "She"
t_he = "she"
t_his = "her"
t_him = "her"
t_has = "has"
t_is = "is"
t_does = "does"
if(NEUTER)
t_He = "It"
t_he = "it"
t_his = "its"
t_him = "it"
t_has = "has"
t_is = "is"
t_does = "does"
msg += "<EM>[src.name]</EM>"
if(species.name != "Human")
@@ -214,15 +227,15 @@
if (src.stat)
msg += "<span class='warning'>[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.</span>\n"
if((stat == 2 || src.losebreath) && distance <= 3)
msg += "<span class='warning'>[t_He] does not appear to be breathing.</span>\n"
msg += "<span class='warning'>[t_He] [t_does] not appear to be breathing.</span>\n"
if(istype(usr, /mob/living/carbon/human) && !usr.stat && Adjacent(usr))
usr.visible_message("<b>[usr]</b> checks [src]'s pulse.", "You check [src]'s pulse.")
spawn(15)
if(distance <= 1 && usr.stat != 1)
if(pulse == PULSE_NONE)
usr << "<span class='deadsay'>[t_He] has no pulse[src.client ? "" : " and [t_his] soul has departed"]...</span>"
usr << "<span class='deadsay'>[t_He] [t_has] no pulse[src.client ? "" : " and [t_his] soul has departed"]...</span>"
else
usr << "<span class='deadsay'>[t_He] has a pulse!</span>"
usr << "<span class='deadsay'>[t_He] [t_has] a pulse!</span>"
if(fire_stacks)
msg += "[t_He] [t_is] covered in some liquid.\n"
if(on_fire)
@@ -244,7 +257,7 @@
if(species.show_ssd && (!species.has_organ["brain"] || has_brain()) && stat != DEAD)
if(!key)
msg += "<span class='deadsay'>[t_He] [t_is] [species.show_ssd]. It doesn't look like they are waking up anytime soon.</span>\n"
msg += "<span class='deadsay'>[t_He] [t_is] fast asleep. It doesn't look like [t_he] [t_is] waking up anytime soon.</span>\n"
else if(!client)
msg += "<span class='deadsay'>[t_He] [t_is] [species.show_ssd].</span>\n"
@@ -269,6 +282,10 @@
for(var/obj/item/organ/external/temp in organs)
if(temp)
if(temp.status & ORGAN_DESTROYED)
is_destroyed["[temp.name]"] = 1
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[t_He] [t_is] missing [t_his] [temp.name].</b></span>\n"
continue
if(temp.status & ORGAN_ROBOT)
if(!(temp.brute_dam + temp.burn_dam))
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has a robot [temp.name]!</span>\n"
@@ -301,7 +318,7 @@
if(wound_flavor_text["head"] && (is_destroyed["head"] || (!skipmask && !(wear_mask && istype(wear_mask, /obj/item/clothing/mask/gas)))))
msg += wound_flavor_text["head"]
else if(is_bleeding["head"])
msg += "<span class='warning'>[src] has blood running down [t_his] face!</span>\n"
msg += "<span class='warning'>[src] [t_has] blood running down [t_his] face!</span>\n"
if(wound_flavor_text["upper body"] && !w_uniform && !skipjumpsuit) //No need. A missing chest gibs you.
msg += wound_flavor_text["upper body"]
@@ -352,11 +369,11 @@
display_shoes = 1
if(display_chest)
msg += "<span class='danger'>[src] has blood soaking through from under [t_his] clothing!</span>\n"
msg += "<span class='danger'>[src] [t_has] blood soaking through from under [t_his] clothing!</span>\n"
if(display_shoes)
msg += "<span class='danger'>[src] has blood running from [t_his] shoes!</span>\n"
msg += "<span class='danger'>[src] [t_has] blood running from [t_his] shoes!</span>\n"
if(display_gloves)
msg += "<span class='danger'>[src] has blood running from under [t_his] gloves!</span>\n"
msg += "<span class='danger'>[src] [t_has] blood running from under [t_his] gloves!</span>\n"
*/
for(var/limb in wound_flavor_text)
@@ -365,7 +382,7 @@
for(var/limb in is_bleeding)
msg += is_bleeding[limb]
for(var/implant in get_visible_implants(0))
msg += "<span class='danger'>[src] has \a [implant] sticking out of [t_his] flesh!</span>\n"
msg += "<span class='danger'>[src] [t_has] \a [implant] sticking out of [t_his] flesh!</span>\n"
if(digitalcamo)
msg += "[t_He] [t_is] repulsively uncanny!\n"
@@ -421,7 +438,7 @@
if (pose)
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "\n[t_He] is [pose]"
msg += "\n[t_He] [t_is] [pose]"
user << msg
+3 -3
View File
@@ -445,7 +445,7 @@
else if(exhaled_pp > safe_exhaled_max * 0.7)
if (!co2_alert || prob(1))
var/word = pick("dizzy","short of breath","faint","momentarily confused")
src << "<span class='warning>You feel [word].</span>"
src << "<span class='warning'>You feel [word].</span>"
//scale linearly from 0 to 1 between safe_exhaled_max and safe_exhaled_max*0.7
var/ratio = 1.0 - (safe_exhaled_max - exhaled_pp)/(safe_exhaled_max*0.3)
@@ -459,7 +459,7 @@
else if(exhaled_pp > safe_exhaled_max * 0.6)
if (prob(0.3))
var/word = pick("a little dizzy","short of breath")
src << "<span class='warning>You feel [word].</span>"
src << "<span class='warning'>You feel [word].</span>"
else
co2_alert = 0
@@ -486,7 +486,7 @@
// Enough to make us sleep as well
if(SA_pp > SA_sleep_min)
sleeping = min(sleeping+2, 10)
Sleeping(5)
// There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
else if(SA_pp > 0.15)
+25 -22
View File
@@ -520,27 +520,30 @@ default behaviour is:
var/atom/movable/t = M.pulling
M.stop_pulling()
//this is the gay blood on floor shit -- Added back -- Skie
if (M.lying && (prob(M.getBruteLoss() / 6)))
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
//pull damage with injured people
if(prob(25))
M.adjustBruteLoss(1)
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!</span>")
if(M.pull_damage())
if(prob(25))
M.adjustBruteLoss(2)
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
if(ishuman(M))
var/mob/living/carbon/H = M
var/blood_volume = round(H:vessel.get_reagent_amount("blood"))
if(blood_volume > 0)
H:vessel.remove_reagent("blood",1)
if(!istype(M.loc, /turf/space))
var/area/A = get_area(M)
if(A.has_gravity)
//this is the gay blood on floor shit -- Added back -- Skie
if (M.lying && (prob(M.getBruteLoss() / 6)))
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
//pull damage with injured people
if(prob(25))
M.adjustBruteLoss(1)
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!</span>")
if(M.pull_damage())
if(prob(25))
M.adjustBruteLoss(2)
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/blood_volume = round(H.vessel.get_reagent_amount("blood"))
if(blood_volume > 0)
H.vessel.remove_reagent("blood", 1)
step(pulling, get_dir(pulling.loc, T))
@@ -787,7 +790,7 @@ default behaviour is:
inertia_dir = 1
else if(y >= world.maxy -TRANSITIONEDGE)
inertia_dir = 2
src << "<span class='warning>Something you are carrying is preventing you from leaving.</span>"
src << "<span class='warning'>Something you are carrying is preventing you from leaving.</span>"
return
..()
@@ -0,0 +1,30 @@
//list(ckey = real_name,)
//Since the ckey is used as the icon_state, the current system will only permit a single custom robot sprite per ckey.
//While it might be possible for a ckey to use that custom sprite for several real_names, it seems rather pointless to support it.
var/list/robot_custom_icons
/hook/startup/proc/load_robot_custom_sprites()
var/config_file = file2text("config/custom_sprites.txt")
var/list/lines = text2list(config_file, "\n")
robot_custom_icons = list()
for(var/line in lines)
//split entry into ckey and real_name
var/split_idx = findtext(line, "-") //this works if ckey cannot contain dashes, and findtext starts from the beginning
if(!split_idx || split_idx == length(line))
continue //bad entry
var/ckey = copytext(line, 1, split_idx)
var/real_name = copytext(line, split_idx+1)
robot_custom_icons[ckey] = real_name
return 1
/mob/living/silicon/robot/proc/set_custom_sprite()
var/rname = robot_custom_icons[ckey]
if(rname && rname == real_name)
custom_sprite = 1
icon = 'icons/mob/custom_synthetic.dmi'
if(icon_state == "robot")
icon_state = "[ckey]-Standard"
+1 -17
View File
@@ -302,23 +302,7 @@
camera.c_tag = changed_name
if(!custom_sprite) //Check for custom sprite
var/file = file2text("config/custom_sprites.txt")
var/lines = text2list(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = text2list(line, "-")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
if(Entry.len < 2)
continue;
if(Entry[1] == src.ckey && Entry[2] == src.real_name) //They're in the list? Custom sprite time, var and icon change required
custom_sprite = 1
icon = CUSTOM_ITEM_SYNTH
if(icon_state == "robot")
icon_state = "[src.ckey]-Standard"
set_custom_sprite()
//Flavour text.
if(client)
@@ -504,7 +504,7 @@ var/global/list/robot_modules = list(
src.modules += L
src.modules += new /obj/item/weapon/tray/robotray(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
var/datum/reagents/R = new/datum/reagents(50)
@@ -61,7 +61,8 @@
/mob/living/simple_animal/hostile/retaliate/goat/Retaliate()
..()
src.visible_message("\red [src] gets an evil-looking gleam in their eye.")
if(stat == CONSCIOUS)
visible_message("<span class='warning'>[src] gets an evil-looking gleam in their eye.</span>")
/mob/living/simple_animal/hostile/retaliate/goat/Move()
..()
@@ -305,7 +305,7 @@
purge = 3
adjustBruteLoss(damage)
else
usr << "<span class='danger>This weapon is ineffective, it does no damage.</span>"
usr << "<span class='danger'>This weapon is ineffective, it does no damage.</span>"
visible_message("<span class='danger'>\The [src] has been attacked with \the [O] by [user].</span>")
user.do_attack_animation(src)
+18
View File
@@ -1031,3 +1031,21 @@ mob/proc/yank_out_object()
/mob/proc/setEarDamage()
return
//Throwing stuff
/mob/proc/toggle_throw_mode()
if (src.in_throw_mode)
throw_mode_off()
else
throw_mode_on()
/mob/proc/throw_mode_off()
src.in_throw_mode = 0
if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
src.throw_icon.icon_state = "act_throw_off"
/mob/proc/throw_mode_on()
src.in_throw_mode = 1
if(src.throw_icon)
src.throw_icon.icon_state = "act_throw_on"
-6
View File
@@ -88,12 +88,6 @@
return 1
return 0
/mob/proc/isAI()
return 0
/mob/living/silicon/ai/isAI()
return 1
/mob/proc/isMobAI()
return 0
+1 -1
View File
@@ -69,4 +69,4 @@
return extra_href
/datum/topic_state/air_alarm/proc/has_access(var/mob/user)
return user && (user.isAI() || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO))
return user && (user.isMobAI() || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO))
+2 -2
View File
@@ -15,7 +15,7 @@
ui.close()
return 0
if(href_list["track"])
if(usr.isAI())
if(usr.isMobAI())
var/mob/living/silicon/ai/AI = usr
var/mob/living/carbon/human/H = locate(href_list["track"]) in mob_list
if(hassensorlevel(H, SUIT_SENSOR_TRACKING))
@@ -66,7 +66,7 @@
crewmembers = sortByKey(crewmembers, "name")
data["isAI"] = user.isAI()
data["isAI"] = user.isMobAI()
data["crewmembers"] = crewmembers
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+3 -3
View File
@@ -136,7 +136,7 @@
if(href_list["notify_laws"])
owner << "<span class='danger'>Law Notice</span>"
owner.laws.show_laws(owner)
if(owner.isAI())
if(owner.isMobAI())
var/mob/living/silicon/ai/AI = owner
for(var/mob/living/silicon/robot/R in AI.connected_robots)
R << "<span class='danger'>Law Notice</span>"
@@ -163,7 +163,7 @@
package_laws(data, "inherent_laws", owner.laws.inherent_laws)
package_laws(data, "supplied_laws", owner.laws.supplied_laws)
data["isAI"] = owner.isAI()
data["isAI"] = owner.isMobAI()
data["isMalf"] = is_malf(user)
data["isSlaved"] = owner.is_slaved()
data["isAdmin"] = is_admin(user)
@@ -186,7 +186,7 @@
/datum/nano_module/law_manager/proc/package_laws(var/list/data, var/field, var/list/datum/ai_law/laws)
var/packaged_laws[0]
for(var/datum/ai_law/AL in laws)
packaged_laws[++packaged_laws.len] = list("law" = sanitize(AL.law), "index" = AL.get_index(), "state" = owner.laws.get_state_law(AL), "ref" = "\ref[AL]")
packaged_laws[++packaged_laws.len] = list("law" = AL.law, "index" = AL.get_index(), "state" = owner.laws.get_state_law(AL), "ref" = "\ref[AL]")
data[field] = packaged_laws
data["has_[field]"] = packaged_laws.len
+3 -6
View File
@@ -189,9 +189,7 @@
..()
spawn(2)
var/area/A = get_area(src)
if(A && !A.requires_power)
on = 1
on = has_power()
switch(fitting)
if("tube")
@@ -393,7 +391,7 @@
// true if area has power and lightswitch is on
/obj/machinery/light/proc/has_power()
var/area/A = src.loc.loc
return A.lightswitch && A.power_light
return A.lightswitch && (!A.requires_power || A.power_light)
/obj/machinery/light/proc/flicker(var/amount = rand(10, 20))
if(flickering) return
@@ -565,8 +563,7 @@
// called when area power state changes
/obj/machinery/light/power_change()
spawn(10)
var/area/A = src.loc.loc
seton(A.lightswitch && A.power_light)
seton(has_power())
// called when on fire
+3 -11
View File
@@ -119,7 +119,7 @@
if(href_list["amount"])
var/id = href_list["add"]
var/amount = text2num(href_list["amount"])
var/amount = isgoodnumber(text2num(href_list["amount"]))
R.trans_id_to(src, id, amount)
else if (href_list["addcustom"])
@@ -133,7 +133,7 @@
if(href_list["amount"])
var/id = href_list["remove"]
var/amount = text2num(href_list["amount"])
var/amount = isgoodnumber(text2num(href_list["amount"]))
if(mode)
reagents.trans_id_to(beaker, id, amount)
else
@@ -297,18 +297,10 @@
/obj/machinery/chem_master/proc/isgoodnumber(var/num)
if(isnum(num))
if(num > 200)
num = 200
else if(num < 0)
num = 1
else
num = round(num)
return num
return Clamp(round(num), 0, 200)
else
return 0
/obj/machinery/chem_master/condimaster
name = "CondiMaster 3000"
condi = 1
@@ -1,5 +1,5 @@
/obj/item/weapon/reagent_containers/borghypo
name = "Cyborg Hypospray"
name = "cyborg hypospray"
desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment."
icon = 'icons/obj/syringe.dmi'
item_state = "hypo"
@@ -7,13 +7,15 @@
amount_per_transfer_from_this = 5
volume = 30
possible_transfer_amounts = null
var/mode = 1
var/charge_cost = 50
var/charge_tick = 0
var/recharge_time = 5 //Time it takes for shots to recharge (in seconds)
var/list/datum/reagents/reagent_list = list()
var/list/reagent_ids = list("tricordrazine", "inaprovaline", "spaceacillin")
var/list/reagent_volumes = list()
var/list/reagent_names = list()
/obj/item/weapon/reagent_containers/borghypo/surgeon
reagent_ids = list("bicaridine", "inaprovaline", "dexalin")
@@ -23,46 +25,38 @@
/obj/item/weapon/reagent_containers/borghypo/New()
..()
for(var/R in reagent_ids)
add_reagent(R)
for(var/T in reagent_ids)
reagent_volumes[T] = volume
var/datum/reagent/R = chemical_reagents_list[T]
reagent_names += R.name
processing_objects.Add(src)
/obj/item/weapon/reagent_containers/borghypo/Destroy()
processing_objects.Remove(src)
..()
/obj/item/weapon/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg
charge_tick++
if(charge_tick < recharge_time) return 0
/obj/item/weapon/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg+
if(++charge_tick < recharge_time)
return 0
charge_tick = 0
if(isrobot(loc))
var/mob/living/silicon/robot/R = loc
if(R && R.cell)
var/datum/reagents/RG = reagent_list[mode]
if(RG.total_volume < RG.maximum_volume) //Don't recharge reagents and drain power if the storage is full.
R.cell.use(charge_cost) //Take power from borg...
RG.add_reagent(reagent_ids[mode], 5) //And fill hypo with reagent.
for(var/T in reagent_ids)
if(reagent_volumes[T] < volume)
R.cell.use(charge_cost)
reagent_volumes[T] = min(reagent_volumes[T] + 5, volume)
return 1
// Use this to add more chemicals for the borghypo to produce.
/obj/item/weapon/reagent_containers/borghypo/proc/add_reagent(var/reagent)
reagent_ids |= reagent
var/datum/reagents/RG = new(30)
RG.my_atom = src
reagent_list += RG
var/datum/reagents/R = reagent_list[reagent_list.len]
R.add_reagent(reagent, 30)
/obj/item/weapon/reagent_containers/borghypo/attack(mob/living/M as mob, mob/user as mob)
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
user << "<span class='warning'>The injector is empty.</span>"
/obj/item/weapon/reagent_containers/borghypo/attack(var/mob/living/M, var/mob/user)
if(!istype(M))
return
if (!istype(M))
if(!reagent_volumes[reagent_ids[mode]])
user << "<span class='warning'>The injector is empty.</span>"
return
var/mob/living/carbon/human/H = M
@@ -75,37 +69,80 @@
user << "<span class='danger'>You cannot inject a robotic limb.</span>"
return
if (R.total_volume && M.can_inject(user, 1))
if (M.can_inject(user, 1))
user << "<span class='notice'>You inject [M] with the injector.</span>"
M << "<span class='notice'>You feel a tiny prick!</span>"
if(M.reagents)
var/trans = R.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BLOOD)
user << "<span class='notice'>[trans] units injected. [R.total_volume] units remaining.</span>"
var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]])
M.reagents.add_reagent(reagent_ids[mode], t)
reagent_volumes[reagent_ids[mode]] -= t
admin_inject_log(user, M, src, reagent_ids[mode], t)
user << "<span class='notice'>[t] units injected. [reagent_volumes[reagent_ids[mode]]] units remaining.</span>"
return
/obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user as mob)
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) //Change the mode
mode++
if(mode > reagent_list.len)
mode = 1
/obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user as mob) //Change the mode
var/t = ""
for(var/i = 1 to reagent_ids.len)
if(t)
t += ", "
if(mode == i)
t += "<b>[reagent_names[i]]</b>"
else
t += "<a href='?src=\ref[src];reagent=[reagent_ids[i]]'>[reagent_names[i]]</a>"
t = "Available reagents: [t]."
user << t
charge_tick = 0 //Prevents wasted chems/cell charge if you're cycling through modes.
var/datum/reagent/R = chemical_reagents_list[reagent_ids[mode]]
user << "<span class='notice'>Synthesizer is now producing '[R.name]'.</span>"
return
/obj/item/weapon/reagent_containers/borghypo/Topic(var/href, var/list/href_list)
if(href_list["reagent"])
var/t = reagent_ids.Find(href_list["reagent"])
if(t)
playsound(loc, 'sound/effects/pop.ogg', 50, 0)
mode = t
var/datum/reagent/R = chemical_reagents_list[reagent_ids[mode]]
usr << "<span class='notice'>Synthesizer is now producing '[R.name]'.</span>"
/obj/item/weapon/reagent_containers/borghypo/examine(mob/user)
if(!..(user, 2))
return
var/empty = 1
var/datum/reagent/R = chemical_reagents_list[reagent_ids[mode]]
for(var/datum/reagents/RS in reagent_list)
var/datum/reagent/R = locate() in RS.reagent_list
if(R)
user << "<span class='notice'>It currently has [R.volume] units of [R.name] stored.</span>"
empty = 0
user << "<span class='notice'>It is currently producing [R.name] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left.</span>"
if(empty)
user << "<span class='notice'>It is currently empty. Allow some time for the internal syntheszier to produce more.</span>"
/obj/item/weapon/reagent_containers/borghypo/service
name = "cyborg drink synthesizer"
desc = "A portable drink dispencer."
icon = 'icons/obj/drinks.dmi'
icon_state = "shaker"
charge_cost = 20
recharge_time = 3
volume = 60
possible_transfer_amounts = list(5, 10, 20, 30)
reagent_ids = list("beer", "kahlua", "whiskey", "wine", "vodka", "gin", "rum", "tequilla", "vermouth", "cognac", "ale", "mead", "water", "sugar", "ice", "tea", "icetea", "cola", "spacemountainwind", "dr_gibb", "space_up", "tonic", "sodawater", "lemon_lime", "orangejuice", "limejuice", "watermelonjuice")
/obj/item/weapon/reagent_containers/borghypo/service/attack(var/mob/M, var/mob/user)
return
/obj/item/weapon/reagent_containers/borghypo/service/afterattack(var/obj/target, var/mob/user, var/proximity)
if(!proximity)
return
if(!target.is_open_container() || !target.reagents)
return
if(!reagent_volumes[reagent_ids[mode]])
user << "<span class='notice'>[src] is out of this reagent, give it some time to refill.</span>"
return
if(!target.reagents.get_free_space())
user << "<span class='notice'>[target] is full.</span>"
return
var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]])
target.reagents.add_reagent(reagent_ids[mode], t)
reagent_volumes[reagent_ids[mode]] -= t
user << "<span class='notice'>You transfer [t] units of the solution to [target].</span>"
return
@@ -18,7 +18,6 @@
attack(mob/M as mob, mob/user as mob, def_zone)
if(standard_feed_mob(user, M))
robot_refill(user)
return
return 0
@@ -29,22 +28,10 @@
if(standard_dispenser_refill(user, target))
return
if(standard_pour_into(user, target))
robot_refill(user)
return
return ..()
proc/robot_refill(var/mob/living/silicon/robot/user)
if(!istype(user))
return 0
user.cell.use(30)
var/refill = reagents.get_master_reagent_id()
user << "Now synthesizing [amount_per_transfer_from_this] units of [refill]..."
spawn(300)
reagents.add_reagent(refill, amount_per_transfer_from_this)
user << "Cyborg [src] refilled."
self_feed_message(var/mob/user)
user << "<span class='notice'>You swallow a gulp from \the [src].</span>"
@@ -42,7 +42,6 @@
/obj/machinery/smartfridge/,
/obj/machinery/biogenerator,
/obj/machinery/constructable_frame,
/obj/machinery/bunsen_burner,
/obj/machinery/radiocarbon_spectrometer
)
+10 -10
View File
@@ -91,14 +91,14 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
/obj/machinery/r_n_d/circuit_imprinter/dismantle()
for(var/obj/I in component_parts)
if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker))
reagents.trans_to_obj(I, reagents.total_volume)
if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker))
reagents.trans_to_obj(I, reagents.total_volume)
for(var/f in materials)
if(materials[f] >= SHEET_MATERIAL_AMOUNT)
var/path = getMaterialType(f)
if(path)
var/obj/item/stack/S = new f(loc)
S.amount = round(materials[f] / SHEET_MATERIAL_AMOUNT)
S.amount = round(materials[f] / SHEET_MATERIAL_AMOUNT)
..()
/obj/machinery/r_n_d/circuit_imprinter/attackby(var/obj/item/O as obj, var/mob/user as mob)
@@ -120,17 +120,17 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
if(!linked_console)
user << "\The [src] must be linked to an R&D console first."
return 1
if(O.is_open_container())
return 0
if(O.is_open_container())
return 0
if(!istype(O, /obj/item/stack/material/glass) && !istype(O, /obj/item/stack/material/gold) && !istype(O, /obj/item/stack/material/diamond) && !istype(O, /obj/item/stack/material/uranium))
user << "<span class='notice'>You cannot insert this item into \the [src].</span>"
return 1
return 1
if(stat)
return 1
if(TotalMaterials() + SHEET_MATERIAL_AMOUNT > max_material_storage)
user << "<span class='notice'>\The [src]'s material bin is full. Please remove material before adding more.</span>"
return 1
return 1
var/obj/item/stack/stack = O
@@ -149,7 +149,7 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
var/stacktype = stack.type
var/t = getMaterialName(stacktype)
if(t)
if(do_after(usr, 16))
if(do_after(usr, 16))
if(stack.use(amount))
user << "<span class='notice'>You add [amount] sheets to \the [src].</span>"
materials[t] += amount * SHEET_MATERIAL_AMOUNT
@@ -158,7 +158,7 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
/obj/machinery/r_n_d/circuit_imprinter/proc/addToQueue(var/datum/design/D)
queue += D
return
return
/obj/machinery/r_n_d/circuit_imprinter/proc/removeFromQueue(var/index)
queue.Cut(index, index + 1)
@@ -204,4 +204,4 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
if(mat_efficiency != 1) // No matter out of nowhere
if(new_item.matter && new_item.matter.len > 0)
for(var/i in new_item.matter)
new_item.matter[i] = new_item.matter[i] * mat_efficiency
new_item.matter[i] = new_item.matter[i] * mat_efficiency
+8 -2
View File
@@ -321,6 +321,12 @@ other types of metals and chemistry for reagents).
materials = list("metal" = 3000, "glass" = 1000, "diamond" = 2000)
build_path = /obj/item/weapon/pickaxe/diamonddrill
sort_string = "KAAAE"
///////////////////////////////////
/////////Shield Generators/////////
///////////////////////////////////
datum/design/circuit/shield
req_tech = list("bluespace" = 4, "phorontech" = 3)
materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 10000, "$diamond" = 5000, "$gold" = 10000)
/datum/design/item/medical
materials = list("metal" = 30, "glass" = 20)
@@ -375,7 +381,7 @@ other types of metals and chemistry for reagents).
req_tech = list(TECH_MATERIAL = 2)
materials = list("metal" = 3000)
build_path = /obj/item/weapon/reagent_containers/glass/beaker/noreact
sort_string = "MADAA"
sort_string = "MADAA"
/datum/design/item/beaker/bluespace
name = TECH_BLUESPACE
@@ -1646,4 +1652,4 @@ datum/design/rust_injector
build_type = IMPRINTER
materials = list("glass" = 2000, "sacid" = 20, "phoron" = 3000, "uranium" = 2000)
build_path = "/obj/item/weapon/circuitboard/rust_core"
*/
*/
@@ -1,56 +0,0 @@
/obj/machinery/bunsen_burner
name = "bunsen burner"
desc = "A flat, self-heating device designed for bringing chemical mixtures to boil."
icon = 'icons/obj/device.dmi'
icon_state = "bunsen0"
var/heating = 0 //whether the bunsen is turned on
var/heated = 0 //whether the bunsen has been on long enough to let stuff react
var/obj/item/weapon/reagent_containers/held_container
var/heat_time = 50
/obj/machinery/bunsen_burner/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/reagent_containers))
if(held_container)
user << "\red You must remove the [held_container] first."
else
held_container = W
user.drop_from_inventory(held_container, src)
user << "\blue You put the [held_container] onto the [src]."
var/image/I = image("icon"=W, "layer"=FLOAT_LAYER)
underlays += I
if(heating)
spawn(heat_time)
try_heating()
else
user << "\red You can't put the [W] onto the [src]."
/obj/machinery/bunsen_burner/attack_hand(mob/user as mob)
if(held_container)
underlays = null
user << "\blue You remove the [held_container] from the [src]."
held_container.loc = src.loc
held_container.attack_hand(user)
held_container = null
else
user << "\red There is nothing on the [src]."
/obj/machinery/bunsen_burner/proc/try_heating()
src.visible_message("\blue \icon[src] [src] hisses.")
if(held_container && heating)
heated = 1
held_container.reagents.handle_reactions()
heated = 0
spawn(heat_time)
try_heating()
/obj/machinery/bunsen_burner/verb/toggle()
set src in view(1)
set name = "Toggle bunsen burner"
set category = "IC"
heating = !heating
icon_state = "bunsen[heating]"
if(heating)
spawn(heat_time)
try_heating()
@@ -45,7 +45,7 @@ How they spawn stuff is decided by behaviour vars, which are explained below
var/atom/summoned_object
if(ispath(summoned_object_type,/turf))
if(istype(get_turf(user),/turf/simulated/shuttle) || istype(spawn_place, /turf/simulated/shuttle))
user << "<span class='warning>You can't build things on shuttles!</span>"
user << "<span class='warning'>You can't build things on shuttles!</span>"
continue
spawn_place.ChangeTurf(summoned_object_type)
summoned_object = spawn_place
+4
View File
@@ -78,6 +78,10 @@
var/obj/item/weapon/grab/G = W
if (istype(G.affecting, /mob/living))
var/mob/living/M = G.affecting
var/obj/occupied = turf_is_crowded()
if(occupied)
user << "<span class='danger'>There's \a [occupied] in the way.</span>"
return
if (G.state < 2)
if(user.a_intent == I_HURT)
if (prob(15)) M.Weaken(5)