Merge pull request #8382 from comma/monkey_revenge

Allows you to scoop monkeys up
This commit is contained in:
PsiOmegaDelta
2015-03-09 21:17:03 +01:00
14 changed files with 153 additions and 223 deletions

View File

@@ -1061,6 +1061,7 @@
#include "code\modules\mob\living\logout.dm"
#include "code\modules\mob\living\say.dm"
#include "code\modules\mob\living\blob\blob.dm"
#include "code\modules\mob\living\carbon\breathe.dm"
#include "code\modules\mob\living\carbon\carbon.dm"
#include "code\modules\mob\living\carbon\carbon_defines.dm"
#include "code\modules\mob\living\carbon\carbon_powers.dm"

View File

@@ -220,7 +220,7 @@
/datum/gas_mixture/proc/remove_ratio(ratio, out_group_multiplier = 1)
if(ratio <= 0)
return null
out_group_multiplier = max(1, min(group_multiplier, out_group_multiplier))
out_group_multiplier = between(1, out_group_multiplier, group_multiplier)
ratio = min(ratio, 1)
@@ -237,6 +237,11 @@
return removed
//Removes a volume of gas from the mixture and returns a gas_mixture containing the removed air with the given volume
/datum/gas_mixture/proc/remove_volume(removed_volume)
var/datum/gas_mixture/removed = remove_ratio(removed_volume/volume, 1)
removed.volume = removed_volume
return removed
//Removes moles from the gas mixture, limited by a given flag. Returns a gax_mixture containing the removed air.
/datum/gas_mixture/proc/remove_by_flag(flag, amount)

View File

@@ -34,6 +34,12 @@
else
return null
//Currently used only for cryo cells, because they are also pipes and so overriding their return_air() would break their pipe-behaviour.
//If cryo cells are ever rewritten so that the part that contains the human is separate from the pipe part --
//such as rewriting them so that they are a machine that contains a pipe segment (or a pipe that contains a machine that contains the human?) -- then this can be removed.
/atom/proc/return_air_for_internal_lifeform()
return return_air()
/atom/proc/check_eye(user as mob)
if (istype(user, /mob/living/silicon/ai)) // WHYYYY
return 1

View File

@@ -331,7 +331,13 @@
put_mob(usr)
return
/obj/machinery/atmospherics/unary/cryo_cell/return_air_for_internal_lifeform()
//assume that the cryo cell has some kind of breath mask or something that
//draws from the cryo tube's environment, instead of the cold internal air.
if(loc)
return loc.return_air()
else
return null
/datum/data/function/proc/reset()
return

View File

@@ -62,16 +62,6 @@
else
return null
/obj/proc/handle_internal_lifeform(mob/lifeform_inside_me, breath_request)
//Return: (NONSTANDARD)
// null if object handles breathing logic for lifeform
// datum/air_group to tell lifeform to process using that breath return
//DEFAULT: Take air from turf to give to have mob process
if(breath_request>0)
return remove_air(breath_request)
else
return null
/atom/movable/proc/initialize()
return

View File

@@ -353,53 +353,24 @@ obj/structure/ex_act(severity)
moving = 0
// Should I return a copy here? If the caller edits or del()s the returned
// datum, there might be problems if I don't...
/obj/structure/transit_tube_pod/return_air()
var/datum/gas_mixture/GM = new()
GM.copy_from(air_contents)
return GM
return air_contents
// For now, copying what I found in an unused FEA file (and almost identical in a
// used ZAS file). Means that assume_air and remove_air don't actually alter the
// air contents.
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return air_contents.merge(giver)
/obj/structure/transit_tube_pod/remove_air(amount)
return air_contents.remove(amount)
// Called when a pod arrives at, and before a pod departs from a station,
// giving it a chance to mix its internal air supply with the turf it is
// currently on.
/obj/structure/transit_tube_pod/proc/mix_air()
var/datum/gas_mixture/environment = loc.return_air()
var/env_pressure = environment.return_pressure()
var/int_pressure = air_contents.return_pressure()
var/total_pressure = env_pressure + int_pressure
if(total_pressure == 0)
return
// Math here: Completely made up, not based on realistic equasions.
// Goal is to balance towards equal pressure, but ensure some gas
// transfer in both directions regardless.
// Feel free to rip this out and replace it with something better,
// I don't really know muhch about how gas transfer rates work in
// SS13.
var/transfer_in = max(0.1, 0.5 * (env_pressure - int_pressure) / total_pressure)
var/transfer_out = max(0.1, 0.3 * (int_pressure - env_pressure) / total_pressure)
var/datum/gas_mixture/from_env = loc.remove_air(environment.total_moles * transfer_in)
var/datum/gas_mixture/from_int = air_contents.remove(air_contents.total_moles * transfer_out)
loc.assume_air(from_int)
air_contents.merge(from_env)
//note that share_ratio assumes both gas mixes have the same volume,
//so if the volume is changed this may need to be changed as well.
air_contents.share_ratio(environment, 1)
// When the player moves, check if the pos is currently stopped at a station.
// if it is, check the direction. If the direction matches the direction of

