Conflicts:
	code/game/objects/items/devices/transfer_valve.dm
This commit is contained in:
Whitellama
2014-08-17 17:50:07 -07:00
672 changed files with 505 additions and 543 deletions

View File

@@ -254,7 +254,6 @@
//send resources to the client. It's here in its own proc so we can move it around easiliy if need be
/client/proc/send_resources()
// preload_vox() //Causes long delays with initial start window and subsequent windows when first logged in.
getFiles(
'html/search.js',

18
code/modules/client/preferences.dm Normal file → Executable file
View File

@@ -277,7 +277,7 @@ datum/preferences
if(gear_datums[gear_name])
var/datum/gear/G = gear_datums[gear_name]
total_cost += G.cost
dat += "[gear_name] <a href='byond://?src=\ref[user];preference=loadout;task=remove;gear=[gear_name]'>\[remove\]</a><br>"
dat += "[G.display_name]<br>"
dat += "<b>Used:</b> [total_cost] points."
else
@@ -285,6 +285,8 @@ datum/preferences
if(total_cost < MAX_GEAR_COST)
dat += " <a href='byond://?src=\ref[user];preference=loadout;task=input'>\[add\]</a>"
if(gear && gear.len)
dat += " <a href='byond://?src=\ref[user];preference=loadout;task=remove'>\[remove\]</a>"
dat += "<br><br><b>Occupation Choices</b><br>"
dat += "\t<a href='?_src_=prefs;preference=job;task=menu'><b>Set Preferences</b></a><br>"
@@ -892,10 +894,18 @@ datum/preferences
user << "\red That item will exceed the maximum loadout cost of [MAX_GEAR_COST] points."
else if(href_list["task"] == "remove")
var/to_remove = href_list["gear"]
if(!to_remove) return
if(isnull(gear) || !islist(gear))
gear = list()
if(!gear.len)
return
var/choice = input(user, "Select gear to remove: ") as null|anything in gear
if(!choice)
return
for(var/gear_name in gear)
if(gear_name == to_remove)
if(gear_name == choice)
gear -= gear_name
break

View File

@@ -170,6 +170,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost, you won't be able to play this round for another 30 minutes! You can't change your mind so choose wisely!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost") return //didn't want to ghost after-all
resting = 1
var/turf/location = get_turf(src)
message_admins("[key_name_admin(usr)] has ghosted. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[location.x];Y=[location.y];Z=[location.z]'>JMP</a>)")
log_game("[key_name_admin(usr)] has ghosted.")
var/mob/dead/observer/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
return

View File

@@ -1,6 +1,6 @@
/mob/living/carbon/Life()
..()
// Increase germ_level regularly
if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
germ_level++
@@ -14,7 +14,7 @@
src.nutrition -= HUNGER_FACTOR/10
if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
src.bodytemperature += 2
// Moving around increases germ_level faster
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
germ_level++
@@ -104,9 +104,9 @@
shock_damage *= siemens_coeff
if (shock_damage<1)
return 0
src.apply_damage(shock_damage, BURN, def_zone, used_weapon="Electrocution")
playsound(loc, "sparks", 50, 1, -1)
if (shock_damage > 10)
src.visible_message(
@@ -211,8 +211,8 @@
if (istype(src,/mob/living/carbon/human) && src:w_uniform)
var/mob/living/carbon/human/H = src
H.w_uniform.add_fingerprint(M)
if(lying)
if(lying || src.sleeping)
src.sleeping = max(0,src.sleeping-5)
if(src.sleeping == 0)
src.resting = 0
@@ -221,7 +221,7 @@
else
M.visible_message("<span class='notice'>[M] hugs [src] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [src] to make [t_him] feel better!</span>")
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)

View File

@@ -280,6 +280,7 @@
for(var/datum/wound/W in temp.wounds)
if(W.internal && !temp.open) continue // can't see internal wounds
var/this_wound_desc = W.desc
if(W.damage_type == BURN && W.salved) this_wound_desc = "salved [this_wound_desc]"
if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]"
else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]"
if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"

View File

