diff --git a/code/_helpers/unsorted_vr.dm b/code/_helpers/unsorted_vr.dm new file mode 100644 index 0000000000..e9b5f86f0b --- /dev/null +++ b/code/_helpers/unsorted_vr.dm @@ -0,0 +1,10 @@ +/* + get_holder_at_turf_level(): Similar to get_turf(), will return the "highest up" holder of this atom, excluding the turf. + Example: A fork inside a box inside a locker will return the locker. Essentially, get_just_before_turf(). +*/ //Credit to /vg/ +/proc/get_holder_at_turf_level(const/atom/movable/O) + if(!istype(O)) //atom/movable does not include areas + return + var/atom/A + for(A=O, A && !isturf(A.loc), A=A.loc); // semicolon is for the empty statement + return A \ No newline at end of file diff --git a/code/game/objects/mob_spawner_vr.dm b/code/game/objects/mob_spawner_vr.dm new file mode 100644 index 0000000000..c1d0ba1ec1 --- /dev/null +++ b/code/game/objects/mob_spawner_vr.dm @@ -0,0 +1,105 @@ +/obj/structure/mob_spawner + name = "mob spawner" + desc = "This shouldn't be seen, yell at a dev." + icon = 'icons/effects/effects.dmi' + icon_state = "rift" + anchored = 1 + + var/last_spawn = 0 + var/spawn_delay = 10 MINUTES + + var/list/spawn_types = list( + /mob/living/simple_animal/corgi = 100, + /mob/living/simple_animal/cat = 25 + ) + + var/total_spawns = -1 //Total mob spawns, over all time, -1 for no limit + var/simultaneous_spawns = 3 //Max spawned mobs active at one time + var/mob_faction + + var/destructable = 0 + var/health = 50 + + var/list/spawned_mobs = list() + +/obj/structure/mob_spawner/initialize() + ..() + processing_objects.Add(src) + last_spawn = world.time + rand(0,spawn_delay) + +/obj/structure/mob_spawner/Destroy() + processing_objects.Remove(src) + for(var/mob/living/L in spawned_mobs) + L.source_spawner = null + spawned_mobs.Cut() + return ..() + +/obj/structure/mob_spawner/process() + if(!can_spawn()) + return + var/chosen_mob = choose_spawn() + if(chosen_mob) + do_spawn(chosen_mob) + +/obj/structure/mob_spawner/proc/can_spawn() + if(!total_spawns) + return 0 + if(spawned_mobs.len >= simultaneous_spawns) + return 0 + if(world.time < last_spawn + spawn_delay) + return 0 + return 1 + +/obj/structure/mob_spawner/proc/choose_spawn() + return pickweight(spawn_types) + +/obj/structure/mob_spawner/proc/do_spawn(var/mob_path) + if(!ispath(mob_path)) + return 0 + var/mob/living/L = new mob_path(get_turf(src)) + L.source_spawner = src + spawned_mobs.Add(L) + last_spawn = world.time + if(total_spawns > 0) + total_spawns-- + if(mob_faction) + L.faction = mob_faction + return L + +/obj/structure/mob_spawner/proc/get_death_report(var/mob/living/L) + if(L in spawned_mobs) + spawned_mobs.Remove(L) + +/obj/structure/mob_spawner/attackby(var/obj/item/I, var/mob/living/user) + if(!I.force || I.flags & NOBLUDGEON || !destructable) + return + + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + user.do_attack_animation(src) + visible_message("\The [src] has been [I.attack_verb.len ? "[pick(I.attack_verb)]":"attacked"] with \the [I] by [user].") + take_damage(I.force) + +/obj/structure/mob_spawner/bullet_act(var/obj/item/projectile/Proj) + ..() + take_damage(Proj.get_structure_damage()) + +/obj/structure/mob_spawner/proc/take_damage(var/damage) + health -= damage + if(health <= 0) + visible_message("\The [src] breaks apart!") + qdel(src) + +/obj/structure/mob_spawner/clear_zlevel/can_spawn() + if(!..()) + return 0 + var/turf/T = get_turf(src) + if(!T) + return 0 + for(var/mob/living/L in player_list) + var/turf/L_T + if(L.stat == DEAD) + continue + L_T = get_turf(L) + if(T.z == L_T.z) + return 0 + return 1 \ No newline at end of file diff --git a/code/game/objects/structures/trash_pile.dm b/code/game/objects/structures/trash_pile.dm index f4a7d146d2..7f3a6792b2 100644 --- a/code/game/objects/structures/trash_pile.dm +++ b/code/game/objects/structures/trash_pile.dm @@ -9,6 +9,8 @@ var/list/searchedby = list()// Characters that have searched this trashpile, with values of searched time. var/mob/living/hider // A simple animal that might be hiding in the pile + var/obj/structure/mob_spawner/mouse_nest/mouse_nest = null + var/chance_alpha = 79 // Alpha list is junk items and normal random stuff. var/chance_beta = 20 // Beta list is actually maybe some useful illegal items. If it's not alpha or gamma, it's beta. var/chance_gamma = 1 // Gamma list is unique items only, and will only spawn one of each. This is a sub-chance of beta chance. @@ -40,6 +42,12 @@ "boxfort", "trashbag", "brokecomp") + mouse_nest = new(src) + +/obj/structure/trash_pile/Destroy() + qdel(mouse_nest) + mouse_nest = null + return ..() /obj/structure/trash_pile/attackby(obj/item/W as obj, mob/user as mob) var/w_type = W.type @@ -252,3 +260,30 @@ else return produce_beta_item() +/obj/structure/mob_spawner/mouse_nest + name = "trash" + desc = "A small heap of trash, perfect for mice to nest in." + icon = 'icons/obj/trash_piles.dmi' + icon_state = "randompile" + spawn_types = list(/mob/living/simple_animal/mouse) + simultaneous_spawns = 2 + +/obj/structure/mob_spawner/mouse_nest/initialize() + ..() + icon_state = pick( + "pile1", + "pile2", + "pilechair", + "piletable", + "pilevending", + "brtrashpile", + "microwavepile", + "rackpile", + "boxfort", + "trashbag", + "brokecomp") + +/obj/structure/mob_spawner/mouse_nest/do_spawn(var/mob_path) + . = ..() + var/atom/A = get_holder_at_turf_level(src) + A.visible_message("[.] crawls out of \the [src].") \ No newline at end of file diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index d6c2bc0405..9ea12b967c 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -1,3 +1,8 @@ /mob/living/death() clear_fullscreens() + //VOREStation Edit - Mob spawner stuff + if(source_spawner) + source_spawner.get_death_report(src) + source_spawner = null + //VOREStation Edit End . = ..() \ No newline at end of file diff --git a/code/modules/mob/living/living_defines_vr.dm b/code/modules/mob/living/living_defines_vr.dm index 566c21dad8..8b463df93b 100644 --- a/code/modules/mob/living/living_defines_vr.dm +++ b/code/modules/mob/living/living_defines_vr.dm @@ -1,2 +1,3 @@ /mob/living - var/ooc_notes = null \ No newline at end of file + var/ooc_notes = null + var/obj/structure/mob_spawner/source_spawner = null \ No newline at end of file diff --git a/vorestation.dme b/vorestation.dme index b0ac82c068..b36a95c38d 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -84,6 +84,7 @@ #include "code\_helpers\type2type.dm" #include "code\_helpers\type2type_vr.dm" #include "code\_helpers\unsorted.dm" +#include "code\_helpers\unsorted_vr.dm" #include "code\_helpers\vector.dm" #include "code\_helpers\sorts\__main.dm" #include "code\_helpers\sorts\comparators.dm" @@ -783,6 +784,7 @@ #include "code\game\objects\explosion.dm" #include "code\game\objects\explosion_recursive.dm" #include "code\game\objects\items.dm" +#include "code\game\objects\mob_spawner_vr.dm" #include "code\game\objects\objs.dm" #include "code\game\objects\structures.dm" #include "code\game\objects\stumble_into_vr.dm"