View File

@@ -78,4 +78,26 @@
name = "cortical borer"
desc = "It's a slimy brain slug. Gross."
icon_state = "borer"
origin_tech = "biotech=6"
origin_tech = "biotech=6"
/obj/item/weapon/holder/monkey
name = "monkey"
desc = "It's a monkey. Ook."
icon_state = "cat"
icon = 'icons/mob/monkey.dmi'
icon_state = "monkey1"
/obj/item/weapon/holder/monkey/farwa
name = "farwa"
desc = "It's a farwa."
icon_state = "tajkey1"
/obj/item/weapon/holder/monkey/stok
name = "stok"
desc = "It's a stok. stok."
icon_state = "stokkey1"
/obj/item/weapon/holder/monkey/neaera
name = "neaera"
desc = "It's a neaera."
icon_state = "skrellkey1"

View File

@@ -0,0 +1,80 @@
//Common breathing procs
/mob/living/carbon/proc/breathe()
//if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
var/datum/gas_mixture/breath = null
//First, check if we can breathe at all
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline")) //crit aka circulatory shock
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
spawn emote("gasp")
else
//Okay, we can breathe, now check if we can get air
breath = get_breath_from_internal() //First, check for air from internals
if(!breath)
breath = get_breath_from_environment() //No breath from internals so let's try to get air from our location
handle_breath(breath)
handle_post_breath(breath)
/mob/living/carbon/proc/get_breath_from_internal(var/volume_needed=BREATH_VOLUME) //hopefully this will allow overrides to specify a different default volume without breaking any cases where volume is passed in.
if(internal)
if (!contents.Find(internal))
internal = null
if (!(wear_mask && (wear_mask.flags & AIRTIGHT)))
internal = null
if(internal)
if (internals)
internals.icon_state = "internal1"
return internal.remove_air_volume(volume_needed)
else
if (internals)
internals.icon_state = "internal0"
return null
/mob/living/carbon/proc/get_breath_from_environment(var/volume_needed=BREATH_VOLUME)
var/datum/gas_mixture/breath = null
var/datum/gas_mixture/environment
if(loc)
environment = loc.return_air_for_internal_lifeform()
if(environment)
breath = environment.remove_volume(volume_needed)
handle_chemical_smoke(environment) //handle chemical smoke while we're at it
if(breath)
//handle mask filtering
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
var/obj/item/clothing/mask/M = wear_mask
var/datum/gas_mixture/filtered = M.filter_air(breath)
loc.assume_air(filtered)
return breath
return null
//Handle possble chem smoke effect
/mob/living/carbon/proc/handle_chemical_smoke(var/datum/gas_mixture/environment)
if(wear_mask && (wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT))
return
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
if(smoke)
//maybe check air pressure here or something to see if breathing in smoke is even possible.
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
break // If they breathe in the nasty stuff once, no need to continue checking
/mob/living/carbon/proc/handle_breath(datum/gas_mixture/breath)
return
/mob/living/carbon/proc/handle_post_breath(datum/gas_mixture/breath)
if(breath)
loc.assume_air(breath) //by default, exhale

View File

@@ -69,11 +69,6 @@
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
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
//Updates the number of stored chemicals for powers
handle_changeling()
@@ -328,95 +323,26 @@
var/datum/organ/external/O = pick(organs)
if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage)
proc/breathe()
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
/** breathing **/
handle_chemical_smoke(var/datum/gas_mixture/environment)
if(wear_mask && (wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT))
return
if(glasses && (glasses.flags & BLOCK_GAS_SMOKE_EFFECT))
return
if(head && (head.flags & BLOCK_GAS_SMOKE_EFFECT))
return
..()
var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath
// HACK NEED CHANGING LATER
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline"))
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
spawn emote("gasp")
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
else
//First, check for air from internal atmosphere (using an air tank and mask generally)
breath = get_breath_from_internal(BREATH_VOLUME) // Super hacky -- TLE
//breath = get_breath_from_internal(0.5) // Manually setting to old BREATH_VOLUME amount -- TLE
//No breath from internal atmosphere so get breath from location
if(!breath)
if(isobj(loc))
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_MOLES)
else if(isturf(loc))
var/breath_moles = 0
/*if(environment.return_pressure() > ONE_ATMOSPHERE)
// Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
else*/
// Not enough air around, take a percentage of what's there to model this properly
breath_moles = environment.total_moles*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
var/obj/item/clothing/mask/M = wear_mask
var/datum/gas_mixture/filtered = M.filter_air(breath)
loc.assume_air(filtered)
if(!is_lung_ruptured())
if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5)
if(prob(5))
rupture_lung()
// Handle filtering
var/block = 0
if(wear_mask)
if(wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)
block = 1
if(glasses)
if(glasses.flags & BLOCK_GAS_SMOKE_EFFECT)
block = 1
if(head)
if(head.flags & BLOCK_GAS_SMOKE_EFFECT)
block = 1
if(!block)
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
if(smoke)
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
break // If they breathe in the nasty stuff once, no need to continue checking
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
handle_breath(breath)
if(breath)
loc.assume_air(breath)
//spread some viruses while we are at it
if (virus2.len > 0 && prob(10))
// log_debug("[src] : Exhaling some viruses")
for(var/mob/living/carbon/M in view(1,src))
src.spread_disease_to(M)
handle_post_breath(datum/gas_mixture/breath)
..()
//spread some viruses while we are at it
if(breath && virus2.len > 0 && prob(10))
for(var/mob/living/carbon/M in view(1,src))
src.spread_disease_to(M)
proc/get_breath_from_internal(volume_needed)
get_breath_from_internal(volume_needed=BREATH_VOLUME)
if(internal)
var/obj/item/weapon/tank/rig_supply
@@ -435,7 +361,7 @@
return null
proc/handle_breath(datum/gas_mixture/breath)
handle_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
return