@@ -2,7 +2,7 @@
//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
#define HUMAN_MAX_OXYLOSS 1 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it.
#define HUMAN_CRIT_MAX_OXYLOSS ( (last_tick_duration) /5) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 100HP to get through, so (1/3)*last_tick_duration per second. Breaths however only happen every 4 ticks.
#define HUMAN_CRIT_MAX_OXYLOSS ( (last_tick_duration) /6) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 50HP to get through, so (1/6)*last_tick_duration per second. Breaths however only happen every 4 ticks.
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
#define HEAT_DAMAGE_LEVEL_2 4 //Amount of damage applied when your body temperature passes the 400K point
@@ -71,7 +71,7 @@
//No need to update all of these procs if the guy is dead.
if(stat != DEAD && !in_stasis)
if(air_master.current_cycle%4==2 || failed_last_breath) //First, resolve location and get a breath
if(air_master.current_cycle%4==2 || failed_last_breath || (health < config.health_threshold_crit)) //First, resolve location and get a breath
breathe() //Only try to take a breath every 4 ticks, unless suffocating
else //Still give containing object the chance to interact
@@ -550,7 +550,7 @@
breath.nitrogen += inhaled_gas_used
if("phoron")
breath.phoron += inhaled_gas_used
if("CO2")
if("carbon_dioxide")
breath.carbon_dioxide += inhaled_gas_used
// Too much exhaled gas in the air

View File

@@ -108,7 +108,7 @@
var/list/trays = list()
for(var/obj/machinery/hydroponics/tray in range(1))
if(tray.nutrilevel < 10)
if(tray.nutrilevel < 10 && src.Adjacent(tray))
trays += tray
var/obj/machinery/hydroponics/target = input("Select a tray:") as null|anything in trays
@@ -127,7 +127,7 @@
var/list/trays = list()
for(var/obj/machinery/hydroponics/tray in range(1))
if(tray.weedlevel > 0)
if(tray.weedlevel > 0 && src.Adjacent(tray))
trays += tray
var/obj/machinery/hydroponics/target = input("Select a tray:") as null|anything in trays
@@ -186,7 +186,8 @@
var/list/choices = list()
for(var/mob/living/carbon/human/H in oview(1,src))
choices += H
if(src.Adjacent(H))
choices += H
var/mob/living/carbon/human/M = input(src,"Who do you wish to take a sample from?") in null|choices

View File

@@ -309,6 +309,7 @@
dead_mob_list -= src
living_mob_list += src
tod = null
timeofdeath = 0
// restore us to conciousness
stat = CONSCIOUS

View File

@@ -386,13 +386,6 @@ var/list/ai_list = list()
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
checklaws()
//Uncomment this line of code if you are enabling the AI Vocal (VOX) announcements.
/*
if(href_list["say_word"])
play_vox_word(href_list["say_word"], null, src)
return
*/
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawi"])
switch(ioncheck[L])

View File

@@ -4,126 +4,3 @@
return
//If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
..(message)
// These Verbs are commented out since we've disabled the AI vocal (VOX) announcements.
// If you re-enable them there is 3 lines in ai.dm Topic() that you need to uncomment as well.
// just search for VOX in there.
/*
var/announcing_vox = 0 // Stores the time of the last announcement
var/const/VOX_CHANNEL = 200
var/const/VOX_DELAY = 100 // 10 seconds
var/const/VOX_PATH = "sound/vox/"
/mob/living/silicon/ai/verb/announcement_help()
set name = "Announcement Help"
set desc = "Display a list of vocal words to announce to the crew."
set category = "AI Commands"
var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.<BR> \
<UL><LI>You can also click on the word to preview it.</LI>\
<LI>You can only say 30 words for every announcement.</LI>\
<LI>Do not use punctuation as you would normally, if you want a pause you can use the full stop and comma characters by separating them with spaces, like so: 'Alpha . Test , Bravo'.</LI></UL>\
<font class='bad'>WARNING:</font><BR>Misuse of the announcement system will get you job banned.<HR>"
var/index = 0
var/list/vox_words = flist(VOX_PATH) // flist will return a list of strings with all the files in the path
for(var/word in vox_words)
index++
var/stripped_word = copytext(word, 1, length(word) - 3) // Remove the .wav
dat += "<A href='?src=\ref[src];say_word=[stripped_word]'>[capitalize(stripped_word)]</A>"
if(index != vox_words.len)
dat += " / "
src << browse(dat, "window=announce_help;size=500x400")
/mob/living/silicon/ai/verb/announcement()
set name = "Announcement"
set desc = "Create a vocal announcement by typing in the available words to create a sentence."
set category = "AI Commands"
if(announcing_vox > world.time)
src << "<span class='notice'>Please wait [round((announcing_vox - world.time) / 10)] seconds.</span>"
return
var/message = input(src, "WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", src.last_announcement) as text
last_announcement = message
if(!message || announcing_vox > world.time)
return
var/list/words = text2list(trim(message), " ")
var/list/incorrect_words = list()
if(words.len > 30)
words.len = 30
// Detect incorrect words which aren't .wav files.
for(var/word in words)
word = trim(word)
if(!word)
words -= word
continue
if(!vox_word_exists(word))
incorrect_words += word
if(incorrect_words.len)
src << "<span class='notice'>These words are not available on the announcement system: [english_list(incorrect_words)].</span>"
return
announcing_vox = world.time + VOX_DELAY
log_game("[key_name_admin(src)] made a vocal announcement with the following message: [message].")
for(var/word in words)
play_vox_word(word, src.z, null)
/proc/play_vox_word(var/word, var/z_level, var/mob/only_listener)
word = lowertext(word)
if(vox_word_exists(word))
var/sound_file = get_vox_file(word)
var/sound/voice = sound(sound_file, wait = 1, channel = VOX_CHANNEL)
voice.status = SOUND_STREAM
// If there is no single listener, broadcast to everyone in the same z level
if(!only_listener)
// Play voice for all mobs in the z level
for(var/mob/M in player_list)
if(M.client)
var/turf/T = get_turf(M)
if(T.z == z_level)
M << voice
else
only_listener << voice
return 1
return 0
/proc/vox_word_exists(var/word)
return fexists("[VOX_PATH][word].wav")
/proc/get_vox_file(var/word)
if(vox_word_exists(word))
return file("[VOX_PATH][word].wav")
// Dynamically loading it has bad results with sounds overtaking each other, even with the wait variable.
// We send the file to the user when they login.
/client/proc/preload_vox()
var/list/vox_files = flist(VOX_PATH)
for(var/file in vox_files)
// src << "Downloading [file]"
var/sound/S = sound("[VOX_PATH][file]")
src << browse_rsc(S)
*/

