diff --git a/code/controllers/subsystems/throwing.dm b/code/controllers/subsystems/throwing.dm index 4dc2001e17e..0849837efd8 100644 --- a/code/controllers/subsystems/throwing.dm +++ b/code/controllers/subsystems/throwing.dm @@ -33,7 +33,7 @@ SUBSYSTEM_DEF(throwing) continue if (QDELETED(TT)) if(!QDELETED(AM)) - AM.end_throw() + AM.end_throw(TT) processing -= AM if (MC_TICK_CHECK) return @@ -103,7 +103,7 @@ SUBSYSTEM_DEF(throwing) /datum/thrownthing/Destroy() SSthrowing.processing -= thrownthing - thrownthing.end_throw() + thrownthing.end_throw(src) thrownthing = null target = null thrower = null @@ -192,7 +192,7 @@ SUBSYSTEM_DEF(throwing) if(!QDELETED(thrownthing)) thrownthing.fall() - thrownthing.end_throw() + thrownthing.end_throw(src) qdel(src) /datum/thrownthing/proc/hit_atom(atom/A) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index d2be93779da..11366d63dc9 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -563,7 +563,7 @@ appearance_flags &= ~remove_flags return old_appearance != appearance_flags -/atom/movable/proc/end_throw() +/atom/movable/proc/end_throw(datum/thrownthing/TT) throwing = null /atom/movable/proc/reset_movement_delay() diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 9b3eba8970b..1320fd5f0ec 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -468,7 +468,7 @@ return TRUE return ..() -/obj/item/end_throw() +/obj/item/end_throw(datum/thrownthing/TT) . = ..() squash_item() diff --git a/code/modules/mob_holder/_holder.dm b/code/modules/mob_holder/_holder.dm index a462eff5ba0..a16a23e5fe3 100644 --- a/code/modules/mob_holder/_holder.dm +++ b/code/modules/mob_holder/_holder.dm @@ -46,7 +46,8 @@ icon = initial(icon) /obj/item/holder/Exited(atom/movable/am, atom/new_loc) - am.vis_flags = initial(am.vis_flags) + if(!(locate(/mob) in contents)) + am.vis_flags = initial(am.vis_flags) . = ..() /obj/item/holder/proc/destroy_all() @@ -72,15 +73,15 @@ update_state() /obj/item/holder/dropped() - ..() + . = ..() update_state(1) /obj/item/holder/throw_impact(atom/hit_atom, datum/thrownthing/TT) - ..() + . = ..() update_state(1) /obj/item/holder/proc/update_state(var/delay) - set waitfor = 0 + set waitfor = FALSE for(var/mob/M in contents) unregister_all_movement(last_holder, M) @@ -97,11 +98,13 @@ mob_container.dropInto(loc) M.reset_view() qdel(src) - else if(last_holder != loc) + return + + if(last_holder != loc) for(var/mob/M in contents) register_all_movement(loc, M) update_icon() - last_holder = loc + last_holder = loc /obj/item/holder/onDropInto(var/atom/movable/AM) if(ismob(loc)) // Bypass our holding mob and drop directly to its loc diff --git a/mods/pyrelight/_pyrelight.dme b/mods/pyrelight/_pyrelight.dme index 8310c9ab456..caa6a547399 100644 --- a/mods/pyrelight/_pyrelight.dme +++ b/mods/pyrelight/_pyrelight.dme @@ -12,6 +12,10 @@ #include "datum\factions.dm" #include "datum\locations.dm" #include "datum\religions.dm" +#include "mobs\birds\_bird.dm" +#include "mobs\birds\crow.dm" +#include "mobs\birds\hawk.dm" +#include "mobs\birds\pigeon.dm" #include "plants\_plants.dm" #include "plants\_plot.dm" #include "plants\_subsystem.dm" @@ -20,6 +24,8 @@ #include "plants\plants_fruit_template.dm" #include "plants\fruit_subtypes\nightweave.dm" #include "plants\plant_subtypes\nightweave.dm" +#include "structures\aviary.dm" +#include "undead\_undead.dm" #include "undead\undead.dm" #include "undead\undead_skeleton.dm" #include "undead\undead_zombie.dm" diff --git a/mods/pyrelight/icons/mobs/crow.dmi b/mods/pyrelight/icons/mobs/crow.dmi new file mode 100644 index 00000000000..0159a677fd1 Binary files /dev/null and b/mods/pyrelight/icons/mobs/crow.dmi differ diff --git a/mods/pyrelight/icons/mobs/hawk.dmi b/mods/pyrelight/icons/mobs/hawk.dmi new file mode 100644 index 00000000000..022401dcf06 Binary files /dev/null and b/mods/pyrelight/icons/mobs/hawk.dmi differ diff --git a/mods/pyrelight/icons/mobs/pigeon.dmi b/mods/pyrelight/icons/mobs/pigeon.dmi new file mode 100644 index 00000000000..b7b9184568f Binary files /dev/null and b/mods/pyrelight/icons/mobs/pigeon.dmi differ diff --git a/mods/pyrelight/icons/structures/aviary.dmi b/mods/pyrelight/icons/structures/aviary.dmi new file mode 100644 index 00000000000..8ba4c4443f9 Binary files /dev/null and b/mods/pyrelight/icons/structures/aviary.dmi differ diff --git a/mods/pyrelight/icons/structures/hutch.dmi b/mods/pyrelight/icons/structures/hutch.dmi new file mode 100644 index 00000000000..8d5f7e2165b Binary files /dev/null and b/mods/pyrelight/icons/structures/hutch.dmi differ diff --git a/mods/pyrelight/mobs/birds/_bird.dm b/mods/pyrelight/mobs/birds/_bird.dm new file mode 100644 index 00000000000..1363d3b9de8 --- /dev/null +++ b/mods/pyrelight/mobs/birds/_bird.dm @@ -0,0 +1,38 @@ +/mob/living/simple_animal/trained_bird + mob_size = MOB_SIZE_SMALL + abstract_type = /mob/living/simple_animal/trained_bird + holder_type = /obj/item/holder/bird + +/mob/living/simple_animal/trained_bird/proc/handle_holder_interaction(mob/user) + return FALSE + +/mob/living/simple_animal/trained_bird/proc/process_target(mob/thrower, atom/target) + visible_message("\The [src] follows [thrower]'s directions and attacks [target]!") + return FALSE + +/mob/living/simple_animal/trained_bird/proc/process_handler_failure(mob/thrower, atom/target) + visible_message("\The [src] ignores [target] in favour of attacking [thrower]!") + return FALSE + +/obj/item/holder/bird + w_class = MOB_SIZE_SMALL + +/obj/item/holder/bird/attack_self(mob/user) + var/mob/living/simple_animal/trained_bird/bird = locate() in contents + if(bird?.handle_holder_interaction(user)) + return TRUE + return ..() + +/obj/item/holder/bird/end_throw(datum/thrownthing/TT) + var/mob/living/simple_animal/trained_bird/bird = locate() in contents + . = ..() + if(!TT.thrower || !bird || QDELETED(src) || bird.loc != src) + return + bird.dropInto(loc) + qdel(src) // This will happen shortly regardless, but might as well skip the 1ds delay. + bird.visible_message("\The [bird] was thrown by \the [TT.thrower] at \the [TT.target].") + if(bird.ai) + if(bird.ai.is_friend(TT.thrower)) + bird.process_target(TT.thrower, TT.target) + else + bird.process_handler_failure(TT.thrower, TT.target) diff --git a/mods/pyrelight/mobs/birds/crow.dm b/mods/pyrelight/mobs/birds/crow.dm new file mode 100644 index 00000000000..ca3d3068563 --- /dev/null +++ b/mods/pyrelight/mobs/birds/crow.dm @@ -0,0 +1,9 @@ +/datum/mob_controller/passive/crow + emote_speech = list("Caw.","Caw!","Caw...") + emote_hear = list("croaks", "caws") + emote_see = list("preens its feathers", "hops around") + +/mob/living/simple_animal/trained_bird/crow + name = "crow" + icon = 'mods/pyrelight/icons/mobs/crow.dmi' + ai = /datum/mob_controller/passive/crow diff --git a/mods/pyrelight/mobs/birds/hawk.dm b/mods/pyrelight/mobs/birds/hawk.dm new file mode 100644 index 00000000000..4564b51eedd --- /dev/null +++ b/mods/pyrelight/mobs/birds/hawk.dm @@ -0,0 +1,16 @@ +/mob/living/simple_animal/trained_bird/hawk + name = "hawk" + icon = 'mods/pyrelight/icons/mobs/hawk.dmi' + ai = /datum/mob_controller/passive/hunter/hawk + +/datum/mob_controller/passive/hunter/hawk + emote_speech = list("Skree!","SKREE!","Skree!?") + emote_hear = list("screeches", "screams") + emote_see = list("preens its feathers", "flicks its wings", "looks sharply around") + +// Throw bird at target/afterattack on holder: + // Pass husbandry check + // Item: retrieves + // Mob: attacks + // Fail husbandry check + // Attacks you (for a short time, like goats) diff --git a/mods/pyrelight/mobs/birds/pigeon.dm b/mods/pyrelight/mobs/birds/pigeon.dm new file mode 100644 index 00000000000..ff8a2f1cbe8 --- /dev/null +++ b/mods/pyrelight/mobs/birds/pigeon.dm @@ -0,0 +1,9 @@ +/mob/living/simple_animal/trained_bird/pigeon + name = "pigeon" + icon = 'mods/pyrelight/icons/mobs/pigeon.dmi' + ai = /datum/mob_controller/passive/pigeon + +/datum/mob_controller/passive/pigeon + emote_speech = list("Oo-ooo.","Oo-ooo?","Oo-ooo...") + emote_hear = list("coos") + emote_see = list("preens its feathers", "puffs out its neck", "ruffles its wings") diff --git a/mods/pyrelight/structures/aviary.dm b/mods/pyrelight/structures/aviary.dm new file mode 100644 index 00000000000..504d1ac1f7c --- /dev/null +++ b/mods/pyrelight/structures/aviary.dm @@ -0,0 +1,73 @@ +/datum/storage/aviary + can_hold = list(/obj/item/holder/bird) + max_w_class = MOB_SIZE_SMALL + storage_slots = 10 + +/datum/storage/aviary/open(mob/user) + . = ..() + var/atom/aviary = holder + if(istype(aviary)) + aviary.queue_icon_update() + +/datum/storage/aviary/close(mob/user) + . = ..() + var/atom/aviary = holder + if(istype(aviary)) + aviary.queue_icon_update() + +/obj/structure/aviary + name = "aviary" + desc = "A hutch for containing birds like hawks or crows." + icon = 'mods/pyrelight/icons/structures/aviary.dmi' + icon_state = ICON_STATE_WORLD + material = /decl/material/solid/organic/wood + storage = /datum/storage/aviary + var/decl/material/door_material = /decl/material/solid/organic/plantmatter/grass/dry + var/initial_animal_type + var/initial_animal_count + +/obj/structure/aviary/Initialize(ml, _mat, _reinf_mat) + . = ..() + + if(ispath(door_material)) + door_material = GET_DECL(door_material) + + if(initial_animal_type && initial_animal_count) + for(var/i = 1 to initial_animal_count) + var/obj/item/holder/bird/bird_item = new(src) + var/bird_type = islist(initial_animal_type) ? pick(initial_animal_type) : initial_animal_type + bird_item.sync(new bird_type(bird_item)) + else + update_icon() + +/obj/structure/aviary/on_update_icon() + . = ..() + if(door_material) + add_overlay(overlay_image(icon, "[icon_state]-doors-[storage?.opened ? "open" : "closed"]", door_material.color, RESET_COLOR)) + +// Mapped subtypes. +/obj/structure/aviary/crow + initial_animal_type = /mob/living/simple_animal/trained_bird/crow + initial_animal_count = 5 + +/obj/structure/aviary/pigeon + initial_animal_type = /mob/living/simple_animal/trained_bird/pigeon + initial_animal_count = 5 + +/obj/structure/aviary/hawk + initial_animal_type = /mob/living/simple_animal/trained_bird/hawk + initial_animal_count = 5 + +// Rabbits are a kind of bird, right? +/obj/structure/aviary/rabbit + name = "rabbit hutch" + icon = 'mods/pyrelight/icons/structures/hutch.dmi' + desc = "A hutch for containing rabbits." + +/obj/structure/aviary/rabbit/mapped + initial_animal_type = list( + /mob/living/simple_animal/passive/rabbit, + /mob/living/simple_animal/passive/rabbit/black, + /mob/living/simple_animal/passive/rabbit/brown + ) + initial_animal_count = 5