mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
basic gutlunchers and ashwalker ranching (#79508)
## About The Pull Request this pr transforms gutlunchers into basic mobs and gives them a small ranch that ashwalkers can manage. gutlunches come in various colors and sizes! female gutlunches will come in different shades of red and males will come in shades of blue. the child born will have a mix of his parent's colors.  female gutlunches can make various healing milk and medicine from its udder. but it will need to consume ores before it can start making milk, u can either feed it by hand or u can put ores in the wooden trough and they will go eat from it whenever they get hungry. feeding it gold or bluespace ore will improve the healing quality of the milk for a short while  the male gutlunchers are obedient pets. their stats vary from one another in speed, attack and health. a male gutlunchers stats will depend on the stats of his parents, the higher his parent's stats are the better chances he has at rolling higher stats. so u can selectively breed them to make sure they have the best stats possible. they will listen to all ur commands and can mine walls or attack enemies if given the command. also i wanted the farm to have wood fences so i added them to the game, they cost 5 wood planks to make ## Why It's Good For The Game refactors gutlunches into basic mobs. also i turned breeding into a component so it can be applied to all animals and created a breed command, pets that have this command and the component will go breed with a partner u point at. ## Changelog 🆑 refactor: gutlunches have been refactored into basic mobs. please report any bugs add: ashwalkers have a small ranch they can manage fix: wall tearer compnent wont runtime when interacting with mineral walls /🆑
This commit is contained in:
@@ -61,10 +61,11 @@
|
||||
/turf/closed/indestructible/riveted/boss,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"al" = (
|
||||
/obj/structure/stone_tile/surrounding_tile{
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/wooden_fence{
|
||||
dir = 1
|
||||
},
|
||||
/turf/closed/mineral/volcanic/lava_land_surface,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"aq" = (
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
@@ -76,13 +77,11 @@
|
||||
/turf/closed/mineral/volcanic/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"ar" = (
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
dir = 4
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/wooden_fence{
|
||||
dir = 9
|
||||
},
|
||||
/obj/structure/stone_tile{
|
||||
dir = 4
|
||||
},
|
||||
/turf/closed/mineral/volcanic/lava_land_surface,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"as" = (
|
||||
/turf/closed/wall/mineral/wood,
|
||||
@@ -155,12 +154,6 @@
|
||||
/obj/item/flashlight/flare/torch,
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"az" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 4
|
||||
},
|
||||
/turf/closed/mineral/volcanic/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"aF" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 8
|
||||
@@ -213,7 +206,7 @@
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/stone_tile,
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck,
|
||||
/mob/living/basic/mining/gutlunch/milk,
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"aR" = (
|
||||
@@ -287,7 +280,7 @@
|
||||
/obj/structure/stone_tile{
|
||||
dir = 4
|
||||
},
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen,
|
||||
/mob/living/basic/mining/gutlunch/warrior,
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"bd" = (
|
||||
@@ -331,13 +324,11 @@
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"bh" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 4
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/wooden_fence{
|
||||
dir = 5
|
||||
},
|
||||
/obj/structure/stone_tile{
|
||||
dir = 8
|
||||
},
|
||||
/turf/closed/mineral/volcanic/lava_land_surface,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"bi" = (
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
@@ -520,15 +511,16 @@
|
||||
/turf/closed/mineral/volcanic/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"bJ" = (
|
||||
/obj/structure/stone_tile/surrounding_tile,
|
||||
/turf/closed/mineral/volcanic/lava_land_surface,
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/mob/living/basic/mining/gutlunch/milk,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"cp" = (
|
||||
/obj/structure/stone_tile/cracked,
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 1
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/wooden_fence{
|
||||
dir = 8
|
||||
},
|
||||
/turf/closed/mineral/volcanic/lava_land_surface,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"cF" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
@@ -687,6 +679,12 @@
|
||||
/obj/item/flashlight/flare/torch,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"fM" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/mob/living/basic/mining/gutlunch/warrior,
|
||||
/obj/item/flashlight/lantern,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"gi" = (
|
||||
/obj/structure/table/optable,
|
||||
/obj/structure/stone_tile{
|
||||
@@ -758,6 +756,10 @@
|
||||
/obj/effect/decal/cleanable/blood,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"mo" = (
|
||||
/obj/structure/stone_tile/block,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"mp" = (
|
||||
/obj/structure/stone_tile/surrounding/cracked,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
@@ -808,6 +810,16 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"qm" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"qn" = (
|
||||
/obj/item/storage/box/rxglasses,
|
||||
/obj/structure/stone_tile{
|
||||
@@ -821,6 +833,11 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"qH" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/wooden_fence,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"qV" = (
|
||||
/obj/structure/stone_tile/surrounding_tile{
|
||||
dir = 8
|
||||
@@ -882,6 +899,16 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"sz" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"ty" = (
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"tY" = (
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
dir = 1
|
||||
@@ -924,6 +951,13 @@
|
||||
/obj/item/flashlight/flare/torch,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"vV" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/wooden_fence{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"wB" = (
|
||||
/obj/structure/stone_tile/block,
|
||||
/obj/structure/stone_tile{
|
||||
@@ -1047,6 +1081,14 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Dz" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/stone_tile{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/stone_tile,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Ee" = (
|
||||
/obj/structure/stone_tile/block/cracked,
|
||||
/obj/structure/stone_tile{
|
||||
@@ -1119,9 +1161,16 @@
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/ash_walkers)
|
||||
"GW" = (
|
||||
/obj/structure/stone_tile/surrounding_tile{
|
||||
dir = 8
|
||||
/obj/structure/stone_tile/cracked{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/closet/crate/internals,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
@@ -1177,6 +1226,18 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"JD" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/ore_container/gutlunch_trough,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Kg" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/wooden_fence{
|
||||
dir = 10
|
||||
},
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Kt" = (
|
||||
/obj/structure/water_source/puddle{
|
||||
pixel_x = -3;
|
||||
@@ -1185,6 +1246,12 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"KQ" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/reagent_containers/cup/bucket/wooden,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"KR" = (
|
||||
/obj/structure/stone_tile/block/cracked,
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
@@ -1248,9 +1315,10 @@
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Oe" = (
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked,
|
||||
/obj/structure/ore_box,
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/stone_tile{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"OY" = (
|
||||
@@ -1258,6 +1326,29 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Pk" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/corner/end/wooden_fence,
|
||||
/obj/structure/railing/corner/end/flip/wooden_fence,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"PA" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/mob/living/basic/mining/gutlunch/warrior,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"PK" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/stone_tile,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Rq" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/railing/wooden_fence{
|
||||
dir = 6
|
||||
},
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"RE" = (
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
dir = 1
|
||||
@@ -1302,6 +1393,12 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Tl" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/flashlight/lantern,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Tr" = (
|
||||
/obj/machinery/hydroponics/soil,
|
||||
/obj/structure/stone_tile/block{
|
||||
@@ -1310,6 +1407,11 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"TC" = (
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/item/flashlight/lantern,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"TO" = (
|
||||
/obj/structure/stone_tile{
|
||||
dir = 4
|
||||
@@ -1337,17 +1439,8 @@
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Uh" = (
|
||||
/obj/structure/stone_tile/cracked{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/closet/crate/internals,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/pickaxe,
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/obj/structure/stone_tile/block,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"UI" = (
|
||||
@@ -1384,6 +1477,12 @@
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Zr" = (
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked,
|
||||
/obj/structure/ore_box,
|
||||
/obj/effect/mapping_helpers/no_lava,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
|
||||
(1,1,1) = {"
|
||||
aa
|
||||
@@ -1639,8 +1738,8 @@ ak
|
||||
ak
|
||||
ak
|
||||
IS
|
||||
RH
|
||||
Aj
|
||||
Gv
|
||||
ty
|
||||
Nv
|
||||
Kt
|
||||
du
|
||||
@@ -1770,10 +1869,10 @@ ak
|
||||
ak
|
||||
ak
|
||||
ak
|
||||
KR
|
||||
Aj
|
||||
eu
|
||||
ah
|
||||
Zr
|
||||
Gv
|
||||
qm
|
||||
Gv
|
||||
as
|
||||
mm
|
||||
cF
|
||||
@@ -1793,9 +1892,9 @@ ak
|
||||
ak
|
||||
bI
|
||||
Oe
|
||||
Uh
|
||||
ah
|
||||
cp
|
||||
Gv
|
||||
qm
|
||||
Gv
|
||||
as
|
||||
as
|
||||
as
|
||||
@@ -1804,20 +1903,20 @@ ak
|
||||
cQ
|
||||
"}
|
||||
(20,1,1) = {"
|
||||
aa
|
||||
al
|
||||
ar
|
||||
az
|
||||
az
|
||||
az
|
||||
bh
|
||||
az
|
||||
bC
|
||||
bJ
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
al
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Dz
|
||||
qm
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
bC
|
||||
@@ -1825,3 +1924,289 @@ ah
|
||||
ah
|
||||
cR
|
||||
"}
|
||||
(21,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
ar
|
||||
cp
|
||||
cp
|
||||
cp
|
||||
cp
|
||||
cp
|
||||
Kg
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
qm
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
"}
|
||||
(22,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
fM
|
||||
Gv
|
||||
Gv
|
||||
TC
|
||||
Gv
|
||||
qH
|
||||
KQ
|
||||
Gv
|
||||
Gv
|
||||
qm
|
||||
Gv
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
"}
|
||||
(23,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
PA
|
||||
qH
|
||||
KQ
|
||||
Gv
|
||||
Gv
|
||||
qm
|
||||
Gv
|
||||
PK
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
"}
|
||||
(24,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
Gv
|
||||
bJ
|
||||
bJ
|
||||
Gv
|
||||
Gv
|
||||
qH
|
||||
Tl
|
||||
Gv
|
||||
Gv
|
||||
qm
|
||||
sz
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
"}
|
||||
(25,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
bJ
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
qH
|
||||
Gv
|
||||
sz
|
||||
sz
|
||||
qm
|
||||
Gv
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
"}
|
||||
(26,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
Gv
|
||||
bJ
|
||||
bJ
|
||||
Gv
|
||||
Gv
|
||||
Pk
|
||||
sz
|
||||
Gv
|
||||
Oe
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(27,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
Gv
|
||||
Gv
|
||||
TC
|
||||
Gv
|
||||
Gv
|
||||
qH
|
||||
Gv
|
||||
Dz
|
||||
Oe
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(28,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
Gv
|
||||
JD
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
qH
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Dz
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(29,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
PA
|
||||
qH
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(30,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
al
|
||||
TC
|
||||
Gv
|
||||
PA
|
||||
Gv
|
||||
TC
|
||||
qH
|
||||
Gv
|
||||
mo
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(31,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
bh
|
||||
vV
|
||||
vV
|
||||
vV
|
||||
vV
|
||||
vV
|
||||
Rq
|
||||
Uh
|
||||
ty
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(32,1,1) = {"
|
||||
ah
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
Gv
|
||||
ty
|
||||
ah
|
||||
ah
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(33,1,1) = {"
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"p" = (
|
||||
/obj/structure/material_stand,
|
||||
/obj/structure/ore_container/material_stand,
|
||||
/turf/open/misc/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"q" = (
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
/turf/open/floor/fakebasalt,
|
||||
/area/centcom/basketball)
|
||||
"ie" = (
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen,
|
||||
/mob/living/basic/mining/gutlunch/warrior,
|
||||
/turf/open/floor/fakebasalt,
|
||||
/area/centcom/basketball)
|
||||
"ix" = (
|
||||
@@ -609,7 +609,7 @@
|
||||
/turf/open/lava/smooth/basketball,
|
||||
/area/centcom/basketball)
|
||||
"Fy" = (
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck,
|
||||
/mob/living/basic/mining/gutlunch/milk,
|
||||
/turf/open/floor/fakebasalt,
|
||||
/area/centcom/basketball)
|
||||
"FS" = (
|
||||
|
||||
@@ -33902,7 +33902,7 @@
|
||||
/turf/open/floor/plating/snowed/smoothed/icemoon,
|
||||
/area/icemoon/underground/explored)
|
||||
"ksu" = (
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch,
|
||||
/mob/living/basic/mining/gutlunch/warrior,
|
||||
/turf/open/misc/asteroid/snow/icemoon,
|
||||
/area/icemoon/underground/explored)
|
||||
"ksC" = (
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
#define BB_PATH_TO_USE "BB_path_to_use"
|
||||
///How close a mob must be for us to select it as a target, if that is less than how far we can maintain it as a target
|
||||
#define BB_AGGRO_RANGE "BB_aggro_range"
|
||||
///are we hungry? determined by the udder compnent
|
||||
#define BB_CHECK_HUNGRY "BB_check_hungry"
|
||||
///are we ready to breed?
|
||||
#define BB_BREED_READY "BB_breed_ready"
|
||||
///maximum kids we can have
|
||||
#define BB_MAX_CHILDREN "BB_max_children"
|
||||
|
||||
/// Store a single or list of emotes at this key
|
||||
#define BB_EMOTE_KEY "BB_emotes"
|
||||
|
||||
@@ -190,6 +190,9 @@
|
||||
/// the bonfire we will light up
|
||||
#define BB_MOOK_BONFIRE_TARGET "bonfire_target"
|
||||
|
||||
//gutlunch keys
|
||||
///the trough we will eat from
|
||||
#define BB_TROUGH_TARGET "trough_target"
|
||||
//leaper keys
|
||||
///key holds our volley ability
|
||||
#define BB_LEAPER_VOLLEY "leaper_volley"
|
||||
|
||||
@@ -1352,5 +1352,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
/// Trait given to a dragon who fails to defend their rifts
|
||||
#define TRAIT_RIFT_FAILURE "fail_dragon_loser"
|
||||
|
||||
///trait determines if this mob can breed given by /datum/component/breeding
|
||||
#define TRAIT_MOB_BREEDER "mob_breeder"
|
||||
/// Trait given to mobs that we do not want to mindswap
|
||||
#define TRAIT_NO_MINDSWAP "no_mindswap"
|
||||
|
||||
@@ -2,74 +2,77 @@
|
||||
* Find a compatible, living partner, if we're also alone.
|
||||
*/
|
||||
/datum/ai_behavior/find_partner
|
||||
action_cooldown = 40 SECONDS
|
||||
|
||||
/// Range to look.
|
||||
var/range = 7
|
||||
|
||||
/// Maximum number of children
|
||||
var/max_children = 3
|
||||
|
||||
/datum/ai_behavior/find_partner/perform(seconds_per_tick, datum/ai_controller/controller, target_key, partner_types_key, child_types_key)
|
||||
. = ..()
|
||||
|
||||
max_children = controller.blackboard[BB_MAX_CHILDREN] || max_children
|
||||
var/mob/pawn_mob = controller.pawn
|
||||
var/list/partner_types = controller.blackboard[partner_types_key]
|
||||
var/list/child_types = controller.blackboard[child_types_key]
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
|
||||
var/mob/living/partner
|
||||
var/children = 0
|
||||
for(var/mob/other in oview(range, pawn_mob))
|
||||
if(other.stat != CONSCIOUS) //Check if it's conscious FIRST.
|
||||
continue
|
||||
var/is_child = is_type_in_list(other, child_types)
|
||||
if(is_child) //Check for children SECOND.
|
||||
children++
|
||||
else if(is_type_in_list(other, partner_types))
|
||||
if(other.ckey)
|
||||
continue
|
||||
else if(!is_child && other.gender == MALE && !(other.flags_1 & HOLOGRAM_1)) //Better safe than sorry ;_;
|
||||
partner = other
|
||||
|
||||
//shyness check. we're not shy in front of things that share a faction with us.
|
||||
else if(isliving(other) && !pawn_mob.faction_check_atom(other))
|
||||
for(var/mob/living/other in oview(range, pawn_mob))
|
||||
if(!pawn_mob.faction_check_atom(other))
|
||||
finish_action(controller, FALSE)
|
||||
return
|
||||
|
||||
if(partner && children < max_children)
|
||||
controller.set_blackboard_key(target_key, partner)
|
||||
if(children >= max_children)
|
||||
finish_action(controller, FALSE)
|
||||
return
|
||||
|
||||
if(other.stat != CONSCIOUS) //Check if it's conscious FIRST.
|
||||
continue
|
||||
|
||||
if(is_type_in_list(other, child_types)) //Check for children SECOND.
|
||||
children++
|
||||
continue
|
||||
|
||||
if(!is_type_in_list(other, partner_types) || !HAS_TRAIT(other, TRAIT_MOB_BREEDER))
|
||||
continue
|
||||
|
||||
if(other.ckey)
|
||||
continue
|
||||
|
||||
if(other.gender != living_pawn.gender && !(other.flags_1 & HOLOGRAM_1)) //Better safe than sorry ;_;
|
||||
controller.set_blackboard_key(target_key, other)
|
||||
finish_action(controller, TRUE)
|
||||
|
||||
finish_action(controller, FALSE)
|
||||
|
||||
finish_action(controller, TRUE)
|
||||
|
||||
/**
|
||||
* Reproduce.
|
||||
*/
|
||||
/datum/ai_behavior/make_babies
|
||||
action_cooldown = 40 SECONDS
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH
|
||||
|
||||
/datum/ai_behavior/make_babies/setup(datum/ai_controller/controller, target_key, child_types_key)
|
||||
. = ..()
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
if(!target)
|
||||
return FALSE
|
||||
set_movement_target(controller, target)
|
||||
return TRUE
|
||||
|
||||
/datum/ai_behavior/make_babies/perform(seconds_per_tick, datum/ai_controller/controller, target_key, child_types_key)
|
||||
. = ..()
|
||||
var/mob/target = controller.blackboard[target_key]
|
||||
if(!target || target.stat != CONSCIOUS)
|
||||
if(QDELETED(target) || target.stat != CONSCIOUS)
|
||||
finish_action(controller, FALSE, target_key)
|
||||
return
|
||||
|
||||
var/child_type = pick_weight(controller.blackboard[child_types_key])
|
||||
var/turf/turf_loc = get_turf(controller.pawn.loc)
|
||||
if(turf_loc)
|
||||
new child_type(turf_loc)
|
||||
|
||||
var/mob/living/basic/living_pawn = controller.pawn
|
||||
living_pawn.set_combat_mode(FALSE)
|
||||
living_pawn.melee_attack(target)
|
||||
finish_action(controller, TRUE, target_key)
|
||||
|
||||
/datum/ai_behavior/make_babies/finish_action(datum/ai_controller/controller, succeeded, target_key)
|
||||
. = ..()
|
||||
|
||||
controller.clear_blackboard_key(target_key)
|
||||
if(!succeeded)
|
||||
return
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
living_pawn.set_combat_mode(initial(living_pawn.combat_mode))
|
||||
|
||||
@@ -3,11 +3,19 @@
|
||||
*/
|
||||
/datum/ai_planning_subtree/make_babies
|
||||
var/chance = 5
|
||||
operational_datums = list(/datum/component/breed)
|
||||
|
||||
/datum/ai_planning_subtree/make_babies/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
|
||||
if(controller.pawn.gender != FEMALE || !SPT_PROB(chance, seconds_per_tick))
|
||||
if(!SPT_PROB(chance, seconds_per_tick))
|
||||
return
|
||||
|
||||
if(controller.blackboard_key_exists(BB_BABIES_TARGET))
|
||||
controller.queue_behavior(/datum/ai_behavior/make_babies, BB_BABIES_TARGET, BB_BABIES_CHILD_TYPES)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
if(controller.pawn.gender == FEMALE || !controller.blackboard[BB_BREED_READY])
|
||||
return
|
||||
|
||||
var/partner_types = controller.blackboard[BB_BABIES_PARTNER_TYPES]
|
||||
@@ -21,7 +29,4 @@
|
||||
return
|
||||
|
||||
// Find target
|
||||
if(controller.blackboard_key_exists(BB_BABIES_TARGET))
|
||||
controller.queue_behavior(/datum/ai_behavior/make_babies, BB_BABIES_TARGET, BB_BABIES_CHILD_TYPES)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
controller.queue_behavior(/datum/ai_behavior/find_partner, BB_BABIES_TARGET, BB_BABIES_PARTNER_TYPES, BB_BABIES_CHILD_TYPES)
|
||||
|
||||
@@ -45,3 +45,20 @@
|
||||
return
|
||||
|
||||
return corgi_pawn.access_card.GetAccess()
|
||||
|
||||
/datum/ai_controller/basic_controller/dog/puppy
|
||||
blackboard = list(
|
||||
BB_DOG_HARASS_HARM = TRUE,
|
||||
BB_VISION_RANGE = AI_DOG_VISION_RANGE,
|
||||
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/holding_object,
|
||||
// With tongs in hand!
|
||||
BB_TARGET_HELD_ITEM = /obj/item/kitchen/tongs,
|
||||
)
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/random_speech/dog,
|
||||
/datum/ai_planning_subtree/pet_planning,
|
||||
/datum/ai_planning_subtree/dog_harassment,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/flee_target,
|
||||
)
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
/// Do we reset the target after attacking something, so we can check for status changes.
|
||||
var/always_reset_target = FALSE
|
||||
|
||||
|
||||
/datum/ai_behavior/hunt_target/setup(datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key)
|
||||
. = ..()
|
||||
var/atom/hunt_target = controller.blackboard[hunting_target_key]
|
||||
@@ -123,10 +124,27 @@
|
||||
controller.clear_blackboard_key(hunting_target_key)
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target
|
||||
///do we toggle combat mode before interacting with the object?
|
||||
var/switch_combat_mode = FALSE
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/target_caught(mob/living/hunter, obj/structure/cable/hunted)
|
||||
if(switch_combat_mode)
|
||||
hunter.combat_mode = !(hunter.combat_mode)
|
||||
hunter.UnarmedAttack(hunted, TRUE)
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/finish_action(datum/ai_controller/controller, succeeded, hunting_target_key, hunting_cooldown_key)
|
||||
. = ..()
|
||||
if(!switch_combat_mode)
|
||||
return
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
living_pawn.combat_mode = initial(living_pawn.combat_mode)
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/switch_combat_mode
|
||||
switch_combat_mode = TRUE
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/reset_target
|
||||
always_reset_target = TRUE
|
||||
|
||||
/datum/ai_behavior/hunt_target/use_ability_on_target
|
||||
always_reset_target = TRUE
|
||||
///the ability we will use
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* A component to allow us to breed
|
||||
*/
|
||||
/datum/component/breed
|
||||
/// additional mobs we can breed with
|
||||
var/list/can_breed_with
|
||||
///path of the baby
|
||||
var/baby_path
|
||||
///time to wait after breeding
|
||||
var/breed_timer
|
||||
///AI key we set when we're ready to breed
|
||||
var/breed_key = BB_BREED_READY
|
||||
///are we ready to breed?
|
||||
var/ready_to_breed = TRUE
|
||||
///callback after we give birth to the child
|
||||
var/datum/callback/post_birth
|
||||
|
||||
/datum/component/breed/Initialize(list/can_breed_with = list(), breed_timer = 40 SECONDS, baby_path, post_birth)
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
if(ishuman(parent)) //sin detected
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
if(!ispath(baby_path))
|
||||
stack_trace("attempted to add a breeding component with invalid baby path!")
|
||||
return
|
||||
|
||||
src.can_breed_with = can_breed_with
|
||||
src.breed_timer = breed_timer
|
||||
src.baby_path = baby_path
|
||||
src.post_birth = post_birth
|
||||
|
||||
ADD_TRAIT(parent, TRAIT_SUBTREE_REQUIRED_OPERATIONAL_DATUM, type)
|
||||
|
||||
/datum/component/breed/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(breed_with_partner))
|
||||
ADD_TRAIT(parent, TRAIT_MOB_BREEDER, REF(src))
|
||||
var/mob/living/parent_mob = parent
|
||||
parent_mob.ai_controller?.set_blackboard_key(breed_key, TRUE)
|
||||
|
||||
/datum/component/breed/UnregisterFromParent()
|
||||
UnregisterSignal(parent, COMSIG_HOSTILE_PRE_ATTACKINGTARGET)
|
||||
REMOVE_TRAIT(parent, TRAIT_MOB_BREEDER, REF(src))
|
||||
post_birth = null
|
||||
|
||||
|
||||
/datum/component/breed/proc/breed_with_partner(mob/living/source, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(source.combat_mode)
|
||||
return
|
||||
|
||||
if(!is_type_in_typecache(target, can_breed_with))
|
||||
return
|
||||
|
||||
if(!HAS_TRAIT(target, TRAIT_MOB_BREEDER) || target.gender == source.gender)
|
||||
return
|
||||
|
||||
if(!ready_to_breed)
|
||||
source.balloon_alert(source, "not ready!")
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
var/turf/delivery_destination = get_turf(source)
|
||||
var/mob/living/baby = new baby_path(delivery_destination)
|
||||
new /obj/effect/temp_visual/heart(delivery_destination)
|
||||
toggle_status(source)
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(toggle_status), source), breed_timer)
|
||||
post_birth?.Invoke(baby, target)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
/datum/component/breed/proc/toggle_status(mob/living/source)
|
||||
ready_to_breed = !ready_to_breed
|
||||
source.ai_controller?.set_blackboard_key(BB_BREED_READY, ready_to_breed)
|
||||
|
||||
@@ -158,7 +158,37 @@
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
/**
|
||||
* # Pet Command: targeted Ability
|
||||
* # Breed command. breed with a partner!
|
||||
*/
|
||||
/datum/pet_command/point_targeting/breed
|
||||
command_name = "Breed"
|
||||
command_desc = "Command your pet to attempt to breed with a partner."
|
||||
radial_icon = 'icons/mob/simple/animal.dmi'
|
||||
radial_icon_state = "heart"
|
||||
speech_commands = list("breed", "consummate")
|
||||
|
||||
/datum/pet_command/point_targeting/breed/set_command_target(mob/living/parent, atom/target)
|
||||
if(isnull(target) || !isliving(target))
|
||||
return
|
||||
if(!HAS_TRAIT(parent, TRAIT_MOB_BREEDER) || !HAS_TRAIT(target, TRAIT_MOB_BREEDER))
|
||||
return
|
||||
if(isnull(parent.ai_controller))
|
||||
return
|
||||
if(!parent.ai_controller.blackboard[BB_BREED_READY] || isnull(parent.ai_controller.blackboard[BB_BABIES_PARTNER_TYPES]))
|
||||
return
|
||||
var/mob/living/living_target = target
|
||||
if(!living_target.ai_controller?.blackboard[BB_BREED_READY])
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/pet_command/point_targeting/breed/execute_action(datum/ai_controller/controller)
|
||||
if(is_type_in_list(controller.blackboard[BB_CURRENT_PET_TARGET], controller.blackboard[BB_BABIES_PARTNER_TYPES]))
|
||||
controller.queue_behavior(/datum/ai_behavior/make_babies, BB_CURRENT_PET_TARGET)
|
||||
controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
/**
|
||||
* # Pet Command: Targetted Ability
|
||||
* Tells a pet to use some kind of ability on the next thing you point at
|
||||
*/
|
||||
/datum/pet_command/point_targeting/use_ability
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/datum/component/torn_wall/Initialize()
|
||||
. = ..()
|
||||
if (!iswallturf(parent) || isindestructiblewall(parent))
|
||||
if (!isclosedturf(parent) || isindestructiblewall(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
/datum/component/torn_wall/RegisterWithParent()
|
||||
@@ -53,6 +53,12 @@
|
||||
return
|
||||
var/turf/closed/wall/attached_wall = parent
|
||||
playsound(attached_wall, 'sound/effects/meteorimpact.ogg', 100, vary = TRUE)
|
||||
|
||||
if(ismineralturf(attached_wall))
|
||||
var/turf/closed/mineral/mineral_turf = attached_wall
|
||||
mineral_turf.gets_drilled()
|
||||
return
|
||||
|
||||
attached_wall.dismantle_wall(devastated = TRUE)
|
||||
|
||||
/// Fix it up on weld
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
/datum/component/udder/Initialize(udder_type = /obj/item/udder, datum/callback/on_milk_callback, datum/callback/on_generate_callback, reagent_produced_typepath = /datum/reagent/consumable/milk)
|
||||
if(!isliving(parent)) //technically is possible to drop this on carbons... but you wouldn't do that to me, would you?
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
udder = new udder_type(null, parent, on_generate_callback, reagent_produced_typepath)
|
||||
udder = new udder_type(null)
|
||||
udder.add_features(parent, on_generate_callback, reagent_produced_typepath)
|
||||
src.on_milk_callback = on_milk_callback
|
||||
|
||||
/datum/component/udder/RegisterWithParent()
|
||||
@@ -70,14 +71,68 @@
|
||||
var/mob/living/udder_mob
|
||||
///optional proc to callback to when the udder generates milk
|
||||
var/datum/callback/on_generate_callback
|
||||
///do we require some food to generate milk?
|
||||
var/require_consume_type
|
||||
///how long does each food consumption allow us to make milk
|
||||
var/require_consume_timer = 2 MINUTES
|
||||
///hunger key we set to look for food
|
||||
var/hunger_key = BB_CHECK_HUNGRY
|
||||
|
||||
/obj/item/udder/Initialize(mapload, udder_mob, on_generate_callback, reagent_produced_typepath = /datum/reagent/consumable/milk)
|
||||
src.udder_mob = udder_mob
|
||||
src.on_generate_callback = on_generate_callback
|
||||
/obj/item/udder/proc/add_features(parent, callback, reagent = /datum/reagent/consumable/milk)
|
||||
udder_mob = parent
|
||||
on_generate_callback = callback
|
||||
create_reagents(size, REAGENT_HOLDER_ALIVE)
|
||||
src.reagent_produced_typepath = reagent_produced_typepath
|
||||
reagent_produced_typepath = reagent
|
||||
initial_conditions()
|
||||
if(isnull(require_consume_type))
|
||||
return
|
||||
RegisterSignal(udder_mob, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(on_mob_consume))
|
||||
RegisterSignal(udder_mob, COMSIG_ATOM_ATTACKBY, PROC_REF(on_mob_feed))
|
||||
udder_mob.ai_controller?.set_blackboard_key(BB_CHECK_HUNGRY, TRUE)
|
||||
|
||||
/obj/item/udder/proc/on_mob_consume(datum/source, atom/feed)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(feed, require_consume_type))
|
||||
return
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_consumption), feed)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
/obj/item/udder/proc/on_mob_feed(datum/source, atom/used_item, mob/living/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(used_item, require_consume_type))
|
||||
return
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_consumption), used_item, user)
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
/obj/item/udder/proc/handle_consumption(atom/movable/food, mob/user)
|
||||
if(locate(food.type) in src)
|
||||
if(user)
|
||||
user.balloon_alert(user, "already full!")
|
||||
return
|
||||
playsound(udder_mob.loc,'sound/items/eatfood.ogg', 50, TRUE)
|
||||
udder_mob.visible_message(span_notice("[udder_mob] gobbles up [food]!"), span_notice("You gobble up [food]!"))
|
||||
var/atom/movable/final_food = food
|
||||
if(isstack(food)) //if stack, only consume 1
|
||||
var/obj/item/stack/food_stack = food
|
||||
final_food = food_stack.split_stack(udder_mob, 1)
|
||||
final_food.forceMove(src)
|
||||
|
||||
/obj/item/udder/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
||||
if(!istype(arrived, require_consume_type))
|
||||
return ..()
|
||||
|
||||
udder_mob.ai_controller?.set_blackboard_key(hunger_key, FALSE)
|
||||
QDEL_IN(arrived, require_consume_timer)
|
||||
return ..()
|
||||
|
||||
/obj/item/udder/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(!istype(gone, require_consume_type))
|
||||
return
|
||||
udder_mob.ai_controller?.set_blackboard_key(hunger_key, TRUE)
|
||||
|
||||
|
||||
/obj/item/udder/Destroy()
|
||||
. = ..()
|
||||
@@ -101,10 +156,13 @@
|
||||
* Proc called every 2 seconds from SSMobs to add whatever reagent the udder is generating.
|
||||
*/
|
||||
/obj/item/udder/proc/generate()
|
||||
if(prob(5))
|
||||
reagents.add_reagent(reagent_produced_typepath, rand(5, 10), added_purity = 1)
|
||||
if(on_generate_callback)
|
||||
on_generate_callback.Invoke(reagents.total_volume, reagents.maximum_volume)
|
||||
if(!isnull(require_consume_type) && !(locate(require_consume_type) in src))
|
||||
return
|
||||
if(prob(95))
|
||||
return
|
||||
reagents.add_reagent(reagent_produced_typepath, rand(5, 10), added_purity = 1)
|
||||
if(on_generate_callback)
|
||||
on_generate_callback.Invoke(reagents.total_volume, reagents.maximum_volume)
|
||||
|
||||
/**
|
||||
* Proc called from attacking the component parent with the correct item, moves reagents into the glass basically.
|
||||
@@ -125,48 +183,20 @@
|
||||
|
||||
/**
|
||||
* # gutlunch udder subtype
|
||||
*
|
||||
* Used by gutlunches, and generates healing reagents instead of milk on eating gibs instead of a process. Starts empty!
|
||||
* Female gutlunches (ahem, guthens if you will) make babies when their udder is full under processing, instead of milk generation
|
||||
*/
|
||||
|
||||
/obj/item/udder/gutlunch
|
||||
name = "nutrient sac"
|
||||
|
||||
/obj/item/udder/gutlunch/initial_conditions()
|
||||
if(!udder_mob)
|
||||
return
|
||||
if(udder_mob.gender == FEMALE)
|
||||
START_PROCESSING(SSobj, src)
|
||||
RegisterSignal(udder_mob, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(on_mob_attacking))
|
||||
|
||||
/obj/item/udder/gutlunch/process(seconds_per_tick)
|
||||
var/mob/living/simple_animal/hostile/asteroid/gutlunch/gutlunch = udder_mob
|
||||
if(reagents.total_volume != reagents.maximum_volume)
|
||||
return
|
||||
if(gutlunch.make_babies())
|
||||
reagents.clear_reagents()
|
||||
//usually this would be a callback but this is a specifically gutlunch feature so fuck it, gutlunch specific proccall
|
||||
gutlunch.regenerate_icons(reagents.total_volume, reagents.maximum_volume)
|
||||
|
||||
/**
|
||||
* signal called on parent attacking an atom
|
||||
*/
|
||||
/obj/item/udder/gutlunch/proc/on_mob_attacking(mob/living/simple_animal/hostile/gutlunch, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(is_type_in_typecache(target, gutlunch.wanted_objects)) //we eats
|
||||
generate()
|
||||
gutlunch.visible_message(span_notice("[udder_mob] slurps up [target]."))
|
||||
qdel(target)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK //there is no longer a target to attack
|
||||
require_consume_type = /obj/item/stack/ore
|
||||
reagent_produced_typepath = /datum/reagent/medicine/mine_salve
|
||||
|
||||
/obj/item/udder/gutlunch/generate()
|
||||
var/made_something = FALSE
|
||||
if(prob(60))
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(locate(/obj/item/stack/ore/gold) in src)
|
||||
reagents.add_reagent(/datum/reagent/consumable/cream, rand(2, 5), added_purity = 1)
|
||||
made_something = TRUE
|
||||
if(prob(45))
|
||||
if(locate(/obj/item/stack/ore/bluespace_crystal) in src)
|
||||
reagents.add_reagent(/datum/reagent/medicine/salglu_solution, rand(2,5))
|
||||
made_something = TRUE
|
||||
if(made_something && on_generate_callback)
|
||||
if(on_generate_callback)
|
||||
on_generate_callback.Invoke(reagents.total_volume, reagents.maximum_volume)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* A component to allow us to collect ore
|
||||
*/
|
||||
/datum/element/ore_collecting
|
||||
|
||||
|
||||
/datum/element/ore_collecting/Attach(datum/target)
|
||||
. = ..()
|
||||
|
||||
if(!isliving(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
RegisterSignal(target, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(collect_ore))
|
||||
|
||||
/datum/element/ore_collecting/Detach(datum/target)
|
||||
. = ..()
|
||||
UnregisterSignal(target, COMSIG_HOSTILE_PRE_ATTACKINGTARGET)
|
||||
|
||||
/datum/element/ore_collecting/proc/collect_ore(mob/living/source, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(target, /obj/item/stack/ore))
|
||||
return
|
||||
|
||||
var/atom/movable/movable_target = target
|
||||
movable_target.forceMove(source)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
@@ -28,17 +28,15 @@
|
||||
src.tear_time = tear_time
|
||||
src.reinforced_multiplier = reinforced_multiplier
|
||||
src.do_after_key = do_after_key
|
||||
RegisterSignal(target, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(on_attacked_wall))
|
||||
RegisterSignals(target, list(COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_LIVING_UNARMED_ATTACK), PROC_REF(on_attacked_wall))
|
||||
|
||||
/datum/element/wall_tearer/Detach(datum/source)
|
||||
. = ..()
|
||||
UnregisterSignal(source, COMSIG_LIVING_UNARMED_ATTACK)
|
||||
UnregisterSignal(source, list(COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_LIVING_UNARMED_ATTACK))
|
||||
|
||||
/// Try to tear up a wall
|
||||
/datum/element/wall_tearer/proc/on_attacked_wall(mob/living/tearer, atom/target, proximity_flag)
|
||||
SIGNAL_HANDLER
|
||||
if (!proximity_flag)
|
||||
return NONE
|
||||
if (DOING_INTERACTION_WITH_TARGET(tearer, target) || (!isnull(do_after_key) && DOING_INTERACTION(tearer, do_after_key)))
|
||||
tearer.balloon_alert(tearer, "busy!")
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
@@ -39,3 +39,9 @@
|
||||
name = "Pony"
|
||||
icon_file = 'icons/mob/simple/animal.dmi'
|
||||
json_config = 'code/datums/greyscale/json_configs/pony.json'
|
||||
|
||||
/datum/greyscale_config/gutlunch
|
||||
name = "Gutlunch"
|
||||
icon_file = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
|
||||
json_config = 'code/datums/greyscale/json_configs/gutlunch.json'
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"gutlunch": [
|
||||
{
|
||||
"type": "icon_state",
|
||||
"icon_state": "gutlunch",
|
||||
"blend_mode": "overlay",
|
||||
"color_ids": [ 1 ]
|
||||
},
|
||||
{
|
||||
"type": "icon_state",
|
||||
"icon_state": "gutlunch_face",
|
||||
"blend_mode": "overlay"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -303,6 +303,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_STRUCTURE), \
|
||||
new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 2 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_DOORS), \
|
||||
new/datum/stack_recipe("wooden stairs frame", /obj/structure/stairs_frame/wood, 10, time = 5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_STRUCTURE), \
|
||||
new/datum/stack_recipe("wooden fence", /obj/structure/railing/wooden_fence, 2, time = 5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_STRUCTURE), \
|
||||
new/datum/stack_recipe("coffin", /obj/structure/closet/crate/coffin, 5, time = 1.5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_FURNITURE), \
|
||||
new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 1.5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_FURNITURE), \
|
||||
new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 1.5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_TOOLS), \
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
///structure to contain ores
|
||||
/obj/structure/ore_container
|
||||
|
||||
/obj/structure/ore_container/attackby(obj/item/ore, mob/living/carbon/human/user, list/modifiers)
|
||||
if(istype(ore, /obj/item/stack/ore) && !user.combat_mode)
|
||||
ore.forceMove(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/structure/ore_container/Entered(atom/movable/mover)
|
||||
. = ..()
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/structure/ore_container/Exited(atom/movable/mover)
|
||||
. = ..()
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/structure/ore_container/ui_interact(mob/user, datum/tgui/ui)
|
||||
. = ..()
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "OreContainer")
|
||||
ui.open()
|
||||
|
||||
/obj/structure/ore_container/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["ores"] = list()
|
||||
for(var/obj/item/stack/ore/ore_item in contents)
|
||||
data["ores"] += list(list(
|
||||
"id" = REF(ore_item),
|
||||
"name" = ore_item.name,
|
||||
"amount" = ore_item.amount,
|
||||
))
|
||||
return data
|
||||
|
||||
/obj/structure/ore_container/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["ore_images"] = list()
|
||||
for(var/obj/item/stack/ore_item as anything in subtypesof(/obj/item/stack/ore))
|
||||
data["ore_images"] += list(list(
|
||||
"name" = initial(ore_item.name),
|
||||
"icon" = icon2base64(getFlatIcon(image(icon = initial(ore_item.icon), icon_state = initial(ore_item.icon_state)), no_anim=TRUE))
|
||||
))
|
||||
return data
|
||||
|
||||
/obj/structure/ore_container/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
|
||||
if(. || !isliving(ui.user))
|
||||
return TRUE
|
||||
|
||||
var/mob/living/customer = ui.user
|
||||
var/obj/item/stack_to_move
|
||||
switch(action)
|
||||
if("withdraw")
|
||||
if(isnull(params["reference"]))
|
||||
return TRUE
|
||||
stack_to_move = locate(params["reference"]) in contents
|
||||
if(isnull(stack_to_move))
|
||||
return TRUE
|
||||
stack_to_move.forceMove(get_turf(customer))
|
||||
return TRUE
|
||||
@@ -17,6 +17,8 @@
|
||||
var/climbable = TRUE
|
||||
///Initial direction of the railing.
|
||||
var/ini_dir
|
||||
///item released when deconstructed
|
||||
var/item_deconstruct = /obj/item/stack/rods
|
||||
|
||||
/datum/armor/structure_railing
|
||||
melee = 35
|
||||
@@ -98,13 +100,11 @@
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/deconstruct(disassembled)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
if (istype(src,/obj/structure/railing/corner)) // Corner railings only cost 1 rod
|
||||
var/obj/item/stack/rods/rod = new /obj/item/stack/rods(drop_location(), 1)
|
||||
transfer_fingerprints_to(rod)
|
||||
else
|
||||
var/obj/item/stack/rods/rod = new /obj/item/stack/rods(drop_location(), 2)
|
||||
transfer_fingerprints_to(rod)
|
||||
if((flags_1 & NODECONSTRUCT_1))
|
||||
return ..()
|
||||
var/rods_to_make = istype(src,/obj/structure/railing/corner) ? 1 : 2
|
||||
var/obj/rod = new item_deconstruct(drop_location(), rods_to_make)
|
||||
transfer_fingerprints_to(rod)
|
||||
return ..()
|
||||
|
||||
///Implements behaviour that makes it possible to unanchor the railing.
|
||||
@@ -156,3 +156,35 @@
|
||||
/obj/structure/railing/proc/check_anchored(checked_anchored)
|
||||
if(anchored == checked_anchored)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/structure/railing/wooden_fence
|
||||
name = "wooden fence"
|
||||
desc = "wooden fence meant to keep animals in."
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "wooden_railing"
|
||||
item_deconstruct = /obj/item/stack/sheet/mineral/wood
|
||||
plane = GAME_PLANE_FOV_HIDDEN
|
||||
layer = ABOVE_MOB_LAYER
|
||||
|
||||
/obj/structure/railing/wooden_fence/Initialize(mapload)
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_change_layer))
|
||||
adjust_dir_layer(dir)
|
||||
|
||||
/obj/structure/railing/wooden_fence/proc/on_change_layer(datum/source, old_dir, new_dir)
|
||||
SIGNAL_HANDLER
|
||||
adjust_dir_layer(new_dir)
|
||||
|
||||
/obj/structure/railing/wooden_fence/proc/adjust_dir_layer(direction)
|
||||
var/new_layer = (direction & NORTH) ? MOB_LAYER : ABOVE_MOB_LAYER
|
||||
layer = new_layer
|
||||
|
||||
|
||||
/obj/structure/railing/corner/end/wooden_fence
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "wooden_railing_corner"
|
||||
|
||||
/obj/structure/railing/corner/end/flip/wooden_fence
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "wooden_railing_corner_flipped"
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
/datum/action/cooldown/mob_cooldown/burrow = BB_BURROW_ABILITY,
|
||||
)
|
||||
grant_actions_by_list(innate_actions)
|
||||
|
||||
AddElement(/datum/element/ore_collecting)
|
||||
AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
|
||||
AddComponent(/datum/component/ai_listen_to_weather)
|
||||
AddComponent(\
|
||||
@@ -67,17 +67,6 @@
|
||||
|
||||
RegisterSignal(src, COMSIG_ATOM_PRE_BULLET_ACT, PROC_REF(block_bullets))
|
||||
|
||||
/mob/living/basic/mining/goldgrub/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(!proximity_flag)
|
||||
return
|
||||
|
||||
if(istype(attack_target, /obj/item/stack/ore))
|
||||
consume_ore(attack_target)
|
||||
|
||||
/mob/living/basic/mining/goldgrub/proc/block_bullets(datum/source, obj/projectile/hitting_projectile)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
@@ -135,12 +124,14 @@
|
||||
max_eggs_held = 1,\
|
||||
)
|
||||
|
||||
/mob/living/basic/mining/goldgrub/proc/consume_ore(obj/item/target_ore)
|
||||
/mob/living/basic/mining/goldgrub/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
||||
. = ..()
|
||||
if(!istype(arrived, /obj/item/stack/ore))
|
||||
return
|
||||
playsound(src,'sound/items/eatfood.ogg', rand(10,50), TRUE)
|
||||
target_ore.forceMove(src)
|
||||
if(!can_lay_eggs)
|
||||
return
|
||||
if(!istype(target_ore, /obj/item/stack/ore/bluespace_crystal) || prob(60))
|
||||
if(!istype(arrived, /obj/item/stack/ore/bluespace_crystal) || prob(60))
|
||||
return
|
||||
new /obj/item/food/egg/green/grub_egg(get_turf(src))
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/obj/structure/ore_container/gutlunch_trough
|
||||
name = "gutlunch trough"
|
||||
desc = "The gutlunches will eat out of it!"
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "gutlunch_trough"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
///list of materials in the trough
|
||||
var/list/list_of_materials = list()
|
||||
|
||||
/obj/structure/ore_container/gutlunch_trough/Entered(atom/movable/mover)
|
||||
if(!istype(mover, /obj/item/stack/ore))
|
||||
return ..()
|
||||
if(list_of_materials[mover.type])
|
||||
return ..()
|
||||
list_of_materials[mover.type] = list("pixel_x" = rand(-5, 8), "pixel_y" = rand(-2, -7))
|
||||
return ..()
|
||||
|
||||
/obj/structure/ore_container/gutlunch_trough/Exited(atom/movable/mover)
|
||||
if(!istype(mover, /obj/item/stack/ore) || !isnull(locate(mover.type) in contents))
|
||||
return ..()
|
||||
list_of_materials -= mover.type
|
||||
return ..()
|
||||
|
||||
/obj/structure/ore_container/gutlunch_trough/deconstruct(disassembled = TRUE)
|
||||
if(flags_1 & NODECONSTRUCT_1)
|
||||
return
|
||||
new /obj/item/stack/sheet/mineral/wood(drop_location(), 5)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/ore_container/gutlunch_trough/update_overlays()
|
||||
. = ..()
|
||||
for(var/ore_entry in list_of_materials)
|
||||
var/obj/item/ore_item = ore_entry
|
||||
var/image/ore_icon = image(icon = initial(ore_item.icon), icon_state = initial(ore_item.icon_state), layer = LOW_ITEM_LAYER)
|
||||
var/list/pixel_positions = list_of_materials[ore_entry]
|
||||
ore_icon.transform = ore_icon.transform.Scale(0.4, 0.4)
|
||||
ore_icon.pixel_x = pixel_positions["pixel_x"]
|
||||
ore_icon.pixel_y = pixel_positions["pixel_y"]
|
||||
. += ore_icon
|
||||
@@ -0,0 +1,167 @@
|
||||
#define MAX_ATTACK_DIFFERENCE 3
|
||||
#define MAX_LOWER_ATTACK 15
|
||||
#define MINIMUM_POSSIBLE_SPEED 1
|
||||
#define MAX_POSSIBLE_HEALTH 100
|
||||
|
||||
/mob/living/basic/mining/gutlunch
|
||||
name = "gutlunch"
|
||||
desc = "A scavenger that eats raw ores, often found alongside ash walkers. Produces a thick, nutritious milk."
|
||||
icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
|
||||
icon_state = "gutlunch"
|
||||
combat_mode = FALSE
|
||||
icon_living = "gutlunch"
|
||||
icon_dead = "gutlunch"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
basic_mob_flags = DEL_ON_DEATH
|
||||
speak_emote = list("warbles", "quavers")
|
||||
faction = list(FACTION_MINING, FACTION_ASHWALKER)
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "gently pushes aside"
|
||||
response_disarm_simple = "gently push aside"
|
||||
response_harm_continuous = "squishes"
|
||||
response_harm_simple = "squish"
|
||||
friendly_verb_continuous = "pinches"
|
||||
friendly_verb_simple = "pinch"
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
death_message = "is pulped into bugmash."
|
||||
greyscale_config = /datum/greyscale_config/gutlunch
|
||||
///possible colors we can have
|
||||
var/list/possible_colors = list(COLOR_WHITE)
|
||||
///can we breed?
|
||||
var/can_breed = TRUE
|
||||
|
||||
/mob/living/basic/mining/gutlunch/Initialize(mapload)
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack))
|
||||
if(greyscale_config)
|
||||
set_greyscale(colors = list(pick(possible_colors)))
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
if(!can_breed)
|
||||
return
|
||||
AddComponent(\
|
||||
/datum/component/breed,\
|
||||
can_breed_with = typecacheof(list(/mob/living/basic/mining/gutlunch)),\
|
||||
baby_path = /mob/living/basic/mining/gutlunch/grub,\
|
||||
post_birth = CALLBACK(src, PROC_REF(after_birth)),\
|
||||
breed_timer = 3 MINUTES,\
|
||||
)
|
||||
|
||||
/mob/living/basic/mining/gutlunch/proc/pre_attack(mob/living/puncher, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(target, /obj/structure/ore_container/gutlunch_trough))
|
||||
return
|
||||
|
||||
var/obj/ore_food = locate(/obj/item/stack/ore) in target
|
||||
|
||||
if(isnull(ore_food))
|
||||
balloon_alert(src, "no food!")
|
||||
else
|
||||
melee_attack(ore_food)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
/mob/living/basic/mining/gutlunch/proc/after_birth(mob/living/basic/mining/gutlunch/grub/baby, mob/living/partner)
|
||||
var/our_color = LAZYACCESS(atom_colours, FIXED_COLOUR_PRIORITY) || COLOR_GRAY
|
||||
var/partner_color = LAZYACCESS(partner.atom_colours, FIXED_COLOUR_PRIORITY) || COLOR_GRAY
|
||||
baby.add_atom_colour(BlendRGB(our_color, partner_color, 1), FIXED_COLOUR_PRIORITY)
|
||||
var/atom/male_parent = (gender == MALE) ? src : partner
|
||||
baby.inherited_stats = new(male_parent)
|
||||
|
||||
/mob/living/basic/mining/gutlunch/proc/roll_stats(input_attack, input_speed, input_health)
|
||||
melee_damage_lower = rand(input_attack, min(MAX_LOWER_ATTACK, input_attack + MAX_ATTACK_DIFFERENCE))
|
||||
melee_damage_upper = melee_damage_lower + MAX_ATTACK_DIFFERENCE
|
||||
speed = rand(MINIMUM_POSSIBLE_SPEED, input_speed)
|
||||
maxHealth = rand(input_health, MAX_POSSIBLE_HEALTH)
|
||||
health = maxHealth
|
||||
|
||||
/mob/living/basic/mining/gutlunch/milk
|
||||
name = "gubbuck"
|
||||
gender = FEMALE
|
||||
possible_colors = list("#E39FBB","#817178","#9d667d")
|
||||
ai_controller = /datum/ai_controller/basic_controller/gutlunch/gutlunch_milk
|
||||
///overlay we display when our udder is full!
|
||||
var/mutable_appearance/full_udder
|
||||
|
||||
/mob/living/basic/mining/gutlunch/milk/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/callback/milking_callback = CALLBACK(src, TYPE_PROC_REF(/atom/movable, update_overlays))
|
||||
AddComponent(\
|
||||
/datum/component/udder,\
|
||||
udder_type = /obj/item/udder/gutlunch,\
|
||||
on_milk_callback = milking_callback,\
|
||||
on_generate_callback = milking_callback,\
|
||||
)
|
||||
full_udder = mutable_appearance(icon, "gl_full")
|
||||
full_udder.color = LAZYACCESS(atom_colours, FIXED_COLOUR_PRIORITY) || COLOR_GRAY
|
||||
|
||||
/mob/living/basic/mining/gutlunch/warrior
|
||||
name = "gunther"
|
||||
gender = MALE
|
||||
melee_damage_lower = 8
|
||||
melee_damage_upper = 13
|
||||
speed = 5
|
||||
maxHealth = 70
|
||||
health = 70
|
||||
ai_controller = /datum/ai_controller/basic_controller/gutlunch/gutlunch_warrior
|
||||
possible_colors = list("#6d77ff","#8578e4","#97b6f6")
|
||||
//pet commands when we tame the gutluncher
|
||||
var/static/list/pet_commands = list(
|
||||
/datum/pet_command/idle,
|
||||
/datum/pet_command/free,
|
||||
/datum/pet_command/point_targeting/attack,
|
||||
/datum/pet_command/point_targeting/breed,
|
||||
/datum/pet_command/follow,
|
||||
/datum/pet_command/point_targeting/fetch,
|
||||
/datum/pet_command/mine_walls,
|
||||
)
|
||||
|
||||
/mob/living/basic/mining/gutlunch/warrior/Initialize(mapload)
|
||||
. = ..()
|
||||
roll_stats(melee_damage_lower, speed, maxHealth)
|
||||
AddComponent(/datum/component/obeys_commands, pet_commands)
|
||||
AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE)
|
||||
|
||||
/mob/living/basic/mining/gutlunch/milk/update_overlays(new_udder_volume, max_udder_volume)
|
||||
. = ..()
|
||||
if(new_udder_volume != max_udder_volume)
|
||||
return
|
||||
. += full_udder
|
||||
|
||||
/mob/living/basic/mining/gutlunch/grub
|
||||
name = "grublunch"
|
||||
possible_colors = list("#cc9797", "#b74c4c")
|
||||
can_breed = FALSE
|
||||
gender = NEUTER
|
||||
ai_controller = /datum/ai_controller/basic_controller/gutlunch/gutlunch_baby
|
||||
///list of stats we inherited
|
||||
var/datum/gutlunch_inherited_stats/inherited_stats
|
||||
|
||||
/mob/living/basic/mining/gutlunch/grub/Initialize(mapload)
|
||||
. = ..()
|
||||
transform = transform.Scale(0.6, 0.6)
|
||||
AddComponent(\
|
||||
/datum/component/growth_and_differentiation,\
|
||||
growth_time = 3 MINUTES,\
|
||||
growth_probability = 100,\
|
||||
lower_growth_value = 0.5,\
|
||||
upper_growth_value = 1,\
|
||||
signals_to_kill_on = list(COMSIG_MOB_CLIENT_LOGIN),\
|
||||
optional_checks = CALLBACK(src, PROC_REF(ready_to_grow)),\
|
||||
optional_grow_behavior = CALLBACK(src, PROC_REF(determine_growth_path)),\
|
||||
)
|
||||
|
||||
/mob/living/basic/mining/gutlunch/grub/proc/ready_to_grow()
|
||||
return (stat == CONSCIOUS)
|
||||
|
||||
/mob/living/basic/mining/gutlunch/grub/proc/determine_growth_path()
|
||||
var/final_type = prob(50) ? /mob/living/basic/mining/gutlunch/warrior : /mob/living/basic/mining/gutlunch/milk
|
||||
var/mob/living/basic/mining/gutlunch/grown_mob = new final_type(get_turf(src))
|
||||
if(grown_mob.gender == MALE && inherited_stats)
|
||||
grown_mob.roll_stats(inherited_stats.attack, inherited_stats.speed, inherited_stats.health)
|
||||
qdel(src)
|
||||
|
||||
#undef MAX_ATTACK_DIFFERENCE
|
||||
#undef MAX_LOWER_ATTACK
|
||||
#undef MINIMUM_POSSIBLE_SPEED
|
||||
#undef MAX_POSSIBLE_HEALTH
|
||||
@@ -0,0 +1,119 @@
|
||||
/datum/ai_controller/basic_controller/gutlunch
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
|
||||
/datum/ai_controller/basic_controller/gutlunch/gutlunch_warrior
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
|
||||
BB_BABIES_PARTNER_TYPES = list(/mob/living/basic/mining/gutlunch/milk),
|
||||
BB_BABIES_CHILD_TYPES = list(/mob/living/basic/mining/gutlunch/grub),
|
||||
BB_MAX_CHILDREN = 5,
|
||||
)
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/target_retaliate/check_faction,
|
||||
/datum/ai_planning_subtree/pet_planning,
|
||||
/datum/ai_planning_subtree/make_babies,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
/datum/ai_planning_subtree/befriend_ashwalkers,
|
||||
)
|
||||
|
||||
///find ashwalkers and add them to the list of masters
|
||||
/datum/ai_planning_subtree/befriend_ashwalkers
|
||||
|
||||
/datum/ai_planning_subtree/befriend_ashwalkers/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
controller.queue_behavior(/datum/ai_behavior/befriend_ashwalkers)
|
||||
|
||||
/datum/ai_behavior/befriend_ashwalkers
|
||||
action_cooldown = 5 SECONDS
|
||||
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/befriend_ashwalkers/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
|
||||
for(var/mob/living/potential_friend in oview(9, living_pawn))
|
||||
if(!isashwalker(potential_friend))
|
||||
continue
|
||||
if((living_pawn.faction.Find(REF(potential_friend))))
|
||||
continue
|
||||
living_pawn.befriend(potential_friend)
|
||||
to_chat(potential_friend, span_nicegreen("[living_pawn] looks at you with endearing eyes!"))
|
||||
finish_action(controller, TRUE)
|
||||
return
|
||||
|
||||
finish_action(controller, FALSE)
|
||||
return
|
||||
|
||||
|
||||
|
||||
/datum/ai_controller/basic_controller/gutlunch/gutlunch_baby
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
BB_FIND_MOM_TYPES = list(/mob/living/basic/mining/gutlunch/milk),
|
||||
)
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/target_retaliate,
|
||||
/datum/ai_planning_subtree/flee_target,
|
||||
/datum/ai_planning_subtree/look_for_adult,
|
||||
)
|
||||
|
||||
/datum/ai_controller/basic_controller/gutlunch/gutlunch_milk
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/target_retaliate,
|
||||
/datum/ai_planning_subtree/flee_target,
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/food_trough
|
||||
)
|
||||
|
||||
///consume food!
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/food_trough
|
||||
target_key = BB_TROUGH_TARGET
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/food_trough
|
||||
finding_behavior = /datum/ai_behavior/find_hunt_target/food_trough
|
||||
hunt_targets = list(/obj/structure/ore_container/gutlunch_trough)
|
||||
hunt_chance = 75
|
||||
hunt_range = 9
|
||||
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/food_trough/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
if(!controller.blackboard[BB_CHECK_HUNGRY])
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/food_trough
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/food_trough/valid_dinner(mob/living/basic/source, obj/target, radius)
|
||||
if(isnull(target))
|
||||
return FALSE
|
||||
|
||||
if(isnull(locate(/obj/item/stack/ore) in target))
|
||||
return FALSE
|
||||
|
||||
return can_see(source, target, radius)
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/food_trough
|
||||
always_reset_target = TRUE
|
||||
switch_combat_mode = TRUE
|
||||
|
||||
/datum/pet_command/mine_walls
|
||||
command_name = "Mine"
|
||||
command_desc = "Command your pet to mine down walls."
|
||||
speech_commands = list("mine", "smash")
|
||||
|
||||
/datum/pet_command/mine_walls/try_activate_command(mob/living/commander)
|
||||
var/mob/living/parent = weak_parent.resolve()
|
||||
if(isnull(parent))
|
||||
return
|
||||
//no walls for us to mine
|
||||
var/target_in_vicinity = locate(/turf/closed/mineral) in oview(9, parent)
|
||||
if(isnull(target_in_vicinity))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/pet_command/mine_walls/execute_action(datum/ai_controller/controller)
|
||||
if(controller.blackboard_key_exists(BB_CURRENT_PET_TARGET))
|
||||
controller.queue_behavior(/datum/ai_behavior/mine_wall, BB_CURRENT_PET_TARGET)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
controller.queue_behavior(/datum/ai_behavior/find_mineral_wall, BB_CURRENT_PET_TARGET)
|
||||
@@ -0,0 +1,14 @@
|
||||
///stats we inherit from the parent
|
||||
/datum/gutlunch_inherited_stats
|
||||
///attack we inherited
|
||||
var/attack
|
||||
///speed we inherited
|
||||
var/speed
|
||||
///health we inherited
|
||||
var/health
|
||||
|
||||
/datum/gutlunch_inherited_stats/New(mob/living/basic/parent)
|
||||
. = ..()
|
||||
attack = parent.melee_damage_lower
|
||||
speed = parent.speed
|
||||
health = parent.maxHealth
|
||||
@@ -107,7 +107,7 @@
|
||||
ore_target.forceMove(src)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
if(istype(target, /obj/structure/material_stand))
|
||||
if(istype(target, /obj/structure/ore_container/material_stand))
|
||||
if(held_ore)
|
||||
held_ore.forceMove(target)
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
@@ -71,7 +71,7 @@ GLOBAL_LIST_INIT(mook_commands, list(
|
||||
target_key = BB_MATERIAL_STAND_TARGET
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/material_stand
|
||||
finding_behavior = /datum/ai_behavior/find_hunt_target
|
||||
hunt_targets = list(/obj/structure/material_stand)
|
||||
hunt_targets = list(/obj/structure/ore_container/material_stand)
|
||||
hunt_range = 9
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/material_stand/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
@@ -83,6 +83,7 @@ GLOBAL_LIST_INIT(mook_commands, list(
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target/material_stand
|
||||
required_distance = 0
|
||||
always_reset_target = TRUE
|
||||
switch_combat_mode = TRUE
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT
|
||||
|
||||
///try to face the counter when depositing ores
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///unique items that spawn at the mook village
|
||||
/obj/structure/material_stand
|
||||
/obj/structure/ore_container/material_stand
|
||||
name = "material stand"
|
||||
desc = "Is everyone free to use this thing?"
|
||||
icon = 'icons/mob/simple/jungle/mook.dmi'
|
||||
@@ -10,22 +10,8 @@
|
||||
bound_width = 64
|
||||
bound_height = 64
|
||||
|
||||
/obj/structure/material_stand/attackby(obj/item/ore, mob/living/carbon/human/user, list/modifiers)
|
||||
if(istype(ore, /obj/item/stack/ore))
|
||||
ore.forceMove(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/structure/material_stand/Entered(atom/movable/mover)
|
||||
. = ..()
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/structure/material_stand/Exited(atom/movable/mover)
|
||||
. = ..()
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
///put ore icons on the counter!
|
||||
/obj/structure/material_stand/update_overlays()
|
||||
/obj/structure/ore_container/material_stand/update_overlays()
|
||||
. = ..()
|
||||
for(var/obj/item/stack/ore/ore_item in contents)
|
||||
var/image/ore_icon = image(icon = initial(ore_item.icon), icon_state = initial(ore_item.icon_state), layer = LOW_ITEM_LAYER)
|
||||
@@ -34,52 +20,6 @@
|
||||
ore_icon.pixel_y = rand(2, 4)
|
||||
. += ore_icon
|
||||
|
||||
/obj/structure/material_stand/ui_interact(mob/user, datum/tgui/ui)
|
||||
. = ..()
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "MaterialStand")
|
||||
ui.open()
|
||||
|
||||
/obj/structure/material_stand/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["ores"] = list()
|
||||
for(var/obj/item/stack/ore/ore_item in contents)
|
||||
data["ores"] += list(list(
|
||||
"id" = REF(ore_item),
|
||||
"name" = ore_item.name,
|
||||
"amount" = ore_item.amount,
|
||||
))
|
||||
return data
|
||||
|
||||
/obj/structure/material_stand/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["ore_images"] = list()
|
||||
for(var/obj/item/stack/ore_item as anything in subtypesof(/obj/item/stack/ore))
|
||||
data["ore_images"] += list(list(
|
||||
"name" = initial(ore_item.name),
|
||||
"icon" = icon2base64(getFlatIcon(image(icon = initial(ore_item.icon), icon_state = initial(ore_item.icon_state)), no_anim=TRUE))
|
||||
))
|
||||
return data
|
||||
|
||||
/obj/structure/material_stand/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
|
||||
if(. || !isliving(usr))
|
||||
return TRUE
|
||||
|
||||
var/mob/living/customer = usr
|
||||
var/obj/item/stack_to_move
|
||||
switch(action)
|
||||
if("withdraw")
|
||||
if(isnull(params["reference"]))
|
||||
return TRUE
|
||||
stack_to_move = locate(params["reference"]) in contents
|
||||
if(isnull(stack_to_move))
|
||||
return TRUE
|
||||
stack_to_move.forceMove(get_turf(customer))
|
||||
return TRUE
|
||||
|
||||
/obj/effect/landmark/mook_village
|
||||
name = "mook village landmark"
|
||||
icon_state = "x"
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
var/is_slow = FALSE
|
||||
///Item slots that are available for this corgi to equip stuff into
|
||||
var/list/strippable_inventory_slots = list()
|
||||
///can this mob breed?
|
||||
var/can_breed = TRUE
|
||||
|
||||
/mob/living/basic/pet/dog/corgi/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -34,6 +36,13 @@
|
||||
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CORGI, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
|
||||
RegisterSignal(src, COMSIG_MOB_TRIED_ACCESS, PROC_REF(on_tried_access))
|
||||
RegisterSignals(src, list(COMSIG_BASICMOB_LOOK_ALIVE, COMSIG_BASICMOB_LOOK_DEAD), PROC_REF(on_appearance_change))
|
||||
if(!can_breed)
|
||||
return
|
||||
AddComponent(\
|
||||
/datum/component/breed,\
|
||||
can_breed_with = typecacheof(list(/mob/living/basic/pet/dog/corgi)),\
|
||||
baby_path = /mob/living/basic/pet/dog/corgi/puppy,\
|
||||
)
|
||||
|
||||
/mob/living/basic/pet/dog/corgi/Destroy()
|
||||
QDEL_NULL(inventory_head)
|
||||
@@ -532,9 +541,11 @@
|
||||
icon_dead = "puppy_dead"
|
||||
density = FALSE
|
||||
pass_flags = PASSMOB
|
||||
ai_controller = /datum/ai_controller/basic_controller/dog/puppy
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
collar_icon_state = "puppy"
|
||||
strippable_inventory_slots = list(/datum/strippable_item/pet_collar, /datum/strippable_item/corgi_id) //puppies are too small to handle hats and back slot items
|
||||
can_breed = FALSE
|
||||
|
||||
//PUPPY IAN! SQUEEEEEEEEE~
|
||||
/mob/living/basic/pet/dog/corgi/puppy/ian
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
//Gutlunches, passive mods that devour blood and gibs
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch
|
||||
name = "gutlunch"
|
||||
desc = "A scavenger that eats raw meat, often found alongside ash walkers. Produces a thick, nutritious milk."
|
||||
icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
|
||||
icon_state = "gutlunch"
|
||||
icon_living = "gutlunch"
|
||||
icon_dead = "gutlunch"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
speak_emote = list("warbles", "quavers")
|
||||
emote_hear = list("trills.")
|
||||
emote_see = list("sniffs.", "burps.")
|
||||
weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
|
||||
faction = list(FACTION_MINING, FACTION_ASHWALKER)
|
||||
density = FALSE
|
||||
speak_chance = 1
|
||||
turns_per_move = 8
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
move_to_delay = 15
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "gently pushes aside"
|
||||
response_disarm_simple = "gently push aside"
|
||||
response_harm_continuous = "squishes"
|
||||
response_harm_simple = "squish"
|
||||
friendly_verb_continuous = "pinches"
|
||||
friendly_verb_simple = "pinch"
|
||||
combat_mode = FALSE
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
stat_attack = HARD_CRIT
|
||||
gender = NEUTER
|
||||
stop_automated_movement = FALSE
|
||||
stop_automated_movement_when_pulled = TRUE
|
||||
stat_exclusive = TRUE
|
||||
robust_searching = TRUE
|
||||
search_objects = 3 //Ancient simplemob AI shitcode. This makes them ignore all other mobs.
|
||||
del_on_death = TRUE
|
||||
loot = list(/obj/effect/decal/cleanable/blood/gibs)
|
||||
death_message = "is pulped into bugmash."
|
||||
|
||||
animal_species = /mob/living/simple_animal/hostile/asteroid/gutlunch
|
||||
childtype = list(/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch = 100)
|
||||
|
||||
wanted_objects = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/blood/gibs/, /obj/item/organ)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/Initialize(mapload)
|
||||
. = ..()
|
||||
if(wanted_objects.len)
|
||||
AddComponent(/datum/component/udder, /obj/item/udder/gutlunch, CALLBACK(src, PROC_REF(regenerate_icons)), CALLBACK(src, PROC_REF(regenerate_icons)))
|
||||
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/CanAttack(atom/the_target) // Gutlunch-specific version of CanAttack to handle stupid stat_exclusive = true crap so we don't have to do it for literally every single simple_animal/hostile except the two that spawn in lavaland
|
||||
if(!the_target || !isturf(the_target.loc)) // bail out on invalids
|
||||
return FALSE
|
||||
|
||||
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
|
||||
return FALSE
|
||||
|
||||
if(isliving(the_target))
|
||||
var/mob/living/L = the_target
|
||||
|
||||
if(faction_check_atom(L) && !attack_same)
|
||||
return FALSE
|
||||
if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive)
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
if(isobj(the_target) && is_type_in_typecache(the_target, wanted_objects))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/regenerate_icons(new_udder_volume, max_udder_volume)
|
||||
cut_overlays()
|
||||
var/static/gutlunch_full_overlay
|
||||
if(isnull(gutlunch_full_overlay))
|
||||
gutlunch_full_overlay = iconstate2appearance(icon, "gl_full")
|
||||
if(new_udder_volume == max_udder_volume)
|
||||
add_overlay(gutlunch_full_overlay)
|
||||
..()
|
||||
|
||||
//Male gutlunch. They're smaller and more colorful!
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck
|
||||
name = "gubbuck"
|
||||
gender = MALE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck/Initialize(mapload)
|
||||
. = ..()
|
||||
add_atom_colour(pick("#E39FBB", "#D97D64", "#CF8C4A"), FIXED_COLOUR_PRIORITY)
|
||||
update_transform(0.85)
|
||||
|
||||
//Lady gutlunch. They make the babby.
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen
|
||||
name = "guthen"
|
||||
gender = FEMALE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch
|
||||
name = "grublunch"
|
||||
wanted_objects = list() //They don't eat.
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
var/growth = 0
|
||||
|
||||
//Baby gutlunch
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch/Initialize(mapload)
|
||||
. = ..()
|
||||
add_atom_colour("#9E9E9E", FIXED_COLOUR_PRIORITY) //Somewhat hidden
|
||||
update_transform(0.45)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch/Life(seconds_per_tick = SSMOBS_DT, times_fired)
|
||||
..()
|
||||
growth++
|
||||
if(growth > 50) //originally used a timer for this but it was more of a problem than it was worth.
|
||||
growUp()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch/proc/growUp()
|
||||
var/mob/living/L
|
||||
if(prob(45))
|
||||
L = new /mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck(loc)
|
||||
else
|
||||
L = new /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen(loc)
|
||||
mind?.transfer_to(L)
|
||||
L.faction = faction
|
||||
L.setDir(dir)
|
||||
L.Stun(20, ignore_canstun = TRUE)
|
||||
visible_message(span_notice("[src] grows up into [L]."))
|
||||
qdel(src)
|
||||
@@ -51,10 +51,6 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/legionnaire,
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/legionnairehead,
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/pandora,
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch,
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch,
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck,
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen,
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear,
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/lesser,
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf,
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 132 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 198 KiB |
+7
-1
@@ -990,6 +990,7 @@
|
||||
#include "code\datums\components\bloodysoles.dm"
|
||||
#include "code\datums\components\boomerang.dm"
|
||||
#include "code\datums\components\boss_music.dm"
|
||||
#include "code\datums\components\breeding.dm"
|
||||
#include "code\datums\components\bullet_intercepting.dm"
|
||||
#include "code\datums\components\bumpattack.dm"
|
||||
#include "code\datums\components\burning.dm"
|
||||
@@ -1399,6 +1400,7 @@
|
||||
#include "code\datums\elements\noticable_organ.dm"
|
||||
#include "code\datums\elements\obj_regen.dm"
|
||||
#include "code\datums\elements\openspace_item_click_handler.dm"
|
||||
#include "code\datums\elements\ore_collecting.dm"
|
||||
#include "code\datums\elements\organ_set_bonus.dm"
|
||||
#include "code\datums\elements\pet_bonus.dm"
|
||||
#include "code\datums\elements\plant_backfire.dm"
|
||||
@@ -2533,6 +2535,7 @@
|
||||
#include "code\game\objects\structures\morgue.dm"
|
||||
#include "code\game\objects\structures\mystery_box.dm"
|
||||
#include "code\game\objects\structures\noticeboard.dm"
|
||||
#include "code\game\objects\structures\ore_containers.dm"
|
||||
#include "code\game\objects\structures\petrified_statue.dm"
|
||||
#include "code\game\objects\structures\pinatas.dm"
|
||||
#include "code\game\objects\structures\plasticflaps.dm"
|
||||
@@ -4523,6 +4526,10 @@
|
||||
#include "code\modules\mob\living\basic\lavaland\goliath\goliath_ai.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\goliath\goliath_trophy.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\goliath\tentacle.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\gutlunchers\gutluncher_foodtrough.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\gutlunchers\gutlunchers.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\gutlunchers\gutlunchers_ai.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\gutlunchers\gutlunchers_inherit_datum.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\hivelord\hivelord.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\hivelord\hivelord_ai.dm"
|
||||
#include "code\modules\mob\living\basic\lavaland\hivelord\spawn_hivelord_brood.dm"
|
||||
@@ -4841,7 +4848,6 @@
|
||||
#include "code\modules\mob\living\simple_animal\hostile\megafauna\legion.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\megafauna\wendigo.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\curse_blob.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\gutlunch.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\mining_mobs.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\polarbear.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\wolf.dm"
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ type Data = {
|
||||
ore_images: Ore_images[];
|
||||
};
|
||||
|
||||
export const MaterialStand = (props, context) => {
|
||||
export const OreContainer = (props, context) => {
|
||||
const { act, data } = useBackend<Data>(context);
|
||||
const { ores = [] } = data;
|
||||
const [searchItem, setSearchItem] = useLocalState(context, 'searchItem', '');
|
||||
@@ -27,7 +27,7 @@ export const MaterialStand = (props, context) => {
|
||||
const ores_filtered =
|
||||
searchItem.length > 0 ? ores.filter((ore) => search(ore)) : ores;
|
||||
return (
|
||||
<Window title="Material Stand" width={550} height={400}>
|
||||
<Window title="Ore Container" width={550} height={400}>
|
||||
<Window.Content>
|
||||
<Stack fill vertical>
|
||||
<Stack.Item>
|
||||
@@ -0,0 +1,5 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch : /mob/living/basic/mining/gutlunch{@OLD}
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch : /mob/living/basic/mining/gutlunch/grub{@OLD}
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck : /mob/living/basic/mining/gutlunch/milk{@OLD}
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen : /mob/living/basic/mining/gutlunch/warrior{@OLD}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/obj/structure/material_stand : /obj/structure/ore_container/material_stand{@OLD}
|
||||
Reference in New Issue
Block a user