View File

@@ -19,6 +19,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
/datum/paiController
var/inquirer = null
var/list/pai_candidates = list()
var/list/asked = list()
@@ -224,6 +225,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
M << browse(dat, "window=paiRecruit;size=580x580;")
proc/findPAI(var/obj/item/device/paicard/p, var/mob/user)
inquirer = user
requestRecruits()
var/list/available = list()
for(var/datum/paiCandidate/c in paiController.pai_candidates)
@@ -363,7 +365,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
if(!C) return
asked.Add(C.key)
asked[C.key] = world.time
var/response = alert(C, "Someone is requesting a pAI personality. Would you like to play as a personal AI?", "pAI Request", "Yes", "No", "Never for this round")
var/response = alert(C, "[inquirer] is requesting a pAI personality. Would you like to play as a personal AI?", "pAI Request", "Yes", "No", "Never for this round")
if(!C) return //handle logouts that happen whilst the alert is waiting for a response.
if(response == "Yes")
recruitWindow(C.mob)
@@ -372,4 +374,4 @@ var/datum/paiController/paiController // Global handler for pAI candidates
if(warning == "Yes")
asked[C.key] = INFINITY
else
question(C)
question(C)

View File

@@ -69,9 +69,9 @@
/obj/item/weapon/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
return
/obj/item/weapon/gripper/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
/obj/item/weapon/gripper/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
if(!target || !flag) //Target is invalid or we are not adjacent.
if(!target || !proximity) //Target is invalid or we are not adjacent.
return
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
@@ -80,25 +80,22 @@
wrapped = thing
break
if(wrapped) //Already have an item.
if(wrapped) //Already have an item.
//Temporary put wrapped into user so target's attackby() checks pass.
wrapped.loc = user
//Pass the attack on to the target.
//Pass the attack on to the target. This might delete/relocate wrapped.
target.attackby(wrapped,user)
if(wrapped && src && wrapped.loc == user)
//If wrapped did neither get deleted nor put into target, put it back into the gripper.
if(wrapped && user && (wrapped.loc == user))
wrapped.loc = src
//Sanity/item use checks.
if(!wrapped || !user)
return
if(wrapped.loc != src.loc)
else
wrapped = null
return
if(istype(target,/obj/item)) //Check that we're not pocketing a mob.
else if(istype(target,/obj/item)) //Check that we're not pocketing a mob.
//...and that the item is not in a container.
if(!isturf(target.loc))
@@ -158,9 +155,9 @@
/obj/item/weapon/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
return
/obj/item/weapon/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
/obj/item/weapon/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
if(!flag) return //Not adjacent.
if(!proximity) return //Not adjacent.
//We only want to deal with using this on turfs. Specific items aren't important.
var/turf/T = get_turf(target)
@@ -357,4 +354,4 @@
stack = stack_plastic
stack.amount++
decompiler.stored_comms[type]--;
decompiler.stored_comms[type]--;

View File

