Fixes #721, fixes #710, fixes #706 (#731)

This commit is contained in:
NanakoAC
2016-08-12 23:00:27 +03:00
committed by skull132
parent db449f4c68
commit 9d58b77e18
8 changed files with 205 additions and 71 deletions
+75 -25
View File
@@ -12,6 +12,9 @@
var/name_dead
var/isalive
var/last_loc_general//This stores a general location of the object. Ie, a container or a mob
var/last_loc_specific//This stores specific extra information about the location, pocket, hand, worn on head, etc. Only relevant to mobs
/obj/item/weapon/holder/New()
if (!item_state)
item_state = icon_state
@@ -30,18 +33,18 @@
return
for(var/mob/M in contents)
var/atom/movable/mob_container
mob_container = M
mob_container.forceMove(src.loc)//if the holder was placed into a disposal, this should place the animal in the disposal
M.reset_view()
for(var/mob/M in contents)
var/atom/movable/mob_container
mob_container = M
mob_container.forceMove(src.loc)//if the holder was placed into a disposal, this should place the animal in the disposal
M.reset_view()
var/mob/L = get_holding_mob()
if (L)
L.drop_from_inventory(src)
qdel(src)
qdel(src)
return
if (isalive && contained.stat == DEAD)
held_death(1)//If we get here, it means the mob died sometime after we picked it up. We pass in 1 so that we can play its deathmessage
@@ -61,6 +64,33 @@
for(var/mob/M in src.contents)
M.attackby(W,user)
/obj/item/weapon/holder/dropped(mob/user)
///When an object is put into a container, drop fires twice.
//once with it on the floor, and then once in the container
//This conditional allows us to ignore that first one. Handling of mobs dropped on the floor is done in process
if (istype(loc, /turf))
return
if (istype(loc, /obj/item/weapon/storage)) //The second drop reads the container its placed into as the location
update_location()
/obj/item/weapon/holder/equipped(var/mob/user, var/slot)
..()
update_location(slot)
/obj/item/weapon/holder/proc/update_location(var/slotnumber = null)
if (!slotnumber)
if (istype(loc, /mob))
slotnumber = get_equip_slot()
report_onmob_location(1, slotnumber, contained)
/obj/item/weapon/holder/attack_self(mob/M as mob)
if (contained && !(contained.stat & DEAD))
@@ -115,26 +145,47 @@
grabber << "Your hand is full!"
return
src.verbs += /mob/living/proc/get_holder_location//This has to be before we move the mob into the holder
var/obj/item/weapon/holder/H = new holder_type(loc)
src.forceMove(H)
H.name = loc.name
H.attack_hand(grabber)
H.contained = src
if (src.stat == DEAD)
H.held_death()//We've scooped up an animal that's already dead. use the proper dead icons
else
H.isalive = 1//We note that the mob is alive when picked up. If it dies later, we can know that its death happened while held, and play its deathmessage for it
spawn(2)
var/obj/item/weapon/holder/H = new holder_type(loc)
H.name = loc.name
src.forceMove(H)
if (user == src)
grabber << "<span class='notice'>[src.name] climbs up onto you.</span>"
src << "<span class='notice'>You climb up onto [grabber].</span>"
else
grabber << "<span class='notice'>You scoop up [src].</span>"
src << "<span class='notice'>[grabber] scoops you up.</span>"
grabber.status_flags |= PASSEMOTES
return
H.contained = src
if (src.stat == DEAD)
H.held_death()//We've scooped up an animal that's already dead. use the proper dead icons
else
H.isalive = 1//We note that the mob is alive when picked up. If it dies later, we can know that its death happened while held, and play its deathmessage for it
if (user == src)
grabber << "<span class='notice'>[src.name] climbs up onto you.</span>"
src << "<span class='notice'>You climb up onto [grabber].</span>"
else
grabber << "<span class='notice'>You scoop up [src].</span>"
src << "<span class='notice'>[grabber] scoops you up.</span>"
grabber.status_flags |= PASSEMOTES
H.attack_hand(grabber)//We put this last to prevent some race conditions
return
/mob/living/proc/get_holder_location()
set category = "Abilities"
set name = "Check held location"
set desc = "Find out where on their person, someone is holding you."
if (!usr.get_holding_mob())
src << "Nobody is holding you!"
return
if (istype(usr.loc, /obj/item/weapon/holder))
var/obj/item/weapon/holder/H = usr.loc
H.report_onmob_location(0, H.get_equip_slot(), src)
//Mob specific holders.
//w_class mainly determines whether they can fit in trashbags. <=2 can, >=3 cannot
@@ -231,7 +282,6 @@
origin_tech = "biotech=2"
w_class = 1
/obj/item/weapon/holder/mouse/white
icon_state = "mouse_white"
icon_state_dead = "mouse_white_dead"
@@ -32,7 +32,7 @@
mob_swap_flags = HUMAN|SIMPLE_ANIMAL|SLIME|MONKEY
mob_push_flags = ALLMOBS
hunger_enabled = 0
var/list/construct_spells = list()
/mob/living/simple_animal/construct/cultify()
@@ -2,6 +2,7 @@
name = "mouse"
real_name = "mouse"
desc = "It's a small rodent."
icon = 'icons/mob/mouse.dmi'
icon_state = "mouse_gray"
icon_living = "mouse_gray"
icon_dead = "mouse_gray_dead"
@@ -14,6 +15,9 @@
'sound/effects/creatures/mouse_squeaks_3.ogg',
'sound/effects/creatures/mouse_squeaks_4.ogg')
var/last_softsqueak = null//Used to prevent the same soft squeak twice in a row
var/squeals = 5//Spam control. You people are why we cant have nice things >:(
var/maxSqueals = 5//SPAM PROTECTION
var/last_squealgain = 0// #TODO-FUTURE: Remove from life() once something else is created
pass_flags = PASSTABLE
small = 1
@@ -40,10 +44,19 @@
/mob/living/simple_animal/mouse/Life()
..()
//Player-animals don't do random speech normally, so this is here
if(client)
//Player-animals don't do random speech normally, so this is here
//Player-controlled mice will still squeak, but less often than NPC mice
if(client && stat == CONSCIOUS && prob(speak_chance*0.4))
squeak_soft()
if (stat == CONSCIOUS && prob(speak_chance*0.1))
squeak_soft(0)
if (squeals < maxSqueals)
var/diff = world.time - last_squealgain
if (diff > 600)
world << "+1 squeak"
squeals++
last_squealgain = world.time
if(!ckey && stat == CONSCIOUS && prob(0.5))
stat = UNCONSCIOUS
@@ -60,9 +73,12 @@
else if(prob(5))
audible_emote("snuffles.")
/mob/living/simple_animal/mouse/New()
..()
nutrition = rand(max_nutrition*0.25, max_nutrition*0.75)
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
@@ -83,12 +99,12 @@
if (body_color == "white")
holder_type = /obj/item/weapon/holder/mouse/white
verbs += /mob/living/simple_animal/mouse/proc/squeak
verbs += /mob/living/simple_animal/mouse/proc/squeak_soft
verbs += /mob/living/simple_animal/mouse/proc/squeak_loud
//verbs += /mob/living/simple_animal/mouse/proc/squeak
//verbs += /mob/living/simple_animal/mouse/proc/squeak_soft
//verbs += /mob/living/simple_animal/mouse/proc/squeak_loud(1)
/mob/living/simple_animal/mouse/speak_audio()
squeak_soft()
squeak_soft(0)
@@ -116,34 +132,54 @@
//Plays a sound.
//This is triggered when a mob steps on an NPC mouse, or manually by a playermouse
/mob/living/simple_animal/mouse/proc/squeak()
set name = "Squeak"
set category = "Abilities"
/mob/living/simple_animal/mouse/proc/squeak(var/manual = 1)
playsound(src, 'sound/effects/mousesqueek.ogg', 70, 1)
if (manual)
log_say("[key_name(src)] squeaks! ")
//Plays a random selection of four sounds, at a low volume
//This is triggered randomly periodically by any mouse, or manually
/mob/living/simple_animal/mouse/proc/squeak_soft()
set name = "Soft Squeaking"
set category = "Abilities"
/mob/living/simple_animal/mouse/proc/squeak_soft(var/manual = 1)
var/list/new_squeaks = last_softsqueak ? soft_squeaks - last_softsqueak : soft_squeaks
var/sound = pick(new_squeaks)
last_softsqueak = sound
playsound(src, sound, 6, 1)
if (manual)
log_say("[key_name(src)] squeaks softly! ")
//Plays a loud sound
//Triggered manually, when a mouse dies, or rarely when its stepped on
/mob/living/simple_animal/mouse/proc/squeak_loud()
/mob/living/simple_animal/mouse/proc/squeak_loud(var/manual = 0)
if (squeals > 0 || !manual)
playsound(src, 'sound/effects/creatures/mouse_squeak_loud.ogg', 50, 1)
squeals --
log_say("[key_name(src)] squeals! ")
else
src << "\red Your hoarse mousey throat can't squeal just now, stop and take a breath!"
//Wrapper verbs for the squeak functions
/mob/living/simple_animal/mouse/verb/squeak_loud_verb()
set name = "Squeal!"
set category = "Abilities"
playsound(src, 'sound/effects/creatures/mouse_squeak_loud.ogg', 50, 1)
squeak_loud(1)
/mob/living/simple_animal/mouse/verb/squeak_soft_verb()
set name = "Soft Squeaking"
set category = "Abilities"
squeak_soft(1)
/mob/living/simple_animal/mouse/verb/squeak_verb()
set name = "Squeak"
set category = "Abilities"
squeak(1)
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
if( ishuman(AM) )
@@ -151,15 +187,15 @@
var/mob/M = AM
M << "\blue \icon[src] Squeek!"
if (prob(95))
squeak()
squeak(0)
else
squeak_loud()//You trod on its tail
squeak_loud(0)//You trod on its tail
..()
/mob/living/simple_animal/mouse/death()
layer = MOB_LAYER
if (ckey || prob(50))
squeak_loud()//deathgasp
squeak_loud(0)//deathgasp
if(client)
client.time_died_as_mouse = world.time
@@ -13,7 +13,7 @@
var/break_stuff_probability = 10
stop_automated_movement_when_pulled = 0
var/destroy_surroundings = 1
hunger_enabled = 0//Until automated eating mechanics are enabled, disable hunger for hostile mobs
var/shuttletarget = null
var/enroute = 0
@@ -66,6 +66,9 @@
var/supernatural = 0
var/purge = 0
//Hunger/feeding vars
var/hunger_enabled = 1//If set to 0, a creature ignores hunger
var/max_nutrition = 75
var/nutrition_step = 0.2 //nutrition lost per tick and per step, calculated from mob_size, 0.4 is a fallback
var/bite_factor = 0.4
@@ -87,7 +90,7 @@
/mob/living/simple_animal/Move(NewLoc, direct)
. = ..()
if(.)
if(src.nutrition && src.stat != DEAD)
if(src.nutrition && src.stat != DEAD && hunger_enabled)
src.nutrition -= nutrition_step
@@ -101,12 +104,14 @@
/mob/living/simple_animal/examine(mob/user)
..()
if (!nutrition)
user << "<span class='danger'>It looks starving!</span>"
else if (nutrition < max_nutrition *0.5)
user << "<span class='notice'>It looks hungry.</span>"
else if ((reagents.total_volume > 0 && nutrition > max_nutrition *0.75) || nutrition > max_nutrition *0.9)
user << "It looks full and contented."
if (hunger_enabled)
if (!nutrition)
user << "<span class='danger'>It looks starving!</span>"
else if (nutrition < max_nutrition *0.5)
user << "<span class='notice'>It looks hungry.</span>"
else if ((reagents.total_volume > 0 && nutrition > max_nutrition *0.75) || nutrition > max_nutrition *0.9)
user << "It looks full and contented."
/mob/living/simple_animal/Life()
..()
@@ -247,28 +252,28 @@
//This allows animals to digest food, and only food
//Most drugs, poisons etc, are designed to work on carbons and affect many values a simple animal doesnt have
/mob/living/simple_animal/proc/process_food()
if (nutrition)
nutrition -= nutrition_step//Bigger animals get hungry faster
nutrition = max(0,min(nutrition, max_nutrition))//clamp the value
else
if (prob(3))
src << "You feel hungry..."
if (hunger_enabled)
if (nutrition)
nutrition -= nutrition_step//Bigger animals get hungry faster
nutrition = max(0,min(nutrition, max_nutrition))//clamp the value
else
if (prob(3))
src << "You feel hungry..."
if (!reagents || !reagents.total_volume)
return
if (!reagents || !reagents.total_volume)
return
for(var/datum/reagent/current in reagents.reagent_list)
var/removed = min(current.metabolism*digest_factor, current.volume)
if (istype(current, /datum/reagent/nutriment))//If its food, it feeds us
var/datum/reagent/nutriment/N = current
nutrition += removed*N.nutriment_factor
health = min(health+(removed*N.regen_factor), maxHealth)
current.remove_self(removed)//If its not food, it just does nothing. no fancy effects
for(var/datum/reagent/current in reagents.reagent_list)
var/removed = min(current.metabolism*digest_factor, current.volume)
if (istype(current, /datum/reagent/nutriment))//If its food, it feeds us
var/datum/reagent/nutriment/N = current
nutrition += removed*N.nutriment_factor
health = min(health+(removed*N.regen_factor), maxHealth)
current.remove_self(removed)//If its not food, it just does nothing. no fancy effects
/mob/living/simple_animal/proc/can_eat()
if (nutrition > max_nutrition * 0.9)
if (!hunger_enabled || nutrition > max_nutrition * 0.9)
return 0//full
else if ((nutrition > max_nutrition * 0.8) || health < maxHealth)
+3
View File
@@ -931,6 +931,9 @@ proc/is_blind(A)
var/atom/a = src
while (x < 5)
x++
if (isnull(a))
return null
a = a.loc
if (istype(a, /turf))
return null//We must be on a table or a floor, or maybe in a wall. Either way we're not held.