mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-12 16:37:19 +01:00
Held Mob Fixes (#691)
changes: bugfix: "Animals climbing onto people will now show a different, correct message, instead of the scooped one" bugfix: "Fixed an issue where a held animal could be duplicated" bugfix: "Fixed animals bugging out when placed in crates or unworn containers" Also removes some unnecessary scooping code from a few animals, which already exists in the parent class
This commit is contained in:
+48
-78
@@ -12,10 +12,6 @@
|
||||
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
|
||||
var/checkverb
|
||||
|
||||
/obj/item/weapon/holder/New()
|
||||
if (!item_state)
|
||||
item_state = icon_state
|
||||
@@ -29,52 +25,42 @@
|
||||
|
||||
/obj/item/weapon/holder/process()
|
||||
|
||||
if (!(istype(loc,/obj/item/weapon/storage)))//Mobs bug out if placed directly into a container
|
||||
if(!get_holding_mob())
|
||||
|
||||
for(var/mob/M in contents)
|
||||
|
||||
var/atom/movable/mob_container
|
||||
mob_container = M
|
||||
mob_container.loc = src.loc//if the holder was placed into a disposal, this should place the animal in the disposal
|
||||
M.reset_view()
|
||||
M.verbs -= /mob/living/proc/get_holder_location
|
||||
qdel(src)
|
||||
if(!get_holding_mob() || contained.loc != src)
|
||||
if (is_unsafe_container(loc) && contained.loc == src)
|
||||
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()
|
||||
|
||||
var/mob/L = get_holding_mob()
|
||||
if (L)
|
||||
L.drop_from_inventory(src)
|
||||
|
||||
qdel(src)
|
||||
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
|
||||
|
||||
|
||||
//This function checks if the current location is safe to release inside
|
||||
//it returns 1 if the creature will bug out when released
|
||||
/obj/item/weapon/holder/proc/is_unsafe_container(var/obj/place)
|
||||
if (istype(place, /obj/item/weapon/storage))
|
||||
return 1
|
||||
else if (istype(place, /obj/structure/closet/crate))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
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))
|
||||
@@ -121,51 +107,34 @@
|
||||
//update_icon()
|
||||
|
||||
|
||||
/mob/living/proc/get_scooped(var/mob/living/carbon/grabber)
|
||||
if(!holder_type || buckled || pinned.len)
|
||||
/mob/living/proc/get_scooped(var/mob/living/carbon/grabber, var/mob/user = null)
|
||||
if(!holder_type || buckled || pinned.len || !Adjacent(grabber))
|
||||
return
|
||||
|
||||
if ((grabber.hand == 0 && grabber.r_hand) || (grabber.hand == 1 && grabber.l_hand))//Checking if the hand is full
|
||||
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
|
||||
|
||||
spawn(2)
|
||||
var/obj/item/weapon/holder/H = new holder_type(loc)
|
||||
src.loc = H
|
||||
H.name = loc.name
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
grabber << "You scoop up [src]."
|
||||
src << "[grabber] scoops you up."
|
||||
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)
|
||||
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
|
||||
|
||||
//Mob specific holders.
|
||||
//w_class mainly determines whether they can fit in trashbags. <=2 can, >=3 cannot
|
||||
@@ -262,6 +231,7 @@
|
||||
origin_tech = "biotech=2"
|
||||
w_class = 1
|
||||
|
||||
|
||||
/obj/item/weapon/holder/mouse/white
|
||||
icon_state = "mouse_white"
|
||||
icon_state_dead = "mouse_white_dead"
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
var/mob/living/carbon/H = over_object
|
||||
if(!istype(H) || !Adjacent(H))
|
||||
return ..()
|
||||
get_scooped(H)
|
||||
get_scooped(H, usr)
|
||||
return
|
||||
|
||||
@@ -129,16 +129,6 @@
|
||||
. = ..()
|
||||
set_flee_target(AM.thrower? AM.thrower : src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/MouseDrop(atom/over_object)
|
||||
|
||||
var/mob/living/carbon/H = over_object
|
||||
if(!istype(H) || !Adjacent(H)) return ..()
|
||||
|
||||
if(H.a_intent == "help")
|
||||
get_scooped(H)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
//Basic friend AI
|
||||
/mob/living/simple_animal/cat/fluff
|
||||
|
||||
@@ -156,17 +156,6 @@
|
||||
squeak_loud()//You trod on its tail
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/mouse/MouseDrop(atom/over_object)
|
||||
|
||||
var/mob/living/carbon/H = over_object
|
||||
if(!istype(H) || !Adjacent(H)) return ..()
|
||||
|
||||
if(H.a_intent == "help")
|
||||
get_scooped(H)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/mouse/death()
|
||||
layer = MOB_LAYER
|
||||
if (ckey || prob(50))
|
||||
|
||||
@@ -490,6 +490,6 @@
|
||||
if(!istype(H) || !Adjacent(H))
|
||||
return ..()
|
||||
|
||||
get_scooped(H)
|
||||
get_scooped(H, usr)
|
||||
return
|
||||
return ..()
|
||||
Reference in New Issue
Block a user