@@ -1,9 +1,9 @@
/mob/living/silicon/robot/updatehealth()
if(status_flags & GODMODE)
health = 200
health = maxHealth
stat = CONSCIOUS
return
health = 200 - (getBruteLoss() + getFireLoss())
health = maxHealth - (getBruteLoss() + getFireLoss())
return
/mob/living/silicon/robot/getBruteLoss()
@@ -145,4 +145,4 @@
brute -= (picked.brute_damage - brute_was)
burn -= (picked.electronics_damage - burn_was)
parts -= picked
parts -= picked

View File

@@ -6,7 +6,9 @@
name = "RoboTray"
desc = "An autoloading tray specialized for carrying refreshments."
/obj/item/weapon/tray/robotray/afterattack(atom/target, mob/user as mob)
/obj/item/weapon/tray/robotray/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity)
return
if ( !target )
return
// pick up items, mostly copied from base tray pickup proc

View File

@@ -430,6 +430,9 @@
// And uncomment this, too.
//new_character.dna.UpdateSE()
// Do the initial caching of the player's body icons.
new_character.regenerate_icons()
new_character.key = key //Manually transfer the key to log them in
return new_character

View File

@@ -155,14 +155,14 @@
// sync the organ's damage with its wounds
src.update_damages()
//If limb took enough damage, try to cut or tear it off
if(body_part != UPPER_TORSO && body_part != LOWER_TORSO) //as hilarious as it is, getting hit on the chest too much shouldn't effectively gib you.
if(config.limbs_can_break && brute_dam >= max_damage * config.organ_health_multiplier)
if( (edge && prob(5 * brute)) || (brute > 20 && prob(2 * brute)) )
droplimb(1)
return
owner.updatehealth()
var/result = update_icon()
@@ -206,6 +206,9 @@ This function completely restores a damaged organ to perfect condition.
perma_injury = 0
brute_dam = 0
burn_dam = 0
germ_level = 0
wounds.Cut()
number_wounds = 0
// handle internal organs
for(var/datum/organ/internal/current_organ in internal_organs)
@@ -265,25 +268,6 @@ This function completely restores a damaged organ to perfect condition.
if(W)
wounds += W
/datum/organ/external/proc/get_wound_type(var/type = CUT, var/damage)
//if you look a the names in the wound's stages list for each wound type you will see the logic behind these values
switch(type)
if(CUT)
if (damage <= 5) return /datum/wound/cut/small
if (damage <= 15) return /datum/wound/cut/deep
if (damage <= 25) return /datum/wound/cut/flesh
if (damage <= 50) return /datum/wound/cut/gaping
if (damage <= 60) return /datum/wound/cut/gaping_big
return /datum/wound/cut/massive
if(BRUISE)
return /datum/wound/bruise
if(BURN)
if (damage <= 5) return /datum/wound/burn/moderate
if (damage <= 15) return /datum/wound/burn/large
if (damage <= 30) return /datum/wound/burn/severe
if (damage <= 40) return /datum/wound/burn/deep
return /datum/wound/burn/carbonised
/****************************************************
PROCESSING & UPDATING
****************************************************/
@@ -394,10 +378,9 @@ Note that amputating the affected organ does in fact remove the infection from t
if(germ_level >= INFECTION_LEVEL_ONE)
//having an infection raises your body temperature
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature
if (fever_temperature > owner.bodytemperature)
//need to make sure we raise temperature fast enough to get around environmental cooling preventing us from reaching fever_temperature
owner.bodytemperature += (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature
//need to make sure we raise temperature fast enough to get around environmental cooling preventing us from reaching fever_temperature
owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature)
if(prob(round(germ_level/10)))
if (antibiotics < 5)

View File