View File

@@ -27,10 +27,6 @@
if(air_master.current_cycle%4==2)
//Only try to take a breath every 4 seconds, unless suffocating
breathe()
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
//Updates the number of stored chemicals for powers
handle_changeling()
@@ -152,85 +148,7 @@
domutcheck(src,null)
emote("gasp")
proc/breathe()
if(reagents)
if(reagents.has_reagent("lexorin")) return
if(!loc) return //probably ought to make a proper fix for this, but :effort: --NeoFite
var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath
if(health < 0)
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(75)) //High chance of gasping for air
spawn emote("gasp")
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
else
//First, check for air from internal atmosphere (using an air tank and mask generally)
breath = get_breath_from_internal(BREATH_VOLUME)
//No breath from internal atmosphere so get breath from location
if(!breath)
if(istype(loc, /obj/))
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
else if(istype(loc, /turf/))
var/breath_moles = environment.total_moles*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
var/obj/item/clothing/mask/M = wear_mask
var/datum/gas_mixture/filtered = M.filter_air(breath)
loc.assume_air(filtered)
// Handle chem smoke effect -- Doohl
var/block = 0
if(wear_mask)
if(istype(wear_mask, /obj/item/clothing/mask/gas))
block = 1
if(!block)
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
if(smoke)
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
break // If they breathe in the nasty stuff once, no need to continue checking
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
handle_breath(breath)
if(breath)
loc.assume_air(breath)
proc/get_breath_from_internal(volume_needed)
if(internal)
if (!contents.Find(internal))
internal = null
if (!(wear_mask && (wear_mask.flags & AIRTIGHT)))
internal = null
if(internal)
if (internals)
internals.icon_state = "internal1"
return internal.remove_air_volume(volume_needed)
else
if (internals)
internals.icon_state = "internal0"
return null
proc/handle_breath(datum/gas_mixture/breath)
handle_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
return

View File

@@ -14,6 +14,7 @@
//var/uni_append = "12C4E2" // Small appearance modifier for different species.
var/list/uni_append = list(0x12C,0x4E2) // Same as above for DNA2.
var/update_muts = 1 // Monkey gene must be set at start.
holder_type = /obj/item/weapon/holder/monkey
/mob/living/carbon/monkey/tajara
name = "farwa"
@@ -22,6 +23,7 @@
icon_state = "tajkey1"
greaterform = "Tajara"
uni_append = list(0x0A0,0xE00) // 0A0E00
holder_type = /obj/item/weapon/holder/monkey/farwa
/mob/living/carbon/monkey/skrell
name = "neaera"
@@ -30,6 +32,7 @@
icon_state = "skrellkey1"
greaterform = "Skrell"
uni_append = list(0x01C,0xC92) // 01CC92
holder_type = /obj/item/weapon/holder/monkey/neaera
/mob/living/carbon/monkey/unathi
name = "stok"
@@ -38,6 +41,7 @@
icon_state = "stokkey1"
greaterform = "Unathi"
uni_append = list(0x044,0xC5D) // 044C5D
holder_type = /obj/item/weapon/holder/monkey/stok
/mob/living/carbon/monkey/New()
@@ -133,8 +137,9 @@
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M as mob)
if (M.a_intent == "help")
if (M.a_intent == "help" && a_intent == "help")
help_shake_act(M)
get_scooped(M)
else
if (M.a_intent == "hurt")
var/datum/unarmed_attack/attack = null

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 158 KiB