@@ -7,7 +7,7 @@
var/current_stage = 0
// description of the wound
var/desc = ""
var/desc = "wound" //default in case something borks
// amount of damage this wound causes
var/damage = 0
@@ -207,6 +207,44 @@
return (damage_type == BRUISE && wound_damage() >= 20 || damage_type == CUT && wound_damage() >= 5)
/** WOUND DEFINITIONS **/
//Note that the MINIMUM damage before a wound can be applied should correspond to
//the damage amount for the stage with the same name as the wound.
//e.g. /datum/wound/cut/deep should only be applied for 15 damage and up,
//because in it's stages list, "deep cut" = 15.
/proc/get_wound_type(var/type = CUT, var/damage)
switch(type)
if(CUT)
switch(damage)
if(70 to INFINITY)
return /datum/wound/cut/massive
if(60 to 70)
return /datum/wound/cut/gaping_big
if(50 to 60)
return /datum/wound/cut/gaping
if(25 to 50)
return /datum/wound/cut/flesh
if(15 to 25)
return /datum/wound/cut/deep
if(0 to 15)
return /datum/wound/cut/small
if(BRUISE)
return /datum/wound/bruise
if(BURN)
switch(damage)
if(50 to INFINITY)
return /datum/wound/burn/carbonised
if(40 to 50)
return /datum/wound/burn/deep
if(30 to 40)
return /datum/wound/burn/severe
if(15 to 30)
return /datum/wound/burn/large
if(0 to 15)
return /datum/wound/burn/moderate
return null //no wound
/** CUTS **/
/datum/wound/cut/small
// link wound descriptions to amounts of damage
@@ -220,7 +258,7 @@
damage_type = CUT
/datum/wound/cut/flesh
max_bleeding_stage = 3
max_bleeding_stage = 4
stages = list("ugly ripped flesh wound" = 35, "ugly flesh wound" = 30, "flesh wound" = 25, "blood soaked clot" = 15, "large scab" = 5, "fresh skin" = 0)
damage_type = CUT
@@ -249,25 +287,26 @@ datum/wound/cut/massive
/** BURNS **/
/datum/wound/burn/moderate
stages = list("ripped burn" = 10, "moderate burn" = 5, "moderate salved burn" = 2, "fresh skin" = 0)
stages = list("ripped burn" = 10, "moderate burn" = 5, "healing moderate burn" = 2, "fresh skin" = 0)
damage_type = BURN
/datum/wound/burn/large
stages = list("ripped large burn" = 20, "large burn" = 15, "large salved burn" = 5, "fresh skin" = 0)
stages = list("ripped large burn" = 20, "large burn" = 15, "healing large burn" = 5, "fresh skin" = 0)
damage_type = BURN
/datum/wound/burn/severe
stages = list("ripped severe burn" = 35, "severe burn" = 30, "severe salved burn" = 10, "burn scar" = 0)
stages = list("ripped severe burn" = 35, "severe burn" = 30, "healing severe burn" = 10, "burn scar" = 0)
damage_type = BURN
/datum/wound/burn/deep
stages = list("ripped deep burn" = 45, "deep burn" = 40, "deep salved burn" = 15, "large burn scar" = 0)
stages = list("ripped deep burn" = 45, "deep burn" = 40, "healing deep burn" = 15, "large burn scar" = 0)
damage_type = BURN
/datum/wound/burn/carbonised
stages = list("carbonised area" = 50, "treated carbonised area" = 20, "massive burn scar" = 0)
stages = list("carbonised area" = 50, "healing carbonised area" = 20, "massive burn scar" = 0)
damage_type = BURN
/** INTERNAL BLEEDING **/
/datum/wound/internal_bleeding
internal = 1
stages = list("severed vein" = 30, "cut vein" = 20, "damaged vein" = 10, "bruised vein" = 5)

View File

@@ -35,6 +35,9 @@
/obj/machinery/power/smes/New()
..()
spawn(5)
if(!powernet)
connect_to_network()
dir_loop:
for(var/d in cardinal)
var/turf/T = get_step(src, d)
@@ -46,6 +49,8 @@
stat |= BROKEN
return
terminal.master = src
if(!terminal.powernet)
terminal.connect_to_network()
updateicon()
return

View File

@@ -1099,8 +1099,7 @@ datum
else if(!alien || alien != IS_DIONA)
M.adjustOxyLoss(-2*REM)
if(holder.has_reagent("lexorin"))
holder.remove_reagent("lexorin", 2*REM)
holder.remove_reagent("lexorin", 2*REM)
..()
return
@@ -1123,8 +1122,7 @@ datum
else if(!alien || alien != IS_DIONA)
M.adjustOxyLoss(-M.getOxyLoss())
if(holder.has_reagent("lexorin"))
holder.remove_reagent("lexorin", 2*REM)
holder.remove_reagent("lexorin", 2*REM)
..()
return
@@ -1221,8 +1219,7 @@ datum
M.AdjustParalysis(-1)
M.AdjustStunned(-1)
M.AdjustWeakened(-1)
if(holder.has_reagent("mindbreaker"))
holder.remove_reagent("mindbreaker", 5)
holder.remove_reagent("mindbreaker", 5)
M.hallucination = max(0, M.hallucination - 10)
if(prob(60)) M.adjustToxLoss(1)
..()
@@ -1315,7 +1312,7 @@ datum
var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"]
if(istype(E))
if(E.damage > 0)
E.damage -= 1
E.damage = max(E.damage - 1, 0)
..()
return
@@ -1336,7 +1333,7 @@ datum
//Peridaxon is hard enough to get, it's probably fair to make this all internal organs
for(var/datum/organ/internal/I in H.internal_organs)
if(I.damage > 0)
I.damage -= 0.20
I.damage = max(I.damage - 0.20, 0)
..()
return
@@ -1600,8 +1597,7 @@ datum
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(holder.has_reagent("inaprovaline"))
holder.remove_reagent("inaprovaline", 2*REM)
holder.remove_reagent("inaprovaline", 2*REM)
..()
return
reaction_obj(var/obj/O, var/volume)
@@ -2039,7 +2035,7 @@ datum
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.nutrition -= nutriment_factor
M.nutrition = max(M.nutrition - nutriment_factor, 0)
M.overeatduration = 0
if(M.nutrition < 0)//Prevent from going into negatives.
M.nutrition = 0
@@ -2068,25 +2064,29 @@ datum
description = "This is what makes chilis hot."
reagent_state = LIQUID
color = "#B31008" // rgb: 179, 16, 8
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
switch(data)
if(1 to 15)
M.bodytemperature += 5 * TEMPERATURE_DAMAGE_COEFFICIENT
if(holder.has_reagent("frostoil"))
holder.remove_reagent("frostoil", 5)
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(5,20)
if(15 to 25)
M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(10,20)
if(25 to INFINITY)
M.bodytemperature += 15 * TEMPERATURE_DAMAGE_COEFFICIENT
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(15,20)
if(!M)
M = holder.my_atom
if(!data)
data = 1
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.species && !(H.species.flags & (NO_PAIN | IS_SYNTHETIC)) )
switch(data)
if(1 to 2)
H << "\red <b>Your insides feel uncomfortably hot !</b>"
if(2 to 20)
if(prob(5))
H << "\red <b>Your insides feel uncomfortably hot !</b>"
if(20 to INFINITY)
H.apply_effect(2,AGONY,0)
if(prob(5))
H.visible_message("<span class='warning'>[H] [pick("dry heaves!","coughs!","splutters!")]</span>")
H << "\red <b>You feel like your insides are burning !</b>"
else if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(10,25)
holder.remove_reagent("frostoil", 5)
holder.remove_reagent(src.id, FOOD_METABOLISM)
data++
..()
@@ -2152,10 +2152,29 @@ datum
victim.Weaken(5)
//victim.Paralyse(10)
//victim.drop_item()
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(prob(5))
M.visible_message("<span class='warning'>[M] [pick("dry heaves!","coughs!","splutters!")]</span>")
if(!M)
M = holder.my_atom
if(!data)
data = 1
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.species && !(H.species.flags & (NO_PAIN | IS_SYNTHETIC)) )
switch(data)
if(1)
H << "\red <b>You feel like your insides are burning !</b>"
if(2 to INFINITY)
H.apply_effect(4,AGONY,0)
if(prob(5))
H.visible_message("<span class='warning'>[H] [pick("dry heaves!","coughs!","splutters!")]</span>")
H << "\red <b>You feel like your insides are burning !</b>"
else if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(15,30)
holder.remove_reagent("frostoil", 5)
holder.remove_reagent(src.id, FOOD_METABOLISM)
data++
..()
return
frostoil
@@ -2166,25 +2185,14 @@ datum
color = "#B31008" // rgb: 139, 166, 233
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
switch(data)
if(1 to 15)
M.bodytemperature -= 5 * TEMPERATURE_DAMAGE_COEFFICIENT
if(holder.has_reagent("capsaicin"))
holder.remove_reagent("capsaicin", 5)
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature -= rand(5,20)
if(15 to 25)
M.bodytemperature -= 10 * TEMPERATURE_DAMAGE_COEFFICIENT
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature -= rand(10,20)
if(25 to INFINITY)
M.bodytemperature -= 15 * TEMPERATURE_DAMAGE_COEFFICIENT
if(prob(1)) M.emote("shiver")
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature -= rand(15,20)
data++
if(!M)
M = holder.my_atom
M.bodytemperature = max(M.bodytemperature - 10 * TEMPERATURE_DAMAGE_COEFFICIENT, 0)
if(prob(1))
M.emote("shiver")
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature = max(M.bodytemperature - rand(10,20), 0)
holder.remove_reagent("capsaicin", 5)
holder.remove_reagent(src.id, FOOD_METABOLISM)
..()
return
@@ -2593,8 +2601,7 @@ datum
on_mob_life(var/mob/living/M as mob)
if(M.getBruteLoss() && prob(20)) M.heal_organ_damage(1,0)
if(holder.has_reagent("capsaicin"))
holder.remove_reagent("capsaicin", 10*REAGENTS_METABOLISM)
holder.remove_reagent("capsaicin", 10*REAGENTS_METABOLISM)
..()
return
@@ -2637,7 +2644,7 @@ datum
on_mob_life(var/mob/living/M as mob)
..()
M.make_jittery(5)
if(adj_temp > 0 && holder.has_reagent("frostoil"))
if(adj_temp > 0)
holder.remove_reagent("frostoil", 10*REAGENTS_METABOLISM)
holder.remove_reagent(src.id, 0.1)
@@ -2807,25 +2814,14 @@ datum
adj_temp = -9
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
switch(data)
if(1 to 15)
M.bodytemperature -= 5 * TEMPERATURE_DAMAGE_COEFFICIENT
if(holder.has_reagent("capsaicin"))
holder.remove_reagent("capsaicin", 5)
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature -= rand(5,20)
if(15 to 25)
M.bodytemperature -= 10 * TEMPERATURE_DAMAGE_COEFFICIENT
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature -= rand(10,20)
if(25 to INFINITY)
M.bodytemperature -= 15 * TEMPERATURE_DAMAGE_COEFFICIENT
if(prob(1)) M.emote("shiver")
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature -= rand(15,20)
data++
if(!M)
M = holder.my_atom
if(prob(1))
M.emote("shiver")
M.bodytemperature = max(M.bodytemperature - 10 * TEMPERATURE_DAMAGE_COEFFICIENT, 0)
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature = max(M.bodytemperature - rand(10,20), 0)
holder.remove_reagent("capsaicin", 5)
holder.remove_reagent(src.id, FOOD_METABOLISM)
..()
return

View File

@@ -137,10 +137,3 @@
/datum/computer/file/embedded_program/docking/simple/escape_pod/prepare_for_undocking()
eject_time = world.time + eject_delay*10
/*
/datum/computer/file/embedded_program/docking/simple/escape_pod/ready_for_undocking()
if (world.time < eject_time)
return 0
return ..()
*/

View File

@@ -34,15 +34,14 @@
if (moving_status == SHUTTLE_IDLE)
return //someone cancelled the launch
move(departing, interim, direction)
moving_status = SHUTTLE_INTRANSIT
move(departing, interim, direction)
arrive_time = world.time + travel_time*10
while (world.time < arrive_time)
sleep(5)
move(interim, destination, direction)
moving_status = SHUTTLE_IDLE
/datum/shuttle/proc/dock()
@@ -69,6 +68,8 @@
return 0
//just moves the shuttle from A to B, if it can be moved
//A note to anyone overriding move in a subtype. move() must absolutely not, under any circumstances, fail to move the shuttle.
//If you want to conditionally cancel shuttle launches, that logic must go in short_jump() or long_jump()
/datum/shuttle/proc/move(var/area/origin, var/area/destination, var/direction=null)
//world << "move_shuttle() called for [shuttle_tag] leaving [origin] en route to [destination]."

View File

@@ -202,7 +202,7 @@
var/is_chest_organ_damaged = 0
var/datum/organ/external/chest/chest = target.get_organ("chest")
for(var/datum/organ/internal/I in chest.internal_organs)
for(var/datum/organ/internal/I in chest.internal_organs)
if(I.damage > 0)
is_chest_organ_damaged = 1
break
@@ -244,7 +244,7 @@
if(I && I.damage > 0)
if(I.robotic < 2)
user.visible_message("\blue [user] treats damage to [target]'s [I.name] with [tool_name].", \
"You treat damage to [target]'s [I.name] with [tool_name]." )
"\blue You treat damage to [target]'s [I.name] with [tool_name]." )
else
user.visible_message("\blue [user] pokes [target]'s mechanical [I.name] with [tool_name]...", \
"\blue You poke [target]'s mechanical [I.name] with [tool_name]... \red For no effect, since it's robotic.")

View File

@@ -89,7 +89,7 @@ proc/do_surgery(mob/living/M, mob/living/user, obj/item/tool)
//We had proper tools! (or RNG smiled.) and User did not move or change hands.
if( prob(S.tool_quality(tool)) && do_mob(user, M, rand(S.min_duration, S.max_duration)))
S.end_step(user, M, user.zone_sel.selecting, tool) //finish successfully
else //or
else if (tool in user.contents && user.Adjacent(M)) //or
S.fail_step(user, M, user.zone_sel.selecting, tool) //malpractice~
return 1 //don't want to do weapony things after surgery
return 0

View File

@@ -48,7 +48,7 @@
turn_off() //so engine verbs are correctly set
/obj/vehicle/train/cargo/engine/Move()
if(on && cell.charge < power_use)
if(on && cell.charge < charge_use)
turn_off()
update_stats()
if(load && is_train_head())
@@ -183,20 +183,7 @@
if(get_dist(usr,src) <= 1)
usr << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition."
/obj/vehicle/train/cargo/engine/verb/check_power()
set name = "Check power level"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!cell)
usr << "There is no power cell installed in [src]."
return
usr << "The power meter reads [round(cell.percent(), 0.01)]%"
usr << "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%"
/obj/vehicle/train/cargo/engine/verb/start_engine()
set name = "Start engine"
@@ -214,7 +201,7 @@
if (on)
usr << "You start [src]'s engine."
else
if(cell.charge < power_use)
if(cell.charge < charge_use)
usr << "[src] is out of power."
else
usr << "[src]'s engine won't start."
@@ -288,13 +275,22 @@
// more engines increases this limit by car_limit per
// engine.
//-------------------------------------------------------
/obj/vehicle/train/cargo/engine/update_train_stats()
..()
/obj/vehicle/train/cargo/engine/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
update_move_delay()
//Update move delay
if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += config.run_speed //base reference speed
move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight
/obj/vehicle/train/cargo/trolley/update_train_stats()
..()
/obj/vehicle/train/cargo/trolley/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
if(!lead && !tow)
anchored = 0
@@ -305,12 +301,3 @@
else
anchored = 1
verbs -= /atom/movable/verb/pull
/obj/vehicle/train/cargo/engine/proc/update_move_delay()
if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += config.run_speed //base reference speed
move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight

View File

@@ -62,7 +62,8 @@
// Vehicle procs
//-------------------------------------------
/obj/vehicle/train/explode()
tow.unattach()
if (tow)
tow.unattach()
unattach()
..()
@@ -142,6 +143,15 @@
if (T.tow)
user << "\red [T] is already towing something."
return
//check for cycles.
var/obj/vehicle/train/next_car = T
while (next_car)
if (next_car == src)
user << "\red That seems very silly."
return
next_car = next_car.lead
//latch with src as the follower
lead = T
T.tow = src
@@ -192,23 +202,28 @@
// size of the train, to limit super long trains.
//-------------------------------------------------------
/obj/vehicle/train/update_stats()
if(tow)
return tow.update_stats() //take us to the very end
else
update_train_stats() //we're at the end
//first, seek to the end of the train
var/obj/vehicle/train/T = src
while(T.tow)
//check for cyclic train.
if (T.tow == src)
lead.tow = null
lead.update_stats()
lead = null
update_stats()
return
T = T.tow
/obj/vehicle/train/proc/update_train_stats()
if(powered && on)
active_engines = 1 //increment active engine count if this is a running engine
else
active_engines = 0
//now walk back to the front.
var/active_engines = 0
var/train_length = 0
while(T)
train_length++
if (powered && on)
active_engines++
T.update_car(train_length, active_engines)
T = T.lead
train_length = 1
if(istype(tow))
active_engines += tow.active_engines
train_length += tow.train_length
//update the next section of train ahead of us
if(istype(lead))
lead.update_train_stats()
/obj/vehicle/train/proc/update_car(var/train_length, var/active_engines)
return

View File

@@ -22,7 +22,7 @@
var/movable = 1
var/obj/item/weapon/cell/cell
var/power_use = 5 //set this to adjust the amount of power the vehicle uses per move
var/charge_use = 5 //set this to adjust the amount of power the vehicle uses per move
var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable
var/load_item_visible = 1 //set if the loaded item should be overlayed on the vehicle sprite
@@ -39,7 +39,7 @@
/obj/vehicle/Move()
if(world.time > l_move_time + move_delay)
if(on && powered && cell.charge < power_use)
if(on && powered && cell.charge < charge_use)
turn_off()
var/init_anc = anchored
@@ -51,7 +51,7 @@
anchored = init_anc
if(on && powered)
cell.use(power_use)
cell.use(charge_use)
if(load)
load.forceMove(loc)// = loc
@@ -172,7 +172,7 @@
/obj/vehicle/proc/turn_on()
if(stat)
return 0
if(powered && cell.charge < power_use)
if(powered && cell.charge < charge_use)
return 0
on = 1
luminosity = initial(luminosity)
@@ -228,7 +228,7 @@
turn_off()
return
if(cell.charge < power_use)
if(cell.charge < charge_use)
turn_off()
return