diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index a014d30878e..2b4c3586bf9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,15 +9,27 @@ assignees: '' **Issue Description**: + + **What did you expect to happen**: + + **What happened instead**: + + **Why is this bad/What are the consequences**: + + **Steps to reproduce the problem**: + + **When did the problem start happening**: + + **Extra information**: diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm index fb8cbaf4304..37231b29651 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -49652,8 +49652,8 @@ /obj/item/radio/intercom{ pixel_y = 28 }, -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, /turf/simulated/floor/plasteel{ icon_state = "vault"; dir = 8 @@ -49673,8 +49673,8 @@ }, /area/security/armoury) "bLK" = ( -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, /turf/simulated/floor/plasteel{ icon_state = "vault"; dir = 8 diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index 5c09a328037..ccfadc2ab79 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -4795,10 +4795,10 @@ /obj/structure/reagent_dispensers/peppertank{ pixel_y = 29 }, -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, /turf/simulated/floor/plasteel{ tag = "icon-vault (WEST)"; icon_state = "vault"; diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm new file mode 100644 index 00000000000..41d298fffb1 --- /dev/null +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm @@ -0,0 +1,2238 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"ac" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"ad" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"ae" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"af" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ag" = ( +/obj/effect/mob_spawn/human/corpse/damaged, +/obj/effect/decal/cleanable/blood/old, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ah" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ai" = ( +/obj/structure/disposalpipe/sortjunction{ + dir = 1 + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"aj" = ( +/obj/effect/decal/cleanable/pie_smudge, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ak" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"al" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"am" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"an" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ao" = ( +/obj/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"ap" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aq" = ( +/obj/structure/disposalpipe/trunk, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"ar" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"as" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"at" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"au" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"av" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aw" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ay" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"az" = ( +/obj/item/bikehorn, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aA" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"aB" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/pie_smudge, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aC" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aD" = ( +/obj/item/bikehorn, +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aE" = ( +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"aF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aG" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aH" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aI" = ( +/obj/item/bikehorn, +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aJ" = ( +/obj/item/bikehorn, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aK" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"aL" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"aM" = ( +/obj/effect/decal/cleanable/pie_smudge, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aN" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aO" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"aQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/structure/table, +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/escape, +/obj/item/pen/multi, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aR" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/structure/table, +/obj/item/flashlight/lamp/bananalamp, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aS" = ( +/obj/effect/decal/cleanable/pie_smudge, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aT" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/item/pickaxe, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aU" = ( +/obj/effect/spawner/window/reinforced, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"aV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aW" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aX" = ( +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/structure/disposaloutlet{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"aY" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aZ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/floor/light, +/area/ruin/powered/clownplanet) +"ba" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bb" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bc" = ( +/turf/simulated/floor/light, +/area/ruin/powered/clownplanet) +"bd" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"be" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bf" = ( +/turf/simulated/mineral/clown/volcanic, +/area/ruin/powered/clownplanet) +"bg" = ( +/obj/item/pickaxe, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bh" = ( +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bi" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bj" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bk" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"bl" = ( +/obj/item/bikehorn, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bm" = ( +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bn" = ( +/obj/effect/decal/cleanable/cobweb, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bo" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bp" = ( +/obj/effect/decal/cleanable/pie_smudge, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bq" = ( +/obj/machinery/disposal/deliveryChute{ + dir = 1 + }, +/obj/structure/disposalpipe/trunk, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"br" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bs" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/junction{ + dir = 1; + icon_state = "pipe-y" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bu" = ( +/obj/effect/decal/cleanable/blood/oil, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"bv" = ( +/obj/effect/mob_spawn/human/corpse/damaged, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bw" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bx" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/baseturf_helper/lava_land/surface, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"by" = ( +/obj/structure/table/glass, +/obj/item/gun/magic/staff/slipping, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bB" = ( +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bD" = ( +/obj/effect/decal/mecha_wreckage/honker, +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"bH" = ( +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bL" = ( +/obj/item/reagent_containers/food/drinks/trophy/gold_cup, +/obj/structure/table/glass, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bM" = ( +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bN" = ( +/obj/machinery/disposal/deliveryChute, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bO" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bP" = ( +/obj/structure/statue/bananium/clown, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bQ" = ( +/obj/structure/table/glass, +/obj/item/grown/bananapeel/bluespace, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bR" = ( +/obj/structure/table/glass, +/obj/item/clothing/shoes/magboots/clown, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bS" = ( +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bT" = ( +/obj/item/slime_extract/rainbow, +/obj/structure/table/glass, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bU" = ( +/obj/item/bikehorn/airhorn, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bW" = ( +/obj/item/bikehorn, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bY" = ( +/obj/effect/mob_spawn/human/corpse/damaged, +/obj/effect/decal/cleanable/blood/old, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bZ" = ( +/obj/machinery/door/airlock/bananium, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"ca" = ( +/obj/item/bikehorn, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"cc" = ( +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"ch" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"cu" = ( +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"dK" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"dL" = ( +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"dM" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"dO" = ( +/obj/machinery/light, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"eX" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/lavaland/surface/outdoors/explored) +"gX" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/chasm/straight_down/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"hY" = ( +/obj/machinery/light, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/clownplanet) +"pv" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/clownplanet) +"ye" = ( +/turf/simulated/floor/plating/lava/smooth, +/area/ruin/powered/clownplanet) +"CB" = ( +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/hope, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/lavaland/surface/outdoors/explored) +"KX" = ( +/obj/item/grown/bananapeel{ + color = "#2F3000"; + name = "stealth banana peel" + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"LH" = ( +/obj/machinery/disposal/deliveryChute{ + desc = "The following is engraved upon the chute: A FATE WORSE THAN DEATH LIES WITHIN"; + dir = 1; + name = "THE TRIAL OF HONKITUDE" + }, +/obj/structure/disposalpipe/trunk, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/ruin/powered/clownplanet) +"Mv" = ( +/obj/effect/mapping_helpers/no_lava, +/mob/living/simple_animal/hostile/retaliate/clown, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"MR" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/clownplanet) +"TD" = ( +/obj/structure/disposalpipe/trunk, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/ruin/powered/clownplanet) +"VH" = ( +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"Xm" = ( +/obj/item/clothing/head/cone, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/lavaland/surface/outdoors/explored) +"XO" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"Yf" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/clownplanet) +"YI" = ( +/obj/machinery/light/small, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/ruin/powered/clownplanet) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +XO +XO +XO +XO +XO +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +cc +cc +cc +cc +cc +cc +cc +pv +XO +gX +XO +XO +gX +pv +cc +cc +cc +cc +cc +aa +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +aa +cc +cc +cc +ye +ye +ye +ye +ye +cc +cc +gX +gX +KX +gX +gX +cc +cc +ye +ye +ye +cc +cc +cc +aa +aa +aa +aa +"} +(4,1,1) = {" +aa +aa +aa +aa +cc +cc +ye +ye +ye +ab +aA +ab +aA +ye +cc +cc +gX +gX +gX +cc +cc +ye +ye +aU +cu +ye +ye +cc +cc +aa +aa +aa +"} +(5,1,1) = {" +aa +aa +aa +cc +cc +ye +ye +ab +ch +VH +aH +ay +aS +aA +ye +cc +cc +cc +cc +cc +bO +bB +aU +ye +ye +ye +ye +ye +cc +cc +aa +aa +"} +(6,1,1) = {" +aa +aa +aa +cc +ye +ye +cc +at +ah +af +aI +af +av +aL +ye +cc +bB +bH +bB +cc +bB +bH +bY +bB +aU +ye +aU +ye +ye +cc +Yf +aa +"} +(7,1,1) = {" +aa +aa +cc +cc +ye +ab +aj +ap +am +ah +af +aA +aL +aL +cc +bn +br +bB +bH +bH +bB +bH +bB +bB +bB +cc +ye +cu +ye +cc +cc +aa +"} +(8,1,1) = {" +aa +aa +cc +ye +ye +ae +af +av +am +aL +aX +aL +aN +aY +bf +cc +bs +br +bB +cc +cc +bH +cc +bB +bB +bB +aU +ye +ye +ye +cc +aa +"} +(9,1,1) = {" +aa +aa +cc +ye +ab +af +af +ay +an +an +aL +aN +aN +aN +bg +bf +cc +cc +br +bB +bB +bH +bB +bB +ca +bH +dO +cc +ye +ye +cc +aa +"} +(10,1,1) = {" +aa +Mv +cc +ye +ac +ag +af +av +aL +am +aL +aN +aN +aZ +bc +bh +br +br +br +bB +cc +bB +bB +bH +bH +bB +bB +ye +aU +ye +cc +cc +"} +(11,1,1) = {" +aa +hY +cc +ye +ad +ch +ak +ay +am +am +aL +aN +aT +aZ +bc +bf +cc +br +br +bB +bB +cc +bB +bB +bB +bB +bH +ye +aU +ye +ye +cc +"} +(12,1,1) = {" +aa +Mv +cc +ye +ae +af +af +az +am +ac +ap +aL +aN +ba +bh +cc +cc +br +bB +bB +cc +cc +bB +bB +cc +bB +bH +ye +cu +aU +ye +cc +"} +(13,1,1) = {" +XO +Mv +cc +ye +cc +ah +af +ap +aC +aj +af +ap +aL +aL +bi +ch +aA +cc +cc +cc +bP +bS +cc +dM +bB +bH +ca +bB +ye +aU +ye +cc +"} +(14,1,1) = {" +XO +Xm +cc +cc +ye +ac +af +af +af +af +aJ +af +ay +an +bj +al +am +cc +cc +bL +bM +bM +bM +cc +bB +bH +bH +bB +ye +aU +ye +cc +"} +(15,1,1) = {" +eX +eX +LH +ch +ch +au +af +ch +af +aF +ch +aj +af +ay +as +an +aC +av +cc +dK +bQ +bT +bM +cc +cc +bH +bB +bB +ye +aU +ye +cc +"} +(16,1,1) = {" +eX +CB +YI +cc +ye +cu +ah +aA +ah +av +ah +af +af +au +bk +aC +av +bj +ch +bN +bM +bU +bM +bZ +bB +bH +bB +cc +ye +aU +ye +cc +"} +(17,1,1) = {" +eX +eX +TD +ch +ch +ai +ay +an +an +aL +an +aO +af +av +bl +bo +bt +bx +cc +bM +bR +by +bM +cc +bB +bB +bB +bB +ye +aU +ye +cc +"} +(18,1,1) = {" +XO +eX +cc +cc +ye +aL +as +am +am +an +an +an +ar +aC +av +bp +aL +bv +cc +bL +bM +bM +bM +cc +bB +bB +bB +bB +ye +aU +ye +cc +"} +(19,1,1) = {" +XO +Mv +cc +ye +ye +aL +as +am +aD +an +an +aL +cc +cc +aK +cc +bD +cc +bB +cc +bP +dL +cc +dM +bB +bH +bH +bB +ye +aU +ye +cc +"} +(20,1,1) = {" +aa +Mv +cc +ye +cc +aL +ar +an +an +am +an +aL +aV +bb +bm +cc +bu +aA +bB +bB +cc +cc +bY +bB +bB +bH +bB +ye +aU +cu +ye +cc +"} +(21,1,1) = {" +aa +hY +cc +ye +cc +aL +aw +aB +aL +am +aL +aQ +aN +bc +bc +bf +cc +aK +br +bB +bB +cc +bB +bH +bB +bB +bB +ye +aU +ye +ye +cc +"} +(22,1,1) = {" +aa +Mv +cc +ye +aq +ao +ar +aL +aP +am +aL +aR +aN +bc +bc +bq +ch +bw +cc +bB +bB +bH +bH +bH +bB +bW +dO +cc +aU +ye +cc +cc +"} +(23,1,1) = {" +aa +aa +cc +ye +cc +cc +ar +an +an +aD +aK +aN +aW +bd +bh +bf +cc +br +br +bB +bB +bH +bH +bB +bB +cc +cc +ye +cu +ye +cc +aa +"} +(24,1,1) = {" +aa +aa +cc +ye +cc +cc +as +an +aL +an +aL +aL +aV +be +bf +cc +bs +br +bB +bB +bB +bB +bB +cc +bB +bB +ye +cu +ye +ye +cc +aa +"} +(25,1,1) = {" +aa +aa +cc +ye +ye +cc +ar +an +an +an +aC +ap +aL +cc +cc +br +br +bB +bB +bB +bH +bW +bB +bB +bB +cc +ye +aU +ye +cc +cc +aa +"} +(26,1,1) = {" +aa +aa +cc +cc +ye +cc +cc +aC +ap +aG +af +af +aE +cc +ye +cc +bO +bB +bB +cc +bB +bB +cc +bB +bB +ye +cu +ye +ye +cc +Yf +aa +"} +(27,1,1) = {" +aa +aa +aa +cc +cc +ye +ye +cc +cu +cc +aM +ar +cu +cc +ye +cc +cc +cc +cc +cc +bB +bB +bB +ye +ye +ye +ye +ye +cc +cc +aa +aa +"} +(28,1,1) = {" +aa +aa +aa +aa +cc +cc +ye +ye +ye +aU +aU +aU +cc +ye +cc +cc +gX +gX +gX +cc +cc +ye +ye +cu +aU +ye +ye +cc +cc +aa +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +cc +cc +cc +ye +ye +ye +ye +ye +cc +cc +gX +gX +KX +gX +gX +cc +cc +ye +ye +ye +cc +cc +cc +aa +aa +aa +aa +"} +(30,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +cc +cc +cc +cc +cc +cc +cc +MR +XO +XO +XO +XO +gX +MR +cc +cc +cc +cc +cc +aa +aa +aa +aa +aa +aa +"} +(31,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +XO +gX +XO +XO +XO +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm new file mode 100644 index 00000000000..01797b0ea59 --- /dev/null +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm @@ -0,0 +1,1364 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/obj/effect/baseturf_helper/lava_land/surface, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"ac" = ( +/obj/item/stack/medical/ointment, +/obj/structure/table, +/obj/item/stack/medical/bruise_pack, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ad" = ( +/obj/structure/table, +/obj/item/stack/medical/bruise_pack, +/obj/item/stack/medical/bruise_pack, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ae" = ( +/obj/machinery/power/smes, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"af" = ( +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ag" = ( +/obj/structure/reagent_dispensers/beerkeg, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ah" = ( +/obj/item/reagent_containers/food/drinks/mug, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ai" = ( +/obj/machinery/shower, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"aj" = ( +/obj/structure/sink, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ak" = ( +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"al" = ( +/obj/effect/decal/cleanable/blood/oil, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"am" = ( +/obj/machinery/door/airlock/hatch, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"an" = ( +/obj/structure/toilet{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ao" = ( +/turf/simulated/floor/plating/ice/smooth, +/area/ruin/powered/snow_biodome) +"ap" = ( +/obj/structure/flora/rock/icy, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aq" = ( +/turf/simulated/wall/mineral/wood, +/area/ruin/powered/snow_cabin) +"ar" = ( +/obj/machinery/door/airlock/wood, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_cabin) +"as" = ( +/obj/structure/fans, +/turf/simulated/wall/mineral/wood, +/area/ruin/powered/snow_cabin) +"at" = ( +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"au" = ( +/obj/structure/bed, +/obj/item/bedsheet/blue, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"av" = ( +/obj/structure/bookcase/random, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aw" = ( +/obj/structure/table/wood, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"ax" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/snacks/beans, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"ay" = ( +/obj/structure/closet/crate/trashcart, +/obj/item/trash/semki, +/obj/item/trash/candy, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"az" = ( +/obj/structure/flora/tree/pine, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aA" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aB" = ( +/obj/structure/flora/rock/pile/icy, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aC" = ( +/obj/structure/flora/tree/dead, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aD" = ( +/obj/machinery/door/airlock/wood, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aE" = ( +/obj/structure/extinguisher_cabinet, +/turf/simulated/wall/mineral/wood, +/area/ruin/powered/snow_cabin) +"aF" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/h_chocolate, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aG" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aH" = ( +/mob/living/simple_animal/hostile/skeleton/eskimo, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aI" = ( +/obj/structure/flora/bush, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aJ" = ( +/obj/vehicle/atv, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aK" = ( +/obj/structure/table/wood, +/obj/item/key/snowmobile, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aL" = ( +/obj/structure/displaycase/lavaland_winter, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aM" = ( +/turf/simulated/floor/carpet, +/area/ruin/powered/snow_cabin) +"aN" = ( +/obj/structure/bed/dogbed, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aO" = ( +/obj/machinery/door/airlock/multi_tile/glass, +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"aP" = ( +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"aQ" = ( +/obj/structure/flora/grass/both, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aR" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bi" = ( +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_cabin) +"bl" = ( +/turf/simulated/floor/wood/cold, +/area/ruin/powered/snow_biodome) +"bv" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/plating/ice/smooth, +/area/ruin/powered/snow_biodome) +"bw" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"bx" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"by" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bz" = ( +/obj/machinery/light, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"bB" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bD" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bM" = ( +/obj/machinery/light, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bN" = ( +/obj/machinery/light, +/turf/simulated/floor/plating/ice/smooth, +/area/ruin/powered/snow_biodome) +"dS" = ( +/obj/machinery/light/small, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"eb" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"eg" = ( +/obj/machinery/vending/coffee, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"gh" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"gz" = ( +/obj/structure/chair/stool, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"hA" = ( +/obj/machinery/light/built{ + dir = 1 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"qt" = ( +/obj/machinery/door/airlock/silver, +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"tb" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"tl" = ( +/turf/simulated/floor/pod/light, +/area/ruin/powered/snow_biodome) +"vf" = ( +/obj/machinery/door/airlock/multi_tile/glass, +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_cabin) +"xU" = ( +/obj/item/storage/toolbox/mechanical, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"zT" = ( +/obj/machinery/door/airlock/silver, +/obj/structure/fans/tiny, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"AM" = ( +/obj/structure/table, +/obj/item/pen, +/obj/item/paper, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Dd" = ( +/obj/structure/rack, +/obj/item/clothing/suit/hooded/wintercoat/science, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/gloves/fingerless, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Ef" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Ez" = ( +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/multi_tile/glass, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"HP" = ( +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"HR" = ( +/obj/structure/closet/secure_closet/freezer/fridge/open, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"JZ" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"KS" = ( +/obj/structure/closet, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/item/twohanded/required/chainsaw, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Mp" = ( +/obj/item/clothing/mask/balaclava, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Oj" = ( +/obj/structure/table, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"PD" = ( +/obj/machinery/door/airlock/hatch, +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"PK" = ( +/obj/structure/table, +/obj/item/pen, +/obj/item/paper_bin, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Qa" = ( +/obj/effect/mapping_helpers/no_lava, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"QI" = ( +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"QK" = ( +/obj/structure/table, +/obj/item/storage/fancy/cigarettes/cigpack_carp, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"QN" = ( +/obj/effect/spawner/window, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"Sj" = ( +/obj/effect/decal/cleanable/blood/oil, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Ub" = ( +/obj/structure/filingcabinet, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"UM" = ( +/obj/machinery/computer/monitor/secret{ + dir = 1 + }, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Wg" = ( +/turf/simulated/wall/r_wall, +/area/ruin/powered/snow_biodome) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +Wg +Wg +Wg +Wg +PD +Wg +Wg +Wg +Wg +Wg +Wg +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +Wg +Wg +Wg +Wg +Wg +Dd +gh +HP +tl +gh +HP +Ub +Wg +Wg +Wg +Wg +Wg +aa +aa +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +Wg +Wg +Wg +ak +by +ak +Wg +Dd +HP +HP +tl +PK +gz +UM +Wg +ak +ak +ak +Wg +Wg +Wg +QI +QI +aa +aa +aa +"} +(4,1,1) = {" +aa +aa +aa +Wg +Wg +ak +aC +ak +ak +ak +Wg +QN +QN +QN +qt +QN +QN +QN +Wg +ak +ak +ak +ak +ak +Wg +Wg +QI +QI +aa +aa +"} +(5,1,1) = {" +aa +aa +Wg +Wg +ao +ao +ak +aI +ak +ak +by +az +ak +aB +ak +ak +ak +aI +by +ak +ak +ak +ak +ak +ak +Wg +Wg +QI +tb +aa +"} +(6,1,1) = {" +aa +aa +Wg +bv +ao +ao +ao +ao +ak +aI +ak +ak +ak +ak +ak +ak +ak +ak +ak +aQ +ak +ak +ak +az +ak +ak +Wg +QI +tb +aa +"} +(7,1,1) = {" +aa +Wg +Wg +ap +ak +ao +ao +ao +ao +ak +ak +ak +ak +ak +az +ak +aC +ak +ak +aI +aI +ak +ak +ak +ak +bM +Wg +Wg +tb +aa +"} +(8,1,1) = {" +aa +Wg +ak +ak +ak +ak +ak +ao +ao +ao +ao +ak +ak +ak +ak +ak +ak +ak +ap +aI +ak +aQ +ak +ak +ak +az +ak +Wg +tb +tb +"} +(9,1,1) = {" +aa +Wg +Wg +Wg +ak +az +ak +ak +ao +ao +ao +ao +ao +ak +ak +ak +ak +ak +ak +ak +ak +aC +ak +ak +ak +ak +ak +Wg +hA +tb +"} +(10,1,1) = {" +Wg +Wg +af +Wg +ak +ak +ak +ak +ak +ak +ak +ao +ao +ao +ao +ak +aI +az +ak +ak +ak +ak +ak +aI +ak +ak +ak +Wg +tb +tb +"} +(11,1,1) = {" +Wg +ac +af +aq +aq +aq +aq +aq +aq +aq +bD +ao +ao +ao +ao +ao +ak +ak +bl +bl +ak +aI +ak +ak +ak +Wg +Wg +Wg +Wg +tb +"} +(12,1,1) = {" +Wg +ad +af +ar +bw +at +aD +at +aL +aq +ak +az +ak +ao +ao +ao +ao +ao +bl +bl +ak +ak +ak +az +bM +Wg +Dd +Dd +Wg +tb +"} +(13,1,1) = {" +Wg +ae +af +aq +au +au +aq +at +bz +aq +ak +ak +ak +ao +ao +ao +ao +ao +bl +bl +ao +ak +ak +ak +aI +Wg +Mp +dS +Wg +tb +"} +(14,1,1) = {" +Wg +af +al +aq +aq +aq +aE +at +at +aq +ak +ak +aC +ak +ao +ak +ao +ao +bl +bl +ao +ao +aI +ak +ak +Wg +tl +tl +Wg +tb +"} +(15,1,1) = {" +Wg +ae +af +aq +av +at +at +aH +aM +vf +ap +ak +ak +ak +ak +ak +ak +ao +bl +bl +ao +ao +ak +ak +ak +aO +tl +tl +Ez +Qa +"} +(16,1,1) = {" +Wg +ag +ah +as +aw +aA +aA +at +aM +bi +ak +ak +aQ +ak +ak +az +ak +ak +bl +bl +ak +ao +ao +ak +ak +aP +tl +tl +aP +Qa +"} +(17,1,1) = {" +Wg +ah +af +aq +ax +aK +aF +at +at +aq +ak +aI +ak +ak +ak +ak +ak +ak +ak +ak +ak +ao +ao +ao +ak +Wg +tl +tl +Wg +tb +"} +(18,1,1) = {" +Wg +Wg +am +aq +av +at +aG +at +bz +aq +aR +ak +ak +ak +ak +ab +ak +ak +aC +ak +ak +ak +ao +ao +ao +Wg +HP +dS +Wg +tb +"} +(19,1,1) = {" +Wg +ai +af +aq +av +bx +aH +at +aN +aq +ak +ak +ak +az +ak +ak +ak +ak +ak +ak +ak +ak +ak +ao +bN +Wg +QK +AM +Wg +tb +"} +(20,1,1) = {" +Wg +aj +af +aq +aq +aq +aq +aq +aq +aq +bD +ak +ak +ak +ak +aI +ak +az +ak +ak +ak +ak +az +ak +ao +Wg +Wg +Wg +Wg +tb +"} +(21,1,1) = {" +Wg +Wg +an +Wg +ay +ak +ak +ak +ak +ak +ak +ak +ak +ak +aC +ak +ak +ak +ak +ap +ak +ak +ak +ak +ak +ak +ak +Wg +tb +tb +"} +(22,1,1) = {" +aa +Wg +Wg +Wg +ak +ak +aI +ak +ap +ak +ak +ak +ak +ak +ak +ak +ak +ak +ak +ak +aI +ak +ak +aQ +ak +ak +ak +Wg +hA +tb +"} +(23,1,1) = {" +aa +Wg +ak +ak +az +ak +aJ +ak +ak +ak +ak +ak +ak +az +ak +aQ +ak +aC +ak +aI +ak +az +aI +aI +ak +ak +ak +Wg +tb +tb +"} +(24,1,1) = {" +aa +Wg +Wg +ak +ak +aB +ak +ak +aC +ak +ak +ak +ak +aI +ak +ap +ak +ak +ak +ak +ak +ak +aI +aI +ak +bM +Wg +Wg +tb +aa +"} +(25,1,1) = {" +aa +aa +Wg +ap +ak +ak +ak +ak +ak +aQ +ak +ak +ak +aI +ak +ak +ak +ak +aQ +ak +ak +aB +ak +ak +aC +ak +Wg +QI +tb +aa +"} +(26,1,1) = {" +aa +aa +Wg +Wg +ak +ak +az +ak +ak +ak +bB +ak +ak +ak +ak +ak +az +ak +bB +ak +ak +az +ak +ak +ak +Wg +Wg +QI +aa +aa +"} +(27,1,1) = {" +aa +aa +aa +Wg +Wg +ak +ak +ak +ak +ak +Wg +QN +QN +QN +zT +QN +QN +QN +Wg +ak +ak +ak +ak +ak +Wg +Wg +QI +QI +aa +aa +"} +(28,1,1) = {" +aa +aa +aa +aa +Wg +Wg +Wg +ak +bB +ak +Wg +eg +HP +tl +tl +tl +Sj +xU +Wg +ak +bB +ak +Wg +Wg +Wg +QI +QI +aa +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +aa +Wg +Wg +Wg +Wg +Wg +HR +eb +gz +Oj +JZ +KS +Ef +Wg +Wg +Wg +Wg +Wg +aa +aa +aa +aa +aa +aa +aa +"} +(30,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +Wg +Wg +Wg +Wg +Wg +Wg +Wg +Wg +Wg +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index 8bf85306742..18ff8e4f1bc 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -1066,6 +1066,7 @@ /obj/structure/stone_tile/block/cracked{ dir = 1 }, +/obj/item/cultivator/rake, /obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) @@ -1305,6 +1306,7 @@ dir = 8 }, /obj/structure/stone_tile/center, +/obj/item/hatchet/wooden, /obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) @@ -1326,10 +1328,10 @@ /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "dw" = ( -/obj/item/reagent_containers/glass/bucket, /obj/structure/stone_tile/block/cracked{ dir = 4 }, +/obj/item/reagent_containers/glass/bucket/wooden, /obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) diff --git a/_maps/map_files/RandomZLevels/beach.dmm b/_maps/map_files/RandomZLevels/beach.dmm index 2931d7175b7..fe4060ad52d 100644 --- a/_maps/map_files/RandomZLevels/beach.dmm +++ b/_maps/map_files/RandomZLevels/beach.dmm @@ -13,7 +13,7 @@ /turf/unsimulated/beach/water/deep/rock_wall, /area/awaymission/undersea) "ae" = ( -/obj/structure/ladder/dive_point/anchor{ +/obj/structure/ladder/unbreakable/dive_point/anchor{ id = "pirate" }, /turf/unsimulated/beach/water/deep/sand_floor, @@ -217,7 +217,7 @@ /turf/unsimulated/beach/water/deep/wood_floor, /area/awaymission/undersea) "aU" = ( -/obj/structure/ladder/dive_point/anchor, +/obj/structure/ladder/unbreakable/dive_point/anchor, /turf/unsimulated/beach/water/deep/sand_floor, /area/awaymission/undersea) "aV" = ( @@ -1113,7 +1113,7 @@ /turf/unsimulated/beach/water/deep, /area/awaymission/beach) "dv" = ( -/obj/structure/ladder/dive_point/buoy, +/obj/structure/ladder/unbreakable/dive_point/buoy, /turf/unsimulated/beach/water/deep, /area/awaymission/beach) "dw" = ( @@ -1306,7 +1306,7 @@ }, /area/awaymission/beach) "dW" = ( -/obj/structure/ladder/dive_point/buoy{ +/obj/structure/ladder/unbreakable/dive_point/buoy{ id = "pirate" }, /turf/unsimulated/beach/water, diff --git a/_maps/map_files/RandomZLevels/example.dmm b/_maps/map_files/RandomZLevels/example.dmm index fd85d240c36..779a0bede34 100644 --- a/_maps/map_files/RandomZLevels/example.dmm +++ b/_maps/map_files/RandomZLevels/example.dmm @@ -261,7 +261,7 @@ /turf/simulated/floor/plasteel, /area/awaymission/example) "aH" = ( -/obj/structure/ladder{ +/obj/structure/ladder/unbreakable{ height = 1; id = "example" }, @@ -782,7 +782,7 @@ /turf/simulated/floor/plasteel, /area/awaymission/example) "ca" = ( -/obj/structure/ladder{ +/obj/structure/ladder/unbreakable{ id = "example" }, /turf/simulated/floor/plating, diff --git a/_maps/map_files/RandomZLevels/spacehotel.dmm b/_maps/map_files/RandomZLevels/spacehotel.dmm index 8394ca1b635..4b45711ff3d 100644 --- a/_maps/map_files/RandomZLevels/spacehotel.dmm +++ b/_maps/map_files/RandomZLevels/spacehotel.dmm @@ -540,7 +540,7 @@ requires_power = 0 }) "aZ" = ( -/obj/structure/ladder/dive_point/anchor{ +/obj/structure/ladder/unbreakable/dive_point/anchor{ id = "weirddive"; layer = 4.5 }, @@ -1996,7 +1996,7 @@ requires_power = 0 }) "dA" = ( -/obj/structure/ladder/dive_point/anchor{ +/obj/structure/ladder/unbreakable/dive_point/anchor{ layer = 4.5 }, /turf/unsimulated/beach/water/deep/wood_floor{ @@ -2721,8 +2721,8 @@ /turf/unsimulated/beach/water/drop, /area/awaymission/spacehotel) "fC" = ( -/obj/structure/ladder/dive_point/buoy, -/obj/structure/ladder/dive_point/buoy{ +/obj/structure/ladder/unbreakable/dive_point/buoy, +/obj/structure/ladder/unbreakable/dive_point/buoy{ id = "weirddive"; invisibility = 101 }, @@ -3465,7 +3465,7 @@ }, /area/awaymission/spacehotel) "hG" = ( -/obj/structure/ladder{ +/obj/structure/ladder/unbreakable{ height = 1; icon_state = "ladder10"; id = "service" @@ -3525,7 +3525,7 @@ /area/awaymission/spacehotel) "hN" = ( /obj/effect/decal/cleanable/blood/old, -/obj/structure/ladder{ +/obj/structure/ladder/unbreakable{ height = 2; icon_state = "ladder01"; id = "service" diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 661dca15a0e..71d83c16ee1 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -4055,7 +4055,7 @@ /turf/simulated/floor/plasteel, /area/security/armoury) "ahH" = ( -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, /obj/structure/window/reinforced{ dir = 8 }, @@ -4155,7 +4155,7 @@ }, /area/security/brig) "ahR" = ( -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, /obj/structure/window/reinforced{ dir = 4 }, @@ -4324,7 +4324,7 @@ }, /area/security/brig) "aif" = ( -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, /obj/structure/window/reinforced{ dir = 8 }, @@ -4370,7 +4370,7 @@ }, /area/security/brig) "aij" = ( -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, /obj/structure/window/reinforced{ dir = 4 }, @@ -15799,7 +15799,7 @@ "aAd" = ( /obj/effect/spawner/window/reinforced, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aAe" = ( /turf/space, /turf/simulated/shuttle/wall{ @@ -15856,7 +15856,7 @@ tag = "" }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aAm" = ( /turf/simulated/wall/r_wall, /area/crew_quarters/courtroom) @@ -16579,7 +16579,7 @@ initialize_directions = 10 }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aBF" = ( /obj/machinery/atmospherics/unary/vent_pump/high_volume{ dir = 4; @@ -16609,7 +16609,7 @@ tag = "" }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aBG" = ( /obj/machinery/door/airlock/external{ id_tag = "s_docking_airlock"; @@ -17125,7 +17125,7 @@ /obj/effect/spawner/window/reinforced, /obj/machinery/atmospherics/pipe/simple/hidden, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aCD" = ( /obj/machinery/door/airlock/external{ frequency = 1379; @@ -17143,7 +17143,7 @@ tag = "" }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aCE" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "1" @@ -17575,13 +17575,13 @@ d2 = 4 }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aDv" = ( /turf/simulated/wall, /area/security/lobby) "aDw" = ( /turf/simulated/wall/r_wall, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aDx" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; @@ -17598,7 +17598,7 @@ filled = 0.05 }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aDy" = ( /obj/machinery/access_button{ command = "cycle_interior"; @@ -17622,7 +17622,7 @@ tag = "" }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aDz" = ( /obj/structure/rack, /obj/item/clothing/mask/cigarette/pipe, @@ -18153,7 +18153,7 @@ "aEC" = ( /obj/structure/chair/stool, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aED" = ( /obj/machinery/power/terminal, /obj/machinery/light/small{ @@ -18164,7 +18164,7 @@ icon_state = "0-8" }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aEE" = ( /obj/structure/cable{ d1 = 1; @@ -18173,7 +18173,7 @@ tag = "" }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aEF" = ( /obj/structure/table, /obj/item/paper_bin, @@ -18753,7 +18753,7 @@ shock_proof = 1 }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aFR" = ( /obj/structure/cable{ d2 = 8; @@ -18763,7 +18763,7 @@ charge = 0 }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aFS" = ( /obj/structure/cable{ d1 = 2; @@ -18776,11 +18776,11 @@ icon_state = "2-4" }, /turf/simulated/floor/plating, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aFT" = ( /obj/effect/decal/cleanable/fungus, /turf/simulated/wall/r_wall, -/area/solar/auxport) +/area/maintenance/auxsolarport) "aFU" = ( /obj/structure/table, /obj/item/toy/figure/detective, @@ -32864,8 +32864,8 @@ /obj/machinery/light{ dir = 1 }, -/obj/structure/reagent_dispensers/watertank/high, -/obj/item/reagent_containers/glass/bucket, +/obj/structure/table, +/obj/machinery/smartfridge/disks, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -36338,6 +36338,7 @@ /turf/simulated/floor/carpet, /area/crew_quarters/bar) "bou" = ( +/obj/item/reagent_containers/glass/bucket, /obj/structure/sink{ icon_state = "sink"; dir = 8; @@ -79987,7 +79988,7 @@ "cMF" = ( /obj/machinery/door/airlock/engineering{ name = "Engineering Checkpoint"; - req_access_txt = "11" + req_one_access_txt = "11;24" }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 0052c80df84..7c7b0403547 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -8742,7 +8742,7 @@ pixel_x = -3; pixel_y = 3 }, -/obj/item/clothing/glasses/hud/health/health_advanced, +/obj/item/clothing/glasses/hud/health/sunglasses, /obj/item/clothing/glasses/hud/security/sunglasses, /turf/unsimulated/floor{ tag = "icon-floor"; diff --git a/_maps/map_files/templates/spacehotel/s_01.dmm b/_maps/map_files/templates/spacehotel/s_01.dmm index f97f6613f07..8362c0f21cc 100644 --- a/_maps/map_files/templates/spacehotel/s_01.dmm +++ b/_maps/map_files/templates/spacehotel/s_01.dmm @@ -38,7 +38,7 @@ "f" = ( /obj/structure/rack, /obj/item/clothing/head/collectable/police, -/obj/item/clothing/head/nun_hood, +/obj/item/clothing/head/hooded/nun_hood, /obj/item/clothing/head/mailman, /obj/item/clothing/head/nursehat, /obj/item/clothing/head/wizard/fake, diff --git a/_maps/map_files/templates/spacehotel/s_02.dmm b/_maps/map_files/templates/spacehotel/s_02.dmm index c3ee3c4a727..6834bc8d7e8 100644 --- a/_maps/map_files/templates/spacehotel/s_02.dmm +++ b/_maps/map_files/templates/spacehotel/s_02.dmm @@ -38,7 +38,7 @@ "f" = ( /obj/structure/rack, /obj/item/clothing/head/collectable/police, -/obj/item/clothing/head/nun_hood, +/obj/item/clothing/head/hooded/nun_hood, /obj/item/clothing/head/mailman, /obj/item/clothing/head/nursehat, /obj/item/clothing/head/wizard/fake, diff --git a/_maps/test_all_maps.dm b/_maps/test_all_maps.dm index 064bf8defaf..55cb0ff946b 100644 --- a/_maps/test_all_maps.dm +++ b/_maps/test_all_maps.dm @@ -19,6 +19,8 @@ // Lavaland Ruins #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_beach.dmm" + #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_clown_planet.dmm" + #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_winter.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_animal_hospital.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_ash_walker1.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk1.dmm" @@ -44,7 +46,7 @@ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_syndicate_base1.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_ufo_crash.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_xeno_nest.dmm" - + // Space Ruins #include "map_files\RandomRuins\SpaceRuins\abandonedzoo.dmm" diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index fbc28695ebf..d8e051e600e 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -106,9 +106,10 @@ #define SAWN_INTACT 0 #define SAWN_OFF 1 -#define WEAPON_LIGHT 0 -#define WEAPON_MEDIUM 1 -#define WEAPON_HEAVY 2 +#define WEAPON_DUAL_WIELD 0 +#define WEAPON_LIGHT 1 +#define WEAPON_MEDIUM 2 +#define WEAPON_HEAVY 3 #define EXPLODE_NONE 0 //Don't even ask me why we need this. #define EXPLODE_DEVASTATE 1 diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 02b36614cb5..aa4b49ff6fc 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -155,6 +155,10 @@ // /mob/living/carbon signals #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) +// /mob/living/simple_animal/hostile signals +#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget" + #define COMPONENT_HOSTILE_NO_ATTACK 1 + // /obj signals #define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled) #define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) diff --git a/code/__DEFINES/crafting.dm b/code/__DEFINES/crafting.dm index 4b783490568..7bfd2935280 100644 --- a/code/__DEFINES/crafting.dm +++ b/code/__DEFINES/crafting.dm @@ -1,10 +1,28 @@ +//tablecrafting defines #define CAT_NONE "" -#define CAT_WEAPON "Weaponry" +#define CAT_WEAPONRY "Weaponry" +#define CAT_WEAPON "Weapons" #define CAT_AMMO "Ammunition" #define CAT_ROBOT "Robots" -#define CAT_FOOD "Food" #define CAT_MISC "Misc" #define CAT_PRIMAL "Tribal" +#define CAT_CLOTHING "Clothing" +#define CAT_FOOD "Foods" +#define CAT_BREAD "Breads" +#define CAT_BURGER "Burgers" +#define CAT_CAKE "Cakes" +#define CAT_EGG "Egg-Based Food" +#define CAT_MEAT "Meats" +#define CAT_SUSHI "Sushi" +#define CAT_MISCFOOD "Misc. Food" +#define CAT_PASTRY "Pastries" +#define CAT_PIE "Pies" +#define CAT_PIZZA "Pizzas" +#define CAT_SALAD "Salads" +#define CAT_SANDWICH "Sandwiches" +#define CAT_SOUP "Soups" +#define CAT_SPAGHETTI "Spaghettis" +#define CAT_ICE "Frozen" #define RECIPE_MICROWAVE "Microwave" #define RECIPE_OVEN "Oven" diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 14b712754fb..edc77bae4c3 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -13,6 +13,7 @@ #define CONDUCT 32 // conducts electricity (metal etc.) #define ABSTRACT 64 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way #define ON_BORDER 128 // item has priority to check when entering or leaving +#define PREVENT_CLICK_UNDER 256 #define EARBANGPROTECT 1024 diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm index 0fb9253a083..c7b055879f1 100644 --- a/code/__DEFINES/genetics.dm +++ b/code/__DEFINES/genetics.dm @@ -1,6 +1,8 @@ // String identifiers for associative list lookup +#define CHECK_DNA_AND_SPECIES(C) if((!(C.dna)) || (!(C.dna.species))) return + #define MUTCHK_FORCED 1 // mob/var/list/mutations @@ -22,7 +24,6 @@ /////////////////////////////////////// // MUTATIONS /////////////////////////////////////// - // Generic mutations: #define TK 1 #define COLDRES 2 @@ -105,6 +106,9 @@ #define NUTRITION_LEVEL_STARVING 150 #define NUTRITION_LEVEL_CURSED 0 +//Used as an upper limit for species that continuously gain nutriment +#define NUTRITION_LEVEL_ALMOST_FULL 535 + //Blood levels #define BLOOD_VOLUME_MAXIMUM 2000 #define BLOOD_VOLUME_NORMAL 560 @@ -146,4 +150,5 @@ #define RESISTHOT 16 #define RESISTCOLD 17 #define NO_EXAMINE 18 -#define CAN_WINGDINGS 19 \ No newline at end of file +#define CAN_WINGDINGS 19 +#define NOZOMBIE 20 \ No newline at end of file diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index c4478f62837..0e5c5316254 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -4,6 +4,7 @@ // Mobs #define ismegafauna(A) istype(A, /mob/living/simple_animal/hostile/megafauna) +#define iszombie(A) (is_species(A, /datum/species/zombie)) //Simple animals #define isshade(A) (istype(A, /mob/living/simple_animal/shade)) @@ -17,6 +18,8 @@ #define ismecha(A) (istype(A, /obj/mecha)) +#define isspacepod(A) (istype(A, /obj/spacepod)) + #define iseffect(A) (istype(A, /obj/effect)) #define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 27f467d65fc..4eb11963eff 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -390,6 +390,8 @@ #define BLOODY_FOOTPRINT_BASE_ALPHA 150 #define BLOOD_GAIN_PER_STEP 100 #define BLOOD_LOSS_PER_STEP 5 +#define BLOOD_LOSS_IN_SPREAD 20 +#define BLOOD_AMOUNT_PER_DECAL 20 //Bloody shoe blood states #define BLOOD_STATE_HUMAN "blood" @@ -485,10 +487,14 @@ // Cult summon possibilities #define SUMMON_POSSIBILITIES 3 +// Dice rigged options. #define DICE_NOT_RIGGED 1 #define DICE_BASICALLY_RIGGED 2 #define DICE_TOTALLY_RIGGED 3 +// Water temperature +#define COLD_WATER_TEMPERATURE 283.15 // 10 degrees celsius + // Parallax #define PARALLAX_DELAY_DEFAULT world.tick_lag #define PARALLAX_DELAY_MED 1 @@ -498,4 +504,4 @@ // Engine types #define ENGTYPE_SING "Singularity" #define ENGTYPE_SM "Supermatter" -#define ENGTYPE_TESLA "Tesla" \ No newline at end of file +#define ENGTYPE_TESLA "Tesla" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 608fcfcce20..22b43f84b9f 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -64,11 +64,12 @@ // Factor of how fast mob nutrition decreases #define HUNGER_FACTOR 0.1 -// Taste sensitivity - the more the more reagents you'll taste -#define TASTE_SENSITIVITY_NORMAL 1 -#define TASTE_SENSITIVITY_SHARP 1.5 -#define TASTE_SENSITIVITY_DULL 0.75 -#define TASTE_SENSITIVITY_NO_TASTE 0 +// Taste sensitivity - lower is more sensitive +// Represents the minimum portion of total taste the mob can sense +#define TASTE_SENSITIVITY_NORMAL 15 +#define TASTE_SENSITIVITY_SHARP 7.5 +#define TASTE_SENSITIVITY_DULL 20 +#define TASTE_SENSITIVITY_NO_TASTE 101 // Reagent type flags, defines the types of mobs this reagent will affect #define ORGANIC 1 @@ -218,3 +219,5 @@ #define hasorgans(A) (ishuman(A)) #define is_admin(user) (check_rights(R_ADMIN, 0, (user)) != 0) + +#define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return; \ No newline at end of file diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index a28d68a392b..54fd59307f4 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -7,8 +7,9 @@ #define SOUND_BUZZ 64 #define SOUND_INSTRUMENTS 128 #define SOUND_MENTORHELP 256 +#define SOUND_DISCO 512 -#define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_HEARTBEAT|SOUND_BUZZ|SOUND_INSTRUMENTS|SOUND_MENTORHELP) +#define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_HEARTBEAT|SOUND_BUZZ|SOUND_INSTRUMENTS|SOUND_MENTORHELP|SOUND_DISCO) #define CHAT_OOC 1 #define CHAT_DEAD 2 @@ -34,7 +35,7 @@ #define AMBIENT_OCCLUSION 2097152 #define CHAT_GHOSTPDA 4194304 #define NUMPAD_TARGET 8388608 -#define TOGGLES_TOTAL 16777215 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. +#define TOGGLES_TOTAL 16777215 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. #define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_LOOC|MEMBER_PUBLIC|DONATOR_PUBLIC|AMBIENT_OCCLUSION|CHAT_GHOSTPDA|NUMPAD_TARGET) diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 6ef269be1c2..b0a74b6c702 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -34,14 +34,14 @@ #define WAIT_FINISH 3 //shuttle mode defines -#define SHUTTLE_IDLE 0 -#define SHUTTLE_RECALL 1 -#define SHUTTLE_CALL 2 -#define SHUTTLE_DOCKED 3 -#define SHUTTLE_STRANDED 4 -#define SHUTTLE_ESCAPE 5 -#define SHUTTLE_ENDGAME 6 -#define SHUTTLE_IGNITING 7 +#define SHUTTLE_IGNITING 0 +#define SHUTTLE_IDLE 1 +#define SHUTTLE_RECALL 2 +#define SHUTTLE_CALL 3 +#define SHUTTLE_DOCKED 4 +#define SHUTTLE_STRANDED 5 +#define SHUTTLE_ESCAPE 6 +#define SHUTTLE_ENDGAME 7 // Shuttle return values #define SHUTTLE_CAN_DOCK "can_dock" diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index dc2b2e4ec0a..2a23cc8baa0 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -46,11 +46,7 @@ if(IS_WHITELISTED in S.species_traits) GLOB.whitelisted_species += S.name - for(var/D in subtypesof(/datum/crafting_recipe)) - var/datum/crafting_recipe/R = D - if(!initial(R.roundstart_enabled)) - continue - GLOB.crafting_recipes += new R + init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) //Pipe list building init_subtypes(/datum/pipes, GLOB.construction_pipe_list) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index ed4f3242c4d..0b37872decd 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -948,10 +948,16 @@ The _flatIcons list is a cache for generated icon files. return "#[color]" //Imagine removing pixels from the main icon that are covered by pixels from the mask icon. -/proc/get_icon_difference(var/icon/main, var/icon/mask) +//Standard behaviour is to cut pixels from the main icon that are covered by pixels from the mask icon unless passed mask_ready, see below. +/proc/get_icon_difference(var/icon/main, var/icon/mask, var/mask_ready) + /*You should skip prep if the mask is already sprited properly. This significantly improves performance by eliminating most of the realtime icon work. + e.g. A 'ready' mask is a mask where the part you want cut out is missing (no pixels, 0 alpha) from the sprite, and everything else is solid white.*/ + if(istype(main) && istype(mask)) - mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible. - mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white. - mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white pixels. + if(!mask_ready) //Prep the mask if we're using a regular old sprite and not a special-made mask. + mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible. + mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white. + mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white background pixels. + main.AddAlphaMask(mask) //Make the pixels in the main icon that are in the transparent zone of the mask icon also vanish (fully transparent). - return main + return main \ No newline at end of file diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 9e01753d492..49983658d48 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -799,3 +799,29 @@ proc/dd_sortedObjectList(list/incoming) L.Swap(start++, end--) return L + +/proc/counterlist_scale(list/L, scalar) + var/list/out = list() + for(var/key in L) + out[key] = L[key] * scalar + . = out + +/proc/counterlist_sum(list/L) + . = 0 + for(var/key in L) + . += L[key] + +/proc/counterlist_normalise(list/L) + var/avg = counterlist_sum(L) + if(avg != 0) + . = counterlist_scale(L, 1 / avg) + else + . = L + +/proc/counterlist_combine(list/L1, list/L2) + for(var/key in L2) + var/other_value = L2[key] + if(key in L1) + L1[key] += other_value + else + L1[key] = other_value \ No newline at end of file diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index d9d21c60e1e..f383ba3fc33 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -16,6 +16,7 @@ GLOBAL_LIST_INIT(prisoncomputer_list, list()) GLOBAL_LIST_INIT(celltimers_list, list()) // list of all cell timers GLOBAL_LIST_INIT(cell_logs, list()) GLOBAL_LIST_INIT(navigation_computers, list()) +GLOBAL_LIST_INIT(zombie_infection_list, list()) GLOBAL_LIST_INIT(all_areas, list()) GLOBAL_LIST_INIT(machines, list()) @@ -42,6 +43,7 @@ GLOBAL_LIST_INIT(global_radios, list()) //list of all radios, across all z-le GLOBAL_LIST_INIT(meteor_list, list()) //list of all meteors GLOBAL_LIST_INIT(poi_list, list()) //list of points of interest for observe/follow GLOBAL_LIST_INIT(active_jammers, list()) // List of active radio jammers +GLOBAL_LIST_EMPTY(ladders) GLOBAL_LIST_INIT(active_diseases, list()) //List of Active disease in all mobs; purely for quick referencing. diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index b823efe2563..7695b8b5851 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -107,6 +107,9 @@ if(next_move > world.time) // in the year 2000... return + if(!modifiers["catcher"] && A.IsObscured()) + return + if(istype(loc,/obj/mecha)) if(!locate(/turf) in list(A,A.loc)) // Prevents inventory from being drilled return @@ -172,6 +175,24 @@ return +//Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it +/atom/proc/IsObscured() + if(!isturf(loc)) //This only makes sense for things directly on turfs for now + return FALSE + var/turf/T = get_turf_pixel(src) + if(!T) + return FALSE + for(var/atom/movable/AM in T) + if(AM.flags & PREVENT_CLICK_UNDER && AM.density && AM.layer > layer) + return TRUE + return FALSE + +/turf/IsObscured() + for(var/atom/movable/AM in src) + if(AM.flags & PREVENT_CLICK_UNDER && AM.density) + return TRUE + return FALSE + // Default behavior: ignore double clicks, consider them normal clicks instead /mob/proc/DblClickOn(var/atom/A, var/params) return @@ -399,8 +420,8 @@ dir = direction /obj/screen/click_catcher - icon = 'icons/mob/screen_full.dmi' - icon_state = "passage0" + icon = 'icons/mob/screen_gen.dmi' + icon_state = "catcher" plane = CLICKCATCHER_PLANE mouse_opacity = MOUSE_OPACITY_OPAQUE screen_loc = "CENTER" @@ -430,5 +451,7 @@ C.swap_hand() else var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr)) - T.Click(location, control, params) - return 1 + params += "&catcher=1" + if(T) + T.Click(location, control, params) + . = 1 \ No newline at end of file diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 4aa30657778..f9528f2b2b9 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -68,8 +68,14 @@ SUBSYSTEM_DEF(ticker) current_state = GAME_STATE_PREGAME fire() // TG says this is a good idea if(GAME_STATE_PREGAME) + if(!going) + return + // This is so we dont have sleeps in controllers, because that is a bad, bad thing - pregame_timeleft = max(0,round_start_time - world.time) + if(!delay_end) + pregame_timeleft = max(0,round_start_time - world.time) // Normal lobby countdown when roundstart was not delayed + else + pregame_timeleft = max(0,pregame_timeleft - 20) // If roundstart was delayed, we should resume the countdown where it left off if(pregame_timeleft <= 600 && !tipped) // 60 seconds send_tip_of_the_round() @@ -83,6 +89,7 @@ SUBSYSTEM_DEF(ticker) current_state = GAME_STATE_STARTUP Master.SetRunLevel(RUNLEVEL_LOBBY) if(GAME_STATE_PLAYING) + delay_end = 0 // reset this in case round start was delayed mode.process() mode.process_job_tasks() var/game_finished = SSshuttle.emergency.mode >= SHUTTLE_ENDGAME || mode.station_was_nuked diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index e8339f81945..138c670290a 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -738,22 +738,7 @@ if(!istype(M)) to_chat(usr, "This can only be used on instances of type /mob") return - to_chat(M, "Control of your mob has been offered to dead players.") - log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.") - var/minhours = input(usr, "Minimum hours required to play [M]?", "Set Min Hrs", 10) as num - message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts with [minhours] hrs playtime") - var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name ? M.real_name : M.name]?", poll_time = 100, min_hours = minhours) - var/mob/dead/observer/theghost = null - - if(candidates.len) - theghost = pick(candidates) - to_chat(M, "Your mob has been taken over by a ghost!") - message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])") - M.ghostize() - M.key = theghost.key - else - to_chat(M, "There were no ghosts willing to take control.") - message_admins("No ghosts were willing to take control of [key_name_admin(M)])") + offer_control(M) else if(href_list["delete"]) if(!check_rights(R_DEBUG, 0)) diff --git a/code/datums/diseases/pierrot_throat.dm b/code/datums/diseases/pierrot_throat.dm index 6fb0ac53507..451f9f28dbd 100644 --- a/code/datums/diseases/pierrot_throat.dm +++ b/code/datums/diseases/pierrot_throat.dm @@ -59,5 +59,6 @@ if(prob(5)) affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) ) - if(!istype(affected_mob.wear_mask, /obj/item/clothing/mask/gas/virusclown_hat)) - affected_mob.equip_to_slot(new /obj/item/clothing/mask/gas/virusclown_hat(src), slot_wear_mask) \ No newline at end of file + if(!istype(affected_mob.wear_mask, /obj/item/clothing/mask/gas/clown_hat/nodrop)) + affected_mob.unEquip(affected_mob.wear_mask, TRUE) + affected_mob.equip_to_slot(new /obj/item/clothing/mask/gas/clown_hat/nodrop(src), slot_wear_mask) \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 0ab0453cb95..c86a18eba80 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -80,6 +80,8 @@ //zealot_master is a reference to the mob that converted them into a zealot (for ease of investigation and such) var/mob/living/carbon/human/zealot_master = null + var/list/learned_recipes //List of learned recipe TYPES. + /datum/mind/New(new_key) key = new_key soulOwner = src @@ -1151,7 +1153,7 @@ A.set_zeroth_law("") A.show_laws() A.verbs -= /mob/living/silicon/ai/proc/choose_modules - A.malf_picker.remove_verbs(A) + A.malf_picker.remove_malf_verbs(A) qdel(A.malf_picker) SSticker.mode.update_traitor_icons_removed(src) diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index 6ec670bf4f2..ff8a93d3df0 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -1127,7 +1127,7 @@ uniform = /obj/item/clothing/under/color/black suit = /obj/item/clothing/suit/hooded/chaplain_hoodie back = /obj/item/storage/backpack - head = /obj/item/clothing/head/chaplain_hood + head = /obj/item/clothing/head/hooded/chaplain_hood gloves = /obj/item/clothing/gloves/color/black shoes = /obj/item/clothing/shoes/black l_ear = /obj/item/radio/headset/syndicate diff --git a/code/datums/pipe_datums.dm b/code/datums/pipe_datums.dm index cf2ec79fe85..83b77425447 100644 --- a/code/datums/pipe_datums.dm +++ b/code/datums/pipe_datums.dm @@ -337,6 +337,13 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable pipe_icon = "intake" rpd_dispensable = TRUE +/datum/pipes/disposal/sortjunction + pipe_name = "disposals sort junction" + pipe_id = PIPE_DISPOSALS_SORT_RIGHT + orientations = 4 + pipe_icon = "pipe-j1s" + rpd_dispensable = TRUE + //Pipes the RPD can't dispense. Since these don't use an interface, we don't need to bother with setting an icon. We do, however, want to name these for other purposes /datum/pipes/atmospheric/circulator @@ -363,12 +370,8 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable pipe_name = "bent insulated pipe" pipe_id = PIPE_INSULATED_BENT -/datum/pipes/disposal/sortjunction - pipe_name = "disposals sort junction" - pipe_id = PIPE_DISPOSALS_SORT_RIGHT - pipe_icon = "pipe-j1s" - -/datum/pipes/disposal/sortjunction/left +/datum/pipes/disposal/left_sortjunction + pipe_name = "disposals sort junction left" pipe_id = PIPE_DISPOSALS_SORT_LEFT pipe_icon = "pipe-j2s" diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 67e5438656e..7fe8ad7248e 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -12,6 +12,19 @@ Comes with a rustic wooden bar and suicidal bartender." suffix = "lavaland_biodome_beach.dmm" +/datum/map_template/ruin/lavaland/biodome/winter + name = "Biodome Winter" + id = "biodome-winter" + description = "For those getaways where you want to get back to nature, but you don't want to leave the fortified military compound where you spend your days. \ + Includes a unique(*) laser pistol display case, and the recently introduced I.C.E(tm)." + suffix = "lavaland_biodome_winter.dmm" + +/datum/map_template/ruin/lavaland/biodome/clown + name = "Biodome Clown Planet" + id = "biodome-clown" + description = "WELCOME TO CLOWN PLANET! HONK HONK HONK etc.!" + suffix = "lavaland_biodome_clown_planet.dmm" + /datum/map_template/ruin/lavaland/cube name = "The Wishgranter Cube" id = "wishgranter-cube" diff --git a/code/datums/spells/banana_touch.dm b/code/datums/spells/banana_touch.dm new file mode 100644 index 00000000000..4e2f1d44e51 --- /dev/null +++ b/code/datums/spells/banana_touch.dm @@ -0,0 +1,64 @@ +/obj/effect/proc_holder/spell/targeted/touch/banana + name = "Banana Touch" + desc = "A spell popular at wizard birthday parties, this spell will put on a clown costume on the target, \ + stun them with a loud HONK, and mutate them to make them more entertaining! \ + Warning : Effects are permanent on non-wizards." + hand_path = /obj/item/melee/touch_attack/banana + school = "transmutation" + + charge_max = 300 + clothes_req = 1 + cooldown_min = 100 //50 deciseconds reduction per rank + action_icon_state = "clown" + +/obj/item/melee/touch_attack/banana + name = "banana touch" + desc = "It's time to start clowning around." + catchphrase = "NWOLC YRGNA" + on_use_sound = 'sound/items/AirHorn.ogg' + icon_state = "banana_touch" + item_state = "banana_touch" + +/obj/item/melee/touch_attack/banana/afterattack(atom/target, mob/living/carbon/user, proximity) + if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || user.lying || user.handcuffed) + return + + var/datum/effect_system/smoke_spread/s = new + s.set_up(5, 0, target) + s.start() + + to_chat(user, "HONK") + var/mob/living/carbon/human/H = target + H.bananatouched() + ..() + +/mob/living/carbon/human/proc/bananatouched() + to_chat(src, "HONK") + Weaken(7) + Stun(7) + Stuttering(15) + do_jitter_animation(15) + + if(iswizard(src) || (mind && mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE)) //Wizards get non-cursed clown robes and magical mask. + unEquip(shoes, TRUE) + unEquip(wear_mask, TRUE) + unEquip(head, TRUE) + unEquip(wear_suit, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/head/wizard/clown, slot_head, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/suit/wizrobe/clown, slot_wear_suit, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/shoes/clown_shoes/magical, slot_shoes, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clownwiz, slot_wear_mask, TRUE, TRUE) + else + qdel(shoes) + qdel(wear_mask) + qdel(w_uniform) + equip_to_slot_if_possible(new /obj/item/clothing/under/rank/clown/nodrop, slot_w_uniform, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/shoes/clown_shoes/nodrop, slot_shoes, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clown_hat/nodrop, slot_wear_mask, TRUE, TRUE) + dna.SetSEState(CLUMSYBLOCK, TRUE, TRUE) + dna.SetSEState(COMICBLOCK, TRUE, TRUE) + genemutcheck(src, CLUMSYBLOCK, null, MUTCHK_FORCED) + genemutcheck(src, COMICBLOCK, null, MUTCHK_FORCED) + if(!(iswizard(src) || (mind && mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE))) //Mutations are permanent on non-wizards. Can still be removed by genetics fuckery but not mutadone. + dna.default_blocks.Add(CLUMSYBLOCK) + dna.default_blocks.Add(COMICBLOCK) \ No newline at end of file diff --git a/code/datums/spells/charge.dm b/code/datums/spells/charge.dm index 5dd054f67ed..46cdbff7f94 100644 --- a/code/datums/spells/charge.dm +++ b/code/datums/spells/charge.dm @@ -1,7 +1,6 @@ /obj/effect/proc_holder/spell/targeted/charge name = "Charge" desc = "This spell can be used to recharge a variety of things in your hands, from magical artifacts to electrical components. A creative wizard can even use it to grant magical power to a fellow magic user." - school = "transmutation" charge_max = 600 clothes_req = 0 @@ -10,7 +9,7 @@ range = -1 cooldown_min = 400 //50 deciseconds reduction per rank include_user = 1 - + action_icon_state = "charge" /obj/effect/proc_holder/spell/targeted/charge/cast(list/targets,mob/user = usr) for(var/mob/living/L in targets) diff --git a/code/datums/spells/infinite_guns.dm b/code/datums/spells/infinite_guns.dm index 83cafb88666..35699d4634a 100644 --- a/code/datums/spells/infinite_guns.dm +++ b/code/datums/spells/infinite_guns.dm @@ -11,8 +11,6 @@ cooldown_min = 10 //Gun wizard action_icon_state = "bolt_action" - - /obj/effect/proc_holder/spell/targeted/infinite_guns/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/C in targets) C.drop_item() diff --git a/code/datums/spells/mime_malaise.dm b/code/datums/spells/mime_malaise.dm new file mode 100644 index 00000000000..a5afd26d916 --- /dev/null +++ b/code/datums/spells/mime_malaise.dm @@ -0,0 +1,54 @@ +/obj/effect/proc_holder/spell/targeted/touch/mime_malaise + name = "Mime Malaise" + desc = "A spell popular with theater nerd wizards and contrarian pranksters, this spell will put on a mime costume on the target, \ + stun them so that they may contemplate Art, and silence them. \ + Warning : Effects are permanent on non-wizards." + hand_path = /obj/item/melee/touch_attack/mime_malaise + school = "transmutation" + + charge_max = 300 + clothes_req = 1 + cooldown_min = 100 //50 deciseconds reduction per rank + action_icon_state = "mime" + +/obj/item/melee/touch_attack/mime_malaise + name = "mime hand" + desc = "..." + catchphrase = null + on_use_sound = null + icon_state = "fleshtostone" + item_state = "fleshtostone" + +/obj/item/melee/touch_attack/mime_malaise/afterattack(atom/target, mob/living/carbon/user, proximity) + if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || user.lying || user.handcuffed) + return + + var/datum/effect_system/smoke_spread/s = new + s.set_up(5, 0, target) + s.start() + + var/mob/living/carbon/human/H = target + H.mimetouched() + ..() + +/mob/living/carbon/human/proc/mimetouched() + Weaken(7) + Stun(7) + if(iswizard(src) || (mind && mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE)) //Wizards get non-cursed mime outfit. Replace with mime robes if we add those. + unEquip(wear_mask, TRUE) + unEquip(w_uniform, TRUE) + unEquip(wear_suit, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/mime, slot_wear_mask, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/under/mime, slot_w_uniform, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/suit/suspenders, slot_wear_suit, TRUE, TRUE) + Silence(7) + else + qdel(wear_mask) + qdel(w_uniform) + qdel(wear_suit) + equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/mime/nodrop, slot_wear_mask, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/under/mime/nodrop, slot_w_uniform, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/suit/suspenders/nodrop, slot_wear_suit, TRUE, TRUE) + dna.SetSEState(MUTEBLOCK , TRUE, TRUE) + genemutcheck(src, MUTEBLOCK , null, MUTCHK_FORCED) + dna.default_blocks.Add(MUTEBLOCK) \ No newline at end of file diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index 7b648bb72c1..739a03d92c5 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -72,6 +72,7 @@ /obj/effect/proc_holder/spell/noclothes name = "No Clothes" desc = "This always-on spell allows you to cast magic without your garments." + action_icon_state = "no_clothes" /obj/effect/proc_holder/spell/targeted/genetic/mutate name = "Mutate" diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index fb336192b38..0573f3b90ca 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -45,13 +45,6 @@ duration = 10 tick_interval = 0 alert_type = /obj/screen/alert/status_effect/blooddrunk - var/last_health = 0 - var/last_bruteloss = 0 - var/last_fireloss = 0 - var/last_toxloss = 0 - var/last_oxyloss = 0 - var/last_cloneloss = 0 - var/last_staminaloss = 0 /obj/screen/alert/status_effect/blooddrunk name = "Blood-Drunk" @@ -61,108 +54,32 @@ /datum/status_effect/blooddrunk/on_apply() . = ..() if(.) - owner.maxHealth *= 10 - owner.bruteloss *= 10 - owner.fireloss *= 10 if(ishuman(owner)) var/mob/living/carbon/human/H = owner for(var/X in H.bodyparts) var/obj/item/organ/external/BP = X - BP.max_damage *= 10 - BP.min_broken_damage *= 10 - BP.brute_dam *= 10 - BP.burn_dam *= 10 - owner.toxloss *= 10 - owner.oxyloss *= 10 - owner.cloneloss *= 10 - owner.staminaloss *= 10 - owner.updatehealth() - last_health = owner.health - last_bruteloss = owner.getBruteLoss() - last_fireloss = owner.getFireLoss() - last_toxloss = owner.getToxLoss() - last_oxyloss = owner.getOxyLoss() - last_cloneloss = owner.getCloneLoss() - last_staminaloss = owner.getStaminaLoss() + BP.brute_mod *= 0.1 + BP.burn_mod *= 0.1 + H.dna.species.tox_mod *= 0.1 + H.dna.species.oxy_mod *= 0.1 + H.dna.species.clone_mod *= 0.1 + H.dna.species.stamina_mod *= 0.1 add_attack_logs(owner, owner, "gained blood-drunk stun immunity") var/status = CANSTUN | CANWEAKEN | CANPARALYSE | IGNORESLOWDOWN owner.status_flags &= ~status owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, 1) -/datum/status_effect/blooddrunk/tick() //multiply the effect of healing by 10 - if(owner.health > last_health) - var/needs_health_update = FALSE - var/new_bruteloss = owner.getBruteLoss() - if(new_bruteloss < last_bruteloss) - var/heal_amount = (new_bruteloss - last_bruteloss) * 10 - owner.adjustBruteLoss(heal_amount, updating_health = FALSE) - new_bruteloss = owner.getBruteLoss() - needs_health_update = TRUE - last_bruteloss = new_bruteloss - - var/new_fireloss = owner.getFireLoss() - if(new_fireloss < last_fireloss) - var/heal_amount = (new_fireloss - last_fireloss) * 10 - owner.adjustFireLoss(heal_amount, updating_health = FALSE) - new_fireloss = owner.getFireLoss() - needs_health_update = TRUE - last_fireloss = new_fireloss - - var/new_toxloss = owner.getToxLoss() - if(new_toxloss < last_toxloss) - var/heal_amount = (new_toxloss - last_toxloss) * 10 - owner.adjustToxLoss(heal_amount, updating_health = FALSE) - new_toxloss = owner.getToxLoss() - needs_health_update = TRUE - last_toxloss = new_toxloss - - var/new_oxyloss = owner.getOxyLoss() - if(new_oxyloss < last_oxyloss) - var/heal_amount = (new_oxyloss - last_oxyloss) * 10 - owner.adjustOxyLoss(heal_amount, updating_health = FALSE) - new_oxyloss = owner.getOxyLoss() - needs_health_update = TRUE - last_oxyloss = new_oxyloss - - var/new_cloneloss = owner.getCloneLoss() - if(new_cloneloss < last_cloneloss) - var/heal_amount = (new_cloneloss - last_cloneloss) * 10 - owner.adjustCloneLoss(heal_amount, updating_health = FALSE) - new_cloneloss = owner.getCloneLoss() - needs_health_update = TRUE - last_cloneloss = new_cloneloss - - var/new_staminaloss = owner.getStaminaLoss() - if(new_staminaloss < last_staminaloss) - var/heal_amount = (new_staminaloss - last_staminaloss) * 10 - owner.adjustStaminaLoss(heal_amount, updating_health = FALSE) - new_staminaloss = owner.getStaminaLoss() - needs_health_update = TRUE - last_staminaloss = new_staminaloss - - if(needs_health_update) - owner.updatehealth() - owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, 1) - last_health = owner.health - /datum/status_effect/blooddrunk/on_remove() - tick() - owner.maxHealth *= 0.1 - owner.bruteloss *= 0.1 - owner.fireloss *= 0.1 if(ishuman(owner)) var/mob/living/carbon/human/H = owner for(var/X in H.bodyparts) var/obj/item/organ/external/BP = X - BP.brute_dam *= 0.1 - BP.burn_dam *= 0.1 - BP.max_damage /= 10 - BP.min_broken_damage /= 10 - owner.toxloss *= 0.1 - owner.oxyloss *= 0.1 - owner.cloneloss *= 0.1 - owner.staminaloss *= 0.1 - owner.updatehealth() + BP.brute_mod *= 10 + BP.burn_mod *= 10 + H.dna.species.tox_mod *= 10 + H.dna.species.oxy_mod *= 10 + H.dna.species.clone_mod *= 10 + H.dna.species.stamina_mod *= 10 add_attack_logs(owner, owner, "lost blood-drunk stun immunity") owner.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | IGNORESLOWDOWN diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 9345387e304..494379aa821 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -482,10 +482,10 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/security/securitybarriers name = "Security Barriers Crate" - contains = list(/obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier) + contains = list(/obj/item/grenade/barrier, + /obj/item/grenade/barrier, + /obj/item/grenade/barrier, + /obj/item/grenade/barrier) cost = 20 containername = "security barriers crate" @@ -1173,6 +1173,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/organic/hydroponics/seeds name = "Seeds Crate" contains = list(/obj/item/seeds/chili, + /obj/item/seeds/cotton, /obj/item/seeds/berry, /obj/item/seeds/corn, /obj/item/seeds/eggplant, diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index e35ca1eae9f..0cb6a31770c 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -190,6 +190,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 1 job = list("Clown") +/datum/uplink_item/stealthy_weapons/romerol_kit + name = "Romerol" + reference = "ROM" + desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. On death, these nodules take control of the dead body, causing limited revivification, along with slurred speech, aggression, and the ability to infect others with this agent." + item = /obj/item/storage/box/syndie_kit/romerol + cost = 25 + cant_discount = TRUE + //mime /datum/uplink_item/jobspecific/caneshotgun name = "Cane Shotgun and Assassination Shells" @@ -646,6 +654,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous/guardian name = "Holoparasites" + reference = "HPA" desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an organic host as a home base and source of fuel. \ The holoparasites are unable to incoporate themselves to changeling and vampire agents." item = /obj/item/storage/box/syndie_kit/guardian @@ -900,6 +909,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 3 surplus = 10 +/datum/uplink_item/stealthy_weapons/false_briefcase + name = "False Bottomed Briefcase" + desc = "A modified briefcase capable of storing and firing a gun under a false bottom. Use a screwdriver to pry away the false bottom and make modifications. Distinguishable upon close examination due to the added weight." + reference = "FBBC" + item = /obj/item/storage/briefcase/false_bottomed + cost = 3 + /datum/uplink_item/stealthy_weapons/soap name = "Syndicate Soap" desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. You can also drop it underfoot to slip people." diff --git a/code/game/area/areas/ruins/lavaland.dm b/code/game/area/areas/ruins/lavaland.dm index d72c6cc0406..ac4c41b0c42 100644 --- a/code/game/area/areas/ruins/lavaland.dm +++ b/code/game/area/areas/ruins/lavaland.dm @@ -12,6 +12,9 @@ /area/ruin/powered/snow_biodome icon_state = "dk_yellow" +/area/ruin/powered/snow_cabin + icon_state = "bar" + /area/ruin/powered/gluttony icon_state = "dk_yellow" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 757f036c691..dc84c1836dd 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -328,6 +328,9 @@ /atom/proc/emag_act() return +/atom/proc/fart_act(mob/living/M) + return FALSE + /atom/proc/rpd_act() return diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index f90cfc94480..dfe28336631 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -234,14 +234,18 @@ blobber.color = blob_reagent_datum.complementary_color blobber.overmind = src blob_mobs.Add(blobber) + blobber.AIStatus = AI_OFF + blobber.LoseTarget() spawn() - var/list/candidates = pollCandidates("Do you want to play as a blobbernaut?", ROLE_BLOB, 1, 150) + var/list/candidates = pollCandidates("Do you want to play as a blobbernaut?", ROLE_BLOB, 1, 100) if(candidates.len) var/mob/C = pick(candidates) if(C) blobber.key = C.key to_chat(blobber, "You are a blobbernaut! You must assist all blob lifeforms in their mission to consume everything!") to_chat(blobber, "You heal while standing on blob structures, however you will decay slowly if you are damaged outside of the blob.") + if(!blobber.ckey) + blobber.AIStatus = AI_ON return diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 038f331f924..713779af241 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -303,7 +303,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" /datum/changeling/proc/can_absorb_dna(mob/living/carbon/user, mob/living/carbon/target) if(using_stale_dna(user))//If our current DNA is the stalest, we gotta ditch it. - to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.") + to_chat(user, "The DNA we are wearing is stale. Transform and try again.") return if(!target || !target.dna) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index fe0980a24cd..a1bec7a2a83 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -61,7 +61,7 @@ breakouttime = 45 weaken = 1 -/obj/item/clothing/head/culthood +/obj/item/clothing/head/hooded/culthood name = "cult hood" icon_state = "culthood" desc = "A hood worn by the followers of a cult." @@ -72,7 +72,7 @@ min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT -/obj/item/clothing/head/culthood/alt +/obj/item/clothing/head/hooded/culthood/alt icon_state = "cult_hoodalt" item_state = "cult_hoodalt" @@ -83,7 +83,7 @@ icon_state = "cultrobes" item_state = "cultrobes" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - hoodtype = /obj/item/clothing/head/culthood + hoodtype = /obj/item/clothing/head/hooded/culthood allowed = list(/obj/item/tome,/obj/item/melee/cultblade) armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0) flags_inv = HIDEJUMPSUIT @@ -91,7 +91,7 @@ /obj/item/clothing/suit/hooded/cultrobes/alt icon_state = "cultrobesalt" item_state = "cultrobesalt" - hoodtype = /obj/item/clothing/head/culthood/alt + hoodtype = /obj/item/clothing/head/hooded/culthood/alt /obj/item/clothing/head/magus name = "magus helm" @@ -140,15 +140,14 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS allowed = list(/obj/item/tome,/obj/item/melee/cultblade) var/current_charges = 3 - hoodtype = /obj/item/clothing/head/cult_hoodie + hoodtype = /obj/item/clothing/head/hooded/cult_hoodie -/obj/item/clothing/head/cult_hoodie +/obj/item/clothing/head/hooded/cult_hoodie name = "empowered cultist robe" desc = "Empowered garb which creates a powerful shield around the user." icon_state = "cult_hoodalt" armor = list(melee = 50, bullet = 40, laser = 50, energy = 30, bomb = 50, bio = 30, rad = 30) body_parts_covered = HEAD - flags = NODROP flags_inv = HIDEFACE flags_cover = HEADCOVERSEYES @@ -182,10 +181,10 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS armor = list(melee = -50, bullet = -50, laser = -100, energy = -50, bomb = -50, bio = -50, rad = -50) slowdown = -1 - hoodtype = /obj/item/clothing/head/berserkerhood + hoodtype = /obj/item/clothing/head/hooded/berserkerhood -/obj/item/clothing/head/berserkerhood +/obj/item/clothing/head/hooded/berserkerhood name = "flagellant's robes" desc = "Blood-soaked garb infused with dark magic; allows the user to move at inhuman speeds, but at the cost of increased damage." icon_state = "culthood" @@ -349,7 +348,7 @@ force = 15 flags = NODROP | DROPDEL -/obj/item/clothing/head/culthood/alt/ghost +/obj/item/clothing/head/hooded/culthood/alt/ghost flags = NODROP | DROPDEL /obj/item/clothing/suit/cultrobesghost @@ -374,5 +373,5 @@ uniform = /obj/item/clothing/under/color/black suit = /obj/item/clothing/suit/cultrobesghost shoes = /obj/item/clothing/shoes/cult/ghost - head = /obj/item/clothing/head/culthood/alt/ghost + head = /obj/item/clothing/head/hooded/culthood/alt/ghost r_hand = /obj/item/melee/cultblade/ghost \ No newline at end of file diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 8eeee9e4f2a..9a40cb58881 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -1,46 +1,243 @@ +//The malf AI action subtype. All malf actions are subtypes of this. +/datum/action/innate/ai + name = "AI Action" + desc = "You aren't entirely sure what this does, but it's very beepy and boopy." + background_icon_state = "bg_tech_blue" + var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time + var/uses //If we have multiple uses of the same power + var/auto_use_uses = TRUE //If we automatically use up uses on each activation + var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules + +/datum/action/innate/ai/Grant(mob/living/L) + . = ..() + if(!isAI(owner)) + WARNING("AI action [name] attempted to grant itself to non-AI mob [L.real_name] ([L.key])!") + qdel(src) + else + owner_AI = owner + +/datum/action/innate/ai/IsAvailable() + . = ..() + if(owner_AI && owner_AI.malf_cooldown > world.time) + return + +/datum/action/innate/ai/Trigger() + . = ..() + if(auto_use_uses) + adjust_uses(-1) + if(cooldown_period) + owner_AI.malf_cooldown = world.time + cooldown_period + +/datum/action/innate/ai/proc/adjust_uses(amt, silent) + uses += amt + if(!silent && uses) + to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") + if(!uses) + if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! + to_chat(owner, "[name] has run out of uses!") + qdel(src) + +//Framework for ranged abilities that can have different effects by left-clicking stuff. +/datum/action/innate/ai/ranged + name = "Ranged AI Action" + auto_use_uses = FALSE //This is so we can do the thing and disable/enable freely without having to constantly add uses + var/obj/effect/proc_holder/ranged_ai/linked_ability //The linked proc holder that contains the actual ability code + var/linked_ability_type //The path of our linked ability + +/datum/action/innate/ai/ranged/New() + if(!linked_ability_type) + WARNING("Ranged AI action [name] attempted to spawn without a linked ability!") + qdel(src) //uh oh! + return + linked_ability = new linked_ability_type() + linked_ability.attached_action = src + ..() + +/datum/action/innate/ai/ranged/adjust_uses(amt, silent) + uses += amt + if(!silent && uses) + to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") + if(!uses) + if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! + to_chat(owner, "[name] has run out of uses!") + Remove(owner) + QDEL_IN(src, 100) //let any active timers on us finish up + +/datum/action/innate/ai/ranged/Destroy() + QDEL_NULL(linked_ability) + return ..() + +/datum/action/innate/ai/ranged/Activate() + linked_ability.toggle(owner) + return TRUE + +//The actual ranged proc holder. +/obj/effect/proc_holder/ranged_ai + var/enable_text = "Hello World!" //Appears when the user activates the ability + var/disable_text = "Goodbye Cruel World!" //Context clues! + var/datum/action/innate/ai/ranged/attached_action + +/obj/effect/proc_holder/ranged_ai/Destroy() + QDEL_NULL(attached_action) + return ..() + +/obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user) + if(active) + remove_ranged_ability(disable_text) + else + add_ranged_ability(user, enable_text) + +//The datum and interface for the malf unlock menu, which lets them choose actions to unlock. +/datum/module_picker + var/temp + var/processing_time = 50 + var/list/possible_modules + +/datum/module_picker/New() + possible_modules = list() + for(var/type in typesof(/datum/AI_Module)) + var/datum/AI_Module/AM = new type + if((AM.power_type && AM.power_type != /datum/action/innate/ai) || AM.upgrade) + possible_modules += AM + +/datum/module_picker/proc/remove_malf_verbs(mob/living/silicon/ai/AI) //Removes all malfunction-related abilities from the target AI. + for(var/datum/AI_Module/AM in possible_modules) + for(var/datum/action/A in AI.actions) + if(istype(A, initial(AM.power_type))) + qdel(A) + +/datum/module_picker/proc/use(user as mob) + var/dat + dat += {"Select use of processing time: (currently #[processing_time] left.)
+
+ Install Module:
+ The number afterwards is the amount of processing time it consumes.
"} + for(var/datum/AI_Module/large/module in possible_modules) + dat += "[module.module_name]\[?\] ([module.cost])
" + for(var/datum/AI_Module/small/module in possible_modules) + dat += "[module.module_name]\[?\] ([module.cost])
" + dat += "
" + if(temp) + dat += "[temp]" + var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu", 400, 500) + popup.set_content(dat) + popup.open() + return + +/datum/module_picker/Topic(href, href_list) + ..() + + if(!isAI(usr)) + return + var/mob/living/silicon/ai/A = usr + + if(A.stat == DEAD) + to_chat(A, "You are already dead!") + return + + for(var/datum/AI_Module/AM in possible_modules) + if (href_list[AM.mod_pick_name]) + + // Cost check + if(AM.cost > processing_time) + temp = "You cannot afford this module." + break + + var/datum/action/innate/ai/action = locate(AM.power_type) in A.actions + + // Give the power and take away the money. + if(AM.upgrade) //upgrade and upgrade() are separate, be careful! + AM.upgrade(A) + possible_modules -= AM + to_chat(A, AM.unlock_text) + A.playsound_local(A, AM.unlock_sound, 50, 0) + else + if(AM.power_type) + if(!action) //Unlocking for the first time + var/datum/action/AC = new AM.power_type + AC.Grant(A) + A.current_modules += new AM.type + temp = AM.description + if(AM.one_purchase) + possible_modules -= AM + if(AM.unlock_text) + to_chat(A, AM.unlock_text) + if(AM.unlock_sound) + A.playsound_local(A, AM.unlock_sound, 50, 0) + else //Adding uses to an existing module + action.uses += initial(action.uses) + action.desc = "[initial(action.desc)] It has [action.uses] use\s remaining." + action.UpdateButtonIcon() + temp = "Additional use[action.uses > 1 ? "s" : ""] added to [action.name]!" + processing_time -= AM.cost + + if(href_list["showdesc"]) + if(AM.mod_pick_name == href_list["showdesc"]) + temp = AM.description + use(usr) + +//The base module type, which holds info about each ability. /datum/AI_Module - var/uses = 0 var/module_name var/mod_pick_name var/description = "" var/engaged = 0 var/cost = 5 - var/one_time = 0 + var/one_purchase = FALSE //If this module can only be purchased once. This always applies to upgrades, even if the variable is set to false. + var/power_type = /datum/action/innate/ai //If the module gives an active ability, use this. Mutually exclusive with upgrade. + var/upgrade //If the module gives a passive upgrade, use this. Mutually exclusive with power_type. + var/unlock_text = "Hello World!" //Text shown when an ability is unlocked + var/unlock_sound //Sound played when an ability is unlocked - var/power_type +/datum/AI_Module/proc/upgrade(mob/living/silicon/AI/AI) //Apply upgrades! + return -/datum/AI_Module/large/ - uses = 1 - -/datum/AI_Module/small/ - uses = 5 +/datum/AI_Module/large //Big, powerful stuff that can only be used once. +/datum/AI_Module/small //Weak, usually localized stuff with multiple uses. +//Doomsday Device: Starts the self-destruct timer. It can only be stopped by killing the AI completely. /datum/AI_Module/large/nuke_station module_name = "Doomsday Device" mod_pick_name = "nukestation" - description = "Activate a weapon that will disintegrate all organic life on the station after a 450 second delay." + description = "Activate a weapon that will disintegrate all organic life on the station after a 450 second delay. Can only be used while on the station, will fail if your core is moved off station or destroyed." cost = 130 - one_time = 1 + one_purchase = TRUE + power_type = /datum/action/innate/ai/nuke_station + unlock_text = "You slowly, carefully, establish a connection with the on-station self-destruct. You can now activate it at any time." + unlock_sound = 'sound/items/timer.ogg' - power_type = /mob/living/silicon/ai/proc/nuke_station +/datum/action/innate/ai/nuke_station + name = "Doomsday Device" + desc = "Activates the doomsday device. This is not reversible." + button_icon_state = "doomsday_device" + auto_use_uses = FALSE -/mob/living/silicon/ai/proc/nuke_station() - set category = "Malfunction" - set name = "Doomsday Device" +/datum/action/innate/ai/nuke_station/Activate() + var/turf/T = get_turf(owner) + if(!istype(T) || !is_station_level(T.z)) + to_chat(owner, "You cannot activate the doomsday device while off-station!") + return + if(alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", "confirm = TRUE;", "confirm = FALSE;") != "confirm = TRUE;") + return + if(active) + return //prevent the AI from activating an already active doomsday + active = TRUE + set_us_up_the_bomb() - to_chat(src, "Nuclear device armed.") +/datum/action/innate/ai/nuke_station/proc/set_us_up_the_bomb() + to_chat(owner_AI, "Nuclear device armed.") event_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg') set_security_level("delta") - nuking = 1 - var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(src) - doomsday_device = DOOM - doomsday_device.start() - verbs -= /mob/living/silicon/ai/proc/nuke_station + owner_AI.nuking = TRUE + var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(owner_AI) + owner_AI.doomsday_device = DOOM + owner_AI.doomsday_device.start() for(var/obj/item/pinpointer/point in GLOB.pinpointer_list) for(var/mob/living/silicon/ai/A in ai_list) if((A.stat != DEAD) && A.nuking) point.the_disk = A //The pinpointer now tracks the AI core + qdel(src) /obj/machinery/doomsday_device icon = 'icons/obj/machines/nuke_terminal.dmi' @@ -113,49 +310,42 @@ to_chat(world, "The AI cleansed the station of life with the doomsday device!") SSticker.force_ending = 1 - +//AI Turret Upgrade: Increases the health and damage of all turrets. /datum/AI_Module/large/upgrade_turrets module_name = "AI Turret Upgrade" mod_pick_name = "turret" description = "Improves the power and health of all AI turrets. This effect is permanent." cost = 30 - one_time = 1 + upgrade = TRUE + unlock_text = "You establish a power diversion to your turrets, upgrading their health and damage." + unlock_sound = 'sound/items/rped.ogg' - power_type = /mob/living/silicon/ai/proc/upgrade_turrets - -/mob/living/silicon/ai/proc/upgrade_turrets() - set category = "Malfunction" - set name = "Upgrade Turrets" - - if(stat) - return - - src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets +/datum/AI_Module/large/upgrade_turrets/upgrade(mob/living/silicon/AI/AI) for(var/obj/machinery/porta_turret/turret in GLOB.machines) var/turf/T = get_turf(turret) if(is_station_level(T.z)) turret.health += 30 turret.eprojectile = /obj/item/projectile/beam/laser/heavylaser //Once you see it, you will know what it means to FEAR. turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg' - to_chat(src, "Turrets upgraded.") - +//Hostile Station Lockdown: Locks, bolts, and electrifies every airlock on the station. After 90 seconds, the doors reset. /datum/AI_Module/large/lockdown module_name = "Hostile Station Lockdown" mod_pick_name = "lockdown" - description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds." + description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds, briefly \ + opening all doors on the station." cost = 30 - one_time = 1 + one_purchase = TRUE + power_type = /datum/action/innate/ai/lockdown + unlock_text = "You upload a sleeper trojan into the door control systems. You can send a signal to set it off at any time." - power_type = /mob/living/silicon/ai/proc/lockdown - -/mob/living/silicon/ai/proc/lockdown() - set category = "Malfunction" - set name = "Initiate Hostile Lockdown" - - if(stat) - return +/datum/action/innate/ai/lockdown + name = "Lockdown" + desc = "Closes, bolts, and depowers every airlock, firelock, and blast door on the station. After 90 seconds, they will reset themselves." + button_icon_state = "lockdown" + uses = 1 +/datum/action/innate/ai/lockdown/Activate() for(var/obj/machinery/door/D in GLOB.airlocks) if(!is_station_level(D.z)) continue @@ -164,342 +354,360 @@ post_status("alert", "lockdown") - verbs -= /mob/living/silicon/ai/proc/lockdown minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.", "Network Alert") - to_chat(src, "Lockdown Initiated. Network reset in 90 seconds.") + to_chat(owner, "Lockdown Initiated. Network reset in 90 seconds.") spawn(900) minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network reset:") - +//Destroy RCDs: Detonates all non-cyborg RCDs on the station. /datum/AI_Module/large/destroy_rcd module_name = "Destroy RCDs" mod_pick_name = "rcd" description = "Send a specialised pulse to detonate all hand-held and exosuit Rapid Construction Devices on the station." cost = 25 - one_time = 1 + one_purchase = TRUE + power_type = /datum/action/innate/ai/destroy_rcds + unlock_text = "After some improvisation, you rig your onboard radio to be able to send a signal to detonate all RCDs." - power_type = /mob/living/silicon/ai/proc/disable_rcd - -/mob/living/silicon/ai/proc/disable_rcd() - set category = "Malfunction" - set name = "Destroy RCDs" - set desc = "Detonate all RCDs on the station, while sparing onboard cyborg RCDs." - - if(stat || malf_cooldown > world.time) - return +/datum/action/innate/ai/destroy_rcds + name = "Destroy RCDs" + desc = "Detonate all non-cyborg RCDs on the station." + button_icon_state = "detonate_rcds" + uses = 1 + cooldown_period = 100 +/datum/action/innate/ai/destroy_rcds/Activate() for(var/obj/item/rcd/RCD in GLOB.rcd_list) if(!istype(RCD, /obj/item/rcd/borg)) //Ensures that cyborg RCDs are spared. RCD.detonate_pulse() - to_chat(src, "RCD detonation pulse emitted.") - malf_cooldown = world.time + 100 - + to_chat(owner, "RCD detonation pulse emitted.") + owner.playsound_local(owner, 'sound/machines/twobeep.ogg', 50, 0) +//Unlock Mech Domination: Unlocks the ability to dominate mechs. Big shocker, right? /datum/AI_Module/large/mecha_domination - module_name = "Viral Mech Domination" + module_name = "Unlock Mech Domination" mod_pick_name = "mechjack" - description = "Hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave. \ + description = "Allows you to hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave.\ Do not allow the mech to leave the station's vicinity or allow it to be destroyed." cost = 30 - one_time = 1 - - power_type = /mob/living/silicon/ai/proc/mech_takeover - -/mob/living/silicon/ai/proc/mech_takeover() - set name = "Compile Mecha Virus" - set category = "Malfunction" - set desc = "Target a mech by clicking it. Click the appropriate command when ready." - - if(stat) - return - - can_dominate_mechs = 1 //Yep. This is all it does. Honk! - to_chat(src, "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout.") - - verbs -= /mob/living/silicon/ai/proc/mech_takeover + upgrade = TRUE + unlock_text = "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout." + unlock_sound = 'sound/mecha/nominal.ogg' +/datum/AI_Module/large/mecha_domination/upgrade(mob/living/silicon/ai/AI) + AI.can_dominate_mechs = TRUE //Yep. This is all it does. Honk! +//Thermal Sensor Override: Unlocks the ability to disable all fire alarms from doing their job. /datum/AI_Module/large/break_fire_alarms module_name = "Thermal Sensor Override" mod_pick_name = "burnpigs" description = "Gives you the ability to override the thermal sensors on all fire alarms. This will remove their ability to scan for fire and thus their ability to alert. \ Anyone can check the fire alarm's interface and may be tipped off by its status." - one_time = 1 + one_purchase = TRUE cost = 25 + power_type = /datum/action/innate/ai/break_fire_alarms + unlock_text = "You replace the thermal sensing capabilities of all fire alarms with a manual override, allowing you to turn them off at will." - power_type = /mob/living/silicon/ai/proc/break_fire_alarms - -/mob/living/silicon/ai/proc/break_fire_alarms() - set name = "Override Thermal Sensors" - set category = "Malfunction" - - if(stat) - return +/datum/action/innate/ai/break_fire_alarms + name = "Override Thermal Sensors" + desc = "Disables the automatic temperature sensing on all fire alarms, making them effectively useless." + button_icon_state = "break_fire_alarms" + uses = 1 +/datum/action/innate/ai/break_fire_alarms/Activate() for(var/obj/machinery/firealarm/F in GLOB.machines) if(!is_station_level(F.z)) continue - F.emagged = 1 - to_chat(src, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.") - verbs -= /mob/living/silicon/ai/proc/break_fire_alarms - + F.emagged = TRUE + to_chat(owner, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.") + owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, 0) +//Air Alarm Safety Override: Unlocks the ability to enable flooding on all air alarms. /datum/AI_Module/large/break_air_alarms module_name = "Air Alarm Safety Override" mod_pick_name = "allow_flooding" description = "Gives you the ability to disable safeties on all air alarms. This will allow you to use the environmental mode Flood, which disables scrubbers as well as pressure checks on vents. \ Anyone can check the air alarm's interface and may be tipped off by their nonfunctionality." - one_time = 1 + one_purchase = TRUE cost = 50 + power_type = /datum/action/innate/ai/break_air_alarms + unlock_text = "You remove the safety overrides on all air alarms, but you leave the confirm prompts open. You can hit 'Yes' at any time... you bastard." - power_type = /mob/living/silicon/ai/proc/break_air_alarms - -/mob/living/silicon/ai/proc/break_air_alarms() - set name = "Disable Air Alarm Safeties" - set category = "Malfunction" - - if(stat) - return +/datum/action/innate/ai/break_air_alarms + name = "Override Air Alarm Safeties" + desc = "Enables the Flood setting on all air alarms." + button_icon_state = "break_air_alarms" + uses = 1 +/datum/action/innate/ai/break_air_alarms/Activate() for(var/obj/machinery/alarm/AA in GLOB.machines) if(!is_station_level(AA.z)) continue - AA.emagged = 1 - to_chat(src, "All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode.") - verbs -= /mob/living/silicon/ai/proc/break_air_alarms - + AA.emagged = TRUE + to_chat(owner, "All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode.") + owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, 0) +//Overload Machine: Allows the AI to overload a machine, detonating it after a delay. Two uses per purchase. /datum/AI_Module/small/overload_machine module_name = "Machine Overload" mod_pick_name = "overload" - description = "Overloads an electrical machine, causing a small explosion. 2 uses." - uses = 2 + description = "Overheats an electrical machine, causing a small explosion and destroying it. Two uses per purchase." cost = 20 + power_type = /datum/action/innate/ai/overload_machine + unlock_text = "You enable the ability for the station's APCs to direct intense energy into machinery." - power_type = /mob/living/silicon/ai/proc/overload_machine +/datum/action/innate/ai/overload_machine + name = "Overload Machine" + desc = "Overheats a machine, causing a small explosion after a short time." + button_icon_state = "overload_machine" + uses = 2 + auto_use_uses = FALSE -/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M in GLOB.machines) - set name = "Overload Machine" - set category = "Malfunction" +/datum/action/innate/ai/overload_machine/New() + ..() + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc - if(stat) +/datum/action/innate/ai/overload_machine/Activate() + var/select = input("Choose a device to overload", "Overload Machine", null, null) as null|anything in GLOB.machines + if(!select) return + var/obj/machinery/M = select if(istype(M, /obj/machinery)) - for(var/datum/AI_Module/small/overload_machine/overload in current_modules) - if(overload.uses > 0) - overload.uses -- - audible_message("You hear a loud electrical buzzing sound!") - to_chat(src, "Overloading machine circuitry...") - spawn(50) - if(M) - explosion(get_turf(M), 0,1,1,0) - qdel(M) - else - to_chat(src, "Out of uses.") + if(uses > 0) + adjust_uses(-1) + if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() + M.audible_message("You hear a loud electrical buzzing sound!") + to_chat(owner, "Overloading machine circuitry...") + spawn(50) + if(M) + explosion(get_turf(M), 0,1,1,0) + qdel(M) + else + to_chat(owner, "Out of uses.") else - to_chat(src, "That's not a machine.") - + to_chat(owner, "That's not a machine.") + return +//Override Machine: Allows the AI to override a machine, animating it into an angry, living version of itself. /datum/AI_Module/small/override_machine module_name = "Machine Override" mod_pick_name = "override" - description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. 4 uses." - uses = 4 + description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. Four uses." cost = 30 + power_type = /datum/action/innate/ai/override_machine + unlock_text = "You procure a virus from the Space Dark Web and prepare to distribute it to the station's machines." - power_type = /mob/living/silicon/ai/proc/override_machine +/datum/action/innate/ai/override_machine + name = "Override Machine" + desc = "Animates a targeted machine, causing it to attack anyone nearby." + button_icon_state = "override_machine" + uses = 4 + auto_use_uses = FALSE +/datum/action/innate/ai/override_machine/New() + ..() + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc -/mob/living/silicon/ai/proc/override_machine(obj/machinery/M in GLOB.machines) - set name = "Override Machine" - set category = "Malfunction" - - if(stat) +/datum/action/innate/ai/override_machine/Activate() + var/select = input("Choose a device to override", "Override Machine", null, null) as null|anything in GLOB.machines + if(!select) return - if (istype(M, /obj/machinery)) + var/obj/machinery/M = select + if(istype(M, /obj/machinery)) if(!M.can_be_overridden()) - to_chat(src, "Can't override this device.") - for(var/datum/AI_Module/small/override_machine/override in current_modules) - if(override.uses > 0) - override.uses -- - audible_message("You hear a loud electrical buzzing sound!") - to_chat(src, "Reprogramming machine behaviour...") - spawn(50) - if(M && !QDELETED(M)) - new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1) - else - to_chat(src, "Out of uses.") + to_chat(owner, "Can't override this device.") + return + else if(uses > 0) + adjust_uses(-1) + if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() + M.audible_message("You hear a loud electrical buzzing sound!") + to_chat(owner, "Reprogramming machine behaviour...") + spawn(50) + if(M && !QDELETED(M)) + new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1) + else + to_chat(owner, "Out of uses.") else - to_chat(src, "That's not a machine.") - + to_chat(owner, "That's not a machine.") + return +//Robotic Factory: Places a large machine that converts humans that go through it into cyborgs. Unlocking this ability removes shunting. /datum/AI_Module/large/place_cyborg_transformer module_name = "Robotic Factory (Removes Shunting)" mod_pick_name = "cyborgtransformer" description = "Build a machine anywhere, using expensive nanomachines, that can convert a living human into a loyal cyborg slave when placed inside." cost = 100 - power_type = /mob/living/silicon/ai/proc/place_transformer - var/list/turfOverlays = list() + one_purchase = TRUE + power_type = /datum/action/innate/ai/place_transformer + unlock_text = "You prepare a robotics factory for deployment." + unlock_sound = 'sound/machines/ping.ogg' -/datum/AI_Module/large/place_cyborg_transformer/New() - for(var/i=0;i<3;i++) - var/image/I = image("icon"='icons/turf/overlays.dmi') - turfOverlays += I +/datum/action/innate/ai/place_transformer + name = "Place Robotics Factory" + desc = "Places a machine that converts humans into cyborgs. Conveyor belts included!" + button_icon_state = "robotic_factory" + uses = 1 + auto_use_uses = FALSE //So we can attempt multiple times + var/list/turfOverlays + +/datum/action/innate/ai/place_transformer/New() ..() + for(var/i in 1 to 3) + var/image/I = image("icon"='icons/turf/overlays.dmi') + LAZYADD(turfOverlays, I) -/mob/living/silicon/ai/proc/place_transformer() - set name = "Place Robotic Factory" - set category = "Malfunction" - - if(!canPlaceTransformer()) +/datum/action/innate/ai/place_transformer/Activate() + if(!owner_AI.can_place_transformer(src)) return - - var/sure = alert(src, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No") - if(sure == "Yes") - if(!canPlaceTransformer()) - return - var/turf/T = get_turf(eyeobj) - new /obj/machinery/transformer/conveyor(T) - playsound(T, 'sound/effects/phasein.ogg', 100, 1) - var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in current_modules - PCT.uses -- - can_shunt = 0 - to_chat(src, "You cannot shunt anymore.") - -/mob/living/silicon/ai/proc/canPlaceTransformer() - if(!eyeobj || !isturf(src.loc)) + active = TRUE + if(alert(owner, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No") == "No") + active = FALSE return - var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in current_modules - if(!PCT || PCT.uses < 1) - alert(src, "Out of uses.") + if(!owner_AI.can_place_transformer(src)) + active = FALSE + return + var/turf/T = get_turf(owner_AI.eyeobj) + new /obj/machinery/transformer/conveyor(T) + playsound(T, 'sound/effects/phasein.ogg', 100, 1) + owner_AI.can_shunt = FALSE + to_chat(owner, "You are no longer able to shunt your core to APCs.") + adjust_uses(-1) + +/mob/living/silicon/ai/proc/remove_transformer_image(client/C, image/I, turf/T) + if(C && I.loc == T) + C.images -= I + +/mob/living/silicon/ai/proc/can_place_transformer(datum/action/innate/ai/place_transformer/action) + if(!eyeobj || !isturf(loc) || incapacitated() || !action) return var/turf/middle = get_turf(eyeobj) var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z)) - var/alert_msg = "There isn't enough room. Make sure you are placing the machine in a clear area and on a floor." - var/success = 1 - if(turfs.len == 3) - for(var/n=1;n<4,n++) - var/fail - var/turf/T = turfs[n] - if(!istype(T, /turf/simulated/floor)) - fail = 1 - var/datum/camerachunk/C = cameranet.getCameraChunk(T.x, T.y, T.z) - if(!C.visibleTurfs[T]) - alert_msg = "We cannot get camera vision of this location." - fail = 1 - for(var/atom/movable/AM in T.contents) - if(AM.density) - fail = 1 - var/image/I = PCT.turfOverlays[n] - I.loc = T - client.images += I - if(fail) - success = 0 - I.icon_state = "redOverlay" - else - I.icon_state = "greenOverlay" - spawn(30) - if(client && (I.loc == T)) - client.images -= I - if(success) - return 1 - alert(src, alert_msg) - + var/alert_msg = "There isn't enough room! Make sure you are placing the machine in a clear area and on a floor." + var/success = TRUE + for(var/n in 1 to 3) //We have to do this instead of iterating normally because of how overlay images are handled + var/turf/T = turfs[n] + if(!isfloorturf(T)) + success = FALSE + var/datum/camerachunk/C = cameranet.getCameraChunk(T.x, T.y, T.z) + if(!C.visibleTurfs[T]) + alert_msg = "You don't have camera vision of this location!" + success = FALSE + for(var/atom/movable/AM in T.contents) + if(AM.density) + alert_msg = "That area must be clear of objects!" + success = FALSE + var/image/I = action.turfOverlays[n] + I.loc = T + client.images += I + I.icon_state = "[success ? "green" : "red"]Overlay" //greenOverlay and redOverlay for success and failure respectively + addtimer(CALLBACK(src, .proc/remove_transformer_image, client, I, T), 30) + if(!success) + to_chat(src, "[alert_msg]") + return success +//Blackout: Overloads a random number of lights across the station. Three uses. /datum/AI_Module/small/blackout module_name = "Blackout" mod_pick_name = "blackout" - description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses." - uses = 3 + description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. Three uses." cost = 15 + power_type = /datum/action/innate/ai/blackout + unlock_text = "You hook into the powernet and route bonus power towards the station's lighting." - power_type = /mob/living/silicon/ai/proc/blackout +/datum/action/innate/ai/blackout + name = "Blackout" + desc = "Overloads random lights across the station." + button_icon_state = "blackout" + uses = 3 + auto_use_uses = FALSE -/mob/living/silicon/ai/proc/blackout() - set category = "Malfunction" - set name = "Blackout" +/datum/action/innate/ai/blackout/New() + ..() + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc - if(stat) - return - - for(var/datum/AI_Module/small/blackout/blackout in current_modules) - if(blackout.uses > 0) - blackout.uses -- - for(var/obj/machinery/power/apc/apc in GLOB.apcs) - if(prob(30*apc.overload)) - apc.overload_lighting() - else - apc.overload++ - to_chat(src, "Overcurrent applied to the powernet.") +/datum/action/innate/ai/blackout/Activate() + for(var/obj/machinery/power/apc/apc in GLOB.apcs) + if(prob(30 * apc.overload)) + apc.overload_lighting() else - to_chat(src, "Out of uses.") - + apc.overload++ + to_chat(owner, "Overcurrent applied to the powernet.") + owner.playsound_local(owner, "sparks", 50, 0) + adjust_uses(-1) + if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() +//Reactivate Camera Network: Reactivates up to 30 cameras across the station. /datum/AI_Module/small/reactivate_cameras module_name = "Reactivate Camera Network" mod_pick_name = "recam" description = "Runs a network-wide diagnostic on the camera network, resetting focus and re-routing power to failed cameras. Can be used to repair up to 30 cameras." - uses = 30 cost = 10 - one_time = 1 + one_purchase = TRUE + power_type = /datum/action/innate/ai/reactivate_cameras + unlock_text = "You deploy nanomachines to the cameranet." - power_type = /mob/living/silicon/ai/proc/reactivate_cameras +/datum/action/innate/ai/reactivate_cameras + name = "Reactivate Cameras" + desc = "Reactivates disabled cameras across the station; remaining uses can be used later." + button_icon_state = "reactivate_cameras" + uses = 30 + auto_use_uses = FALSE + cooldown_period = 30 -/mob/living/silicon/ai/proc/reactivate_cameras() - set name = "Reactivate Cameranet" - set category = "Malfunction" - - if(stat || malf_cooldown > world.time) - return - var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun. - - for(var/datum/AI_Module/small/reactivate_cameras/camera in current_modules) - for(var/obj/machinery/camera/C in cameranet.cameras) - var/initial_range = initial(C.view_range) //To prevent calling the proc twice - if(camera.uses > 0) - if(!C.status) - C.toggle_cam(src, 1) //Reactivates the camera based on status. Badly named proc. - fixedcams++ - camera.uses-- - if(C.view_range != initial_range) - C.view_range = initial_range //Fixes cameras with bad focus. - camera.uses-- - fixedcams++ - //If a camera is both deactivated and has bad focus, it will cost two uses to fully fix! - else - to_chat(src, "Out of uses.") - verbs -= /mob/living/silicon/ai/proc/reactivate_cameras //It is useless now, clean it up. - break - to_chat(src, "Diagnostic complete! Operations completed: [fixedcams].") - - malf_cooldown = world.time + 30 +/datum/action/innate/ai/reactivate_cameras/New() + ..() + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc +/datum/action/innate/ai/reactivate_cameras/Activate() + var/fixed_cameras = 0 + for(var/V in cameranet.cameras) + if(!uses) + break + var/obj/machinery/camera/C = V + if(!C.status || C.view_range != initial(C.view_range)) + C.toggle_cam(owner_AI, 0) //Reactivates the camera based on status. Badly named proc. + C.view_range = initial(C.view_range) + fixed_cameras++ + uses-- //Not adjust_uses() so it doesn't automatically delete or show a message + to_chat(owner, "Diagnostic complete! Cameras reactivated: [fixed_cameras]. Reactivations remaining: [uses].") + owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, 0) + adjust_uses(0, TRUE) //Checks the uses remaining + if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() +//Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them X-ray vision. /datum/AI_Module/large/upgrade_cameras module_name = "Upgrade Camera Network" mod_pick_name = "upgradecam" - description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-Proofing and light-amplified X-ray vision." //I <3 pointless technobabble + description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-proofing and light-amplified X-ray vision." //I <3 pointless technobabble //This used to have motion sensing as well, but testing quickly revealed that giving it to the whole cameranet is PURE HORROR. - one_time = 1 + one_purchase = TRUE cost = 35 //Decent price for omniscience! + upgrade = TRUE + unlock_text = "OTA firmware distribution complete! Cameras upgraded: CAMSUPGRADED. Light amplification system online." + unlock_sound = 'sound/items/rped.ogg' - power_type = /mob/living/silicon/ai/proc/upgrade_cameras +/datum/AI_Module/large/upgrade_cameras/upgrade(mob/living/silicon/ai/AI) + AI.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE //Night-vision, without which X-ray would be very limited in power. + AI.update_sight() + var/upgraded_cameras = 0 -/mob/living/silicon/ai/proc/upgrade_cameras() - set name = "Upgrade Cameranet" - set category = "Malfunction" - - if(stat) - return - - var/upgradedcams = 0 - RegisterSignal(src, COMSIG_MOB_UPDATE_SIGHT, .proc/update_upgraded_cameras_sight) //Makes sure the AI has night vision, without which X-ray would be very limited in power. - update_sight() - - for(var/obj/machinery/camera/C in cameranet.cameras) + for(var/V in cameranet.cameras) + var/obj/machinery/camera/C = V if(C.assembly) var/upgraded = FALSE @@ -514,107 +722,21 @@ upgraded = TRUE if(upgraded) - upgradedcams++ + upgraded_cameras++ - to_chat(src, "OTA firmware distribution complete! Cameras upgraded: [upgradedcams]. Light amplification system online.") - verbs -= /mob/living/silicon/ai/proc/upgrade_cameras - -/mob/living/silicon/ai/proc/update_upgraded_cameras_sight() - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + unlock_text = replacetext(unlock_text, "CAMSUPGRADED", "[upgraded_cameras]") //This works, since unlock text is called after upgrade() /datum/AI_Module/large/eavesdrop module_name = "Enhanced Surveillance" mod_pick_name = "eavesdrop" description = "Via a combination of hidden microphones and lip reading software, you are able to use your cameras to listen in on conversations." cost = 30 - one_time = 1 + one_purchase = TRUE + upgrade = TRUE + unlock_text = "OTA firmware distribution complete! Cameras upgraded: Enhanced surveillance package online." + unlock_sound = 'sound/items/rped.ogg' - power_type = /mob/living/silicon/ai/proc/surveillance +/datum/AI_Module/large/eavesdrop/upgrade(mob/living/silicon/ai/AI) + if(AI.eyeobj) + AI.eyeobj.relay_speech = TRUE -/mob/living/silicon/ai/proc/surveillance() - set category = "Malfunction" - set name = "Enhanced Surveillance" - - if(eyeobj) - eyeobj.relay_speech = 1 - to_chat(src, "OTA firmware distribution complete! Cameras upgraded: Enhanced surveillance package online.") - verbs -= /mob/living/silicon/ai/proc/surveillance - - -/datum/module_picker - var/temp = null - var/processing_time = 50 - var/list/possible_modules = list() - -/datum/module_picker/New() - for(var/type in subtypesof(/datum/AI_Module)) - var/datum/AI_Module/AM = new type - if(AM.power_type != null) - src.possible_modules += AM - -/datum/module_picker/proc/remove_verbs(var/mob/living/silicon/ai/A) - - for(var/datum/AI_Module/AM in possible_modules) - A.verbs.Remove(AM.power_type) - - -/datum/module_picker/proc/use(user as mob) - var/dat - dat += {"Select use of processing time: (currently #[src.processing_time] left.)
-
- Install Module:
- The number afterwards is the amount of processing time it consumes.
"} - for(var/datum/AI_Module/large/module in src.possible_modules) - dat += "[module.module_name]\[?\] ([module.cost])
" - for(var/datum/AI_Module/small/module in src.possible_modules) - dat += "[module.module_name]\[?\] ([module.cost])
" - dat += "
" - if(src.temp) - dat += "[src.temp]" - var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu") - popup.set_content(dat) - popup.open() - return - -/datum/module_picker/Topic(href, href_list) - ..() - - if(!isAI(usr)) - return - var/mob/living/silicon/ai/A = usr - - if(A.stat == DEAD) - to_chat(A, "You are already dead!") //Omae Wa Mou Shindeiru - return - - for(var/datum/AI_Module/AM in possible_modules) - if(href_list[AM.mod_pick_name]) - - // Cost check - if(AM.cost > src.processing_time) - temp = "You cannot afford this module." - break - - // Add new uses if we can, and it is allowed. - var/datum/AI_Module/already_AM = locate(AM.type) in A.current_modules - if(already_AM) - if(!AM.one_time) - already_AM.uses += AM.uses - src.processing_time -= AM.cost - temp = "Additional use added to [already_AM.module_name]" - break - else - temp = "This module is only needed once." - break - - // Give the power and take away the money. - A.view_core() //A BYOND bug requires you to be viewing your core before your verbs update - A.verbs += AM.power_type - A.current_modules += new AM.type - temp = AM.description - src.processing_time -= AM.cost - - if(href_list["showdesc"]) - if(AM.mod_pick_name == href_list["showdesc"]) - temp = AM.description - use(usr) diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index fb3c10e25ec..3c0ca1955fb 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -158,9 +158,9 @@ ////CTRL CLICK FOR SWARMERS AND SWARMER_ACT()'S//// /mob/living/simple_animal/hostile/swarmer/AttackingTarget() if(!isliving(target)) - target.swarmer_act(src) + return target.swarmer_act(src) else - ..() + return ..() /mob/living/simple_animal/hostile/swarmer/CtrlClickOn(atom/A) face_atom(A) @@ -352,11 +352,11 @@ /obj/structure/lattice/catwalk/swarmer_catwalk/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) to_chat(S, "We have created these for our own benefit. Aborting.") - return FALSE + return FALSE /obj/structure/shuttle/engine/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) to_chat(S, "This shuttle may be important to us later. Aborting.") - return FALSE + return FALSE ////END CTRL CLICK FOR SWARMERS//// diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index 2b6040ed8b6..b8649985da1 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -123,7 +123,7 @@ med_hud_set_health() med_hud_set_status() -/mob/living/simple_animal/hostile/guardian/adjustHealth(amount) //The spirit is invincible, but passes on damage to the summoner +/mob/living/simple_animal/hostile/guardian/adjustHealth(amount, updating_health = TRUE) //The spirit is invincible, but passes on damage to the summoner var/damage = amount * damage_transfer if(summoner) if(loc == summoner) diff --git a/code/game/gamemodes/miniantags/guardian/types/assassin.dm b/code/game/gamemodes/miniantags/guardian/types/assassin.dm index 5eb8c1b1cec..e9ea9239483 100644 --- a/code/game/gamemodes/miniantags/guardian/types/assassin.dm +++ b/code/game/gamemodes/miniantags/guardian/types/assassin.dm @@ -26,11 +26,12 @@ stat(null, "Stealth Cooldown Remaining: [max(round((stealthcooldown - world.time)*0.1, 0.1), 0)] seconds") /mob/living/simple_animal/hostile/guardian/assassin/AttackingTarget() - ..() - if(toggle && (isliving(target) || istype(target, /obj/structure/window) || istype(target, /obj/structure/grille))) - ToggleMode(1) + . = ..() + if(.) + if(toggle && (isliving(target) || istype(target, /obj/structure/window) || istype(target, /obj/structure/grille))) + ToggleMode(1) -/mob/living/simple_animal/hostile/guardian/assassin/adjustHealth(amount, updating_health = TRUE, forced = FALSE) +/mob/living/simple_animal/hostile/guardian/assassin/adjustHealth(amount, updating_health = TRUE) . = ..() if(. > 0 && toggle) ToggleMode(1) diff --git a/code/game/gamemodes/miniantags/guardian/types/fire.dm b/code/game/gamemodes/miniantags/guardian/types/fire.dm index 0c5052f48bd..09a202afb91 100644 --- a/code/game/gamemodes/miniantags/guardian/types/fire.dm +++ b/code/game/gamemodes/miniantags/guardian/types/fire.dm @@ -28,9 +28,9 @@ toggle = TRUE /mob/living/simple_animal/hostile/guardian/fire/AttackingTarget() - ..() + . = ..() if(toggle) - if(ishuman(target) && !summoner) + if(. && ishuman(target) && !summoner) spawn(0) new /obj/effect/hallucination/delusion(target.loc, target, force_kind = "custom", duration = 200, skip_nearby = 0, custom_icon = icon_state, custom_icon_file = icon) else diff --git a/code/game/gamemodes/miniantags/guardian/types/healer.dm b/code/game/gamemodes/miniantags/guardian/types/healer.dm index d9be543f7e2..bf2c92ffb28 100644 --- a/code/game/gamemodes/miniantags/guardian/types/healer.dm +++ b/code/game/gamemodes/miniantags/guardian/types/healer.dm @@ -43,7 +43,7 @@ stat(null, "Bluespace Beacon Cooldown Remaining: [max(round((beacon_cooldown - world.time)*0.1, 0.1), 0)] seconds") /mob/living/simple_animal/hostile/guardian/healer/AttackingTarget() - ..() + . = ..() if(toggle == TRUE) if(loc == summoner) to_chat(src, "You must be manifested to heal!") diff --git a/code/game/gamemodes/miniantags/guardian/types/lightning.dm b/code/game/gamemodes/miniantags/guardian/types/lightning.dm index 88d5a43143d..13b9b67f0a9 100644 --- a/code/game/gamemodes/miniantags/guardian/types/lightning.dm +++ b/code/game/gamemodes/miniantags/guardian/types/lightning.dm @@ -19,8 +19,8 @@ var/successfulshocks = 0 /mob/living/simple_animal/hostile/guardian/beam/AttackingTarget() - ..() - if(isliving(target) && target != src && target != summoner) + . = ..() + if(. && isliving(target) && target != src && target != summoner) cleardeletedchains() for(var/chain in enemychains) var/datum/beam/B = chain diff --git a/code/game/gamemodes/miniantags/guardian/types/ranged.dm b/code/game/gamemodes/miniantags/guardian/types/ranged.dm index fe8a566ad52..871d7be1183 100644 --- a/code/game/gamemodes/miniantags/guardian/types/ranged.dm +++ b/code/game/gamemodes/miniantags/guardian/types/ranged.dm @@ -11,10 +11,9 @@ melee_damage_upper = 10 damage_transfer = 0.9 projectiletype = /obj/item/projectile/guardian - ranged_cooldown_time = 10 + ranged_cooldown_time = 1 //fast! projectilesound = 'sound/effects/hit_on_shattered_glass.ogg' ranged = 1 - rapid = 1 range = 13 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE see_in_dark = 8 diff --git a/code/game/gamemodes/miniantags/guardian/types/standard.dm b/code/game/gamemodes/miniantags/guardian/types/standard.dm index 1380c4a2e95..dc85a48a480 100644 --- a/code/game/gamemodes/miniantags/guardian/types/standard.dm +++ b/code/game/gamemodes/miniantags/guardian/types/standard.dm @@ -19,7 +19,7 @@ battlecry = input /mob/living/simple_animal/hostile/guardian/punch/AttackingTarget() - ..() + . = ..() if(iscarbon(target) && target != summoner) if(length(battlecry) > 11)//no more then 11 letters in a battle cry. visible_message("[src] punches [target]!") diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index 81e052a85d8..1da936b64ee 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -28,7 +28,7 @@ melee_damage_upper = 20 see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - idle_vision_range = 1 // Only attack when target is close + vision_range = 1 // Only attack when target is close wander = 0 attacktext = "glomps" attack_sound = 'sound/effects/blobattack.ogg' @@ -54,7 +54,7 @@ . = ..() AddSpell(new /obj/effect/proc_holder/spell/targeted/smoke) AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall) - + /mob/living/simple_animal/hostile/morph/examine(mob/user) if(morphed) if(form) @@ -153,7 +153,7 @@ restore() /mob/living/simple_animal/hostile/morph/LoseAggro() - vision_range = idle_vision_range + vision_range = initial(vision_range) /mob/living/simple_animal/hostile/morph/AIShouldSleep(var/list/possible_targets) . = ..() @@ -179,4 +179,4 @@ if(do_after(src, 20, target = I)) eat(I) return - target.attack_animal(src) + return ..() diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 740601f3798..f0d8ede6634 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -85,7 +85,7 @@ /mob/living/simple_animal/revenant/narsie_act() return //most humans will now be either bones or harvesters, but we're still un-alive. -/mob/living/simple_animal/revenant/adjustHealth(amount) +/mob/living/simple_animal/revenant/adjustHealth(amount, updating_health = TRUE) if(!revealed) return essence = max(0, essence-amount) diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 09d5fecb8a2..4a8f215ee47 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -290,10 +290,10 @@ emote_hear = list("gaffaws", "laughs") response_help = "hugs" attacktext = "wildly tickles" - maxHealth = 150 - health = 150 - melee_damage_lower = 20 - melee_damage_upper = 20 + maxHealth = 175 + health = 175 + melee_damage_lower = 25 + melee_damage_upper = 25 attack_sound = 'sound/items/bikehorn.ogg' feast_sound = 'sound/spookoween/scary_horn2.ogg' diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 836c51d5a2c..42ebb351e42 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -66,7 +66,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu /datum/objective/assassinate/check_completion() if(target && target.current) - if(target.current.stat == DEAD) + if(target.current.stat == DEAD || iszombie(target)) return 1 if(issilicon(target.current) || isbrain(target.current)) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite return 1 @@ -110,7 +110,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu /datum/objective/maroon/check_completion() if(target && target.current) - if(target.current.stat == DEAD) + if(target.current.stat == DEAD || iszombie(target)) return 1 if(!target.current.ckey) return 1 @@ -167,7 +167,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu if(!target) //If it's a free objective. return 1 if(target.current) - if(target.current.stat == DEAD) + if(target.current.stat == DEAD || iszombie(target)) return 0 if(issilicon(target.current)) return 0 @@ -262,7 +262,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu return 0 if(isbrain(owner.current)) return 0 - if(!owner.current || owner.current.stat == DEAD) + if(!owner.current || owner.current.stat == DEAD || iszombie(owner)) return 0 if(SSticker.force_ending) //This one isn't their fault, so lets just assume good faith return 1 @@ -317,7 +317,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu explanation_text = "Die a glorious death." /datum/objective/die/check_completion() - if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current)) + if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current) || iszombie(owner)) return 1 if(issilicon(owner.current) && owner.current != owner.original) return 1 diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index b5f468ad319..4193ad7b751 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -12,7 +12,7 @@ var/buy_word = "Learn" var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook -/datum/spellbook_entry/proc/IsAvailible() // For config prefs / gamemode restrictions - these are round applied +/datum/spellbook_entry/proc/IsSpellAvailable() // For config prefs / gamemode restrictions - these are round applied return 1 /datum/spellbook_entry/proc/CanBuy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) // Specific circumstances if(book.uses" return dat -/datum/spellbook_entry/noclothes - name = "Remove Clothes Requirement" - spell_type = /obj/effect/proc_holder/spell/noclothes - log_name = "NC" - category = "Defensive" +//Main category - Spells +//Offensive +/datum/spellbook_entry/blind + name = "Blind" + spell_type = /obj/effect/proc_holder/spell/targeted/trigger/blind + log_name = "BD" + category = "Offensive" + cost = 1 -/datum/spellbook_entry/fireball - name = "Fireball" - spell_type = /obj/effect/proc_holder/spell/fireball - log_name = "FB" +/datum/spellbook_entry/lightningbolt + name = "Lightning Bolt" + spell_type = /obj/effect/proc_holder/spell/targeted/lightning + log_name = "LB" + category = "Offensive" + cost = 1 -/datum/spellbook_entry/rod_form - name = "Rod Form" - spell_type = /obj/effect/proc_holder/spell/targeted/rod_form - log_name = "RF" +/datum/spellbook_entry/cluwne + name = "Curse of the Cluwne" + spell_type = /obj/effect/proc_holder/spell/targeted/touch/cluwne + log_name = "CC" + category = "Offensive" -/datum/spellbook_entry/magicm - name = "Magic Missile" - spell_type = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile - log_name = "MM" - category = "Defensive" +/datum/spellbook_entry/banana_touch + name = "Banana Touch" + spell_type = /obj/effect/proc_holder/spell/targeted/touch/banana + log_name = "BT" + cost = 1 + +/datum/spellbook_entry/mime_malaise + name = "Mime Malaise" + spell_type = /obj/effect/proc_holder/spell/targeted/touch/mime_malaise + log_name = "MI" + cost = 1 + +/datum/spellbook_entry/horseman + name = "Curse of the Horseman" + spell_type = /obj/effect/proc_holder/spell/targeted/horsemask + log_name = "HH" + category = "Offensive" /datum/spellbook_entry/disintegrate name = "Disintegrate" spell_type = /obj/effect/proc_holder/spell/targeted/touch/disintegrate log_name = "DG" + category = "Offensive" +/datum/spellbook_entry/fireball + name = "Fireball" + spell_type = /obj/effect/proc_holder/spell/fireball + log_name = "FB" + category = "Offensive" + +/datum/spellbook_entry/fleshtostone + name = "Flesh to Stone" + spell_type = /obj/effect/proc_holder/spell/targeted/touch/flesh_to_stone + log_name = "FS" + category = "Offensive" + +/datum/spellbook_entry/mutate + name = "Mutate" + spell_type = /obj/effect/proc_holder/spell/targeted/genetic/mutate + log_name = "MU" + category = "Offensive" + +/datum/spellbook_entry/rod_form + name = "Rod Form" + spell_type = /obj/effect/proc_holder/spell/targeted/rod_form + log_name = "RF" + category = "Offensive" + +/datum/spellbook_entry/infinite_guns + name = "Lesser Summon Guns" + spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns + log_name = "IG" + category = "Offensive" + cost = 4 + +//Defensive /datum/spellbook_entry/disabletech name = "Disable Tech" spell_type = /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech @@ -128,37 +179,6 @@ category = "Defensive" cost = 1 -/datum/spellbook_entry/repulse - name = "Repulse" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/repulse - log_name = "RP" - category = "Defensive" - -/datum/spellbook_entry/timestop - name = "Time Stop" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop - log_name = "TS" - category = "Defensive" - -/datum/spellbook_entry/smoke - name = "Smoke" - spell_type = /obj/effect/proc_holder/spell/targeted/smoke - log_name = "SM" - category = "Defensive" - cost = 1 - -/datum/spellbook_entry/blind - name = "Blind" - spell_type = /obj/effect/proc_holder/spell/targeted/trigger/blind - log_name = "BD" - cost = 1 - -/datum/spellbook_entry/mindswap - name = "Mindswap" - spell_type = /obj/effect/proc_holder/spell/targeted/mind_transfer - log_name = "MT" - category = "Mobility" - /datum/spellbook_entry/forcewall name = "Force Wall" spell_type = /obj/effect/proc_holder/spell/targeted/forcewall @@ -173,54 +193,18 @@ category = "Defensive" cost = 1 -/datum/spellbook_entry/blink - name = "Blink" - spell_type = /obj/effect/proc_holder/spell/targeted/turf_teleport/blink - log_name = "BL" - category = "Mobility" - -/datum/spellbook_entry/teleport - name = "Teleport" - spell_type = /obj/effect/proc_holder/spell/targeted/area_teleport/teleport - log_name = "TP" - category = "Mobility" - -/datum/spellbook_entry/mutate - name = "Mutate" - spell_type = /obj/effect/proc_holder/spell/targeted/genetic/mutate - log_name = "MU" - -/datum/spellbook_entry/jaunt - name = "Ethereal Jaunt" - spell_type = /obj/effect/proc_holder/spell/targeted/ethereal_jaunt - log_name = "EJ" - category = "Mobility" - -/datum/spellbook_entry/knock - name = "Knock" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock - log_name = "KN" - category = "Mobility" +/datum/spellbook_entry/repulse + name = "Repulse" + spell_type = /obj/effect/proc_holder/spell/aoe_turf/repulse + log_name = "RP" + category = "Defensive" cost = 1 -/datum/spellbook_entry/greaterknock - name = "Greater Knock" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock/greater - log_name = "GK" - category = "Mobility" - cost = 2 - refundable = 0 //global effect on cast - -/datum/spellbook_entry/fleshtostone - name = "Flesh to Stone" - spell_type = /obj/effect/proc_holder/spell/targeted/touch/flesh_to_stone - log_name = "FS" - -/datum/spellbook_entry/summonitem - name = "Summon Item" - spell_type = /obj/effect/proc_holder/spell/targeted/summonitem - log_name = "IS" - category = "Assistance" +/datum/spellbook_entry/smoke + name = "Smoke" + spell_type = /obj/effect/proc_holder/spell/targeted/smoke + log_name = "SM" + category = "Defensive" cost = 1 /datum/spellbook_entry/lichdom @@ -229,28 +213,64 @@ log_name = "LD" category = "Defensive" -/datum/spellbook_entry/lichdom/IsAvailible() +/datum/spellbook_entry/lichdom/IsSpellAvailable() if(SSticker.mode.name == "ragin' mages") return FALSE else return TRUE -/datum/spellbook_entry/lightningbolt - name = "Lightning Bolt" - spell_type = /obj/effect/proc_holder/spell/targeted/lightning - log_name = "LB" +/datum/spellbook_entry/magicm + name = "Magic Missile" + spell_type = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile + log_name = "MM" + category = "Defensive" -/datum/spellbook_entry/infinite_guns - name = "Lesser Summon Guns" - spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns - log_name = "IG" - cost = 4 +/datum/spellbook_entry/timestop + name = "Time Stop" + spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop + log_name = "TS" + category = "Defensive" -/datum/spellbook_entry/horseman - name = "Curse of The Horseman" - spell_type = /obj/effect/proc_holder/spell/targeted/horsemask - log_name = "HH" +//Mobility +/datum/spellbook_entry/knock + name = "Knock" + spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock + log_name = "KN" + category = "Mobility" + cost = 1 +/datum/spellbook_entry/blink + name = "Blink" + spell_type = /obj/effect/proc_holder/spell/targeted/turf_teleport/blink + log_name = "BL" + category = "Mobility" + +/datum/spellbook_entry/jaunt + name = "Ethereal Jaunt" + spell_type = /obj/effect/proc_holder/spell/targeted/ethereal_jaunt + log_name = "EJ" + category = "Mobility" + +/datum/spellbook_entry/greaterknock + name = "Greater Knock" + spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock/greater + log_name = "GK" + category = "Mobility" + refundable = 0 //global effect on cast + +/datum/spellbook_entry/mindswap + name = "Mindswap" + spell_type = /obj/effect/proc_holder/spell/targeted/mind_transfer + log_name = "MT" + category = "Mobility" + +/datum/spellbook_entry/teleport + name = "Teleport" + spell_type = /obj/effect/proc_holder/spell/targeted/area_teleport/teleport + log_name = "TP" + category = "Mobility" + +//Assistance /datum/spellbook_entry/charge name = "Charge" spell_type = /obj/effect/proc_holder/spell/targeted/charge @@ -258,192 +278,20 @@ category = "Assistance" cost = 1 -/datum/spellbook_entry/cluwne - name = "Curse of the Cluwne" - spell_type = /obj/effect/proc_holder/spell/targeted/touch/cluwne - log_name = "CC" - -/datum/spellbook_entry/item - name = "Buy Item" - refundable = 0 - buy_word = "Summon" - var/item_path= null - - -/datum/spellbook_entry/item/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - new item_path(get_turf(user)) - feedback_add_details("wizard_spell_learned",log_name) - return 1 - -/datum/spellbook_entry/item/GetInfo() - var/dat ="" - dat += "[name]" - dat += " Cost:[cost]
" - dat += "[desc]
" - if(surplus>=0) - dat += "[surplus] left.
" - return dat - -/datum/spellbook_entry/item/staffchange - name = "Staff of Change" - desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself." - item_path = /obj/item/gun/magic/staff/change - log_name = "ST" - -/datum/spellbook_entry/item/staffanimation - name = "Staff of Animation" - desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines." - item_path = /obj/item/gun/magic/staff/animate - log_name = "SA" +/datum/spellbook_entry/summonitem + name = "Summon Item" + spell_type = /obj/effect/proc_holder/spell/targeted/summonitem + log_name = "IS" category = "Assistance" - -/datum/spellbook_entry/item/staffchaos - name = "Staff of Chaos" - desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended." - item_path = /obj/item/gun/magic/staff/chaos - log_name = "SC" - -/datum/spellbook_entry/item/staffslipping - name = "Staff of Slipping" - desc = "A staff that shoots magical bananas. These bananas will either slip or stun the target when hit. Surprisingly reliable!" - item_path = /obj/item/gun/magic/staff/slipping - log_name = "SL" cost = 1 -/datum/spellbook_entry/item/staffdoor - name = "Staff of Door Creation" - desc = "A particular staff that can mold solid metal into ornate wooden doors. Useful for getting around in the absence of other transportation. Does not work on glass." - item_path = /obj/item/gun/magic/staff/door - log_name = "SD" - cost = 1 - category = "Mobility" - -/datum/spellbook_entry/item/staffhealing - name = "Staff of Healing" - desc = "An altruistic staff that can heal the lame and raise the dead." - item_path = /obj/item/gun/magic/staff/healing - log_name = "SH" - cost = 1 - category = "Defensive" - -/datum/spellbook_entry/item/scryingorb - name = "Scrying Orb" - desc = "An incandescent orb of crackling energy, using it will allow you to ghost while alive, allowing you to spy upon the station with ease. In addition, buying it will permanently grant you x-ray vision." - item_path = /obj/item/scrying - log_name = "SO" - category = "Defensive" - -/datum/spellbook_entry/item/scryingorb/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - if(..()) - if(!(XRAY in user.mutations)) - user.mutations.Add(XRAY) - user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) - user.see_in_dark = 8 - user.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - to_chat(user, "The walls suddenly disappear.") - return 1 - - -/datum/spellbook_entry/item/soulstones - name = "Six Soul Stone Shards and the spell Artificer" - desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot." - item_path = /obj/item/storage/belt/soulstone/full - log_name = "SS" +/datum/spellbook_entry/noclothes + name = "Remove Clothes Requirement" + spell_type = /obj/effect/proc_holder/spell/noclothes + log_name = "NC" category = "Assistance" -/datum/spellbook_entry/item/soulstones/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - . =..() - if(.) - user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(null)) - return . - -/datum/spellbook_entry/item/necrostone - name = "A Necromantic Stone" - desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command." - item_path = /obj/item/necromantic_stone - log_name = "NS" - category = "Assistance" - -/datum/spellbook_entry/item/wands - name = "Wand Assortment" - desc = "A collection of wands that allow for a wide variety of utility. Wands do not recharge, so be conservative in use. Comes in a handy belt." - item_path = /obj/item/storage/belt/wands/full - log_name = "WA" - category = "Defensive" - -/datum/spellbook_entry/item/armor - name = "Mastercrafted Armor Set" - desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space. Comes bundled with Boots of Gripping." - item_path = /obj/item/clothing/suit/space/hardsuit/wizard - log_name = "HS" - category = "Defensive" - -/datum/spellbook_entry/item/armor/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - . = ..() - if(.) - new /obj/item/clothing/shoes/magboots/wizard(get_turf(user)) - new /obj/item/clothing/gloves/color/purple(get_turf(user))//To complete the outfit - -/datum/spellbook_entry/item/contract - name = "Contract of Apprenticeship" - desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side." - item_path = /obj/item/contract - log_name = "CT" - category = "Assistance" - -/datum/spellbook_entry/item/bloodbottle - name = "Bottle of Blood" - desc = "A bottle of magically infused blood, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned by blood magic are indiscriminate in their killing, and you yourself may become a victim." - item_path = /obj/item/antag_spawner/slaughter_demon - log_name = "BB" - limit = 3 - category = "Assistance" - -/datum/spellbook_entry/item/hugbottle - name = "Bottle of Tickles" - desc = "A bottle of magically infused fun, the smell of which will \ - attract adorable extradimensional beings when broken. These beings \ - are similar to slaughter demons, but are a little weaker and they do not permamently \ - kill their victims, instead putting them in an extradimensional hugspace, \ - to be released on the demon's death. Chaotic, but not ultimately \ - damaging. The crew's reaction to the other hand could be very \ - destructive." - item_path = /obj/item/antag_spawner/slaughter_demon/laughter - cost = 1 //non-destructive; it's just a jape, sibling! - log_name = "HB" - limit = 3 - category = "Assistance" - -/datum/spellbook_entry/item/oozebottle - name = "Bottle of Ooze" - desc = "A bottle of magically infused ooze, which will awake an all-consuming Morph, capable of cunningly disguising itself as any object it comes in contact with and even casting some very basic spells. Be careful though, as Morph diet includes Wizards." - item_path = /obj/item/antag_spawner/morph - cost = 1 - log_name = "BO" - limit = 3 - category = "Assistance" - -/datum/spellbook_entry/item/tarotdeck - name = "Guardian Deck" - desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \ - It would be wise to avoid buying these with anything capable of causing you to swap bodies with others." - item_path = /obj/item/guardiancreator - log_name = "TD" - limit = 1 - category = "Assistance" - -/datum/spellbook_entry/item/mjolnir - name = "Mjolnir" - desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power." - item_path = /obj/item/twohanded/mjollnir - log_name = "MJ" - -/datum/spellbook_entry/item/singularity_hammer - name = "Singularity Hammer" - desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everthing nearby to the point of impact." - item_path = /obj/item/twohanded/singularityhammer - log_name = "SI" - +//Rituals /datum/spellbook_entry/summon name = "Summon Stuff" category = "Rituals" @@ -472,7 +320,7 @@ cost = 0 log_name = "SGH" -/datum/spellbook_entry/summon/ghosts/IsAvailible() +/datum/spellbook_entry/summon/ghosts/IsSpellAvailable() if(!SSticker.mode) // In case spellbook is placed on map return FALSE if(SSticker.mode.name == "ragin' mages") @@ -493,7 +341,7 @@ cost = 0 log_name = "SG" -/datum/spellbook_entry/summon/guns/IsAvailible() +/datum/spellbook_entry/summon/guns/IsSpellAvailable() if(!SSticker.mode) // In case spellbook is placed on map return FALSE if(SSticker.mode.name == "ragin' mages") @@ -502,7 +350,7 @@ return TRUE /datum/spellbook_entry/summon/guns/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - feedback_add_details("wizard_spell_learned",log_name) + feedback_add_details("wizard_spell_learned", log_name) user.rightandwrong(0) book.uses += 1 active = 1 @@ -515,7 +363,7 @@ cost = 0 log_name = "SU" -/datum/spellbook_entry/summon/magic/IsAvailible() +/datum/spellbook_entry/summon/magic/IsSpellAvailable() if(!SSticker.mode) // In case spellbook is placed on map return FALSE if(SSticker.mode.name == "ragin' mages") @@ -524,18 +372,207 @@ return TRUE /datum/spellbook_entry/summon/magic/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - feedback_add_details("wizard_spell_learned",log_name) + feedback_add_details("wizard_spell_learned", log_name) user.rightandwrong(1) book.uses += 1 active = 1 to_chat(user, "You have cast summon magic and gained an extra charge for your spellbook.") return 1 +//Main category - Magical Items +/datum/spellbook_entry/item + name = "Buy Item" + refundable = 0 + buy_word = "Summon" + var/item_path = null + +/datum/spellbook_entry/item/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) + new item_path(get_turf(user)) + feedback_add_details("wizard_spell_learned", log_name) + return 1 + +/datum/spellbook_entry/item/GetInfo() + var/dat ="" + dat += "[name]" + dat += " Cost:[cost]
" + dat += "[desc]
" + if(surplus>=0) + dat += "[surplus] left.
" + return dat + +//Artefacts +/datum/spellbook_entry/item/necrostone + name = "A Necromantic Stone" + desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command." + item_path = /obj/item/necromantic_stone + log_name = "NS" + category = "Artefacts" + +/datum/spellbook_entry/item/scryingorb + name = "Scrying Orb" + desc = "An incandescent orb of crackling energy, using it will allow you to ghost while alive, allowing you to spy upon the station with ease. In addition, buying it will permanently grant you x-ray vision." + item_path = /obj/item/scrying + log_name = "SO" + category = "Artefacts" + +/datum/spellbook_entry/item/scryingorb/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) + if(..()) + if(!(XRAY in user.mutations)) + user.mutations.Add(XRAY) + user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) + user.see_in_dark = 8 + user.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + to_chat(user, "The walls suddenly disappear.") + return TRUE + +/datum/spellbook_entry/item/soulstones + name = "Six Soul Stone Shards and the spell Artificer" + desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot." + item_path = /obj/item/storage/belt/soulstone/full + log_name = "SS" + category = "Artefacts" + +/datum/spellbook_entry/item/soulstones/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) + . = ..() + if(.) + user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(null)) + return . + +/datum/spellbook_entry/item/wands + name = "Wand Assortment" + desc = "A collection of wands that allow for a wide variety of utility. Wands do not recharge, so be conservative in use. Comes in a handy belt." + item_path = /obj/item/storage/belt/wands/full + log_name = "WA" + category = "Artefacts" + +//Weapons and Armors +/datum/spellbook_entry/item/armor + name = "Mastercrafted Armor Set" + desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space. Comes bundled with Boots of Gripping." + item_path = /obj/item/clothing/suit/space/hardsuit/wizard + log_name = "HS" + category = "Weapons and Armors" + +/datum/spellbook_entry/item/armor/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) + . = ..() + if(.) + new /obj/item/clothing/shoes/magboots/wizard(get_turf(user)) + new /obj/item/clothing/gloves/color/purple(get_turf(user)) // To complete the outfit + +/datum/spellbook_entry/item/mjolnir + name = "Mjolnir" + desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power." + item_path = /obj/item/twohanded/mjollnir + log_name = "MJ" + category = "Weapons and Armors" + +/datum/spellbook_entry/item/singularity_hammer + name = "Singularity Hammer" + desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everthing nearby to the point of impact." + item_path = /obj/item/twohanded/singularityhammer + log_name = "SI" + category = "Weapons and Armors" + +//Staves +/datum/spellbook_entry/item/staffdoor + name = "Staff of Door Creation" + desc = "A particular staff that can mold solid metal into ornate wooden doors. Useful for getting around in the absence of other transportation. Does not work on glass." + item_path = /obj/item/gun/magic/staff/door + log_name = "SD" + category = "Staves" + cost = 1 + +/datum/spellbook_entry/item/staffhealing + name = "Staff of Healing" + desc = "An altruistic staff that can heal the lame and raise the dead." + item_path = /obj/item/gun/magic/staff/healing + log_name = "SH" + category = "Staves" + cost = 1 + +/datum/spellbook_entry/item/staffslipping + name = "Staff of Slipping" + desc = "A staff that shoots magical bananas. These bananas will either slip or stun the target when hit. Surprisingly reliable!" + item_path = /obj/item/gun/magic/staff/slipping + log_name = "SL" + category = "Staves" + cost = 1 + +/datum/spellbook_entry/item/staffanimation + name = "Staff of Animation" + desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines." + item_path = /obj/item/gun/magic/staff/animate + log_name = "SA" + category = "Staves" + +/datum/spellbook_entry/item/staffchange + name = "Staff of Change" + desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself." + item_path = /obj/item/gun/magic/staff/change + log_name = "ST" + category = "Staves" + +/datum/spellbook_entry/item/staffchaos + name = "Staff of Chaos" + desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended." + item_path = /obj/item/gun/magic/staff/chaos + log_name = "SC" + category = "Staves" + +//Summons +/datum/spellbook_entry/item/oozebottle + name = "Bottle of Ooze" + desc = "A bottle of magically infused ooze, which will awake an all-consuming Morph, capable of cunningly disguising itself as any object it comes in contact with and even casting some very basic spells. Be careful though, as Morph diet includes Wizards." + item_path = /obj/item/antag_spawner/morph + log_name = "BO" + category = "Summons" + limit = 3 + cost = 1 + +/datum/spellbook_entry/item/hugbottle + name = "Bottle of Tickles" + desc = "A bottle of magically infused fun, the smell of which will \ + attract adorable extradimensional beings when broken. These beings \ + are similar to slaughter demons, but are a little weaker and they do not permamently \ + kill their victims, instead putting them in an extradimensional hugspace, \ + to be released on the demon's death. Chaotic, but not ultimately \ + damaging. The crew's reaction to the other hand could be very \ + destructive." + item_path = /obj/item/antag_spawner/slaughter_demon/laughter + log_name = "HB" + category = "Summons" + limit = 3 + cost = 1 // Non-destructive; it's just a jape, sibling! + +/datum/spellbook_entry/item/bloodbottle + name = "Bottle of Blood" + desc = "A bottle of magically infused blood, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned by blood magic are indiscriminate in their killing, and you yourself may become a victim." + item_path = /obj/item/antag_spawner/slaughter_demon + log_name = "BB" + category = "Summons" + limit = 3 + +/datum/spellbook_entry/item/contract + name = "Contract of Apprenticeship" + desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side." + item_path = /obj/item/contract + log_name = "CT" + category = "Summons" + +/datum/spellbook_entry/item/tarotdeck + name = "Guardian Deck" + desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \ + It would be wise to avoid buying these with anything capable of causing you to swap bodies with others." + item_path = /obj/item/guardiancreator + log_name = "TD" + category = "Summons" + limit = 1 + /obj/item/spellbook name = "spell book" desc = "The legendary book of spells of the wizard." icon = 'icons/obj/library.dmi' - icon_state ="book" + icon_state = "spellbook" throw_speed = 2 throw_range = 5 w_class = WEIGHT_CLASS_TINY @@ -543,19 +580,24 @@ var/temp = null var/op = 1 var/tab = null + var/main_tab = null var/mob/living/carbon/human/owner var/list/datum/spellbook_entry/entries = list() var/list/categories = list() + var/list/main_categories = list("Spells", "Magical Items") + var/list/spell_categories = list("Offensive", "Defensive", "Mobility", "Assistance", "Rituals") + var/list/item_categories = list("Artefacts", "Weapons and Armors", "Staves", "Summons") /obj/item/spellbook/proc/initialize() var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon for(var/T in entry_types) var/datum/spellbook_entry/E = new T - if(E.IsAvailible()) + if(E.IsSpellAvailable()) entries |= E categories |= E.category else qdel(E) + main_tab = main_categories[1] tab = categories[1] /obj/item/spellbook/New() @@ -569,48 +611,64 @@ to_chat(user, "The contract has been used, you can't get your points back now!") else to_chat(user, "You feed the contract back into the spellbook, refunding your points.") - uses+=2 - qdel(O) if(istype(O, /obj/item/antag_spawner/slaughter_demon)) to_chat(user, "On second thought, maybe summoning a demon is a bad idea. You refund your points.") - if(istype(O, /obj/item/antag_spawner/slaughter_demon/laughter)) uses += 1 + for(var/datum/spellbook_entry/item/hugbottle/HB in entries) + if(!isnull(HB.limit)) + HB.limit++ else uses += 2 - for(var/datum/spellbook_entry/item/bloodbottle/BB in entries) - if(!isnull(BB.limit)) - BB.limit++ + for(var/datum/spellbook_entry/item/bloodbottle/BB in entries) + if(!isnull(BB.limit)) + BB.limit++ + qdel(O) + + if(istype(O, /obj/item/antag_spawner/morph)) + to_chat(user, "On second thought, maybe awakening a morph is a bad idea. You refund your points.") + uses += 1 + for(var/datum/spellbook_entry/item/oozebottle/OB in entries) + if(!isnull(OB.limit)) + OB.limit++ qdel(O) /obj/item/spellbook/proc/GetCategoryHeader(var/category) var/dat = "" switch(category) if("Offensive") - dat += "Spells and items geared towards debilitating and destroying.

" - dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + dat += "Spells geared towards debilitating and destroying.

" dat += "For spells: the number after the spell name is the cooldown time.
" dat += "You can reduce this number by spending more points on the spell.
" if("Defensive") - dat += "Spells and items geared towards improving your survivabilty or reducing foes ability to attack.

" - dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + dat += "Spells geared towards improving your survivabilty or reducing foes ability to attack.

" dat += "For spells: the number after the spell name is the cooldown time.
" dat += "You can reduce this number by spending more points on the spell.
" if("Mobility") - dat += "Spells and items geared towards improving your ability to move. It is a good idea to take at least one.

" - dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + dat += "Spells geared towards improving your ability to move. It is a good idea to take at least one.

" dat += "For spells: the number after the spell name is the cooldown time.
" dat += "You can reduce this number by spending more points on the spell.
" if("Assistance") - dat += "Spells and items geared towards bringing in outside forces to aid you or improving upon your other items and abilties.

" - dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + dat += "Spells geared towards improving your other items and abilities.

" dat += "For spells: the number after the spell name is the cooldown time.
" dat += "You can reduce this number by spending more points on the spell.
" if("Rituals") - dat += "These powerful spells change the very fabric of reality. Not always in your favour.
" + dat += "These powerful spells are capable of changing the very fabric of reality. Not always in your favour.
" + if("Weapons and Armors") + dat += "Various weapons and armors to crush your enemies and protect you from harm.

" + dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + if("Staves") + dat += "Various staves granting you their power, which they slowly recharge over time.

" + dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + if("Artefacts") + dat += "Various magical artefacts to aid you.

" + dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + if("Summons") + dat += "Magical items geared towards bringing in outside forces to aid you.

" + dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" return dat /obj/item/spellbook/proc/wrap(var/content) @@ -620,11 +678,16 @@ @@ -644,13 +707,29 @@ user.set_machine(src) var/dat = "" - dat += "
    " + dat += "
      " var/list/cat_dat = list() - for(var/category in categories) - cat_dat[category] = "
      " - dat += "
    • [category]
    • " - - dat += "
    • Points remaining : [uses]
    • " + for(var/main_category in main_categories) + cat_dat[main_category] = "
      " + dat += "
    • [main_category]
    • " + dat += "
    " + switch(main_tab) + if("Spells") + dat += "
      " + for(var/category in categories) + if(category in item_categories) + continue + cat_dat[category] = "
      " + dat += "
    • [category]
    • " + dat += "
    • Points remaining : [uses]
    • " + if("Magical Items") + dat += "" var/datum/spellbook_entry/E @@ -674,7 +753,7 @@ dat += cat_dat[category] dat += "" - user << browse(wrap(dat), "window=spellbook;size=700x500") + user << browse(wrap(dat), "window=spellbook;size=800x600") onclose(user, "spellbook") return @@ -708,13 +787,19 @@ if(!isnull(E.limit)) E.limit += result uses += result + else if(href_list["mainpage"]) + main_tab = sanitize(href_list["mainpage"]) + tab = sanitize(href_list["page"]) + if(main_tab == "Spells") + tab = spell_categories[1] + else if(main_tab == "Magical Items") + tab = item_categories[1] else if(href_list["page"]) tab = sanitize(href_list["page"]) attack_self(H) return 1 -//Single Use Spellbooks// - +//Single Use Spellbooks /obj/item/spellbook/oneuse var/spell = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic var/spellname = "sandbox" @@ -748,7 +833,6 @@ user.create_attack_log("[key_name(user)] learned the spell [spellname] ([S]).") onlearned(user) - /obj/item/spellbook/oneuse/proc/recoil(mob/user) user.visible_message("[src] glows in a black light!") @@ -762,7 +846,7 @@ /obj/item/spellbook/oneuse/fireball spell = /obj/effect/proc_holder/spell/fireball spellname = "fireball" - icon_state ="bookfireball" + icon_state = "bookfireball" desc = "This book feels warm to the touch." /obj/item/spellbook/oneuse/fireball/recoil(mob/user as mob) @@ -773,7 +857,7 @@ /obj/item/spellbook/oneuse/smoke spell = /obj/effect/proc_holder/spell/targeted/smoke spellname = "smoke" - icon_state ="booksmoke" + icon_state = "booksmoke" desc = "This book is overflowing with the dank arts." /obj/item/spellbook/oneuse/smoke/recoil(mob/user as mob) @@ -787,7 +871,7 @@ /obj/item/spellbook/oneuse/blind spell = /obj/effect/proc_holder/spell/targeted/trigger/blind spellname = "blind" - icon_state ="bookblind" + icon_state = "bookblind" desc = "This book looks blurry, no matter how you look at it." /obj/item/spellbook/oneuse/blind/recoil(mob/user as mob) @@ -798,7 +882,7 @@ /obj/item/spellbook/oneuse/mindswap spell = /obj/effect/proc_holder/spell/targeted/mind_transfer spellname = "mindswap" - icon_state ="bookmindswap" + icon_state = "bookmindswap" desc = "This book's cover is pristine, though its pages look ragged and torn." var/mob/stored_swap = null //Used in used book recoils to store an identity for mindswaps @@ -830,7 +914,7 @@ /obj/item/spellbook/oneuse/forcewall spell = /obj/effect/proc_holder/spell/targeted/forcewall spellname = "forcewall" - icon_state ="bookforcewall" + icon_state = "bookforcewall" desc = "This book has a dedication to mimes everywhere inside the front cover." /obj/item/spellbook/oneuse/forcewall/recoil(mob/user as mob) @@ -840,11 +924,10 @@ S.timer = 30 user.drop_item() - /obj/item/spellbook/oneuse/knock spell = /obj/effect/proc_holder/spell/aoe_turf/knock spellname = "knock" - icon_state ="bookknock" + icon_state = "bookknock" desc = "This book is hard to hold closed properly." /obj/item/spellbook/oneuse/knock/recoil(mob/user as mob) @@ -855,7 +938,7 @@ /obj/item/spellbook/oneuse/horsemask spell = /obj/effect/proc_holder/spell/targeted/horsemask spellname = "horses" - icon_state ="bookhorses" + icon_state = "bookhorses" desc = "This book is more horse than your mind has room for." /obj/item/spellbook/oneuse/horsemask/recoil(mob/living/carbon/user as mob) @@ -875,7 +958,7 @@ /obj/item/spellbook/oneuse/charge spell = /obj/effect/proc_holder/spell/targeted/charge spellname = "charging" - icon_state ="bookcharge" + icon_state = "bookcharge" desc = "This book is made of 100% post-consumer wizard." /obj/item/spellbook/oneuse/charge/recoil(mob/user as mob) @@ -886,7 +969,7 @@ /obj/item/spellbook/oneuse/summonitem spell = /obj/effect/proc_holder/spell/targeted/summonitem spellname = "instant summons" - icon_state ="booksummons" + icon_state = "booksummons" desc = "This book is bright and garish, very hard to miss." /obj/item/spellbook/oneuse/summonitem/recoil(mob/user as mob) @@ -897,13 +980,13 @@ /obj/item/spellbook/oneuse/fake_gib spell = /obj/effect/proc_holder/spell/targeted/touch/fake_disintegrate spellname = "disintegrate" - icon_state ="bookfireball" + icon_state = "bookfireball" desc = "This book feels like it will rip stuff apart." /obj/item/spellbook/oneuse/sacredflame spell = /obj/effect/proc_holder/spell/targeted/sacred_flame spellname = "sacred flame" - icon_state ="booksacredflame" + icon_state = "booksacredflame" desc = "Become one with the flames that burn within... and invite others to do so as well." /obj/item/spellbook/oneuse/random diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 407393eb489..0dfd0876817 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -214,7 +214,7 @@ suit = /obj/item/clothing/suit/storage/fr_jacket shoes = /obj/item/clothing/shoes/white l_ear = /obj/item/radio/headset/headset_sec/alt - glasses = /obj/item/clothing/glasses/hud/health/health_advanced + glasses = /obj/item/clothing/glasses/hud/health/sunglasses id = /obj/item/card/id/security suit_store = /obj/item/flashlight/pen l_hand = /obj/item/storage/firstaid/adv diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index 3208e9d3533..849f54169f5 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -175,7 +175,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0) gloves = /obj/item/clothing/gloves/combat shoes = /obj/item/clothing/shoes/jackboots l_ear = /obj/item/radio/headset/heads/blueshield/alt - glasses = /obj/item/clothing/glasses/hud/health/health_advanced + glasses = /obj/item/clothing/glasses/hud/health/sunglasses id = /obj/item/card/id/nanotrasen pda = /obj/item/pda/heads/blueshield backpack_contents = list( diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index aac1c291355..a247fa6810b 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -66,6 +66,12 @@ l_ear = /obj/item/radio/headset/headset_service pda = /obj/item/pda/chef +/datum/outfit/job/chef/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + ..() + if(visualsOnly) + return + var/datum/martial_art/cqc/under_siege/justacook = new + justacook.teach(H) /datum/job/hydro diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index 75c4e466a79..a0c0d2234af 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -322,6 +322,9 @@ /obj/machinery/disco/proc/dance(mob/living/M) //Show your moves set waitfor = FALSE + if(M.client && !(M.client.prefs.sound & SOUND_DISCO)) //We have a client that doesn't want to dance. + rangers -= M //Doing that here as it'll be checked less often than in processing. + return switch(rand(0,9)) if(0 to 1) dance2(M) @@ -460,17 +463,18 @@ var/sound/song_played = sound(selection.song_path) for(var/mob/M in range(10,src)) - if(!(M in rangers)) - rangers[M] = TRUE - M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played) - if(prob(5+(allowed(M) * 4)) && M.canmove && isliving(M)) - dance(M) + if(!M.client || M.client.prefs.sound & SOUND_DISCO) + if(!(M in rangers)) + rangers[M] = TRUE + M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played) for(var/mob/L in rangers) if(get_dist(src, L) > 10) rangers -= L if(!L || !L.client) continue L.stop_sound_channel(CHANNEL_JUKEBOX) + else if(prob(9) && L.canmove && isliving(L)) + dance(L) else if(active) active = FALSE STOP_PROCESSING(SSobj, src) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index e0fb65787cd..6785c5ed8ff 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -1,144 +1,231 @@ -/* -CONTAINS: +#define SINGLE "single" +#define VERTICAL "vertical" +#define HORIZONTAL "horizontal" -Deployable items -Barricades +#define METAL 1 +#define WOOD 2 +#define SAND 3 -for reference: +//Barricades/cover - access_security = 1 - access_brig = 2 - access_armory = 3 - access_forensics_lockers= 4 - access_medical = 5 - access_morgue = 6 - access_tox = 7 - access_tox_storage = 8 - access_genetics = 9 - access_engine = 10 - access_engine_equip= 11 - access_maint_tunnels = 12 - access_external_airlocks = 13 - access_emergency_storage = 14 - access_change_ids = 15 - access_ai_upload = 16 - access_teleporter = 17 - access_eva = 18 - access_heads = 19 - access_captain = 20 - access_all_personal_lockers = 21 - access_chapel_office = 22 - access_tech_storage = 23 - access_atmospherics = 24 - access_bar = 25 - access_janitor = 26 - access_crematorium = 27 - access_kitchen = 28 - access_robotics = 29 - access_rd = 30 - access_cargo = 31 - access_construction = 32 - access_chemistry = 33 - access_cargo_bot = 34 - access_hydroponics = 35 - access_manufacturing = 36 - access_library = 37 - access_lawyer = 38 - access_virology = 39 - access_cmo = 40 - access_qm = 41 - access_court = 42 - access_clown = 43 - access_mime = 44 - -*/ - - -//Barricades, maybe there will be a metal one later... /obj/structure/barricade - anchored = 1.0 - density = 1.0 - var/health = 100.0 - var/maxhealth = 100.0 + name = "chest high wall" + desc = "Looks like this would make good cover." + anchored = TRUE + density = TRUE + max_integrity = 100 + var/proj_pass_rate = 50 //How many projectiles will pass the cover. Lower means stronger cover + var/bar_material = METAL + var/drop_amount = 3 var/stacktype = /obj/item/stack/sheet/metal -/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, stacktype)) - if(src.health < src.maxhealth) - visible_message("[user] begins to repair the [src]!") - if(do_after(user, 20 * W.toolspeed, target = src)) - src.health = src.maxhealth - W:use(1) - visible_message("[user] repairs the [src]!") - return - else - return - return - else if(istype(W, /obj/item/crowbar)) - user.changeNext_move(CLICK_CD_MELEE) - user.visible_message("[user] is prying apart \the [src].", "You begin to pry apart \the [src].") - playsound(src, W.usesound, 200, 1) +/obj/structure/barricade/blob_act(obj/structure/blob/B) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable + take_damage(400, BRUTE, "melee", 0, get_dir(src, B)) - if(do_after(user, 300 * W.toolspeed, target = src) && !QDELETED(src)) - user.visible_message("[user] pries apart \the [src].", "You pry apart \the [src].") - dismantle() +/obj/structure/barricade/ex_act(severity) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable + if(resistance_flags & INDESTRUCTIBLE) return - else - switch(W.damtype) - if("fire") - src.health -= W.force * 1 - if("brute") - src.health -= W.force * 0.75 - else - if(src.health <= 0) - visible_message("\The [src] is smashed apart!") - dismantle() - ..() - -/obj/structure/barricade/ex_act(severity) switch(severity) - if(1.0) - visible_message("\The [src] is blown apart!") + if(1) + obj_integrity = 0 qdel(src) - return - if(2.0) - src.health -= 25 - if(src.health <= 0) - visible_message("\The [src] is blown apart!") - dismantle() - return + if(2) + take_damage(rand(100, 250), BRUTE, "bomb", 0) + if(3) + take_damage(rand(10, 90), BRUTE, "bomb", 0) -/obj/structure/barricade/blob_act() - src.health -= 25 - if(src.health <= 0) - visible_message("The blob eats through \the [src]!") - qdel(src) - return - -/obj/structure/barricade/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff. - if(height==0) - return 1 - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 +/obj/structure/barricade/mech_melee_attack(obj/mecha/M) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable + M.do_attack_animation(src) + var/play_soundeffect = 0 + var/mech_damtype = M.damtype + if(M.selected) + mech_damtype = M.selected.damtype + play_soundeffect = 1 else - return 0 + switch(M.damtype) + if(BRUTE) + playsound(src, 'sound/weapons/punch4.ogg', 50, 1) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 50, 1) + if(TOX) + playsound(src, 'sound/effects/spray2.ogg', 50, 1) + return 0 + else + return 0 + visible_message("[M.name] has hit [src].") + return take_damage(M.force*3, mech_damtype, "melee", play_soundeffect, get_dir(src, M)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs. -/obj/structure/barricade/proc/dismantle() - if(stacktype) - new stacktype(get_turf(src)) - new stacktype(get_turf(src)) - new stacktype(get_turf(src)) +/obj/structure/barricade/deconstruct(disassembled = TRUE) + make_debris() qdel(src) +/obj/structure/barricade/proc/make_debris() + if(stacktype) + new stacktype(get_turf(src), drop_amount) + +/obj/structure/barricade/attackby(obj/item/I, mob/user, params) + if(iswelder(I) && user.a_intent != INTENT_HARM && bar_material == METAL) + var/obj/item/weldingtool/WT = I + if(obj_integrity < max_integrity) + if(WT.remove_fuel(0, user)) + to_chat(user, "You begin repairing [src]...") + playsound(loc, WT.usesound, 40, 1) + if(do_after(user, 40 * I.toolspeed, target = src)) + obj_integrity = Clamp(obj_integrity + 20, 0, max_integrity) + else + return ..() + +/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff. + if(locate(/obj/structure/barricade) in get_turf(mover)) + return TRUE + else if(istype(mover, /obj/item/projectile)) + if(!anchored) + return TRUE + var/obj/item/projectile/proj = mover + if(proj.firer && Adjacent(proj.firer)) + return TRUE + if(prob(proj_pass_rate)) + return TRUE + return FALSE + else + return !density + + + +/////BARRICADE TYPES/////// + /obj/structure/barricade/wooden name = "wooden barricade" desc = "This space is blocked off by a wooden barricade." icon = 'icons/obj/structures.dmi' icon_state = "woodenbarricade" + bar_material = WOOD stacktype = /obj/item/stack/sheet/wood burn_state = FLAMMABLE burntime = 25 +/obj/structure/barricade/wooden/attackby(obj/item/I, mob/user) + if(istype(I,/obj/item/stack/sheet/wood)) + var/obj/item/stack/sheet/wood/W = I + if(W.amount < 5) + to_chat(user, "You need at least five wooden planks to make a wall!") + return + else + to_chat(user, "You start adding [I] to [src]...") + if(do_after(user, 50, target = src)) + W.use(5) + new /turf/simulated/wall/mineral/wood/nonmetal(get_turf(src)) + qdel(src) + return + return ..() + +/obj/structure/barricade/wooden/crude + name = "crude plank barricade" + desc = "This space is blocked off by a crude assortment of planks." + icon_state = "woodenbarricade-old" + drop_amount = 1 + max_integrity = 50 + proj_pass_rate = 65 + +/obj/structure/barricade/wooden/crude/snow + desc = "This space is blocked off by a crude assortment of planks. It seems to be covered in a layer of snow." + icon_state = "woodenbarricade-snow-old" + max_integrity = 75 + +/obj/structure/barricade/sandbags + name = "sandbags" + desc = "Bags of sand. Self explanatory." + icon = 'icons/obj/smooth_structures/sandbags.dmi' + icon_state = "sandbags" + max_integrity = 280 + proj_pass_rate = 20 + pass_flags = LETPASSTHROW + bar_material = SAND + climbable = TRUE + smooth = SMOOTH_TRUE + canSmoothWith = list(/obj/structure/barricade/sandbags, /turf/simulated/wall, /turf/simulated/wall/r_wall, /obj/structure/falsewall, /obj/structure/falsewall/reinforced, /turf/simulated/wall/rust, /turf/simulated/wall/r_wall/rust, /obj/structure/barricade/security) + stacktype = null + +/obj/structure/barricade/security + name = "security barrier" + desc = "A deployable barrier. Provides good cover in fire fights." + icon = 'icons/obj/objects.dmi' + icon_state = "barrier0" + density = FALSE + anchored = FALSE + max_integrity = 180 + proj_pass_rate = 20 + armor = list(melee = 10, bullet = 50, laser = 50, energy = 50, bomb = 10, bio = 100, rad = 100) + stacktype = null + var/deploy_time = 40 + var/deploy_message = TRUE + +/obj/structure/barricade/security/New() + ..() + addtimer(CALLBACK(src, .proc/deploy), deploy_time) + +/obj/structure/barricade/security/proc/deploy() + icon_state = "barrier1" + density = TRUE + anchored = TRUE + if(deploy_message) + visible_message("[src] deploys!") + + +/obj/item/grenade/barrier + name = "barrier grenade" + desc = "Instant cover." + icon = 'icons/obj/grenade.dmi' + icon_state = "flashbang" + item_state = "flashbang" + actions_types = list(/datum/action/item_action/toggle_barrier_spread) + var/mode = SINGLE + +/obj/item/grenade/barrier/examine(mob/user) + . = ..() + to_chat(user, "Alt-click to toggle modes.") + +/obj/item/grenade/barrier/AltClick(mob/living/carbon/user) + if(!istype(user) || !user.Adjacent(src) || user.incapacitated()) + return + toggle_mode(user) + +/obj/item/grenade/barrier/proc/toggle_mode(mob/user) + switch(mode) + if(SINGLE) + mode = VERTICAL + if(VERTICAL) + mode = HORIZONTAL + if(HORIZONTAL) + mode = SINGLE + + to_chat(user, "[src] is now in [mode] mode.") + +/obj/item/grenade/barrier/prime() + new /obj/structure/barricade/security(get_turf(loc)) + switch(mode) + if(VERTICAL) + var/target_turf = get_step(src, NORTH) + if(!(is_blocked_turf(target_turf))) + new /obj/structure/barricade/security(target_turf) + + var/target_turf2 = get_step(src, SOUTH) + if(!(is_blocked_turf(target_turf2))) + new /obj/structure/barricade/security(target_turf2) + if(HORIZONTAL) + var/target_turf = get_step(src, EAST) + if(!(is_blocked_turf(target_turf))) + new /obj/structure/barricade/security(target_turf) + + var/target_turf2 = get_step(src, WEST) + if(!(is_blocked_turf(target_turf2))) + new /obj/structure/barricade/security(target_turf2) + qdel(src) + +/obj/item/grenade/barrier/ui_action_click(mob/user) + toggle_mode(user) + + /obj/structure/barricade/mime name = "floor" desc = "Is... this a floor?" @@ -149,128 +236,10 @@ for reference: /obj/structure/barricade/mime/mrcd stacktype = null -//Actual Deployable machinery stuff +#undef SINGLE +#undef VERTICAL +#undef HORIZONTAL -/obj/machinery/deployable - name = "deployable" - desc = "deployable" - icon = 'icons/obj/objects.dmi' - req_access = list(access_security)//I'm changing this until these are properly tested./N - -/obj/machinery/deployable/barrier - name = "deployable barrier" - desc = "A deployable barrier. Swipe your ID card to lock/unlock it." - icon = 'icons/obj/objects.dmi' - anchored = 0.0 - density = 1.0 - icon_state = "barrier0" - var/health = 100.0 - var/maxhealth = 100.0 - var/locked = 0.0 -// req_access = list(access_maint_tunnels) - -/obj/machinery/deployable/barrier/New() - ..() - - src.icon_state = "barrier[src.locked]" - -/obj/machinery/deployable/barrier/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/card/id)) - if(src.allowed(user)) - if(src.emagged < 2.0) - src.locked = !src.locked - src.anchored = !src.anchored - src.icon_state = "barrier[src.locked]" - if((src.locked == 1.0) && (src.emagged < 2.0)) - to_chat(user, "Barrier lock toggled on.") - return - else if((src.locked == 0.0) && (src.emagged < 2.0)) - to_chat(user, "Barrier lock toggled off.") - return - else - do_sparks(2, 1, src) - visible_message("BZZzZZzZZzZT") - return - return - else if(istype(W, /obj/item/wrench)) - if(src.health < src.maxhealth) - src.health = src.maxhealth - src.emagged = 0 - src.req_access = list(access_security) - visible_message("[user] repairs the [src]!") - return - else if(src.emagged > 0) - src.emagged = 0 - src.req_access = list(access_security) - visible_message("[user] repairs the [src]!") - return - return - else - switch(W.damtype) - if("fire") - src.health -= W.force * 0.75 - if("brute") - src.health -= W.force * 0.5 - else - if(src.health <= 0) - src.explode() - ..() - -/obj/machinery/deployable/barrier/emag_act(user as mob) - if(!emagged) - emagged = 1 - req_access = null - to_chat(user, "You break the ID authentication lock on the [src].") - do_sparks(2, 1, src) - visible_message("BZZzZZzZZzZT") - else if(src.emagged == 1) - src.emagged = 2 - to_chat(user, "You short out the anchoring mechanism on the [src].") - do_sparks(2, 1, src) - visible_message("BZZzZZzZZzZT") - -/obj/machinery/deployable/barrier/ex_act(severity) - switch(severity) - if(1.0) - src.explode() - return - if(2.0) - src.health -= 25 - if(src.health <= 0) - src.explode() - return - -/obj/machinery/deployable/barrier/emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - return - if(prob(50/severity)) - locked = !locked - anchored = !anchored - icon_state = "barrier[src.locked]" - -/obj/machinery/deployable/barrier/blob_act() - src.health -= 25 - if(src.health <= 0) - src.explode() - return - -/obj/machinery/deployable/barrier/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff. - if(height==0) - return 1 - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 - else - return 0 - -/obj/machinery/deployable/barrier/proc/explode() - visible_message("[src] blows apart!") - var/turf/Tsec = get_turf(src) - -/* var/obj/item/stack/rods/ =*/ - new /obj/item/stack/rods(Tsec) - - do_sparks(3, 1, src) - - explosion(src.loc,-1,-1,0) - if(src) - qdel(src) +#undef METAL +#undef WOOD +#undef SAND \ No newline at end of file diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 65854bb1412..89321f2e1a8 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -10,6 +10,7 @@ power_channel = ENVIRON max_integrity = 350 armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100) + flags = PREVENT_CLICK_UNDER var/closingLayer = CLOSED_DOOR_LAYER var/visible = 1 var/operating = FALSE diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 797eee044ad..5abfc313047 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -109,6 +109,7 @@ var/obj/item/gun/energy/E = charging if(E.power_supply.charge < E.power_supply.maxcharge) E.power_supply.give(E.power_supply.chargerate * recharge_coeff) + E.on_recharge() use_power(250) using_power = TRUE diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 1532eeaccbd..c15aed3b757 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -203,6 +203,7 @@ if(D.power_supply.charge < D.power_supply.maxcharge) var/obj/item/ammo_casing/energy/E = D.ammo_type[D.select] D.power_supply.give(E.e_cost) + D.on_recharge() D.update_icon() else D.charge_tick = 0 diff --git a/code/game/machinery/telecomms/ntsl2.dm b/code/game/machinery/telecomms/ntsl2.dm index a5c4f3f1464..c8501d8181e 100644 --- a/code/game/machinery/telecomms/ntsl2.dm +++ b/code/game/machinery/telecomms/ntsl2.dm @@ -109,7 +109,7 @@ GLOBAL_DATUM_INIT(nttc_config, /datum/nttc_configuration, new()) "Mime" = "srvradio", ) // Just command members - var/heads = list("Captain", "Head of Personnel", "Nanotrasen Representative", "Blueshield", "Chief Engineer", "Chief Medical Officer", "Research Director", "Head of Security") + var/heads = list("Captain", "Head of Personnel", "Nanotrasen Representative", "Blueshield", "Chief Engineer", "Chief Medical Officer", "Research Director", "Head of Security", "Magistrate", "AI") // Just ERT var/ert_jobs = list("Emergency Response Team Officer", "Emergency Response Team Engineer", "Emergency Response Team Medic", "Emergency Response Team Leader", "Emergency Response Team Member") // Defined so code compiles and incase someone has a non-standard job @@ -331,7 +331,7 @@ GLOBAL_DATUM_INIT(nttc_config, /datum/nttc_configuration, new()) var/job = signal.data["job"] if((job in ert_jobs) || (job in heads)) for(var/datum/multilingual_say_piece/S in message_pieces) - S.message = "[S.message]" + S.message = "[capitalize(S.message)]" // This only capitalizes the first word // Hacks! // Censor dat shit like nobody's business diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index cf7937474c8..3511814a4dd 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -10,15 +10,14 @@ var/display_color = null // Display color for vending machine listing var/category = CAT_NORMAL // CAT_HIDDEN for contraband, CAT_COIN for premium -/datum/data/vending_product/New(var/path, var/name = null, var/amount = 1, var/price = 0, var/color = null, var/category = CAT_NORMAL) +/datum/data/vending_product/New(path, name = null, amount = 1, price = 0, color = null, category = CAT_NORMAL) ..() product_path = path if(!name) - var/atom/tmp = new path - product_name = initial(tmp.name) - qdel(tmp) + var/atom/temp = path + product_name = initial(temp.name) else product_name = name @@ -138,7 +137,7 @@ var/category = current_list[2] for(var/entry in current_list[1]) - var/datum/data/vending_product/product = new/datum/data/vending_product(entry) + var/datum/data/vending_product/product = new /datum/data/vending_product(entry) product.price = (entry in prices) ? prices[entry] : 0 product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 @@ -1191,7 +1190,7 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" - products = list(/obj/item/seeds/aloe =3, /obj/item/seeds/ambrosia = 3, /obj/item/seeds/apple = 3, /obj/item/seeds/banana = 3, /obj/item/seeds/berry = 3, + products = list(/obj/item/seeds/aloe =3, /obj/item/seeds/ambrosia = 3, /obj/item/seeds/apple = 3, /obj/item/seeds/cotton = 3, /obj/item/seeds/banana = 3, /obj/item/seeds/berry = 3, /obj/item/seeds/cabbage = 3, /obj/item/seeds/carrot = 3, /obj/item/seeds/cherry = 3, /obj/item/seeds/chanter = 3, /obj/item/seeds/chili = 3, /obj/item/seeds/cocoapod = 3, /obj/item/seeds/coffee = 3, /obj/item/seeds/comfrey =3, /obj/item/seeds/corn = 3, /obj/item/seeds/nymph =3, /obj/item/seeds/eggplant = 3, /obj/item/seeds/grape = 3, /obj/item/seeds/grass = 3, /obj/item/seeds/lemon = 3, @@ -1355,7 +1354,7 @@ desc = "Spare tool vending. What? Did you expect some witty description?" icon_state = "engivend" icon_deny = "engivend-deny" - req_access_txt = "11" //Engineering Equipment access + req_one_access_txt = "11;24" // Engineers and atmos techs can use this products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/multitool = 4,/obj/item/airlock_electronics = 10,/obj/item/firelock_electronics = 10,/obj/item/firealarm_electronics = 10,/obj/item/apc_electronics = 10,/obj/item/airalarm_electronics = 10,/obj/item/stock_parts/cell/high = 10,/obj/item/camera_assembly = 10) contraband = list(/obj/item/stock_parts/cell/potato = 3) premium = list(/obj/item/storage/belt/utility = 3) @@ -1470,24 +1469,90 @@ product_slogans = "Dress for success!;Prepare to look swagalicious!;Look at all this free swag!;Why leave style up to fate? Use the ClothesMate!" vend_delay = 15 vend_reply = "Thank you for using the ClothesMate!" - products = list(/obj/item/clothing/head/that=2,/obj/item/clothing/head/fedora=1,/obj/item/clothing/glasses/monocle=1, - /obj/item/clothing/under/suit_jacket/navy=2,/obj/item/clothing/under/kilt=1,/obj/item/clothing/under/overalls=1, - /obj/item/clothing/under/suit_jacket/really_black=2,/obj/item/clothing/suit/storage/lawyer/blackjacket=2,/obj/item/clothing/under/pants/jeans=3,/obj/item/clothing/under/pants/classicjeans=2, - /obj/item/clothing/under/pants/camo = 1,/obj/item/clothing/under/pants/blackjeans=2,/obj/item/clothing/under/pants/khaki=2, - /obj/item/clothing/under/pants/white=2,/obj/item/clothing/under/pants/red=1,/obj/item/clothing/under/pants/black=2, - /obj/item/clothing/under/pants/tan=2,/obj/item/clothing/under/pants/blue=1,/obj/item/clothing/under/pants/track=1,/obj/item/clothing/suit/jacket/miljacket = 1, - /obj/item/clothing/accessory/scarf/red=1,/obj/item/clothing/accessory/scarf/green=1,/obj/item/clothing/accessory/scarf/darkblue=1, - /obj/item/clothing/accessory/scarf/purple=1,/obj/item/clothing/accessory/scarf/yellow=1,/obj/item/clothing/accessory/scarf/orange=1, - /obj/item/clothing/accessory/scarf/lightblue=1,/obj/item/clothing/accessory/scarf/white=1,/obj/item/clothing/accessory/scarf/black=1, - /obj/item/clothing/accessory/scarf/zebra=1,/obj/item/clothing/accessory/scarf/christmas=1,/obj/item/clothing/accessory/stripedredscarf=1, - /obj/item/clothing/accessory/stripedbluescarf=1,/obj/item/clothing/accessory/stripedgreenscarf=1,/obj/item/clothing/accessory/waistcoat=1, - /obj/item/clothing/under/sundress=2,/obj/item/clothing/under/stripeddress = 1, /obj/item/clothing/under/sailordress = 1, /obj/item/clothing/under/redeveninggown = 1, /obj/item/clothing/under/blacktango=1,/obj/item/clothing/suit/jacket=3, - /obj/item/clothing/glasses/regular=2,/obj/item/clothing/glasses/sunglasses/fake=2,/obj/item/clothing/head/sombrero=1,/obj/item/clothing/suit/poncho=1, - /obj/item/clothing/suit/ianshirt=1,/obj/item/clothing/shoes/laceup=2,/obj/item/clothing/shoes/black=4, - /obj/item/clothing/shoes/sandal=1, /obj/item/clothing/gloves/fingerless=2, - /obj/item/storage/belt/fannypack=1, /obj/item/storage/belt/fannypack/blue=1, /obj/item/storage/belt/fannypack/red=1, /obj/item/clothing/suit/mantle = 2, /obj/item/clothing/suit/mantle/old = 1, /obj/item/clothing/suit/mantle/regal = 2) - contraband = list(/obj/item/clothing/under/syndicate/tacticool=1,/obj/item/clothing/mask/balaclava=1,/obj/item/clothing/head/ushanka=1,/obj/item/clothing/under/soviet=1,/obj/item/storage/belt/fannypack/black=1) - premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/under/pants/mustangjeans=1) + products = list(/obj/item/clothing/head/that = 2, + /obj/item/clothing/head/fedora = 1, + /obj/item/clothing/glasses/monocle = 1, + /obj/item/clothing/under/suit_jacket/navy = 2, + /obj/item/clothing/under/kilt = 1, + /obj/item/clothing/under/overalls = 1, + /obj/item/clothing/under/suit_jacket/really_black = 2, + /obj/item/clothing/suit/storage/lawyer/blackjacket = 2, + /obj/item/clothing/under/pants/jeans = 3, + /obj/item/clothing/under/pants/classicjeans = 2, + /obj/item/clothing/under/pants/camo = 1, + /obj/item/clothing/under/pants/blackjeans = 2, + /obj/item/clothing/under/pants/khaki = 2, + /obj/item/clothing/under/pants/white = 2, + /obj/item/clothing/under/pants/red = 1, + /obj/item/clothing/under/pants/black = 2, + /obj/item/clothing/under/pants/tan = 2, + /obj/item/clothing/under/pants/blue = 1, + /obj/item/clothing/under/pants/track = 1, + /obj/item/clothing/suit/jacket/miljacket = 1, + /obj/item/clothing/head/beanie = 3, + /obj/item/clothing/head/beanie/black = 3, + /obj/item/clothing/head/beanie/red = 3, + /obj/item/clothing/head/beanie/green = 3, + /obj/item/clothing/head/beanie/darkblue = 3, + /obj/item/clothing/head/beanie/purple = 3, + /obj/item/clothing/head/beanie/yellow = 3, + /obj/item/clothing/head/beanie/orange = 3, + /obj/item/clothing/head/beanie/cyan = 3, + /obj/item/clothing/head/beanie/christmas = 3, + /obj/item/clothing/head/beanie/striped = 3, + /obj/item/clothing/head/beanie/stripedred = 3, + /obj/item/clothing/head/beanie/stripedblue = 3, + /obj/item/clothing/head/beanie/stripedgreen = 3, + /obj/item/clothing/head/beanie/rasta = 3, + /obj/item/clothing/accessory/scarf/red = 1, + /obj/item/clothing/accessory/scarf/green = 1, + /obj/item/clothing/accessory/scarf/darkblue = 1, + /obj/item/clothing/accessory/scarf/purple = 1, + /obj/item/clothing/accessory/scarf/yellow = 1, + /obj/item/clothing/accessory/scarf/orange = 1, + /obj/item/clothing/accessory/scarf/lightblue = 1, + /obj/item/clothing/accessory/scarf/white = 1, + /obj/item/clothing/accessory/scarf/black = 1, + /obj/item/clothing/accessory/scarf/zebra = 1, + /obj/item/clothing/accessory/scarf/christmas = 1, + /obj/item/clothing/accessory/stripedredscarf = 1, + /obj/item/clothing/accessory/stripedbluescarf = 1, + /obj/item/clothing/accessory/stripedgreenscarf = 1, + /obj/item/clothing/accessory/waistcoat = 1, + /obj/item/clothing/under/sundress = 2, + /obj/item/clothing/under/stripeddress = 1, + /obj/item/clothing/under/sailordress = 1, + /obj/item/clothing/under/redeveninggown = 1, + /obj/item/clothing/under/blacktango = 1, + /obj/item/clothing/suit/jacket = 3, + /obj/item/clothing/glasses/regular = 2, + /obj/item/clothing/glasses/sunglasses_fake = 2, + /obj/item/clothing/head/sombrero = 1, + /obj/item/clothing/suit/poncho = 1, + /obj/item/clothing/suit/ianshirt = 1, + /obj/item/clothing/shoes/laceup = 2, + /obj/item/clothing/shoes/black = 4, + /obj/item/clothing/shoes/sandal = 1, + /obj/item/clothing/gloves/fingerless = 2, + /obj/item/storage/belt/fannypack = 1, + /obj/item/storage/belt/fannypack/blue = 1, + /obj/item/storage/belt/fannypack/red = 1, + /obj/item/clothing/suit/mantle = 2, + /obj/item/clothing/suit/mantle/old = 1, + /obj/item/clothing/suit/mantle/regal = 2) + + contraband = list(/obj/item/clothing/under/syndicate/tacticool = 1, + /obj/item/clothing/mask/balaclava = 1, + /obj/item/clothing/head/ushanka = 1, + /obj/item/clothing/under/soviet = 1, + /obj/item/storage/belt/fannypack/black = 1) + + premium = list(/obj/item/clothing/under/suit_jacket/checkered = 1, + /obj/item/clothing/head/mailman = 1, + /obj/item/clothing/under/rank/mailman = 1, + /obj/item/clothing/suit/jacket/leather = 1, + /obj/item/clothing/under/pants/mustangjeans = 1) + refill_canister = /obj/item/vending_refill/clothing /obj/machinery/vending/clothing/New() @@ -1533,7 +1598,7 @@ /obj/item/fish_eggs/electric_eel = 10, /obj/item/fish_eggs/shrimp = 5, /obj/item/toy/pet_rock = 100, ) contraband = list(/obj/item/fish_eggs/babycarp = 5) - premium = list(/obj/item/toy/pet_rock/fred = 1, /obj/item/toy/pet_rock/roxie = 1) + premium = list(/obj/item/toy/pet_rock/fred = 1, /obj/item/toy/pet_rock/roxie = 1, /obj/item/clothing/gloves/fingerless/rapid/headpat = 1) refill_canister = /obj/item/vending_refill/crittercare /obj/machinery/vending/crittercare/free diff --git a/code/game/objects/effects/decals/Cleanable/aliens.dm b/code/game/objects/effects/decals/Cleanable/aliens.dm index c788e934b45..f4ca5cf613a 100644 --- a/code/game/objects/effects/decals/Cleanable/aliens.dm +++ b/code/game/objects/effects/decals/Cleanable/aliens.dm @@ -3,7 +3,7 @@ desc = "It's green and acidic. It looks like... blood?" icon = 'icons/effects/blood.dmi' basecolor = "#05EE05" - bloodiness = MAX_SHOE_BLOODINESS + bloodiness = BLOOD_AMOUNT_PER_DECAL blood_state = BLOOD_STATE_XENO /obj/effect/decal/cleanable/blood/xeno/splatter diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index c4c903474ef..6c7ea8f3247 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -6,18 +6,18 @@ anchored = TRUE var/amount = 1 //Basically moles. -/obj/effect/decal/cleanable/liquid_fuel/Initialize(newLoc, amt = 1) +/obj/effect/decal/cleanable/liquid_fuel/Initialize(mapload, amt = 1) + . = ..() amount = amt //Be absorbed by any other liquid fuel in the tile. - for(var/obj/effect/decal/cleanable/liquid_fuel/other in newLoc) + for(var/obj/effect/decal/cleanable/liquid_fuel/other in loc) if(other != src) other.amount += amount spawn other.Spread() qdel(src) Spread() - . = ..() /obj/effect/decal/cleanable/liquid_fuel/proc/Spread() //Allows liquid fuels to sometimes flow into other tiles. diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index c410a9130a0..d282e1264e2 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -11,19 +11,30 @@ var/global/list/image/splatter_cache = list() density = FALSE anchored = TRUE layer = TURF_LAYER + plane = GAME_PLANE icon = 'icons/effects/blood.dmi' icon_state = "mfloor1" random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7") blood_DNA = list() var/base_icon = 'icons/effects/blood.dmi' var/blood_state = BLOOD_STATE_HUMAN - var/bloodiness = MAX_SHOE_BLOODINESS + bloodiness = BLOOD_AMOUNT_PER_DECAL var/basecolor = "#A10808" // Color when wet. var/amount = 5 var/dry_timer = 0 var/off_floor = FALSE -/obj/effect/decal/cleanable/blood/Initialize() + +/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C) + if(C.blood_DNA) + blood_DNA |= C.blood_DNA.Copy() + if(bloodiness) + if(C.bloodiness < MAX_SHOE_BLOODINESS) + C.bloodiness += bloodiness + return ..() + + +/obj/effect/decal/cleanable/blood/Initialize(mapload) . = ..() update_icon() if(GAMEMODE_IS_CULT) @@ -87,46 +98,6 @@ var/global/list/image/splatter_cache = list() /obj/effect/decal/cleanable/blood/can_bloodcrawl_in() return TRUE -//Add "bloodiness" of this blood's type, to the human's shoes -/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O, oldloc) - if(!off_floor && ishuman(O)) - var/mob/living/carbon/human/H = O - var/obj/item/organ/external/l_foot = H.get_organ("l_foot") - var/obj/item/organ/external/r_foot = H.get_organ("r_foot") - var/hasfeet = TRUE - if(!l_foot && !r_foot) - hasfeet = FALSE - if(H.shoes && blood_state && bloodiness) - var/obj/item/clothing/shoes/S = H.shoes - var/add_blood = 0 - if(bloodiness >= BLOOD_GAIN_PER_STEP) - add_blood = BLOOD_GAIN_PER_STEP - else - add_blood = bloodiness - bloodiness -= add_blood - S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood) - if(blood_DNA && blood_DNA.len) - S.add_blood(H.blood_DNA, basecolor) - S.blood_state = blood_state - S.blood_color = basecolor - update_icon() - H.update_inv_shoes() - else if(hasfeet && blood_state && bloodiness)//Or feet - var/add_blood = 0 - if(bloodiness >= BLOOD_GAIN_PER_STEP) - add_blood = BLOOD_GAIN_PER_STEP - else - add_blood = bloodiness - bloodiness -= add_blood - H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood) - if(!H.feet_blood_DNA) - H.feet_blood_DNA = list() - H.blood_state = blood_state - H.feet_blood_DNA |= blood_DNA.Copy() - H.feet_blood_color = basecolor - update_icon() - H.update_inv_shoes() - /obj/effect/decal/cleanable/blood/splatter random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5") amount = 2 @@ -167,7 +138,7 @@ var/global/list/image/splatter_cache = list() amount = 0 var/message -/obj/effect/decal/cleanable/blood/writing/Initialize() +/obj/effect/decal/cleanable/blood/writing/Initialize(mapload) . = ..() if(random_icon_states.len) for(var/obj/effect/decal/cleanable/blood/writing/W in loc) @@ -191,6 +162,8 @@ var/global/list/image/splatter_cache = list() icon_state = "gibbl5" random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") no_clear = TRUE + mergeable_decal = FALSE + var/fleshcolor = "#FFFFFF" /obj/effect/decal/cleanable/blood/gibs/update_icon() @@ -238,7 +211,7 @@ var/global/list/image/splatter_cache = list() break -/obj/effect/decal/cleanable/blood/old/Initialize() +/obj/effect/decal/cleanable/blood/old/Initialize(mapload) . = ..() bloodiness = 0 dry() @@ -246,7 +219,7 @@ var/global/list/image/splatter_cache = list() /obj/effect/decal/cleanable/blood/old/can_bloodcrawl_in() return FALSE -/obj/effect/decal/cleanable/blood/gibs/old/Initialize() +/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload) . = ..() bloodiness = 0 dry() diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index d1ba3204bd0..349b8039d92 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -16,6 +16,7 @@ icon_state = "ash" anchored = TRUE scoop_reagents = list("ash" = 10) + mergeable_decal = FALSE /obj/effect/decal/cleanable/dirt name = "dirt" @@ -30,8 +31,8 @@ smooth = SMOOTH_MORE mouse_opacity = FALSE -/obj/effect/decal/cleanable/dirt/Initialize() - ..() +/obj/effect/decal/cleanable/dirt/Initialize(mapload) + . = ..() icon_state = "" /obj/effect/decal/cleanable/dirt/blackpowder @@ -55,7 +56,7 @@ desc = "It's foam." color = "#EBEBEB" -/obj/effect/decal/cleanable/flour/foam/Initialize() +/obj/effect/decal/cleanable/flour/foam/Initialize(mapload) . = ..() QDEL_IN(src, 15 SECONDS) @@ -97,6 +98,7 @@ gender = NEUTER icon = 'icons/effects/effects.dmi' icon_state = "molten" + mergeable_decal = FALSE /obj/effect/decal/cleanable/molten_object/large name = "big gooey grey mass" @@ -173,6 +175,7 @@ density = FALSE anchored = TRUE layer = TURF_LAYER + plane = GAME_PLANE icon = 'icons/effects/effects.dmi' icon_state = "flour" color = "#D5820B" diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 1c8ad706dc8..5193436295e 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -5,7 +5,8 @@ icon_state = "gib1" basecolor = "#030303" random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7") - bloodiness = MAX_SHOE_BLOODINESS + bloodiness = BLOOD_AMOUNT_PER_DECAL + mergeable_decal = FALSE /obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in() return FALSE diff --git a/code/game/objects/effects/decals/Cleanable/tracks.dm b/code/game/objects/effects/decals/Cleanable/tracks.dm index 1e45c2aa4cf..08b9b402cda 100644 --- a/code/game/objects/effects/decals/Cleanable/tracks.dm +++ b/code/game/objects/effects/decals/Cleanable/tracks.dm @@ -30,6 +30,7 @@ var/global/list/image/fluidtrack_cache = list() /obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O, oldloc) + ..() if(ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/clothing/shoes/S = H.shoes @@ -40,19 +41,22 @@ var/global/list/image/fluidtrack_cache = list() hasfeet = FALSE if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor) S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0) - entered_dirs |= H.dir if(!S.blood_DNA) S.blood_DNA = list() S.blood_DNA |= blood_DNA.Copy() + if(!(entered_dirs & H.dir)) + entered_dirs |= H.dir + update_icon() else if(hasfeet && H.bloody_feet[blood_state] && H.feet_blood_color == basecolor)//Or feet //This will need to be changed. H.bloody_feet[blood_state] = max(H.bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP, 0) - entered_dirs |= H.dir if(!H.feet_blood_DNA) H.feet_blood_DNA = list() H.feet_blood_DNA |= blood_DNA.Copy() - update_icon() - + if(!(entered_dirs & H.dir)) + entered_dirs |= H.dir + update_icon() /obj/effect/decal/cleanable/blood/footprints/Uncrossed(atom/movable/O) + ..() if(ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/clothing/shoes/S = H.shoes @@ -63,17 +67,20 @@ var/global/list/image/fluidtrack_cache = list() hasfeet = FALSE if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor) S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0) - exited_dirs |= H.dir if(!S.blood_DNA) S.blood_DNA = list() S.blood_DNA |= blood_DNA.Copy() + if(!(exited_dirs & H.dir)) + exited_dirs |= H.dir + update_icon() else if(hasfeet && H.bloody_feet[blood_state] && H.feet_blood_color == basecolor)//Or feet H.bloody_feet[blood_state] = max(H.bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP, 0) - exited_dirs |= H.dir if(!H.feet_blood_DNA) H.feet_blood_DNA = list() H.feet_blood_DNA |= blood_DNA.Copy() - update_icon() + if(!(exited_dirs & H.dir)) + exited_dirs |= H.dir + update_icon() /obj/effect/decal/cleanable/blood/footprints/update_icon() @@ -108,14 +115,14 @@ var/global/list/image/fluidtrack_cache = list() if(ishuman(A)) var/mob/living/carbon/human/H = A FP.blood_state = H.blood_state - FP.bloodiness = H.bloody_feet[H.blood_state] + FP.bloodiness = H.bloody_feet[H.blood_state] - BLOOD_LOSS_IN_SPREAD FP.basecolor = H.feet_blood_color if(H.blood_DNA) FP.blood_DNA = H.blood_DNA.Copy() else if(istype(A, /obj/item/clothing/shoes)) var/obj/item/clothing/shoes/S = A FP.blood_state = S.blood_state - FP.bloodiness = S.bloody_shoes[S.blood_state] + FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD FP.basecolor = S.blood_color if(S.blood_DNA) FP.blood_DNA = S.blood_DNA.Copy() @@ -123,3 +130,8 @@ var/global/list/image/fluidtrack_cache = list() FP.update_icon() return FP + +/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/blood/footprints/C) + if(blood_state != C.blood_state) //We only replace footprints of the same type as us + return + ..() \ No newline at end of file diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 461273bccdb..870927730a7 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -1,17 +1,71 @@ /obj/effect/decal/cleanable anchored = TRUE var/list/random_icon_states = list() + var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints + var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one? + +/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal + if(mergeable_decal) + return TRUE + +//Add "bloodiness" of this blood's type, to the human's shoes +//This is on /cleanable because fuck this ancient mess +/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O) + ..() + if(!off_floor && ishuman(O)) + var/mob/living/carbon/human/H = O + var/obj/item/organ/external/l_foot = H.get_organ("l_foot") + var/obj/item/organ/external/r_foot = H.get_organ("r_foot") + var/hasfeet = TRUE + if(!l_foot && !r_foot) + hasfeet = FALSE + if(H.shoes && blood_state && bloodiness) + var/obj/item/clothing/shoes/S = H.shoes + var/add_blood = 0 + if(bloodiness >= BLOOD_GAIN_PER_STEP) + add_blood = BLOOD_GAIN_PER_STEP + else + add_blood = bloodiness + bloodiness -= add_blood + S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood) + if(blood_DNA && blood_DNA.len) + S.add_blood(H.blood_DNA, basecolor) + S.blood_state = blood_state + S.blood_color = basecolor + update_icon() + H.update_inv_shoes() + else if(hasfeet && blood_state && bloodiness)//Or feet + var/add_blood = 0 + if(bloodiness >= BLOOD_GAIN_PER_STEP) + add_blood = BLOOD_GAIN_PER_STEP + else + add_blood = bloodiness + bloodiness -= add_blood + H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood) + if(!H.feet_blood_DNA) + H.feet_blood_DNA = list() + H.blood_state = blood_state + H.feet_blood_DNA |= blood_DNA.Copy() + H.feet_blood_color = basecolor + update_icon() + H.update_inv_shoes() /obj/effect/decal/cleanable/proc/can_bloodcrawl_in() return FALSE -/obj/effect/decal/cleanable/New() +/obj/effect/decal/cleanable/Initialize(mapload) + . = ..() + if(loc && isturf(loc)) + for(var/obj/effect/decal/cleanable/C in loc) + if(C != src && C.type == type && !QDELETED(C)) + if(replace_decal(C)) + qdel(src) + return if(random_icon_states && length(src.random_icon_states) > 0) src.icon_state = pick(src.random_icon_states) if(smooth) queue_smooth(src) queue_smooth_neighbors(src) - ..() /obj/effect/decal/cleanable/Destroy() if(smooth) diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index ac0007e42ae..06243b1db8a 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -4,12 +4,12 @@ icon = 'icons/effects/crayondecal.dmi' icon_state = "rune1" layer = MID_TURF_LAYER + plane = GAME_PLANE //makes the graffiti visible over a wall. anchored = TRUE -/obj/effect/decal/cleanable/crayon/New(location, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune") - ..() - loc = location +/obj/effect/decal/cleanable/crayon/Initialize(mapload, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune") + . = ..() name = e_name desc = "A [name] drawn in crayon." diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 8bb117b832c..a145fcea1d4 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -79,7 +79,7 @@ would spawn and follow the beaker, even if it is carried or thrown. reagents.reaction(A) if(istype(A,/atom/movable)) var/atom/movable/AM = A - AM.water_act(life, 310.15, src) + AM.water_act(life, COLD_WATER_TEMPERATURE, src) return ..() diff --git a/code/game/objects/effects/effect_system/effects_water.dm b/code/game/objects/effects/effect_system/effects_water.dm index c4009516f92..12fc9732bb5 100644 --- a/code/game/objects/effects/effect_system/effects_water.dm +++ b/code/game/objects/effects/effect_system/effects_water.dm @@ -21,7 +21,7 @@ reagents.reaction(A) if(istype(A,/atom/movable)) var/atom/movable/AM = A - AM.water_act(life, 310.15, src) + AM.water_act(life, COLD_WATER_TEMPERATURE, src) return ..() ///////////////////////////////////////////// diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 7f1683ba415..d6dbf1dddbb 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -140,6 +140,15 @@ ..() animate(src, alpha = 0, time = duration) +/obj/effect/temp_visual/decoy/fading/threesecond + duration = 40 + +/obj/effect/temp_visual/decoy/fading/fivesecond + duration = 50 + +/obj/effect/temp_visual/decoy/fading/halfsecond + duration = 5 + /obj/effect/temp_visual/fire icon = 'icons/goonstation/effects/fire.dmi' icon_state = "3" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 34ec25c902d..935c587fa57 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -87,6 +87,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d If index term exists and icon_override is not set, this sprite sheet will be used. */ var/list/sprite_sheets = null + var/list/sprite_sheets_inhand = null //Used to override inhand items. Use a single .dmi and suffix the icon states inside with _l and _r for each hand. var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc. var/sprite_sheets_obj = null //Used to override hardcoded clothing inventory object dmis in human clothing proc. diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm index e51bac10005..65f00e98781 100644 --- a/code/game/objects/items/random_items.dm +++ b/code/game/objects/items/random_items.dm @@ -18,8 +18,8 @@ /obj/effect/decal/cleanable/random name = "Random Mess" -/obj/effect/decal/cleanable/random/New() - ..() +/obj/effect/decal/cleanable/random/Initialize(mapload) + . = ..() var/list/list = subtypesof(/obj/effect/decal/cleanable) - list(/obj/effect/decal/cleanable/random,/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/cobweb2) var/T = pick(list) new T(loc) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 0e95f509463..d021c0254a8 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -123,6 +123,19 @@ origin_tech = "biotech=2" stop_bleeding = 1800 +/obj/item/stack/medical/bruise_pack/attackby(obj/item/I, mob/user, params) + if(I.sharp) + if(get_amount() < 2) + to_chat(user, "You need at least two gauzes to do this!") + return + new /obj/item/stack/sheet/cloth(user.drop_location()) + user.visible_message("[user] cuts [src] into pieces of cloth with [I].", \ + "You cut [src] into pieces of cloth with [I].", \ + "You hear cutting.") + use(2) + else + return ..() + /obj/item/stack/medical/bruise_pack/attack(mob/living/M, mob/user) if(..()) return 1 @@ -145,6 +158,11 @@ else to_chat(user, "[affecting] is cut open, you'll need more than a bandage!") +/obj/item/stack/medical/bruise_pack/improvised + name = "improvised gauze" + singular_name = "improvised gauze" + desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds." + stop_bleeding = 900 /obj/item/stack/medical/bruise_pack/advanced name = "advanced trauma kit" diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 8c60bcefa11..c9099d6d38b 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -137,6 +137,44 @@ var/global/list/datum/stack_recipe/snow_recipes = list( ..() recipes = sandstone_recipes +/* + * Sandbags + */ + +/obj/item/stack/sheet/mineral/sandbags + name = "sandbags" + icon_state = "sandbags" + singular_name = "sandbag" + layer = LOW_ITEM_LAYER + merge_type = /obj/item/stack/sheet/mineral/sandbags + +GLOBAL_LIST_INIT(sandbag_recipes, list ( \ + new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \ + )) + +/obj/item/stack/sheet/mineral/sandbags/New() + recipes = GLOB.sandbag_recipes + ..() + +/obj/item/emptysandbag + name = "empty sandbag" + desc = "A bag to be filled with sand." + icon = 'icons/obj/items.dmi' + icon_state = "sandbag" + w_class = WEIGHT_CLASS_TINY + +/obj/item/emptysandbag/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/stack/ore/glass)) + var/obj/item/stack/ore/glass/G = I + to_chat(user, "You fill the sandbag.") + var/obj/item/stack/sheet/mineral/sandbags/S = new /obj/item/stack/sheet/mineral/sandbags(drop_location()) + qdel(src) + if(Adjacent(user) && !issilicon(user)) + user.put_in_hands(S) + G.use(1) + else + return ..() + /obj/item/stack/sheet/mineral/diamond name = "diamond" icon_state = "sheet-diamond" diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index f7df69cad2f..8698a4a2bbe 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -182,6 +182,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list( new /datum/stack_recipe("rake", /obj/item/cultivator/rake, 5, time = 10), new /datum/stack_recipe("ore box", /obj/structure/ore_box, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), new /datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15), + new /datum/stack_recipe("loom", /obj/structure/loom, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ new /datum/stack_recipe("fermenting barrel", /obj/structure/fermenting_barrel, 30, time = 50), new /datum/stack_recipe("firebrand", /obj/item/match/firebrand, 2, time = 100) ) @@ -204,8 +205,9 @@ var/global/list/datum/stack_recipe/wood_recipes = list( * Cloth */ var/global/list/datum/stack_recipe/cloth_recipes = list ( \ - new/datum/stack_recipe("grey jumpsuit", /obj/item/clothing/under/color/grey, 3), \ - new/datum/stack_recipe("black shoes", /obj/item/clothing/shoes/black, 2), \ + new/datum/stack_recipe("white jumpsuit", /obj/item/clothing/under/color/white, 3), \ + new/datum/stack_recipe("white shoes", /obj/item/clothing/shoes/white, 2), \ + new/datum/stack_recipe("white scarf", /obj/item/clothing/accessory/scarf/white, 1), \ null, \ new/datum/stack_recipe("backpack", /obj/item/storage/backpack, 4), \ new/datum/stack_recipe("dufflebag", /obj/item/storage/backpack/duffel, 6), \ @@ -216,11 +218,15 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \ new/datum/stack_recipe("chemistry bag", /obj/item/storage/bag/chemistry, 4), \ new/datum/stack_recipe("bio bag", /obj/item/storage/bag/bio, 4), \ null, \ + new/datum/stack_recipe("improvised gauze", /obj/item/stack/medical/bruise_pack/improvised, 1, 2, 6), \ new/datum/stack_recipe("rag", /obj/item/reagent_containers/glass/rag, 1), \ new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \ + new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \ null, \ new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \ - new/datum/stack_recipe("black gloves", /obj/item/clothing/gloves/color/black, 3), \ + new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 3), \ + new/datum/stack_recipe("white softcap", /obj/item/clothing/head/soft/mime, 2), \ + new/datum/stack_recipe("white beanie", /obj/item/clothing/head/beanie, 2), \ null, \ new/datum/stack_recipe("blindfold", /obj/item/clothing/glasses/sunglasses/blindfold, 3), \ ) @@ -243,6 +249,49 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \ /obj/item/stack/sheet/cloth/ten amount = 10 +GLOBAL_LIST_INIT(durathread_recipes, list ( \ + new/datum/stack_recipe("durathread jumpsuit", /obj/item/clothing/under/misc/durathread, 4, time = 40), + new/datum/stack_recipe("durathread beret", /obj/item/clothing/head/beret/durathread, 2, time = 40), \ + new/datum/stack_recipe("durathread beanie", /obj/item/clothing/head/beanie/durathread, 2, time = 40), \ + new/datum/stack_recipe("durathread bandana", /obj/item/clothing/mask/bandana/durathread, 1, time = 25), \ + )) + +/obj/item/stack/sheet/durathread + name = "durathread" + desc = "A fabric sown from incredibly durable threads, known for its usefulness in armor production." + singular_name = "durathread roll" + icon_state = "sheet-durathread" + item_state = "sheet-cloth" + resistance_flags = FLAMMABLE + force = 0 + throwforce = 0 + merge_type = /obj/item/stack/sheet/durathread + +/obj/item/stack/sheet/durathread/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.durathread_recipes + return ..() + +/obj/item/stack/sheet/cotton + name = "raw cotton bundle" + desc = "A bundle of raw cotton ready to be spun on the loom." + singular_name = "raw cotton ball" + icon_state = "sheet-cotton" + resistance_flags = FLAMMABLE + force = 0 + throwforce = 0 + merge_type = /obj/item/stack/sheet/cotton + var/pull_effort = 30 + var/loom_result = /obj/item/stack/sheet/cloth + +/obj/item/stack/sheet/cotton/durathread + name = "raw durathread bundle" + desc = "A bundle of raw durathread ready to be spun on the loom." + singular_name = "raw durathread ball" + icon_state = "sheet-durathreadraw" + merge_type = /obj/item/stack/sheet/cotton/durathread + pull_effort = 70 + loom_result = /obj/item/stack/sheet/durathread + /* * Cardboard */ diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index a8ddcf6d315..eda3088199e 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -299,7 +299,7 @@ /obj/effect/decal/cleanable/ash/snappop_phoenix var/respawn_time = 300 -/obj/effect/decal/cleanable/ash/snappop_phoenix/New() +/obj/effect/decal/cleanable/ash/snappop_phoenix/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/respawn), respawn_time) diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm index 64f554682fc..503228e58d7 100644 --- a/code/game/objects/items/weapons/pneumaticCannon.dm +++ b/code/game/objects/items/weapons/pneumaticCannon.dm @@ -145,7 +145,8 @@ /obj/item/stack/packageWrap = 8, /obj/item/pipe = 2) time = 300 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /obj/item/pneumatic_cannon/proc/updateTank(obj/item/tank/thetank, removing = 0, mob/living/carbon/human/user) if(removing) diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index eb778b6a280..db34f3ae2c8 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -14,6 +14,15 @@ user.dust() return OBLITERATION +/obj/item/storage/bible/fart_act(mob/living/M) + if(QDELETED(M) || M.stat == DEAD) + return + M.visible_message("[M] farts on \the [name]!") + M.visible_message("A mysterious force smites [M]!") + M.suiciding = TRUE + do_sparks(3, 1, M) + M.gib() + return TRUE // Don't run the fart emote /obj/item/storage/bible/booze name = "bible" diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 6fb552654d9..d4e1ed2d7f1 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -1059,6 +1059,15 @@ desc = "A colorful cardboard box for the clown" icon_state = "box_clown" +/obj/item/storage/box/emptysandbags + name = "box of empty sandbags" + +/obj/item/storage/box/emptysandbags/New() + ..() + contents = list() + for(var/i in 1 to 7) + new /obj/item/emptysandbag(src) + /obj/item/storage/box/rndboards name = "the Liberator's legacy" desc = "A box containing a gift for worthy golems." diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index 2450648cded..0a2a8bcfbbc 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -5,7 +5,7 @@ item_state = "briefcase" flags = CONDUCT hitsound = "swing_hit" - force = 8.0 + force = 8 throw_speed = 2 throw_range = 4 w_class = WEIGHT_CLASS_BULKY @@ -20,10 +20,69 @@ force = 10 /obj/item/storage/briefcase/sniperbundle/New() - ..() + ..() new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate(src) new /obj/item/clothing/accessory/red(src) new /obj/item/clothing/under/syndicate/sniper(src) new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) - new /obj/item/suppressor/specialoffer(src) \ No newline at end of file + new /obj/item/suppressor/specialoffer(src) + +/obj/item/storage/briefcase/false_bottomed + max_w_class = WEIGHT_CLASS_SMALL + max_combined_w_class = 10 + + var/busy_hunting = FALSE + var/bottom_open = FALSE //is the false bottom open? + var/obj/item/stored_item = null //what's in the false bottom. If it's a gun, we can fire it + +/obj/item/storage/briefcase/false_bottomed/Destroy() + if(stored_item)//since the stored_item isn't in the briefcase' contents we gotta remind the game to delete it here. + QDEL_NULL(stored_item) + return ..() + +/obj/item/storage/briefcase/false_bottomed/afterattack(atom/A, mob/user, flag, params) + ..() + if(stored_item && istype(stored_item, /obj/item/gun) && !Adjacent(A)) + var/obj/item/gun/stored_gun = stored_item + stored_gun.afterattack(A, user, flag, params) + +/obj/item/storage/briefcase/false_bottomed/attackby(var/obj/item/I, mob/user) + if(isscrewdriver(I)) + if(!bottom_open && !busy_hunting) + to_chat(user, "You begin to hunt around the rim of the [src]...") + busy_hunting = TRUE + if(do_after(user, 20, target = src)) + if(user) + to_chat(user, "You pry open the false bottom!") + bottom_open = TRUE + busy_hunting = FALSE + else if(bottom_open) + to_chat(user, "You push the false bottom down and close it with a click[stored_item ? ", with the [stored_item] snugly inside." : "."]") + bottom_open = FALSE + else if(bottom_open) + if(stored_item) + to_chat(user, "There's already something in the false bottom!") + return + if(I.w_class > WEIGHT_CLASS_NORMAL) + to_chat(user, "The [I] is too big to fit in the false bottom!") + return + if(!user.drop_item(I)) + user << "The [I] is stuck to your hands!" + return + + stored_item = I + max_w_class = WEIGHT_CLASS_NORMAL - stored_item.w_class + I.forceMove(null) //null space here we go - to stop it showing up in the briefcase + to_chat(user, "You place the [I] into the false bottom of the briefcase.") + else + return ..() + +/obj/item/storage/briefcase/false_bottomed/attack_hand(mob/user) + if(bottom_open && stored_item) + user.put_in_hands(stored_item) + to_chat(user, "You pull out the [stored_item] from the [src]'s false bottom.") + stored_item = null + max_w_class = initial(max_w_class) + else + return ..() diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index a8f0af13b98..6b68ef19c4c 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -121,6 +121,19 @@ desc = "A sleek, sturdy box" icon_state = "box_of_doom" +/obj/item/storage/box/syndie_kit/romerol + name = "Romerol Kit" + desc = "A box containing a deadly virus capable of reanimating dead as zombies." + max_w_class = WEIGHT_CLASS_NORMAL + can_hold = list(/obj/item/reagent_containers/glass/bottle/romerol,/obj/item/reagent_containers/syringe,/obj/item/reagent_containers/dropper) + +/obj/item/storage/box/syndie_kit/romerol/New() + ..() + new /obj/item/reagent_containers/glass/bottle/romerol(src) + new /obj/item/reagent_containers/syringe(src) + new /obj/item/reagent_containers/dropper(src) + return + /obj/item/storage/box/syndie_kit/space name = "Boxed Space Suit and Helmet" can_hold = list(/obj/item/clothing/suit/space/syndicate/black/red, /obj/item/clothing/head/helmet/space/syndicate/black/red, /obj/item/tank/emergency_oxygen/syndi, /obj/item/clothing/mask/gas/syndicate) diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm index 72394db2733..21f43073b73 100644 --- a/code/game/objects/items/weapons/tanks/jetpack.dm +++ b/code/game/objects/items/weapons/tanks/jetpack.dm @@ -48,38 +48,38 @@ return if(!on) - turn_on() + turn_on(user) to_chat(user, "You turn the jetpack on.") else - turn_off() + turn_off(user) to_chat(user, "You turn the jetpack off.") for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() -/obj/item/tank/jetpack/proc/turn_on() +/obj/item/tank/jetpack/proc/turn_on(mob/user) on = TRUE icon_state = "[initial(icon_state)]-on" ion_trail.start() -/obj/item/tank/jetpack/proc/turn_off() +/obj/item/tank/jetpack/proc/turn_off(mob/user) on = FALSE stabilizers = FALSE icon_state = initial(icon_state) ion_trail.stop() -/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user as mob) +/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) if(!on) return 0 if((num < 0.005 || air_contents.total_moles() < num)) - turn_off() + turn_off(user) return 0 var/datum/gas_mixture/removed = air_contents.remove(num) if(removed.total_moles() < 0.005) - turn_off() + turn_off(user) return 0 var/turf/T = get_turf(user) @@ -163,15 +163,65 @@ to_chat(user, "The meter on [src] indicates you are almost out of air!") playsound(user, 'sound/effects/alert.ogg', 50, 1) -/obj/item/tank/jetpack/carbondioxide/mining - name = "mining jetpack" +/obj/item/tank/jetpack/suit + name = "hardsuit jetpack upgrade" + desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." icon_state = "jetpack-mining" - item_state = "jetpack-mining" + item_state = "jetpack-black" origin_tech = "materials=4;magnets=4;engineering=5" - desc = "A tank of compressed carbon dioxide for miners to use as propulsion in local space. The compact size allows for easy storage at the cost of capacity." - volume = 40 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL //same as syndie harness + w_class = WEIGHT_CLASS_NORMAL + actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) + volume = 1 + slot_flags = null + var/datum/gas_mixture/temp_air_contents + var/obj/item/tank/tank = null + var/mob/living/carbon/human/cur_user + +/obj/item/tank/jetpack/suit/New() + ..() + STOP_PROCESSING(SSobj, src) + temp_air_contents = air_contents + +/obj/item/tank/jetpack/suit/attack_self() + return + +/obj/item/tank/jetpack/suit/cycle(mob/user) + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit)) + to_chat(user, "[src] must be connected to a hardsuit!") + return + + var/mob/living/carbon/human/H = user + if(!istype(H.s_store, /obj/item/tank)) + to_chat(user, "You need a tank in your suit storage!") + return + ..() + +/obj/item/tank/jetpack/suit/turn_on(mob/user) + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc) || loc.loc != user) + return + var/mob/living/carbon/human/H = user + tank = H.s_store + air_contents = tank.air_contents + START_PROCESSING(SSobj, src) + cur_user = user + ..() + +/obj/item/tank/jetpack/suit/turn_off(mob/user) + tank = null + air_contents = temp_air_contents + STOP_PROCESSING(SSobj, src) + cur_user = null + ..() + +/obj/item/tank/jetpack/suit/process() + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) + turn_off(cur_user) + return + var/mob/living/carbon/human/H = loc.loc + if(!tank || tank != H.s_store) + turn_off(cur_user) + return + ..() /obj/item/tank/jetpack/rig name = "jetpack" @@ -182,7 +232,7 @@ to_chat(usr, "It's a jetpack. If you can see this, report it on the bug tracker.") return 0 -/obj/item/tank/jetpack/rig/allow_thrust(num, mob/living/user as mob) +/obj/item/tank/jetpack/rig/allow_thrust(num, mob/living/user) if(!on) return 0 @@ -191,7 +241,7 @@ var/datum/gas_mixture/removed = holder.air_supply.air_contents.remove(num) if(removed.total_moles() < 0.005) - turn_off() + turn_off(user) return 0 var/turf/T = get_turf(user) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index f42decd4363..501f1780a0b 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -181,16 +181,16 @@ if(prob(10)) visible_message("[owner] Deflects [I] directly back at the thrower! It's a home run!", "You deflect the [I] directly back at the thrower! It's a home run!") playsound(get_turf(owner), 'sound/weapons/homerun.ogg', 100, 1) - do_attack_animation(I, ATTACK_EFFECT_DISARM) + do_attack_animation(I, ATTACK_EFFECT_DISARM) I.throw_at(I.thrownby, 20, 20, owner) deflectmode = FALSE if(!istype(I, /obj/item/beach_ball)) lastdeflect = world.time + 3000 - return TRUE + return TRUE else if(prob(30)) visible_message("[owner] swings! And [p_they()] miss[p_es()]! How embarassing.", "You swing! You miss! Oh no!") playsound(get_turf(owner), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - do_attack_animation(get_step(owner, pick(alldirs)), ATTACK_EFFECT_DISARM) + do_attack_animation(get_step(owner, pick(alldirs)), ATTACK_EFFECT_DISARM) deflectmode = FALSE if(!istype(I, /obj/item/beach_ball)) lastdeflect = world.time + 3000 @@ -198,7 +198,7 @@ else visible_message("[owner] swings and deflects [I]!", "You swing and deflect the [I]!") playsound(get_turf(owner), 'sound/weapons/baseball_hit.ogg', 50, 1, -1) - do_attack_animation(I, ATTACK_EFFECT_DISARM) + do_attack_animation(I, ATTACK_EFFECT_DISARM) I.throw_at(get_edge_target_turf(owner, pick(cardinal)), rand(8,10), 14, owner) deflectmode = FALSE if(!istype(I, /obj/item/beach_ball)) @@ -239,7 +239,7 @@ playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1) homerun_ready = 0 return - else + else if(!target.anchored) target.throw_at(throw_target, rand(1,2), 7, user) /obj/item/melee/baseball_bat/ablative diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 43f45647985..d7900d82e38 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -34,6 +34,15 @@ LINEN BINS add_fingerprint(user) return +/obj/item/bedsheet/attackby(obj/item/I, mob/user, params) + if(I.sharp) + var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3) + transfer_fingerprints_to(C) + C.add_fingerprint(user) + qdel(src) + to_chat(user, "You tear [src] up.") + else + return ..() /obj/item/bedsheet/blue icon_state = "sheetblue" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 2037293d734..dba81195e6e 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -105,7 +105,7 @@ continue if(istype(M, /mob/living/simple_animal/bot/mulebot)) continue - if(M.buckled) + if(M.buckled || M.anchored) continue M.forceMove(src) diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index 19e08c15bde..f642960e52e 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -15,15 +15,19 @@ var/move_delay = 0 var/egged = 0 -/obj/structure/closet/cardboard/relaymove(mob/user, direction) - if(opened || move_delay || user.stat || user.stunned || user.weakened || user.paralysis || !isturf(loc) || !has_gravity(loc)) +/obj/structure/closet/cardboard/relaymove(mob/living/user, direction) + if(!istype(user) || opened || move_delay || user.incapacitated() || !isturf(loc) || !has_gravity(loc)) return - move_delay = 1 - if(step(src, direction)) - spawn(config.walk_speed) - move_delay = 0 + move_delay = TRUE + var/oldloc = loc + step(src, direction) + if(oldloc != loc) + addtimer(CALLBACK(src, .proc/ResetMoveDelay), config.walk_speed) else - move_delay = 0 + move_delay = FALSE + +/obj/structure/closet/cardboard/proc/ResetMoveDelay() + move_delay = FALSE /obj/structure/closet/cardboard/open() if(opened || !can_open()) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 0cd6e541398..0608eb64cbb 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -25,6 +25,7 @@ new /obj/item/clothing/glasses/welding/superior(src) new /obj/item/clothing/gloves/color/yellow(src) new /obj/item/clothing/shoes/brown(src) + new /obj/item/tank/jetpack/suit(src) new /obj/item/cartridge/ce(src) new /obj/item/radio/headset/heads/ce(src) new /obj/item/storage/toolbox/mechanical(src) @@ -147,3 +148,4 @@ new /obj/item/clothing/suit/fire/atmos(src) new /obj/item/clothing/head/hardhat/atmos(src) new /obj/item/rpd(src) + new /obj/item/destTagger(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 189cbc5893d..73dbc88487a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -273,6 +273,7 @@ new /obj/item/key/ambulance(src) new /obj/item/pinpointer/crew(src) new /obj/item/clothing/shoes/magboots(src) + new /obj/item/handheld_defibrillator(src) /obj/structure/closet/secure_closet/reagents name = "chemical storage closet" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index fe6b0082207..2501c32c2a6 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -251,7 +251,7 @@ new /obj/item/melee/baton/loaded(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/clothing/glasses/hud/security/sunglasses/read_only(src) - new /obj/item/clothing/glasses/hud/health/health_advanced + new /obj/item/clothing/glasses/hud/health/sunglasses new /obj/item/clothing/head/beret/centcom/officer(src) new /obj/item/clothing/head/beret/centcom/officer/navy(src) new /obj/item/clothing/suit/armor/vest/blueshield(src) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index c03b9694cfa..497644a1926 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -6,7 +6,7 @@ GLOBAL_LIST_INIT(captain_display_cases, list()) /proc/updateDisplaycase(mob/living/carbon/human/captain) if(!GLOB.captain_display_cases.len) - return + return var/fingerprint = captain.get_full_print() for(var/item in GLOB.captain_display_cases) var/obj/structure/displaycase/CASE = item @@ -113,6 +113,11 @@ GLOBAL_LIST_INIT(captain_display_cases, list()) occupant = new start_showpiece_type(src) update_icon() +/obj/structure/displaycase/Destroy() + dump() + QDEL_NULL(circuit) + return ..() + /obj/structure/displaycase/captains_laser name = "captain's display case" desc = "A display case for the captain's antique laser gun. Hooked up with an anti-theft system." @@ -125,6 +130,16 @@ GLOBAL_LIST_INIT(captain_display_cases, list()) . = ..() GLOB.captain_display_cases += src +/obj/structure/displaycase/captains_laser/Destroy() + GLOB.captain_display_cases -= src + return ..() + +/obj/structure/displaycase/lavaland_winter + burglar_alarm = TRUE + locked = TRUE + req_access = list(access_cent_specops) + start_showpiece_type = /obj/item/gun/energy/laser/captain + /obj/structure/displaycase/stechkin name = "officer's display case" desc = "A display case containing a humble stechkin pistol. Never forget your roots." @@ -132,15 +147,6 @@ GLOBAL_LIST_INIT(captain_display_cases, list()) req_access = list(access_syndicate_command) start_showpiece_type = /obj/item/gun/projectile/automatic/pistol -/obj/structure/displaycase/Destroy() - dump() - QDEL_NULL(circuit) - return ..() - -/obj/structure/displaycase/captains_laser/Destroy() - GLOB.captain_display_cases -= src - return ..() - /obj/structure/displaycase/examine(mob/user) ..(user) to_chat(user, "Peering through the glass, you see that it contains:") diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index bd97d611576..9c51cc0d451 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -260,6 +260,14 @@ ..() icon_state = "rockpile[rand(1,5)]" +/obj/structure/flora/rock/icy + name = "icy rock" + color = "#cce9eb" + +/obj/structure/flora/rock/pile/icy + name = "icy rocks" + color = "#cce9eb" + /obj/structure/flora/corn_stalk name = "corn stalk" icon = 'icons/obj/flora/plants.dmi' diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 97bd986ceb9..14ee2765d02 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -1,33 +1,59 @@ +// Basic ladder. By default links to the z-level above/below. /obj/structure/ladder name = "ladder" desc = "A sturdy metal ladder." icon = 'icons/obj/structures.dmi' icon_state = "ladder11" - anchored = 1 - var/id = null - var/height = 0 //the 'height' of the ladder. higher numbers are considered physically higher - var/obj/structure/ladder/down = null //the ladder below this one - var/obj/structure/ladder/up = null //the ladder above this one - var/use_verb = "climbs" + anchored = TRUE + var/obj/structure/ladder/down //the ladder below this one + var/obj/structure/ladder/up //the ladder above this one + var/use_verb = "climb" -/obj/structure/ladder/New() - spawn(8) - for(var/obj/structure/ladder/L in world) - if(L.id == id) - if(L.height == (height - 1)) - down = L - if(isnull(L.up)) - L.up = src - continue - if(L.height == (height + 1)) - up = L - if(isnull(L.down)) - L.down = src - continue +/obj/structure/ladder/Initialize(mapload, obj/structure/ladder/up, obj/structure/ladder/down) + . = ..() + if (up) + src.up = up + up.down = src + up.update_icon() + if (down) + src.down = down + down.up = src + down.update_icon() + return INITIALIZE_HINT_LATELOAD - if(up && down) //if both our connections are filled - break - update_icon() +/obj/structure/ladder/Destroy(force) + if((resistance_flags & INDESTRUCTIBLE) && !force) + return QDEL_HINT_LETMELIVE + disconnect() + return ..() + +/obj/structure/ladder/LateInitialize() + // By default, discover ladders above and below us vertically + var/turf/T = get_turf(src) + + if(!down) + for(var/obj/structure/ladder/L in locate(T.x, T.y, T.z - 1)) + down = L + L.up = src // Don't waste effort looping the other way + L.update_icon() + break + if(!up) + for (var/obj/structure/ladder/L in locate(T.x, T.y, T.z + 1)) + up = L + L.down = src // Don't waste effort looping the other way + L.update_icon() + break + + update_icon() + +/obj/structure/ladder/proc/disconnect() + if(up && up.down == src) + up.down = null + up.update_icon() + if(down && down.up == src) + down.up = null + down.update_icon() + up = down = null /obj/structure/ladder/update_icon() if(up && down) @@ -42,61 +68,134 @@ else //wtf make your ladders properly assholes icon_state = "ladder00" -/obj/structure/ladder/attack_hand(mob/user as mob) +/obj/structure/ladder/singularity_pull() + if(!(resistance_flags & INDESTRUCTIBLE)) + visible_message("[src] is torn to pieces by the gravitational pull!") + qdel(src) + +/obj/structure/ladder/proc/travel(going_up, mob/user, is_ghost, obj/structure/ladder/ladder) + if(!is_ghost) + show_fluff_message(going_up, user) + ladder.add_fingerprint(user) + + var/turf/T = get_turf(ladder) + var/atom/movable/AM + if(user.pulling) + AM = user.pulling + AM.forceMove(T) + user.forceMove(T) + if(AM) + user.start_pulling(AM) + +/obj/structure/ladder/proc/use(mob/user, is_ghost = FALSE) + if(!is_ghost && !in_range(src, user)) + return + if(up && down) - switch( alert("Go up or down the ladder?", "Ladder", "Up", "Down", "Cancel") ) + var/result = alert("Go up or down [src]?", "[name]", "Up", "Down", "Cancel") + if (!is_ghost && !in_range(src, user)) + return // nice try + switch(result) if("Up") - user.visible_message("[user] climbs up \the [src]!", \ - "You climb up \the [src]!") - user.forceMove(get_turf(up)) - up.add_fingerprint(user) + travel(TRUE, user, is_ghost, up) if("Down") - user.visible_message("[user] climbs down \the [src]!", \ - "You climb down \the [src]!") - user.forceMove(get_turf(down)) - down.add_fingerprint(user) + travel(FALSE, user, is_ghost, down) if("Cancel") return - else if(up) - user.visible_message("[user] climbs up \the [src]!", \ - "You climb up \the [src]!") - user.forceMove(get_turf(up)) - up.add_fingerprint(user) - + travel(TRUE, user, is_ghost, up) else if(down) - user.visible_message("[user] climbs down \the [src]!", \ - "You climb down \the [src]!") - user.forceMove(get_turf(down)) - down.add_fingerprint(user) + travel(FALSE, user, is_ghost, down) + else + to_chat(user, "[src] doesn't seem to lead anywhere!") - add_fingerprint(user) + if(!is_ghost) + add_fingerprint(user) -/obj/structure/ladder/attackby(obj/item/W, mob/user as mob, params) - return attack_hand(user) +/obj/structure/ladder/attack_hand(mob/user) + use(user) -/obj/structure/ladder/dive_point/buoy +/obj/structure/ladder/attackby(obj/item/W, mob/user, params) + return use(user) + +/obj/structure/ladder/attack_robot(mob/living/silicon/robot/R) + if(R.Adjacent(src)) + return use(R) + +//ATTACK GHOST IGNORING PARENT RETURN VALUE +/obj/structure/ladder/attack_ghost(mob/dead/observer/user) + use(user, TRUE) + +/obj/structure/ladder/proc/show_fluff_message(going_up, mob/user) + if(going_up) + user.visible_message("[user] climbs up [src].","You [use_verb] up [src].") + else + user.visible_message("[user] climbs down [src].","You [use_verb] down [src].") + + +// Indestructible away mission ladders which link based on a mapped ID and height value rather than X/Y/Z. +/obj/structure/ladder/unbreakable + name = "sturdy ladder" + desc = "An extremely sturdy metal ladder." + resistance_flags = INDESTRUCTIBLE + var/id + var/height = 0 // higher numbers are considered physically higher + +/obj/structure/ladder/unbreakable/Initialize(mapload) + GLOB.ladders += src + return ..() + +/obj/structure/ladder/unbreakable/Destroy() + . = ..() + if(. != QDEL_HINT_LETMELIVE) + GLOB.ladders -= src + +/obj/structure/ladder/unbreakable/LateInitialize() + // Override the parent to find ladders based on being height-linked + if(!id || (up && down)) + update_icon() + return + + for(var/O in GLOB.ladders) + var/obj/structure/ladder/unbreakable/L = O + if(L.id != id) + continue // not one of our pals + if(!down && L.height == height - 1) + down = L + L.up = src + L.update_icon() + if (up) + break // break if both our connections are filled + else if(!up && L.height == height + 1) + up = L + L.down = src + L.update_icon() + if (down) + break // break if both our connections are filled + + update_icon() + +/obj/structure/ladder/unbreakable/dive_point/buoy name = "diving point buoy" desc = "A buoy marking the location of an underwater dive area." icon = 'icons/misc/beach.dmi' icon_state = "buoy" id = "dive" height = 2 - use_verb = "dives" + use_verb = "swim" layer = MOB_LAYER + 0.2 //0.1 higher than the water overlay, this also means people can "swim" behind/under it -/obj/structure/ladder/dive_point/anchor +/obj/structure/ladder/unbreakable/dive_point/anchor name = "diving point anchor" desc = "An anchor tethered to the buoy at the surface, to keep the dive area marked." icon = 'icons/misc/beach.dmi' icon_state = "anchor" id = "dive" height = 1 - use_verb = "ascends" light_range = 5 -/obj/structure/ladder/dive_point/New() - ..() +/obj/structure/ladder/dive_point/Initialize(mapload) + . = ..() set_light(light_range, light_power) //magical glowing anchor /obj/structure/ladder/dive_point/update_icon() diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm new file mode 100644 index 00000000000..26bd4136c2a --- /dev/null +++ b/code/game/objects/structures/loom.dm @@ -0,0 +1,38 @@ +#define FABRIC_PER_SHEET 4 + + +///This is a loom. It's usually made out of wood and used to weave fabric like durathread or cotton into their respective cloth types. +/obj/structure/loom + name = "loom" + desc = "A simple device used to weave cloth and other thread-based fabrics together into usable material." + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "loom" + density = TRUE + anchored = TRUE + +/obj/structure/loom/attackby(obj/item/I, mob/user) + if(default_unfasten_wrench(user, I, 5)) + return + if(weave(I, user)) + return + return ..() + +///Handles the weaving. +/obj/structure/loom/proc/weave(obj/item/stack/sheet/cotton/W, mob/user) + if(!istype(W)) + return FALSE + if(!anchored) + user.show_message("The loom needs to be wrenched down.", 1) + return FALSE + if(W.amount < FABRIC_PER_SHEET) + user.show_message("You need at least [FABRIC_PER_SHEET] units of fabric before using this.", 1) + return FALSE + user.show_message("You start weaving \the [W.name] through the loom..", 1) + if(do_after(user, W.pull_effort, target = src)) + if(W.amount >= FABRIC_PER_SHEET) + new W.loom_result(drop_location()) + W.use(FABRIC_PER_SHEET) + user.show_message("You weave \the [W.name] into a workable fabric.", 1) + return TRUE + +#undef FABRIC_PER_SHEET \ No newline at end of file diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 93b2e30b6d9..d4296e1df2f 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -91,9 +91,9 @@ if(climber) climber.Weaken(2) climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You see [climber.name] get knocked off the table") - else if(user.pulling.pass_flags & PASSTABLE) + else if(Adjacent(user) && user.pulling && user.pulling.pass_flags & PASSTABLE) user.Move_Pulled(src) - if (user.pulling.loc == loc) + if(user.pulling.loc == loc) user.visible_message("[user] places [user.pulling] onto [src].", "You place [user.pulling] onto [src].") user.stop_pulling() diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index ada70921c99..0958f3cc0e0 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -600,7 +600,7 @@ wateract = (W.wash(user, src)) busy = 0 if(wateract) - W.water_act(20, 310.15, src) + W.water_act(20, COLD_WATER_TEMPERATURE, src) if("Disconnect") user.visible_message("[user] starts disconnecting [src].", "You begin disconnecting [src]...") if(do_after(user, 40 * O.toolspeed, target = src)) @@ -633,7 +633,7 @@ wateract = (O.wash(user, src)) busy = 0 if(wateract) - O.water_act(20, 310.15, src) + O.water_act(20, COLD_WATER_TEMPERATURE, src) /obj/structure/sink/update_icon() ..() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 16851097844..4090420525d 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -579,6 +579,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f dir = FULLTILE_WINDOW_DIR level = 3 fulltile = TRUE + flags = PREVENT_CLICK_UNDER /obj/structure/window/full/basic desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it." @@ -675,6 +676,7 @@ obj/structure/window/full/reinforced/ice dir = FULLTILE_WINDOW_DIR max_integrity = 200 fulltile = TRUE + flags = PREVENT_CLICK_UNDER reinf = TRUE heat_resistance = 1600 armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100) @@ -734,6 +736,7 @@ obj/structure/window/full/reinforced/ice smooth = SMOOTH_TRUE canSmoothWith = null fulltile = TRUE + flags = PREVENT_CLICK_UNDER dir = FULLTILE_WINDOW_DIR max_integrity = 120 level = 3 diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index f54e28defb1..c67d61770ac 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -25,7 +25,7 @@ /turf/simulated/water_act(volume, temperature, source) . = ..() - + if(volume >= 3) MakeSlippery() @@ -37,7 +37,7 @@ assume_air(lowertemp) qdel(hotspot) -/turf/simulated/proc/MakeSlippery(wet_setting = TURF_WET_WATER) // 1 = Water, 2 = Lube, 3 = Ice, 4 = Permafrost +/turf/simulated/proc/MakeSlippery(wet_setting = TURF_WET_WATER, infinite = FALSE) // 1 = Water, 2 = Lube, 3 = Ice, 4 = Permafrost if(wet >= wet_setting) return wet = wet_setting @@ -57,11 +57,11 @@ else wet_overlay = image('icons/effects/water.dmi', src, "wet_static") overlays += wet_overlay - - spawn(rand(790, 820)) // Purely so for visual effect - if(!istype(src, /turf/simulated)) //Because turfs don't get deleted, they change, adapt, transform, evolve and deform. they are one and they are all. - return - MakeDry(wet_setting) + if(!infinite) + spawn(rand(790, 820)) // Purely so for visual effect + if(!istype(src, /turf/simulated)) //Because turfs don't get deleted, they change, adapt, transform, evolve and deform. they are one and they are all. + return + MakeDry(wet_setting) /turf/simulated/proc/MakeDry(wet_setting = TURF_WET_WATER) if(wet > wet_setting) diff --git a/code/game/turfs/simulated/floor/chasm.dm b/code/game/turfs/simulated/floor/chasm.dm index 17807bd255b..1768b2d472a 100644 --- a/code/game/turfs/simulated/floor/chasm.dm +++ b/code/game/turfs/simulated/floor/chasm.dm @@ -22,7 +22,7 @@ if(!drop_stuff()) STOP_PROCESSING(SSprocessing, src) -/turf/open/chasm/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) +/turf/simulated/floor/chasm/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) underlay_appearance.icon = 'icons/turf/floors.dmi' underlay_appearance.icon_state = "basalt" return TRUE diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index 12b1654994c..2ce85481751 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -53,6 +53,11 @@ to_chat(user, "You forcefully pry off the planks, destroying them in the process.") return make_plating() +/turf/simulated/floor/wood/cold + oxygen = 22 + nitrogen = 82 + temperature = 180 + /turf/simulated/floor/grass name = "grass patch" icon_state = "grass1" @@ -117,7 +122,7 @@ burnt = 1 update_icon() -/turf/open/floor/carpet/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) +/turf/simulated/floor/carpet/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) return FALSE /turf/simulated/floor/carpet/black @@ -142,7 +147,7 @@ floor_tile = /obj/item/stack/tile/arcade_carpet smooth = SMOOTH_FALSE -/turf/open/floor/fakespace/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) +/turf/simulated/floor/fakespace/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) underlay_appearance.icon = 'icons/turf/space.dmi' underlay_appearance.icon_state = SPACE_ICON_STATE underlay_appearance.plane = PLANE_SPACE diff --git a/code/game/turfs/simulated/floor/indestructible.dm b/code/game/turfs/simulated/floor/indestructible.dm index 3705e24eea0..159f78ddd80 100644 --- a/code/game/turfs/simulated/floor/indestructible.dm +++ b/code/game/turfs/simulated/floor/indestructible.dm @@ -23,17 +23,17 @@ return /turf/simulated/floor/indestructible/attackby(obj/item/I, mob/user, params) - return + return /turf/simulated/floor/indestructible/attack_hand(mob/user) - return + return /turf/simulated/floor/indestructible/attack_hulk(mob/user, does_attack_animation = FALSE) return /turf/simulated/floor/indestructible/attack_animal(mob/living/simple_animal/M) return - + /turf/simulated/floor/indestructible/mech_melee_attack(obj/mecha/M) return @@ -81,7 +81,7 @@ planetary_atmos = TRUE desc = "A floor with a square pattern. It's faintly cool to the touch." -/turf/open/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) +/turf/simulated/floor/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) return FALSE /turf/simulated/floor/indestructible/hierophant/two diff --git a/code/game/turfs/simulated/floor/lava.dm b/code/game/turfs/simulated/floor/lava.dm index 66d7eaca83d..b2c29a5ee01 100644 --- a/code/game/turfs/simulated/floor/lava.dm +++ b/code/game/turfs/simulated/floor/lava.dm @@ -41,7 +41,7 @@ /turf/simulated/floor/plating/lava/remove_plating() return -/turf/open/lava/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) +/turf/simulated/floor/plating/lava/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) underlay_appearance.icon = 'icons/turf/floors.dmi' underlay_appearance.icon_state = "basalt" return TRUE diff --git a/code/game/turfs/simulated/floor/mineral.dm b/code/game/turfs/simulated/floor/mineral.dm index a801fd450c5..9031a0a350c 100644 --- a/code/game/turfs/simulated/floor/mineral.dm +++ b/code/game/turfs/simulated/floor/mineral.dm @@ -173,6 +173,18 @@ nitrogen = 0.01 temperature = TCMB + +/turf/simulated/floor/mineral/bananium/lubed/Initialize(mapload) + . = ..() + MakeSlippery(TURF_WET_LUBE, TRUE) + +/turf/simulated/floor/mineral/bananium/lubed/pry_tile(obj/item/C, mob/user, silent = FALSE) //I want to get off Mr Honk's Wild Ride + if(ishuman(user)) + var/mob/living/carbon/human/H = user + to_chat(H, "You lose your footing trying to pry off the tile!") + H.slip("the floor", 0, 5, tilesSlipped = 4, walkSafely = 0, slipAny = 1) + return + //TRANQUILLITE /turf/simulated/floor/mineral/tranquillite name = "silent floor" diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 5c8f2022189..5a097b5fe5b 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -43,7 +43,7 @@ name = "beach" icon = 'icons/misc/beach.dmi' -/turf/simulated/floor/beach/pry_tile(obj/item/C, mob/user, silent = FALSE) +/turf/simulated/floor/beach/pry_tile(obj/item/C, mob/user, silent = FALSE) return /turf/simulated/floor/beach/sand @@ -79,7 +79,7 @@ /turf/simulated/floor/beach/water/Entered(atom/movable/AM, atom/OldLoc) . = ..() if(!linkedcontroller) - return + return if(ismob(AM)) linkedcontroller.mobinpool += AM @@ -107,6 +107,26 @@ /turf/simulated/floor/noslip/MakeSlippery() return +/turf/simulated/floor/noslip/lavaland + oxygen = 14 + nitrogen = 23 + temperature = 300 + +/turf/simulated/floor/lubed + name = "slippery floor" + icon_state = "floor" + +/turf/simulated/floor/lubed/Initialize(mapload) + . = ..() + MakeSlippery(TURF_WET_LUBE, TRUE) + +/turf/simulated/floor/lubed/pry_tile(obj/item/C, mob/user, silent = FALSE) //I want to get off Mr Honk's Wild Ride + if(ishuman(user)) + var/mob/living/carbon/human/H = user + to_chat(H, "You lose your footing trying to pry off the tile!") + H.slip("the floor", 0, 5, tilesSlipped = 4, walkSafely = 0, slipAny = 1) + return + //Clockwork floor: Slowly heals toxin damage on nearby servants. /turf/simulated/floor/clockwork name = "clockwork floor" @@ -124,7 +144,7 @@ new /obj/effect/temp_visual/ratvar/beam(src) realappearence = new /obj/effect/clockwork/overlay/floor(src) realappearence.linked = src - + /turf/simulated/floor/clockwork/Destroy() if(uses_overlay && realappearence) QDEL_NULL(realappearence) diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 11ff392b824..819f6a07ef3 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -7,7 +7,7 @@ broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5") burnt_states = list("floorscorched1", "floorscorched2") - var/unfastened = FALSE + var/unfastened = FALSE footstep_sounds = list( "human" = list('sound/effects/footstep/plating_human.ogg'), @@ -185,7 +185,7 @@ /turf/simulated/floor/engine/blob_act() if(prob(25)) ChangeTurf(baseturf) - + /turf/simulated/floor/engine/cult name = "engraved floor" icon_state = "cult" @@ -335,3 +335,28 @@ /turf/simulated/floor/plating/abductor/New() ..() icon_state = "alienpod[rand(1,9)]" + +/turf/simulated/floor/plating/ice + name = "ice sheet" + desc = "A sheet of solid ice. Looks slippery." + icon = 'icons/turf/floors/ice_turfs.dmi' + icon_state = "unsmooth" + oxygen = 22 + nitrogen = 82 + temperature = 180 + baseturf = /turf/simulated/floor/plating/ice + slowdown = TRUE + smooth = SMOOTH_TRUE + canSmoothWith = list(/turf/simulated/floor/plating/ice/smooth, /turf/simulated/floor/plating/ice) + +/turf/simulated/floor/plating/ice/Initialize(mapload) + . = ..() + MakeSlippery(TURF_WET_PERMAFROST, TRUE) + +/turf/simulated/floor/plating/ice/try_replace_tile(obj/item/stack/tile/T, mob/user, params) + return + +/turf/simulated/floor/plating/ice/smooth + icon_state = "smooth" + smooth = SMOOTH_MORE | SMOOTH_BORDER + canSmoothWith = list(/turf/simulated/floor/plating/ice/smooth, /turf/simulated/floor/plating/ice) diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm index 74d0e216614..6bae5a79d94 100644 --- a/code/game/turfs/simulated/walls_mineral.dm +++ b/code/game/turfs/simulated/walls_mineral.dm @@ -140,7 +140,23 @@ sheet_type = /obj/item/stack/sheet/wood hardness = 70 explosion_block = 0 - canSmoothWith = list(/turf/simulated/wall/mineral/wood, /obj/structure/falsewall/wood) + canSmoothWith = list(/turf/simulated/wall/mineral/wood, /obj/structure/falsewall/wood, /turf/simulated/wall/mineral/wood/nonmetal) + +/turf/simulated/wall/mineral/wood/attackby(obj/item/W, mob/user) + if(W.sharp && W.force) + var/duration = (48 / W.force) * 2 //In seconds, for now. + if(istype(W, /obj/item/hatchet) || istype(W, /obj/item/twohanded/fireaxe)) + duration /= 4 //Much better with hatchets and axes. + if(do_after(user, duration * 10, target = src)) //Into deciseconds. + dismantle_wall(FALSE, FALSE) + return + return ..() + +/turf/simulated/wall/mineral/wood/nonmetal + desc = "A solidly wooden wall. It's a bit weaker than a wall made with metal." + girder_type = /obj/structure/barricade/wooden + hardness = 50 + canSmoothWith = list(/turf/simulated/wall/mineral/wood, /obj/structure/falsewall/wood, /turf/simulated/wall/mineral/wood/nonmetal) /turf/simulated/wall/mineral/iron name = "rough metal wall" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 51285932f00..0ab9ccbef15 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -516,6 +516,5 @@ /turf/AllowDrop() return TRUE -/turf/proc/water_act(volume, temperature, source) - for(var/mob/living/carbon/slime/M in src) - M.apply_water() +/turf/proc/water_act(volume, temperature, source) + return FALSE diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 5a2807e8379..df2f588753f 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -41,6 +41,9 @@ var/global/admin_ooc_colour = "#b82e00" return if(!check_rights(R_ADMIN|R_MOD,0)) + if(!config.ooc_allowed) + to_chat(src, "OOC is globally muted.") + return if(handle_spam_prevention(msg, MUTE_OOC, OOC_COOLDOWN)) return if(findtext(msg, "byond://")) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index a6f186dad73..d32a05eb312 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -784,11 +784,13 @@ var/global/nologevent = 0 log_admin("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].") message_admins("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1) return //alert("Round end delayed", null, null, null, null, null) - going = !( going ) - if(!( going )) + if(going) + going = FALSE + SSticker.delay_end = TRUE to_chat(world, "The game start has been delayed.") log_admin("[key_name(usr)] delayed the game.") else + going = TRUE to_chat(world, "The game will start soon.") log_admin("[key_name(usr)] removed the delay.") feedback_add_details("admin_verb","DELAY") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index d52507bee1d..d57c3124f61 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -210,6 +210,7 @@ var/datum/objective/KillDaCrew = new /datum/objective KillDaCrew.owner = S.mind KillDaCrew.explanation_text = "[objective_verb] everyone else while you're at it." + KillDaCrew.completed = TRUE S.mind.objectives += KillDaCrew to_chat(S, "Objective #[1]: [KillDaWiz.explanation_text]") to_chat(S, "Objective #[2]: [KillDaCrew.explanation_text]") @@ -219,7 +220,8 @@ desc = "A magically infused bottle of clown love, distilled from \ countless hugging attacks. Used in funny rituals to attract \ adorable creatures." - color = "#FF69B4" // HOT PINK + icon = 'icons/obj/wizard.dmi' + icon_state = "vialtickles" veil_msg = "You sense an adorable presence \ lurking just beyond the veil..." objective_verb = "Hug and tickle" @@ -278,6 +280,7 @@ var/datum/objective/KillDaCrew = new /datum/objective KillDaCrew.owner = M.mind KillDaCrew.explanation_text = "[objective_verb] everyone and everything else while you're at it." + KillDaCrew.completed = TRUE M.mind.objectives += KillDaCrew to_chat(M, "Objective #[1]: [KillDaWiz.explanation_text]") to_chat(M, "Objective #[2]: [KillDaCrew.explanation_text]") diff --git a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm index 60cedb281fa..9a5bf275abc 100644 --- a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm +++ b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm @@ -104,6 +104,11 @@ H.rename_character(null, H.dna.species.get_random_name()) else H.rename_character(null, name) + if(is_species(H, /datum/species/golem/tranquillite) && H.mind) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall(null)) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak(null)) + H.mind.miming = TRUE + if(has_owner) new_spawn.mind.assigned_role = "Servant Golem" else diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 300443714ab..57a6df32ab6 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -318,7 +318,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the for(var/D in cardinal) assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipe-item.dmi', state, D) for(var/state in icon_states('icons/obj/pipes/disposal.dmi')) - if(!(state in list("pipe-c", "pipe-j1", "pipe-s", "pipe-t", "pipe-y", "intake", "outlet"))) //Pipes we want sprites for + if(!(state in list("pipe-c", "pipe-j1", "pipe-s", "pipe-t", "pipe-y", "intake", "outlet", "pipe-j1s"))) //Pipes we want sprites for continue for(var/D in cardinal) assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipes/disposal.dmi', state, D) diff --git a/code/modules/client/preference/loadout/loadout_cosmetics.dm b/code/modules/client/preference/loadout/loadout_cosmetics.dm index aa7f5f02576..b7ac6c39493 100644 --- a/code/modules/client/preference/loadout/loadout_cosmetics.dm +++ b/code/modules/client/preference/loadout/loadout_cosmetics.dm @@ -21,12 +21,4 @@ /datum/gear/lipstick/lime display_name = "lipstick, lime" - path = /obj/item/lipstick/lime - -/datum/gear/monocle - display_name = "monocle" - path = /obj/item/clothing/glasses/monocle - -/datum/gear/sunglasses - display_name = "cheap sunglasses" - path = /obj/item/clothing/glasses/sunglasses/fake \ No newline at end of file + path = /obj/item/lipstick/lime \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_donor.dm b/code/modules/client/preference/loadout/loadout_donor.dm index 5558a988209..830b10b7055 100644 --- a/code/modules/client/preference/loadout/loadout_donor.dm +++ b/code/modules/client/preference/loadout/loadout_donor.dm @@ -18,12 +18,10 @@ /datum/gear/donor/furcape display_name = "Fur Cape" path = /obj/item/clothing/suit/furcape - cost = 2 /datum/gear/donor/furcoat display_name = "Fur Coat" path = /obj/item/clothing/suit/furcoat - cost = 2 /datum/gear/donor/kamina display_name = "Spiky Orange-tinted Shades" @@ -33,10 +31,6 @@ display_name = "Spiky Green-tinted Shades" path = /obj/item/clothing/glasses/fluff/kamina/green -/datum/gear/donor/hipster - display_name = "Hipster Glasses" - path = /obj/item/clothing/glasses/regular/hipster - /datum/gear/donor/threedglasses display_name = "Threed Glasses" path = /obj/item/clothing/glasses/threedglasses diff --git a/code/modules/client/preference/loadout/loadout_glasses.dm b/code/modules/client/preference/loadout/loadout_glasses.dm new file mode 100644 index 00000000000..94f2555bdba --- /dev/null +++ b/code/modules/client/preference/loadout/loadout_glasses.dm @@ -0,0 +1,24 @@ +/datum/gear/glasses + subtype_path = /datum/gear/glasses + slot = slot_glasses + sort_category = "Glasses" + +/datum/gear/glasses/sunglasses + display_name = "cheap sunglasses" + path = /obj/item/clothing/glasses/sunglasses_fake + +/datum/gear/glasses/eyepatch + display_name = "Eyepatch" + path = /obj/item/clothing/glasses/eyepatch + +/datum/gear/glasses/hipster + display_name = "Hipster glasses" + path = /obj/item/clothing/glasses/regular/hipster + +/datum/gear/glasses/monocle + display_name = "Monocle" + path = /obj/item/clothing/glasses/monocle + +/datum/gear/glasses/prescription + display_name = "Prescription glasses" + path = /obj/item/clothing/glasses/regular \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_gloves.dm b/code/modules/client/preference/loadout/loadout_gloves.dm new file mode 100644 index 00000000000..cd8d5a7c8e1 --- /dev/null +++ b/code/modules/client/preference/loadout/loadout_gloves.dm @@ -0,0 +1,8 @@ +/datum/gear/gloves + subtype_path = /datum/gear/gloves + slot = slot_gloves + sort_category = "Gloves" + +/datum/gear/gloves/fingerless + display_name = "Fingerless Gloves" + path = /obj/item/clothing/gloves/fingerless \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_shoes.dm b/code/modules/client/preference/loadout/loadout_shoes.dm index 519cadcc044..5031f4333fb 100644 --- a/code/modules/client/preference/loadout/loadout_shoes.dm +++ b/code/modules/client/preference/loadout/loadout_shoes.dm @@ -27,25 +27,32 @@ /datum/gear/shoes/cowboyboots display_name = "cowboy boots, brown" - cost = 1 - path = /obj/item/clothing/shoes/cowboyboots + path = /obj/item/clothing/shoes/cowboy /datum/gear/shoes/cowboyboots_black display_name = "cowboy boots, black" - cost = 1 - path = /obj/item/clothing/shoes/cowboyboots/black + path = /obj/item/clothing/shoes/cowboy/black /datum/gear/shoes/cowboyboots/white display_name = "cowboy boots, white" - cost = 1 - path = /obj/item/clothing/shoes/cowboyboots/white + path = /obj/item/clothing/shoes/cowboy/white /datum/gear/shoes/cowboyboots/pink display_name = "cowboy boots, pink" - cost = 1 - path = /obj/item/clothing/shoes/cowboyboots/pink - + path = /obj/item/clothing/shoes/cowboy/pink + /datum/gear/shoes/laceup display_name = "laceup shoes" - cost = 1 path = /obj/item/clothing/shoes/laceup + +/datum/gear/shoes/blackshoes + display_name = "Black shoes" + path = /obj/item/clothing/shoes/black + +/datum/gear/shoes/brownshoes + display_name = "Brown shoes" + path = /obj/item/clothing/shoes/brown + +/datum/gear/shoes/whiteshoes + display_name = "White shoes" + path = /obj/item/clothing/shoes/white \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_suit.dm b/code/modules/client/preference/loadout/loadout_suit.dm index 3d6b5ded994..32a9bae99e7 100644 --- a/code/modules/client/preference/loadout/loadout_suit.dm +++ b/code/modules/client/preference/loadout/loadout_suit.dm @@ -1,7 +1,6 @@ /datum/gear/suit subtype_path = /datum/gear/suit slot = slot_wear_suit - cost = 2 sort_category = "External Wear" //WINTER COATS @@ -105,6 +104,10 @@ path = /obj/item/clothing/suit/armor/secjacket allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Security Pod Pilot") +/datum/gear/suit/ianshirt + display_name = "Ian Shirt" + path = /obj/item/clothing/suit/ianshirt + /datum/gear/suit/poncho display_name = "poncho, classic" path = /obj/item/clothing/suit/poncho diff --git a/code/modules/client/preference/loadout/loadout_uniform.dm b/code/modules/client/preference/loadout/loadout_uniform.dm index f4a5c465aba..eb5264a0975 100644 --- a/code/modules/client/preference/loadout/loadout_uniform.dm +++ b/code/modules/client/preference/loadout/loadout_uniform.dm @@ -2,7 +2,6 @@ /datum/gear/uniform subtype_path = /datum/gear/uniform slot = slot_w_uniform - cost = 2 sort_category = "Uniforms and Casual Dress" /datum/gear/uniform/skirt diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm index e164a2ab843..c1ad8d6d103 100644 --- a/code/modules/client/preference/preferences_toggles.dm +++ b/code/modules/client/preference/preferences_toggles.dm @@ -201,6 +201,19 @@ to_chat(src, "You will no longer hear musical instruments.") feedback_add_details("admin_verb","TInstru") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/verb/Toggle_disco() //to toggle off the disco machine locally, in case it gets too annoying + set name = "Hear/Silence Dance Machine" + set category = "Preferences" + set desc = "Toggles hearing and dancing to the radiant dance machine" + prefs.sound ^= SOUND_DISCO + prefs.save_preferences(src) + if(prefs.sound & SOUND_DISCO) + to_chat(src, "You will now hear and dance to the radiant dance machine.") + else + to_chat(src, "You will no longer hear or dance to the radiant dance machine.") + usr.stop_sound_channel(CHANNEL_JUKEBOX) + feedback_add_details("admin_verb","Tdd") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /client/verb/setup_character() set name = "Game Preferences" set category = "Preferences" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 39235918323..96cff51ec4d 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -444,7 +444,8 @@ BLIND // can't see anything slowdown = SHOES_SLOWDOWN sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/shoes.dmi' + "Vox" = 'icons/mob/species/vox/shoes.dmi', + "Drask" = 'icons/mob/species/drask/shoes.dmi' ) /obj/item/clothing/shoes/attackby(obj/item/I, mob/user, params) @@ -595,7 +596,7 @@ BLIND // can't see anything min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") flash_protect = 2 strip_delay = 50 put_on_delay = 50 @@ -623,7 +624,7 @@ BLIND // can't see anything put_on_delay = 80 burn_state = FIRE_PROOF hide_tail_by_species = null - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") //Under clothing /obj/item/clothing/under diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index ac6c3b6dd0b..81ab79adbc4 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -265,9 +265,11 @@ "Grey" = 'icons/mob/species/grey/eyes.dmi' ) -/obj/item/clothing/glasses/sunglasses/fake +/obj/item/clothing/glasses/sunglasses_fake desc = "Cheap, plastic sunglasses. They don't even have UV protection." name = "cheap sunglasses" + icon_state = "sun" + item_state = "sunglasses" see_in_dark = 0 flash_protect = 0 tint = 0 diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 1e639beb5de..27cd78afad3 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -38,12 +38,6 @@ "Grey" = 'icons/mob/species/grey/eyes.dmi' ) -/obj/item/clothing/glasses/hud/health/health_advanced - name = "\improper Advanced Health Scanner HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their health status. Includes anti-flash filter." - icon_state = "advmedhud" - flash_protect = 1 - /obj/item/clothing/glasses/hud/health/night name = "\improper Night Vision Health Scanner HUD" desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." @@ -54,6 +48,14 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE prescription_upgradable = 0 +/obj/item/clothing/glasses/hud/health/sunglasses + name = "medical HUDSunglasses" + desc = "Sunglasses with a medical HUD." + icon_state = "sunhudmed" + see_in_dark = 1 + flash_protect = 1 + tint = 1 + /obj/item/clothing/glasses/hud/diagnostic name = "Diagnostic HUD" desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits." @@ -77,6 +79,14 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE prescription_upgradable = 0 +/obj/item/clothing/glasses/hud/diagnostic/sunglasses + name = "diagnostic sunglasses" + desc = "Sunglasses with a diagnostic HUD." + icon_state = "sunhuddiag" + item_state = "glasses" + flash_protect = 1 + tint = 1 + /obj/item/clothing/glasses/hud/security name = "\improper Security HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records." diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index a06b01de65d..a9d5765c861 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -152,10 +152,25 @@ /obj/item/clothing/gloves/fingerless/rapid name = "Gloves of the North Star" desc = "Just looking at these fills you with an urge to beat the shit out of people." + var/accepted_intents = list(INTENT_HARM) + var/click_speed_modifier = CLICK_CD_RAPID /obj/item/clothing/gloves/fingerless/rapid/Touch(mob/living/target, proximity = TRUE) var/mob/living/M = loc - if(M.a_intent == INTENT_HARM) - M.changeNext_move(CLICK_CD_RAPID) - .= FALSE \ No newline at end of file + if(M.a_intent in accepted_intents) + M.changeNext_move(click_speed_modifier) + .= FALSE + +/obj/item/clothing/gloves/fingerless/rapid/admin + name = "Advanced Interactive Gloves" + desc = "The gloves are covered in indecipherable buttons and dials, your mind warps by merely looking at them." + accepted_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) + click_speed_modifier = 0 + siemens_coefficient = 0 + +/obj/item/clothing/gloves/fingerless/rapid/headpat + name = "Gloves of Headpats" + desc = "You feel the irresistable urge to give headpats by merely glimpsing these." + accepted_intents = list(INTENT_HELP) + click_speed_modifier = 0 // That's some serious headpatting \ No newline at end of file diff --git a/code/modules/clothing/head/beanie.dm b/code/modules/clothing/head/beanie.dm new file mode 100644 index 00000000000..af7e805b232 --- /dev/null +++ b/code/modules/clothing/head/beanie.dm @@ -0,0 +1,96 @@ + +//BeanieStation13 Redux + +//Plus a bobble hat, lets be inclusive!! + +/obj/item/clothing/head/beanie //Default is white, this is meant to be seen + name = "white beanie" + desc = "A stylish beanie. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their heads." + icon_state = "beanie" //Default white + item_color = "beanie" + +/obj/item/clothing/head/beanie/black + name = "black beanie" + icon_state = "beanie" + color = "#4A4A4B" //Grey but it looks black + +/obj/item/clothing/head/beanie/red + name = "red beanie" + icon_state = "beanie" + color = "#D91414" //Red + +/obj/item/clothing/head/beanie/green + name = "green beanie" + icon_state = "beanie" + color = "#5C9E54" //Green + +/obj/item/clothing/head/beanie/darkblue + name = "dark blue beanie" + icon_state = "beanie" + color = "#1E85BC" //Blue + +/obj/item/clothing/head/beanie/purple + name = "purple beanie" + icon_state = "beanie" + color = "#9557C5" //purple + +/obj/item/clothing/head/beanie/yellow + name = "yellow beanie" + icon_state = "beanie" + color = "#E0C14F" //Yellow + +/obj/item/clothing/head/beanie/orange + name = "orange beanie" + icon_state = "beanie" + color = "#C67A4B" //orange + +/obj/item/clothing/head/beanie/cyan + name = "cyan beanie" + icon_state = "beanie" + color = "#54A3CE" //Cyan (Or close to it) + +//Striped Beanies have unique sprites + +/obj/item/clothing/head/beanie/christmas + name = "christmas beanie" + icon_state = "beaniechristmas" + item_color = "beaniechristmas" + +/obj/item/clothing/head/beanie/striped + name = "striped beanie" + icon_state = "beaniestriped" + item_color = "beaniestriped" + +/obj/item/clothing/head/beanie/stripedred + name = "red striped beanie" + icon_state = "beaniestripedred" + item_color = "beaniestripedred" + +/obj/item/clothing/head/beanie/stripedblue + name = "blue striped beanie" + icon_state = "beaniestripedblue" + item_color = "beaniestripedblue" + +/obj/item/clothing/head/beanie/stripedgreen + name = "green striped beanie" + icon_state = "beaniestripedgreen" + item_color = "beaniestripedgreen" + +/obj/item/clothing/head/beanie/durathread + name = "durathread beanie" + desc = "A beanie made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "beaniedurathread" + item_color = null + armor = list(melee = 15, bullet = 5, laser = 15, energy = 5, bomb = 10, bio = 0, rad = 0) + +/obj/item/clothing/head/beanie/waldo + name = "red striped bobble hat" + desc = "If you're going on a worldwide hike, you'll need some cold protection." + icon_state = "waldo_hat" + item_color = "waldo_hat" + +/obj/item/clothing/head/beanie/rasta + name = "rastacap" + desc = "Perfect for tucking in those dreadlocks." + icon_state = "beanierasta" + item_color = "beanierasta" \ No newline at end of file diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 4c915e5fc9c..13826e53ea1 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -227,6 +227,24 @@ obj/item/clothing/head/blob item_state = "knight_templar" armor = list(melee = 20, bullet = 7, laser = 2, energy = 2, bomb = 2, bio = 2, rad = 0) +/obj/item/clothing/head/helmet/skull + name = "skull helmet" + desc = "An intimidating tribal helmet, it doesn't look very comfortable." + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + flags_cover = HEADCOVERSEYES + armor = list(melee = 25, bullet = 25, laser = 25, energy = 10, bomb = 10, bio = 5, rad = 20) + icon_state = "skull" + item_state = "skull" + strip_delay = 100 + +/obj/item/clothing/head/helmet/durathread + name = "durathread helmet" + desc = "A helmet made from durathread and leather." + icon_state = "durathread" + item_state = "durathread" + armor = list(melee = 25, bullet = 10, laser = 20, energy = 10, bomb = 30, bio = 15, rad = 20) + strip_delay = 60 + //Commander /obj/item/clothing/head/helmet/ert/command name = "emergency response team commander helmet" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index adcc828d8d5..9c96cbae961 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -39,7 +39,7 @@ //Chaplain -/obj/item/clothing/head/chaplain_hood +/obj/item/clothing/head/hooded/chaplain_hood name = "chaplain's hood" desc = "It's hood that covers the head. It keeps you warm during the space winters." icon_state = "chaplain_hood" @@ -47,7 +47,7 @@ flags_cover = HEADCOVERSEYES //Chaplain -/obj/item/clothing/head/nun_hood +/obj/item/clothing/head/hooded/nun_hood name = "nun hood" desc = "Maximum piety in this star system." icon_state = "nun_hood" @@ -55,7 +55,7 @@ flags_cover = HEADCOVERSEYES //Chaplain -/obj/item/clothing/head/monk_hood +/obj/item/clothing/head/hooded/monk_hood name = "monk hood" desc = "Wooden board not included." icon_state = "monk_hood" @@ -82,6 +82,13 @@ desc = "A beret, an artists favorite headwear." icon_state = "beret" +/obj/item/clothing/head/beret/durathread + name = "durathread beret" + desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "beretdurathread" + item_color = null + armor = list(melee = 15, bullet = 5, laser = 15, energy = 5, bomb = 10, bio = 0, rad = 0) + //Security /obj/item/clothing/head/HoS name = "head of security cap" diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index db7295809b1..8956a456166 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -140,11 +140,7 @@ flags_inv = HIDEEARS | HIDEEYES magical = TRUE -/obj/item/clothing/mask/gas/virusclown_hat - name = "clown wig and mask" - desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask." - icon_state = "clown" - item_state = "clown_hat" +/obj/item/clothing/mask/gas/clown_hat/nodrop flags = NODROP /obj/item/clothing/mask/gas/mime @@ -154,6 +150,9 @@ item_state = "mime" burn_state = FLAMMABLE +/obj/item/clothing/mask/gas/mime/nodrop + flags = NODROP + /obj/item/clothing/mask/gas/monkeymask name = "monkey mask" desc = "A mask used when acting as a monkey." diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 3151ddca083..a60e4b2c2a6 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -483,6 +483,11 @@ item_color = "black" desc = "It's a black bandana." +/obj/item/clothing/mask/bandana/durathread + name = "durathread bandana" + desc = "A bandana made from durathread, you wish it would provide some protection to its wearer, but it's far too thin..." + icon_state = "banddurathread" + /obj/item/clothing/mask/cursedclown name = "cursed clown mask" desc = "This is a very, very odd looking mask." diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index bca650a30b1..bc7d0d6c701 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -88,6 +88,9 @@ to_chat(user, "You switch on the waddle dampeners!") enabled_waddle = FALSE +/obj/item/clothing/shoes/clown_shoes/nodrop + flags = NODROP + /obj/item/clothing/shoes/clown_shoes/magical name = "magical clown shoes" desc = "Standard-issue shoes of the wizarding class clown. Damn they're huge! And powerful! Somehow." @@ -243,30 +246,55 @@ icon_state = "bsing" put_on_delay = 50 -/obj/item/clothing/shoes/cowboyboots +/obj/item/clothing/shoes/cowboy name = "cowboy boots" desc = "A pair a' brown boots." - icon_state = "cowboyboots" - item_color = "cowboyboots" + icon_state = "cowboy_brown" + item_color = "cowboy_brown" -/obj/item/clothing/shoes/cowboyboots/black +/obj/item/clothing/shoes/cowboy/black name = "black cowboy boots" desc = "A pair a' black rustlers' boots" - icon_state = "cowboyboots_black" - item_color = "cowboyboots_black" + icon_state = "cowboy_black" + item_color = "cowboy_black" -/obj/item/clothing/shoes/cowboyboots/white +/obj/item/clothing/shoes/cowboy/white name = "white cowboy boots" desc = "For the rancher in us all." - icon_state = "cowboyboots_white" - item_color = "cowboyboots_white" + icon_state = "cowboy_white" + item_color = "cowboy_white" -/obj/item/clothing/shoes/cowboyboots/pink +/obj/item/clothing/shoes/cowboy/fancy + name = "bilton wrangler boots" + desc = "A pair of authentic haute couture boots from Japanifornia. You doubt they have ever been close to cattle." + icon_state = "cowboy_fancy" + item_color = "cowboy_fancy" + +/obj/item/clothing/shoes/cowboy/pink name = "pink cowgirl boots" desc = "For a Rustlin' tustlin' cowgirl." icon_state = "cowboyboots_pink" item_color = "cowboyboots_pink" +/obj/item/clothing/shoes/cowboy/lizard + name = "lizard skin boots" + desc = "You can hear a faint hissing from inside the boots; you hope it is just a mournful ghost." + icon_state = "lizardboots_green" + +/obj/item/clothing/shoes/cowboy/lizardmasterwork + name = "\improper Hugs-The-Feet lizard skin boots" + desc = "A pair of masterfully crafted lizard skin boots. Finally a good application for the station's most bothersome inhabitants." + icon_state = "lizardboots_blue" + +/obj/effect/spawner/lootdrop/lizardboots + name = "random lizard boot quality" + desc = "Which ever gets picked, the lizard race loses" + icon = 'icons/obj/clothing/shoes.dmi' + icon_state = "lizardboots_green" + loot = list( + /obj/item/clothing/shoes/cowboy/lizard = 7, + /obj/item/clothing/shoes/cowboy/lizardmasterwork = 1) + /obj/item/clothing/shoes/footwraps name = "cloth footwraps" desc = "A roll of treated canvas used for wrapping claws or paws." diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index e97f220bd8e..60523d6c0e8 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -190,7 +190,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT sprite_sheets = null actions_types = list() - has_camera = 0 + has_camera = FALSE /obj/item/clothing/suit/space/hardsuit/ert/paranormal name = "paranormal response team suit" @@ -208,20 +208,26 @@ name = "inquisitor's helmet" icon_state = "hardsuit0-inquisitor" item_color = "inquisitor" + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor name = "inquisitor's hardsuit" icon_state = "hardsuit-inquisitor" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) + slowdown = 0 /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/berserker name = "champion's helmet" desc = "Peering into the eyes of the helmet is enough to seal damnation." icon_state = "hardsuit0-berserker" item_color = "berserker" + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) /obj/item/clothing/suit/space/hardsuit/ert/paranormal/berserker name = "champion's hardsuit" desc = "Voices echo from the hardsuit, driving the user insane." icon_state = "hardsuit-berserker" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/berserker + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) + slowdown = 0 \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 4c74aba8c93..466fb2fc2fd 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -14,7 +14,7 @@ actions_types = list(/datum/action/item_action/toggle_helmet_light) //Species-specific stuff. - species_restricted = list("exclude","Diona","Wryn") + species_restricted = list("exclude","Wryn") sprite_sheets = list( "Unathi" = 'icons/mob/species/unathi/helmet.dmi', "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', @@ -93,9 +93,10 @@ var/obj/item/clothing/head/helmet/space/hardsuit/helmet actions_types = list(/datum/action/item_action/toggle_helmet) var/helmettype = /obj/item/clothing/head/helmet/space/hardsuit + var/obj/item/tank/jetpack/suit/jetpack = null hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran") - species_restricted = list("exclude","Diona","Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Unathi" = 'icons/mob/species/unathi/suit.dmi', "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', @@ -112,10 +113,59 @@ "Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/suits.dmi' ) +/obj/item/clothing/suit/space/hardsuit/New() + if(jetpack && ispath(jetpack)) + jetpack = new jetpack(src) + ..() + /obj/item/clothing/suit/space/hardsuit/attack_self(mob/user) user.changeNext_move(CLICK_CD_MELEE) ..() +/obj/item/clothing/suit/space/hardsuit/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/tank/jetpack/suit)) + if(jetpack) + to_chat(user, "[src] already has a jetpack installed.") + return + if(src == user.get_item_by_slot(slot_wear_suit)) //Make sure the player is not wearing the suit before applying the upgrade. + to_chat(user, "You cannot install the upgrade to [src] while wearing it.") + return + + if(user.unEquip(I)) + I.forceMove(src) + jetpack = I + to_chat(user, "You successfully install the jetpack into [src].") + return + else if(isscrewdriver(I)) + if(!jetpack) + to_chat(user, "[src] has no jetpack installed.") + return + if(src == user.get_item_by_slot(slot_wear_suit)) + to_chat(user, "You cannot remove the jetpack from [src] while wearing it.") + return + + jetpack.turn_off(user) + jetpack.forceMove(drop_location()) + jetpack = null + to_chat(user, "You successfully remove the jetpack from [src].") + return + return ..() + +/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot) + ..() + if(jetpack) + if(slot == slot_wear_suit) + for(var/X in jetpack.actions) + var/datum/action/A = X + A.Grant(user) + +/obj/item/clothing/suit/space/hardsuit/dropped(mob/user) + ..() + if(jetpack) + for(var/X in jetpack.actions) + var/datum/action/A = X + A.Remove(user) + /obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot) if(slot == slot_wear_suit) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit. return 1 @@ -178,6 +228,7 @@ heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite + jetpack = /obj/item/tank/jetpack/suit //Mining hardsuit /obj/item/clothing/head/helmet/space/hardsuit/mining @@ -291,6 +342,7 @@ armor = list(melee = 40, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50) allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi + jetpack = /obj/item/tank/jetpack/suit /obj/item/clothing/suit/space/hardsuit/syndi/update_icon() icon_state = "hardsuit[on]-[item_color]" @@ -438,6 +490,7 @@ icon_state = "hardsuit-hos" armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos + jetpack = /obj/item/tank/jetpack/suit sprite_sheets = null //Singuloth armor @@ -522,6 +575,7 @@ allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank) slowdown = 0 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi + jetpack = /obj/item/tank/jetpack/suit sprite_sheets = list( "Unathi" = 'icons/mob/species/unathi/suit.dmi', "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 9706b254fa8..1e5c9ad6dcb 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -7,7 +7,7 @@ flags_inv = HIDEFACE permeability_coefficient = 0.01 armor = list(melee = 40, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/helmet.dmi', @@ -31,7 +31,7 @@ w_class = WEIGHT_CLASS_BULKY allowed = list(/obj/item/tank, /obj/item/flashlight,/obj/item/gun/energy, /obj/item/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton,/obj/item/restraints/handcuffs) armor = list(melee = 40, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' @@ -72,7 +72,7 @@ allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank,/obj/item/kitchen/knife/combat) armor = list(melee = 40, bullet = 30, laser = 30, energy = 30, bomb = 50, bio = 90, rad = 20) strip_delay = 120 - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' @@ -159,7 +159,7 @@ icon_state = "paramedic-eva-helmet" item_state = "paramedic-eva-helmet" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/helmet.dmi', @@ -180,7 +180,7 @@ item_state = "paramedic-eva" desc = "A brand new paramedic EVA suit. The nitrile seems a bit too thin to be space proof. Used for retrieving bodies in space." armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi', @@ -200,7 +200,7 @@ item_state = "s_suit" desc = "A lightweight space suit with the basic ability to protect the wearer from the vacuum of space during emergencies." armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', @@ -223,7 +223,7 @@ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) flash_protect = 0 - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', @@ -244,7 +244,7 @@ desc = ". . ." icon_state = "spacemimehelmet" item_state = "spacemimehelmet" - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") sprite_sheets = null sprite_sheets_obj = null @@ -254,7 +254,7 @@ desc = ". . ." icon_state = "spacemime_suit" item_state = "spacemime_items" - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") sprite_sheets = null sprite_sheets_obj = null @@ -264,7 +264,7 @@ desc = "An EVA helmet specifically designed for the clown. SPESSHONK!" icon_state = "clownhelmet" item_state = "clownhelmet" - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") sprite_sheets = null sprite_sheets_obj = null @@ -274,7 +274,6 @@ desc = "An EVA suit specifically designed for the clown. SPESSHONK!" icon_state = "spaceclown_suit" item_state = "spaceclown_items" - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") sprite_sheets = null sprite_sheets_obj = null - \ No newline at end of file diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index ae8502f7246..e27b3b8ef1f 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -209,6 +209,15 @@ allowed = list(/obj/item/nullrod/claymore) armor = list(melee = 25, bullet = 5, laser = 5, energy = 5, bomb = 0, bio = 0, rad = 0) +/obj/item/clothing/suit/armor/vest/durathread + name = "durathread vest" + desc = "A vest made of durathread with strips of leather acting as trauma plates." + icon_state = "durathread" + item_state = "durathread" + strip_delay = 60 + burn_state = FLAMMABLE + armor = list(melee = 20, bullet = 10, laser = 30, energy = 5, bomb = 15, bio = 0, rad = 0) + /obj/item/clothing/suit/armor/bulletproof name = "Bulletproof Vest" desc = "A bulletproof vest that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent." @@ -528,14 +537,4 @@ item_state = "bonearmor" blood_overlay_type = "armor" armor = list(melee = 35, bullet = 25, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - -/obj/item/clothing/head/helmet/skull - name = "skull helmet" - desc = "An intimidating tribal helmet, it doesn't look very comfortable." - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE - flags_cover = HEADCOVERSEYES - armor = list(melee = 25, bullet = 25, laser = 25, energy = 10, bomb = 10, bio = 5, rad = 20) - icon_state = "skull" - item_state = "skull" - strip_delay = 100 \ No newline at end of file + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS \ No newline at end of file diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm index 5b2266bb53b..83f0fcfc211 100644 --- a/code/modules/clothing/suits/hood.dm +++ b/code/modules/clothing/suits/hood.dm @@ -2,44 +2,21 @@ /obj/item/clothing/suit/hooded actions_types = list(/datum/action/item_action/toggle) - var/obj/item/clothing/head/hood - var/hoodtype = /obj/item/clothing/head/winterhood //so the chaplain hoodie or other hoodies can override this + var/obj/item/clothing/head/hooded/hood + var/hoodtype = /obj/item/clothing/head/hooded/winterhood //so the chaplain hoodie or other hoodies can override this -/obj/item/clothing/head/chaplain_hood - flags = NODROP - -/obj/item/clothing/head/nun_hood - flags = NODROP - -/obj/item/clothing/head/monk_hood - flags = NODROP - -/obj/item/clothing/head/culthood - flags = NODROP - -/obj/item/clothing/head/culthood/alt - flags = NODROP - -/obj/item/clothing/head/berserkerhood - flags = NODROP - -/obj/item/clothing/head/hooded/drake - flags = NODROP - -/obj/item/clothing/head/hooded/goliath - flags = NODROP - -/obj/item/clothing/suit/hooded/New() +/obj/item/clothing/suit/hooded/Initialize(mapload) + . = ..() MakeHood() - ..() /obj/item/clothing/suit/hooded/Destroy() QDEL_NULL(hood) - return ..() + . = ..() /obj/item/clothing/suit/hooded/proc/MakeHood() if(!hood) - var/obj/item/clothing/head/W = new hoodtype(src) + var/obj/item/clothing/head/hooded/W = new hoodtype(src) + W.suit = src hood = W /obj/item/clothing/suit/hooded/ui_action_click() @@ -63,7 +40,7 @@ var/mob/living/carbon/H = hood.loc H.unEquip(hood, 1) H.update_inv_wear_suit() - hood.loc = src + hood.forceMove(src) for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() @@ -82,7 +59,7 @@ if(H.head) to_chat(H,"You're already wearing something on your head!") return - else if(H.equip_to_slot_if_possible(hood,slot_head,0,0,1)) + else if(H.equip_to_slot_if_possible(hood, slot_head, 0, 0, 1)) suit_adjusted = 1 icon_state = "[initial(icon_state)]_hood" H.update_inv_wear_suit() @@ -91,3 +68,23 @@ A.UpdateButtonIcon() else RemoveHood() + +/obj/item/clothing/head/hooded + var/obj/item/clothing/suit/hooded/suit + +/obj/item/clothing/head/hooded/Destroy() + suit = null + return ..() + +/obj/item/clothing/head/hooded/dropped() + ..() + if(suit) + suit.RemoveHood() + +/obj/item/clothing/head/hooded/equipped(mob/user, slot) + ..() + if(slot != slot_head) + if(suit) + suit.RemoveHood() + else + qdel(src) diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 06a3f35fa29..87b30fe01dc 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -30,7 +30,7 @@ "Vox" = 'icons/mob/species/vox/suit.dmi' ) -//Botonist +//Botanist /obj/item/clothing/suit/apron name = "apron" desc = "A basic blue apron." @@ -85,7 +85,7 @@ icon_state = "chaplain_hoodie" item_state = "chaplain_hoodie" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - hoodtype = /obj/item/clothing/head/chaplain_hood + hoodtype = /obj/item/clothing/head/hooded/chaplain_hood allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen) sprite_sheets = list( @@ -100,7 +100,7 @@ item_state = "nun" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS flags_inv = HIDESHOES|HIDEJUMPSUIT - hoodtype = /obj/item/clothing/head/nun_hood + hoodtype = /obj/item/clothing/head/hooded/nun_hood allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen) sprite_sheets = list( @@ -115,7 +115,7 @@ item_state = "monkrobe" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS flags_inv = HIDESHOES|HIDEJUMPSUIT - hoodtype = /obj/item/clothing/head/monk_hood + hoodtype = /obj/item/clothing/head/hooded/monk_hood allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen) /obj/item/clothing/suit/witchhunter @@ -364,6 +364,9 @@ "Vox" = 'icons/mob/species/vox/suit.dmi' ) +/obj/item/clothing/suit/suspenders/nodrop + flags = NODROP + // Surgeon /obj/item/clothing/suit/apron/surgical name = "surgical apron" @@ -371,7 +374,7 @@ icon_state = "surgical" item_state = "surgical" allowed = list(/obj/item/scalpel, /obj/item/surgical_drapes, /obj/item/cautery, /obj/item/hemostat, /obj/item/retractor) - + //Research Director /obj/item/clothing/suit/mantle/labcoat name = "research director's mantle" diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 25fa28931d3..56204c5d3c2 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -1,1006 +1,1017 @@ -/* - * Contains: - * Lasertag - * Costume - * Winter Coats - * Misc - */ - -/* - * Lasertag - */ -/obj/item/clothing/suit/bluetag - name = "blue laser tag armour" - desc = "Blue Pride, Station Wide." - icon_state = "bluetag" - item_state = "bluetag" - blood_overlay_type = "armor" - body_parts_covered = UPPER_TORSO|LOWER_TORSO - allowed = list (/obj/item/gun/energy/laser/tag/blue) - burn_state = FIRE_PROOF - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/redtag - name = "red laser tag armour" - desc = "Pew pew pew." - icon_state = "redtag" - item_state = "redtag" - blood_overlay_type = "armor" - body_parts_covered = UPPER_TORSO|LOWER_TORSO - allowed = list (/obj/item/gun/energy/laser/tag/red) - burn_state = FIRE_PROOF - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/* - * Costume - */ -/obj/item/clothing/suit/pirate_brown - name = "brown pirate coat" - desc = "Yarr." - icon_state = "pirate_old" - item_state = "pirate_old" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/pirate_black - name = "black pirate coat" - desc = "Yarr." - icon_state = "pirate" - item_state = "pirate" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/hgpirate - name = "pirate captain coat" - desc = "Yarr." - icon_state = "hgpirate" - item_state = "hgpirate" - flags_inv = HIDEJUMPSUIT - - -/obj/item/clothing/suit/cyborg_suit - name = "cyborg suit" - desc = "Suit for a cyborg costume." - icon_state = "death" - item_state = "death" - flags = CONDUCT - fire_resist = T0C+5200 - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - - -/obj/item/clothing/suit/greatcoat - name = "great coat" - desc = "A Nazi great coat." - icon_state = "nazi" - item_state = "nazi" - - -/obj/item/clothing/suit/johnny_coat - name = "johnny~~ coat" - desc = "Johnny~~" - icon_state = "johnny" - item_state = "johnny" - - -/obj/item/clothing/suit/justice - name = "justice suit" - desc = "this pretty much looks ridiculous" - icon_state = "justice" - item_state = "justice" - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - - -/obj/item/clothing/suit/judgerobe - name = "judge's robe" - desc = "This robe commands authority." - icon_state = "judge" - item_state = "judge" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - allowed = list(/obj/item/storage/fancy/cigarettes,/obj/item/stack/spacecash) - flags_inv = HIDEJUMPSUIT - - -/obj/item/clothing/suit/wcoat - name = "waistcoat" - desc = "For some classy, murderous fun." - icon_state = "vest" - item_state = "wcoat" - blood_overlay_type = "armor" - body_parts_covered = UPPER_TORSO|LOWER_TORSO - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/apron/overalls - name = "coveralls" - desc = "A set of denim overalls." - icon_state = "overalls" - item_state = "overalls" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS - - -/obj/item/clothing/suit/syndicatefake - name = "black and red space suit replica" - icon_state = "syndicate-black-red" - item_state = "syndicate-black-red" - desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!" - w_class = WEIGHT_CLASS_NORMAL - allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy) - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - burn_state = FIRE_PROOF - - -/obj/item/clothing/suit/hastur - name = "Hastur's robes" - desc = "Robes not meant to be worn by man." - icon_state = "hastur" - item_state = "hastur" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - - -/obj/item/clothing/suit/imperium_monk - name = "imperium monk" - desc = "Have YOU killed a xeno today?" - icon_state = "imperium_monk" - item_state = "imperium_monk" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - flags_inv = HIDESHOES|HIDEJUMPSUIT - allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen) - -/obj/item/clothing/suit/chickensuit - name = "chicken suit" - desc = "A suit made long ago by the ancient empire KFC." - icon_state = "chickensuit" - item_state = "chickensuit" - body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET - flags_inv = HIDESHOES|HIDEJUMPSUIT - -/obj/item/clothing/suit/corgisuit - name = "corgi suit" - desc = "A suit made long ago by the ancient empire KFC." - icon_state = "corgisuit" - item_state = "chickensuit" - body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET - flags_inv = HIDESHOES|HIDEJUMPSUIT - -/obj/item/clothing/suit/corgisuit/super_hero - name = "super-hero corgi suit" - desc = "A suit made long ago by the ancient empire KFC. This one pulses with a strange power." - flags = NODROP - -/obj/item/clothing/suit/corgisuit/super_hero/en - name = "\improper super-hero E-N suit" - icon_state = "ensuit" - -/obj/item/clothing/suit/corgisuit/super_hero/en/New() - ..() - START_PROCESSING(SSobj, src) - -/obj/item/clothing/suit/corgisuit/super_hero/en/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/clothing/suit/corgisuit/super_hero/en/process() - if(prob(2)) - for(var/obj/M in orange(2,src)) - if(!M.anchored && (M.flags & CONDUCT)) - step_towards(M,src) - for(var/mob/living/silicon/S in orange(2,src)) - if(istype(S, /mob/living/silicon/ai)) continue - step_towards(S,src) - for(var/mob/living/carbon/human/machine/M in orange(2,src)) - step_towards(M,src) - -/obj/item/clothing/suit/monkeysuit - name = "monkey suit" - desc = "A suit that looks like a primate" - icon_state = "monkeysuit" - item_state = "monkeysuit" - body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET|HANDS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - - -/obj/item/clothing/suit/holidaypriest - name = "holiday priest" - desc = "This is a nice holiday my son." - icon_state = "holidaypriest" - item_state = "holidaypriest" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - flags_inv = HIDEJUMPSUIT - allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen) - -/obj/item/clothing/suit/cardborg - name = "cardborg suit" - desc = "An ordinary cardboard box with holes cut in the sides." - icon_state = "cardborg" - item_state = "cardborg" - body_parts_covered = UPPER_TORSO|LOWER_TORSO - flags_inv = HIDEJUMPSUIT - species_disguise = "High-tech robot" - -/obj/item/clothing/suit/cardborg/equipped(mob/living/user, slot) - ..() - if(slot == slot_wear_suit) - disguise(user) - -/obj/item/clothing/suit/cardborg/dropped(mob/living/user) - ..() - user.remove_alt_appearance("standard_borg_disguise") - -/obj/item/clothing/suit/cardborg/proc/disguise(mob/living/carbon/human/H, obj/item/clothing/head/cardborg/borghead) - if(istype(H)) - if(!borghead) - borghead = H.head - if(istype(borghead, /obj/item/clothing/head/cardborg)) //why is this done this way? because equipped() is called BEFORE THE ITEM IS IN THE SLOT WHYYYY - var/image/I = image(icon = 'icons/mob/robots.dmi' , icon_state = "robot", loc = H) - I.override = 1 - I.overlays += image(icon = 'icons/mob/robots.dmi' , icon_state = "eyes-robot") //gotta look realistic - H.add_alt_appearance("standard_borg_disguise", I, GLOB.silicon_mob_list+H) //you look like a robot to robots! (including yourself because you're totally a robot) - -/obj/item/clothing/suit/snowman - name = "snowman outfit" - desc = "Two white spheres covered in white glitter. 'Tis the season." - icon_state = "snowman" - item_state = "snowman" - body_parts_covered = UPPER_TORSO|LOWER_TORSO - flags_inv = HIDEJUMPSUIT - -/obj/item/clothing/suit/poncho - name = "poncho" - desc = "Your classic, non-racist poncho." - icon_state = "classicponcho" - item_state = "classicponcho" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/poncho/green - name = "green poncho" - desc = "Your classic, non-racist poncho. This one is green." - icon_state = "greenponcho" - item_state = "greenponcho" - -/obj/item/clothing/suit/poncho/red - name = "red poncho" - desc = "Your classic, non-racist poncho. This one is red." - icon_state = "redponcho" - item_state = "redponcho" - -/obj/item/clothing/suit/poncho/ponchoshame - name = "poncho of shame" - desc = "Forced to live on your shameful acting as a fake Mexican, you and your poncho have grown inseperable. Literally." - icon_state = "ponchoshame" - item_state = "ponchoshame" - flags = NODROP - -/obj/item/clothing/suit/hooded/carp_costume - name = "carp costume" - desc = "A costume made from 'synthetic' carp scales, it smells." - icon_state = "carp_casual" - item_state = "labcoat" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Space carp like space, so you should too - allowed = list(/obj/item/tank/emergency_oxygen) - hoodtype = /obj/item/clothing/head/hooded/carp_hood - -/obj/item/clothing/head/hooded/carp_hood - name = "carp hood" - desc = "A hood attached to a carp costume." - icon_state = "carp_casual" - body_parts_covered = HEAD - cold_protection = HEAD - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - flags = NODROP|BLOCKHAIR - flags_inv = HIDEEARS - -/obj/item/clothing/suit/hooded/bee_costume // It's Hip! - name = "bee costume" - desc = "Bee the true Queen!" - icon_state = "bee" - item_state = "labcoat" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - flags = THICKMATERIAL - hoodtype = /obj/item/clothing/head/hooded/bee_hood - -/obj/item/clothing/head/hooded/bee_hood - name = "bee hood" - desc = "A hood attached to a bee costume." - icon_state = "bee" - body_parts_covered = HEAD - flags = THICKMATERIAL|NODROP|BLOCKHAIR - flags_inv = HIDEEARS - -/obj/item/clothing/suit/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!? - name = "bloated human suit" - desc = "A horribly bloated suit made from human skins." - icon_state = "lingspacesuit" - item_state = "lingspacesuit" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - -/obj/item/clothing/suit/draculacoat // Bleh! - name = "transylvanian coat" - desc = "What is a spessman? A miserable little pile of secrets." - icon_state = "draculacoat" - item_state = "draculacoat" - -/* - * Winter Coats - */ - -/obj/item/clothing/suit/hooded/wintercoat - name = "winter coat" - desc = "A heavy jacket made from 'synthetic' animal furs." - icon_state = "wintercoat" - item_state = "coatwinter" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0) - allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - - sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi') - -/obj/item/clothing/head/winterhood - name = "winter hood" - desc = "A hood attached to a heavy winter jacket." - icon_state = "winterhood" - body_parts_covered = HEAD - cold_protection = HEAD - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - flags = NODROP|BLOCKHAIR - flags_inv = HIDEEARS - - sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi') - -/obj/item/clothing/suit/hooded/wintercoat/captain - name = "captain's winter coat" - icon_state = "wintercoat_captain" - item_state = "coatcaptain" - armor = list(melee = 25, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0) - allowed = list(/obj/item/gun/energy, /obj/item/reagent_containers/spray/pepper, /obj/item/gun/projectile, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic) - hoodtype = /obj/item/clothing/head/winterhood/captain - -/obj/item/clothing/head/winterhood/captain - icon_state = "winterhood_captain" - -/obj/item/clothing/suit/hooded/wintercoat/security - name = "security winter coat" - icon_state = "wintercoat_sec" - item_state = "coatsecurity" - armor = list(melee = 10, bullet = 10, laser = 10, energy = 5, bomb = 15, bio = 0, rad = 0) - allowed = list(/obj/item/gun/energy, /obj/item/reagent_containers/spray/pepper, /obj/item/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic) - hoodtype = /obj/item/clothing/head/winterhood/security - -/obj/item/clothing/head/winterhood/security - icon_state = "winterhood_sec" - -/obj/item/clothing/suit/hooded/wintercoat/medical - name = "medical winter coat" - icon_state = "wintercoat_med" - item_state = "coatmedical" - allowed = list(/obj/item/analyzer, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer,/obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic) - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 50, rad = 0) - hoodtype = /obj/item/clothing/head/winterhood/medical - -/obj/item/clothing/head/winterhood/medical - icon_state = "winterhood_med" - -/obj/item/clothing/suit/hooded/wintercoat/science - name = "science winter coat" - icon_state = "wintercoat_sci" - item_state = "coatscience" - allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer,/obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic) - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 10, bio = 0, rad = 0) - hoodtype = /obj/item/clothing/head/winterhood/science - -/obj/item/clothing/head/winterhood/science - icon_state = "winterhood_sci" - -/obj/item/clothing/suit/hooded/wintercoat/engineering - name = "engineering winter coat" - icon_state = "wintercoat_engi" - item_state = "coatengineer" - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 20) - allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/t_scanner, /obj/item/rcd) - hoodtype = /obj/item/clothing/head/winterhood/engineering - -/obj/item/clothing/head/winterhood/engineering - icon_state = "winterhood_engi" - -/obj/item/clothing/suit/hooded/wintercoat/engineering/atmos - name = "atmospherics winter coat" - icon_state = "wintercoat_atmos" - item_state = "coatatmos" - hoodtype = /obj/item/clothing/head/winterhood/engineering/atmos - -/obj/item/clothing/head/winterhood/engineering/atmos - icon_state = "winterhood_atmos" - -/obj/item/clothing/suit/hooded/wintercoat/hydro - name = "hydroponics winter coat" - icon_state = "wintercoat_hydro" - item_state = "coathydro" - allowed = list(/obj/item/reagent_containers/spray, /obj/item/plant_analyzer, /obj/item/seeds, /obj/item/reagent_containers/glass/bottle, /obj/item/hatchet, /obj/item/storage/bag/plants) - hoodtype = /obj/item/clothing/head/winterhood/hydro - -/obj/item/clothing/head/winterhood/hydro - icon_state = "winterhood_hydro" - -/obj/item/clothing/suit/hooded/wintercoat/cargo - name = "cargo winter coat" - icon_state = "wintercoat_cargo" - item_state = "coatcargo" - hoodtype = /obj/item/clothing/head/winterhood/cargo - -/obj/item/clothing/head/winterhood/cargo - icon_state = "winterhood_cargo" - -/obj/item/clothing/suit/hooded/wintercoat/miner - name = "mining winter coat" - icon_state = "wintercoat_miner" - item_state = "coatminer" - allowed = list(/obj/item/pickaxe, /obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) - hoodtype = /obj/item/clothing/head/winterhood/miner - -/obj/item/clothing/head/winterhood/miner - icon_state = "winterhood_miner" - - -/* - * Misc - */ - -//hoodies -/obj/item/clothing/suit/hooded/hoodie - name = "black hoodie" - desc = "It's a hoodie. It has a hood. Most hoodies do." - icon_state = "black_hoodie" - item_state = "blueshieldcoat" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen) - hoodtype = /obj/item/clothing/head/hood - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/head/hood - name = "black hood" - desc = "A hood attached to a hoodie." - icon_state = "blackhood" - body_parts_covered = HEAD - cold_protection = HEAD - flags = NODROP|BLOCKHAIR - flags_inv = HIDEEARS - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/head.dmi' - ) - -/obj/item/clothing/head/hood/blue - icon_state = "bluehood" - -/obj/item/clothing/head/hood/white - icon_state = "whitehood" - -/obj/item/clothing/suit/hooded/hoodie/blue - name = "blue hoodie" - icon_state = "blue_hoodie" - hoodtype = /obj/item/clothing/head/hood/blue - -/obj/item/clothing/suit/hooded/hoodie/mit - name = "Martian Institute of Technology hoodie" - desc = "A hoodie proudly worn by students and graduates alike, has the letters 'MIT' on the back." - icon_state = "mit_hoodie" - hoodtype = /obj/item/clothing/head/hood - -/obj/item/clothing/suit/hooded/hoodie/cut - name = "Canaan University of Technology hoodie" - desc = "A bright hoodie with the Canaan University of Technology logo on the front." - icon_state = "cut_hoodie" - hoodtype = /obj/item/clothing/head/hood/white - -/obj/item/clothing/suit/hooded/hoodie/lam - name = "Lunar Academy of Medicine hoodie" - desc = "A bright hoodie with the Lunar Academy of Medicine logo on the back." - icon_state = "lam_hoodie" - hoodtype = /obj/item/clothing/head/hood/white - -/obj/item/clothing/suit/hooded/hoodie/nt - name = "Nanotrasen hoodie" - desc = "A blue hoodie with the Nanotrasen logo on the back." - icon_state = "nt_hoodie" - hoodtype = /obj/item/clothing/head/hood/blue - -/obj/item/clothing/suit/hooded/hoodie/tp - name = "Tharsis Polytech hoodie" - desc = "A dark hoodie with the Tharsis Polytech logo on the back." - icon_state = "tp_hoodie" - hoodtype = /obj/item/clothing/head/hood - -/obj/item/clothing/suit/straight_jacket - name = "straight jacket" - desc = "A suit that completely restrains the wearer." - icon_state = "straight_jacket" - item_state = "straight_jacket" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL - flags_size = ONESIZEFITSALL - strip_delay = 60 - breakouttime = 3000 - -/obj/item/clothing/suit/ianshirt - name = "worn shirt" - desc = "A worn out, curiously comfortable t-shirt with a picture of Ian. You wouldn't go so far as to say it feels like being hugged when you wear it but it's pretty close. Good for sleeping in." - icon_state = "ianshirt" - item_state = "ianshirt" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - - - -//pyjamas -//originally intended to be pinstripes >.> - -/obj/item/clothing/under/bluepyjamas - name = "blue pyjamas" - desc = "Slightly old-fashioned sleepwear." - icon_state = "blue_pyjamas" - item_state = "blue_pyjamas" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS - -/obj/item/clothing/under/redpyjamas - name = "red pyjamas" - desc = "Slightly old-fashioned sleepwear." - icon_state = "red_pyjamas" - item_state = "red_pyjamas" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS - -//coats - -/obj/item/clothing/suit/leathercoat - name = "leather coat" - desc = "A long, thick black leather coat." - icon_state = "leathercoat" - item_state = "leathercoat" - burn_state = FIRE_PROOF - -/obj/item/clothing/suit/browncoat - name = "brown leather coat" - desc = "A long, brown leather coat." - icon_state = "browncoat" - item_state = "browncoat" - -/obj/item/clothing/suit/neocoat - name = "black coat" - desc = "A flowing, black coat." - icon_state = "neocoat" - item_state = "neocoat" - -/obj/item/clothing/suit/browntrenchcoat - name = "brown trench coat" - desc = "It makes you stand out. Just the opposite of why it's typically worn. Nice try trying to blend in while wearing it." - icon_state = "brtrenchcoat" - item_state = "brtrenchcoat" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/blacktrenchcoat - name = "black trench coat" - desc = "That shade of black just makes you look a bit more evil. Good for those mafia types." - icon_state = "bltrenchcoat" - item_state = "bltrenchcoat" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -//trackjackets - -/obj/item/clothing/suit/tracksuit - name = "black tracksuit" - desc = "Lightweight and stylish. What else could a man ask of his tracksuit?" - icon_state = "trackjacket_open" - item_state = "bltrenchcoat" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - ignore_suitadjust = 0 - suit_adjusted = 1 - actions_types = list(/datum/action/item_action/openclose) - adjust_flavour = "unzip" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/tracksuit/green - name = "green tracksuit" - icon_state = "trackjacketgreen_open" - -/obj/item/clothing/suit/tracksuit/red - name = "red tracksuit" - icon_state = "trackjacketred_open" - -/obj/item/clothing/suit/tracksuit/white - name = "white tracksuit" - icon_state = "trackjacketwhite_open" - -//actual suits - -/obj/item/clothing/suit/creamsuit - name = "cream suit" - desc = "A cream coloured, genteel suit." - icon_state = "creamsuit" - item_state = "creamsuit" - -/obj/item/clothing/under/stripper/mankini - name = "the mankini" - desc = "No honest man would wear this abomination" - icon_state = "mankini" - item_color = "mankini" - -/obj/item/clothing/suit/jacket/miljacket - name = "olive military jacket" - desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in olive." - icon_state = "militaryjacket" - item_state = "militaryjacket" - ignore_suitadjust = 1 - actions_types = list() - adjust_flavour = null - allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter,/obj/item/gun/projectile/automatic/pistol,/obj/item/gun/projectile/revolver,/obj/item/gun/projectile/revolver/detective) - -/obj/item/clothing/suit/jacket/miljacket/navy - name = "navy military jacket" - desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in navy blue." - icon_state = "navy_jacket" - -/obj/item/clothing/suit/jacket/miljacket/desert - name = "desert military jacket" - desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in desert beige." - icon_state = "desert_jacket" - -/obj/item/clothing/suit/jacket/miljacket/white - name = "white military jacket" - desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in snow white." - icon_state = "white_jacket" - -/obj/item/clothing/suit/xenos - name = "xenos suit" - desc = "A suit made out of chitinous alien hide." - icon_state = "xenos" - item_state = "xenos_helm" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - flags_size = ONESIZEFITSALL - -//swimsuit -/obj/item/clothing/under/swimsuit/ - -/obj/item/clothing/under/swimsuit/black - name = "black swimsuit" - desc = "An oldfashioned black swimsuit." - icon_state = "swim_black" - item_color = "swim_black" - -/obj/item/clothing/under/swimsuit/blue - name = "blue swimsuit" - desc = "An oldfashioned blue swimsuit." - icon_state = "swim_blue" - item_color = "swim_blue" - -/obj/item/clothing/under/swimsuit/purple - name = "purple swimsuit" - desc = "An oldfashioned purple swimsuit." - icon_state = "swim_purp" - item_color = "swim_purp" - -/obj/item/clothing/under/swimsuit/green - name = "green swimsuit" - desc = "An oldfashioned green swimsuit." - icon_state = "swim_green" - item_color = "swim_green" - -/obj/item/clothing/under/swimsuit/red - name = "red swimsuit" - desc = "An oldfashioned red swimsuit." - icon_state = "swim_red" - item_color = "swim_red" - -/obj/item/clothing/suit/storage/mercy_hoodie - name = "mercy robe" - desc = "A soft white robe made of a synthetic fiber that provides improved protection against biohazards. Possessing multiple overlapping layers, yet light enough to allow complete freedom of movement, it denotes its wearer as a master physician." - icon_state = "mercy_hoodie" - item_state = "mercy_hoodie" - w_class = WEIGHT_CLASS_BULKY - gas_transfer_coefficient = 0.01 - permeability_coefficient = 0.01 - flags_size = ONESIZEFITSALL - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - allowed = list(/obj/item/tank/emergency_oxygen,/obj/item/pen,/obj/item/flashlight/pen) - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL - -/obj/item/clothing/head/mercy_hood - name = "Mercy Hood" - desc = "A soft white hood made of a synthetic fiber that provides improved protection against biohazards. Its elegant design allows a clear field of vision." - icon_state = "mercy_hood" - item_state = "mercy_hood" - permeability_coefficient = 0.01 - flags = BLOCKHAIR - flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES - -/obj/item/clothing/suit/jacket - name = "bomber jacket" - desc = "Aviators not included." - icon_state = "bomber" - item_state = "bomber" - ignore_suitadjust = 0 - allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter) - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS - actions_types = list(/datum/action/item_action/zipper) - adjust_flavour = "unzip" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/jacket/pilot - name = "security bomber jacket" - desc = "A stylish and worn-in armoured black bomber jacket emblazoned with the NT Security crest on the left breast. Looks rugged." - icon_state = "bombersec" - item_state = "bombersec" - ignore_suitadjust = 0 - //Inherited from Security armour. - allowed = list(/obj/item/gun/energy,/obj/item/reagent_containers/spray/pepper,/obj/item/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/flashlight/seclite,/obj/item/melee/classic_baton/telescopic,/obj/item/kitchen/knife/combat) - heat_protection = UPPER_TORSO|LOWER_TORSO - min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT - max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT - strip_delay = 60 - put_on_delay = 40 - flags_size = ONESIZEFITSALL - armor = list(melee = 25, bullet = 15, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) - //End of inheritance from Security armour. - -/obj/item/clothing/suit/jacket/leather - name = "leather jacket" - desc = "Pompadour not included." - icon_state = "leatherjacket" - ignore_suitadjust = 1 - actions_types = list() - adjust_flavour = null - burn_state = FIRE_PROOF - -/obj/item/clothing/suit/jacket/leather/overcoat - name = "leather overcoat" - desc = "That's a damn fine coat." - icon_state = "leathercoat" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS - cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS - -/obj/item/clothing/suit/officercoat - name = "Clown Officer's Coat" - desc = "A classy clown officer's overcoat, also designed by Hugo Boss." - icon_state = "officersuit" - item_state = "officersuit" - ignore_suitadjust = 0 - actions_types = list(/datum/action/item_action/button) - adjust_flavour = "unbutton" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/soldiercoat - name = "Clown Soldier's Coat" - desc = "An overcoat for the clown soldier, to keep him warm during those cold winter nights on the front." - icon_state = "soldiersuit" - item_state = "soldiersuit" - ignore_suitadjust = 0 - actions_types = list(/datum/action/item_action/button) - adjust_flavour = "unbutton" - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' - ) - -/obj/item/clothing/suit/toggle/owlwings - name = "owl cloak" - desc = "A soft brown cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive the ladies mad." - icon_state = "owl_wings" - item_state = "owl_wings" - body_parts_covered = ARMS - armor = list(melee = 5, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) - allowed = list(/obj/item/gun/energy,/obj/item/reagent_containers/spray/pepper,/obj/item/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/flashlight/seclite) - actions_types = list(/datum/action/item_action/toggle_wings) - - -/obj/item/clothing/suit/toggle/owlwings/griffinwings - name = "griffon cloak" - desc = "A plush white cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive your captives mad." - icon_state = "griffin_wings" - item_state = "griffin_wings" - -/obj/item/clothing/suit/toggle/attack_self() - if(icon_state == initial(icon_state)) - icon_state = icon_state + "_t" - item_state = icon_state + "_t" - else - icon_state = initial(icon_state) - item_state = initial(item_state) - usr.update_inv_wear_suit() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/clothing/suit/lordadmiral - name = "Lord Admiral's Coat" - desc = "You'll be the Ruler of the King's Navy in no time." - icon_state = "lordadmiral" - item_state = "lordadmiral" - allowed = list (/obj/item/gun) - -/obj/item/clothing/suit/fluff/noble_coat - name = "noble coat" - desc = "The livid blues, purples and greens are awesome enough to evoke a visceral response in you; it is not dissimilar to indigestion." - icon_state = "noble_coat" - item_state = "noble_coat" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - - -///Advanced Protective Suit, AKA, God Mode in wearable form. - -/obj/item/clothing/suit/advanced_protective_suit - name = "Advanced Protective Suit" - desc = "An incredibly advanced and complex suit; it has so many buttons and dials as to be incomprehensible." - icon_state = "bomb" - item_state = "bomb" - actions_types = list(/datum/action/item_action/toggle) - gas_transfer_coefficient = 0.01 - permeability_coefficient = 0.01 - flags = STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|HEAD - armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100) - cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD - min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - heat_protection = UPPER_TORSO | LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - slowdown = -10 - siemens_coefficient = 0 - var/on = 0 - -/obj/item/clothing/suit/advanced_protective_suit/Destroy() - if(on) - on = 0 - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/clothing/suit/advanced_protective_suit/ui_action_click() - if(on) - on = 0 - to_chat(usr, "You turn the suit's special processes off.") - else - on = 1 - to_chat(usr, "You turn the suit's special processes on.") - START_PROCESSING(SSobj, src) - - -/obj/item/clothing/suit/advanced_protective_suit/IsReflect() - return (on) - -/obj/item/clothing/suit/advanced_protective_suit/process() - if(on) - var/mob/living/carbon/human/user = src.loc - if(user && ishuman(user) && (user.wear_suit == src)) - if(user.reagents.get_reagent_amount("stimulants") < 15) - user.reagents.add_reagent("stimulants", 15) - if(user.reagents.get_reagent_amount("adminordrazine") < 15) - user.reagents.add_reagent("adminordrazine", 15) - if(user.reagents.get_reagent_amount("nanites") < 15) - user.reagents.add_reagent("nanites", 15) - if(user.reagents.get_reagent_amount("syndicate_nanites") < 15) - user.reagents.add_reagent("syndicate_nanites", 15) - else - STOP_PROCESSING(SSobj, src) - -//Syndicate Chaplain Robe (WOLOLO!) -/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe - description_antag = "This robe is made of reinforced fibers, granting it superior protection. The robes also wirelessly generate power for the neurotransmitter in the linked missionary staff while being worn." - armor = list(melee = 10, bullet = 10, laser = 5, energy = 5, bomb = 0, bio = 0, rad = 15) - var/obj/item/nullrod/missionary_staff/linked_staff = null - -/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/Destroy() - if(linked_staff) //delink on destruction - linked_staff.robes = null - linked_staff = null - STOP_PROCESSING(SSobj, src) //probably is cleared in a parent call already, but just in case we're gonna do it here - return ..() - -/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/equipped(mob/living/carbon/human/H, slot) - if(!istype(H) || slot != slot_wear_suit) - STOP_PROCESSING(SSobj, src) - return - else - START_PROCESSING(SSobj, src) - -/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/process() - if(!linked_staff) //if we don't have a linked staff, the rest of this is useless - return - - if(!ishuman(loc)) //if we somehow try to process while not on a human, remove ourselves from processing and return - STOP_PROCESSING(SSobj, src) - return - - var/mob/living/carbon/human/H = loc - - if(linked_staff.faith >= 100) //if the linked staff is fully recharged, do nothing - return - - if(!linked_staff in range(3, get_turf(src))) //staff won't charge at range (to prevent it from being handed off / stolen and used) - if(prob(10)) //10% chance per process should avoid being too spammy, can tweak if it ends up still being too frequent. - to_chat(H, "Your staff is unable to charge at this range. Get closer!") - return - - linked_staff.faith += 5 - if(linked_staff.faith >= 100) //if this charge puts the staff at or above full, notify the wearer - to_chat(H, "Faith renewed; ready to convert new followers.") - -/obj/item/clothing/suit/tailcoat - name = "victorian tailcoat" - desc = "A fancy victorian tailcoat." - icon_state = "tailcoat" - item_state = "tailcoat" - -/obj/item/clothing/suit/victcoat - name = "ladies victorian coat" - desc = "A fancy victorian coat." - icon_state = "ladiesvictoriancoat" - item_state = "ladiesvictoriancoat" - -/obj/item/clothing/suit/victcoat/red - name = "ladies red victorian coat" - icon_state = "ladiesredvictoriancoat" - item_state = "ladiesredvictoriancoat" - -//Mantles! -/obj/item/clothing/suit/mantle - name = "mantle" - desc = "A heavy quilted mantle, for keeping your shoulders warm and stylish." - icon_state = "mantle" - item_state = "mantle" - body_parts_covered = UPPER_TORSO|ARMS - cold_protection = UPPER_TORSO|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - -/obj/item/clothing/suit/mantle/regal - name = "regal shawl" - desc = "A fancy shawl for nobility, made from high quality materials." - icon_state = "regal_mantle" - item_state = "regal_mantle" - -/obj/item/clothing/suit/mantle/old - name = "old wrap" - desc = "A tattered fabric wrap, faded over the years. Smells faintly of cigars." - icon_state = "old_mantle" - item_state = "old_mantle" - +/* + * Contains: + * Lasertag + * Costume + * Winter Coats + * Misc + */ + +/* + * Lasertag + */ +/obj/item/clothing/suit/bluetag + name = "blue laser tag armour" + desc = "Blue Pride, Station Wide." + icon_state = "bluetag" + item_state = "bluetag" + blood_overlay_type = "armor" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + allowed = list (/obj/item/gun/energy/laser/tag/blue) + burn_state = FIRE_PROOF + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/redtag + name = "red laser tag armour" + desc = "Pew pew pew." + icon_state = "redtag" + item_state = "redtag" + blood_overlay_type = "armor" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + allowed = list (/obj/item/gun/energy/laser/tag/red) + burn_state = FIRE_PROOF + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/* + * Costume + */ +/obj/item/clothing/suit/pirate_brown + name = "brown pirate coat" + desc = "Yarr." + icon_state = "pirate_old" + item_state = "pirate_old" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/pirate_black + name = "black pirate coat" + desc = "Yarr." + icon_state = "pirate" + item_state = "pirate" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/hgpirate + name = "pirate captain coat" + desc = "Yarr." + icon_state = "hgpirate" + item_state = "hgpirate" + flags_inv = HIDEJUMPSUIT + + +/obj/item/clothing/suit/cyborg_suit + name = "cyborg suit" + desc = "Suit for a cyborg costume." + icon_state = "death" + item_state = "death" + flags = CONDUCT + fire_resist = T0C+5200 + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + + +/obj/item/clothing/suit/greatcoat + name = "great coat" + desc = "A Nazi great coat." + icon_state = "nazi" + item_state = "nazi" + + +/obj/item/clothing/suit/johnny_coat + name = "johnny~~ coat" + desc = "Johnny~~" + icon_state = "johnny" + item_state = "johnny" + + +/obj/item/clothing/suit/justice + name = "justice suit" + desc = "this pretty much looks ridiculous" + icon_state = "justice" + item_state = "justice" + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + + +/obj/item/clothing/suit/judgerobe + name = "judge's robe" + desc = "This robe commands authority." + icon_state = "judge" + item_state = "judge" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + allowed = list(/obj/item/storage/fancy/cigarettes,/obj/item/stack/spacecash) + flags_inv = HIDEJUMPSUIT + + +/obj/item/clothing/suit/wcoat + name = "waistcoat" + desc = "For some classy, murderous fun." + icon_state = "vest" + item_state = "wcoat" + blood_overlay_type = "armor" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/apron/overalls + name = "coveralls" + desc = "A set of denim overalls." + icon_state = "overalls" + item_state = "overalls" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS + + +/obj/item/clothing/suit/syndicatefake + name = "black and red space suit replica" + icon_state = "syndicate-black-red" + item_state = "syndicate-black-red" + desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!" + w_class = WEIGHT_CLASS_NORMAL + allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy) + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + burn_state = FIRE_PROOF + + +/obj/item/clothing/suit/hastur + name = "Hastur's robes" + desc = "Robes not meant to be worn by man." + icon_state = "hastur" + item_state = "hastur" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + + +/obj/item/clothing/suit/imperium_monk + name = "imperium monk" + desc = "Have YOU killed a xeno today?" + icon_state = "imperium_monk" + item_state = "imperium_monk" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + flags_inv = HIDESHOES|HIDEJUMPSUIT + allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen) + +/obj/item/clothing/suit/chickensuit + name = "chicken suit" + desc = "A suit made long ago by the ancient empire KFC." + icon_state = "chickensuit" + item_state = "chickensuit" + body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET + flags_inv = HIDESHOES|HIDEJUMPSUIT + +/obj/item/clothing/suit/corgisuit + name = "corgi suit" + desc = "A suit made long ago by the ancient empire KFC." + icon_state = "corgisuit" + item_state = "chickensuit" + body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET + flags_inv = HIDESHOES|HIDEJUMPSUIT + +/obj/item/clothing/suit/corgisuit/super_hero + name = "super-hero corgi suit" + desc = "A suit made long ago by the ancient empire KFC. This one pulses with a strange power." + flags = NODROP + +/obj/item/clothing/suit/corgisuit/super_hero/en + name = "\improper super-hero E-N suit" + icon_state = "ensuit" + +/obj/item/clothing/suit/corgisuit/super_hero/en/New() + ..() + START_PROCESSING(SSobj, src) + +/obj/item/clothing/suit/corgisuit/super_hero/en/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/clothing/suit/corgisuit/super_hero/en/process() + if(prob(2)) + for(var/obj/M in orange(2,src)) + if(!M.anchored && (M.flags & CONDUCT)) + step_towards(M,src) + for(var/mob/living/silicon/S in orange(2,src)) + if(istype(S, /mob/living/silicon/ai)) continue + step_towards(S,src) + for(var/mob/living/carbon/human/machine/M in orange(2,src)) + step_towards(M,src) + +/obj/item/clothing/suit/monkeysuit + name = "monkey suit" + desc = "A suit that looks like a primate" + icon_state = "monkeysuit" + item_state = "monkeysuit" + body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET|HANDS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + + +/obj/item/clothing/suit/holidaypriest + name = "holiday priest" + desc = "This is a nice holiday my son." + icon_state = "holidaypriest" + item_state = "holidaypriest" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + flags_inv = HIDEJUMPSUIT + allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen) + +/obj/item/clothing/suit/cardborg + name = "cardborg suit" + desc = "An ordinary cardboard box with holes cut in the sides." + icon_state = "cardborg" + item_state = "cardborg" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + flags_inv = HIDEJUMPSUIT + species_disguise = "High-tech robot" + +/obj/item/clothing/suit/cardborg/equipped(mob/living/user, slot) + ..() + if(slot == slot_wear_suit) + disguise(user) + +/obj/item/clothing/suit/cardborg/dropped(mob/living/user) + ..() + user.remove_alt_appearance("standard_borg_disguise") + +/obj/item/clothing/suit/cardborg/proc/disguise(mob/living/carbon/human/H, obj/item/clothing/head/cardborg/borghead) + if(istype(H)) + if(!borghead) + borghead = H.head + if(istype(borghead, /obj/item/clothing/head/cardborg)) //why is this done this way? because equipped() is called BEFORE THE ITEM IS IN THE SLOT WHYYYY + var/image/I = image(icon = 'icons/mob/robots.dmi' , icon_state = "robot", loc = H) + I.override = 1 + I.overlays += image(icon = 'icons/mob/robots.dmi' , icon_state = "eyes-robot") //gotta look realistic + H.add_alt_appearance("standard_borg_disguise", I, GLOB.silicon_mob_list+H) //you look like a robot to robots! (including yourself because you're totally a robot) + +/obj/item/clothing/suit/snowman + name = "snowman outfit" + desc = "Two white spheres covered in white glitter. 'Tis the season." + icon_state = "snowman" + item_state = "snowman" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + flags_inv = HIDEJUMPSUIT + +/obj/item/clothing/suit/poncho + name = "poncho" + desc = "Your classic, non-racist poncho." + icon_state = "classicponcho" + item_state = "classicponcho" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/poncho/green + name = "green poncho" + desc = "Your classic, non-racist poncho. This one is green." + icon_state = "greenponcho" + item_state = "greenponcho" + +/obj/item/clothing/suit/poncho/red + name = "red poncho" + desc = "Your classic, non-racist poncho. This one is red." + icon_state = "redponcho" + item_state = "redponcho" + +/obj/item/clothing/suit/poncho/ponchoshame + name = "poncho of shame" + desc = "Forced to live on your shameful acting as a fake Mexican, you and your poncho have grown inseperable. Literally." + icon_state = "ponchoshame" + item_state = "ponchoshame" + flags = NODROP + +/obj/item/clothing/suit/hooded/carp_costume + name = "carp costume" + desc = "A costume made from 'synthetic' carp scales, it smells." + icon_state = "carp_casual" + item_state = "labcoat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Space carp like space, so you should too + allowed = list(/obj/item/tank/emergency_oxygen) + hoodtype = /obj/item/clothing/head/hooded/carp_hood + +/obj/item/clothing/head/hooded/carp_hood + name = "carp hood" + desc = "A hood attached to a carp costume." + icon_state = "carp_casual" + body_parts_covered = HEAD + cold_protection = HEAD + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + flags = BLOCKHAIR + flags_inv = HIDEEARS + +/obj/item/clothing/suit/hooded/bee_costume // It's Hip! + name = "bee costume" + desc = "Bee the true Queen!" + icon_state = "bee" + item_state = "labcoat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + flags = THICKMATERIAL + hoodtype = /obj/item/clothing/head/hooded/bee_hood + +/obj/item/clothing/head/hooded/bee_hood + name = "bee hood" + desc = "A hood attached to a bee costume." + icon_state = "bee" + body_parts_covered = HEAD + flags = THICKMATERIAL|BLOCKHAIR + flags_inv = HIDEEARS + +/obj/item/clothing/suit/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!? + name = "bloated human suit" + desc = "A horribly bloated suit made from human skins." + icon_state = "lingspacesuit" + item_state = "lingspacesuit" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + +/obj/item/clothing/suit/draculacoat // Bleh! + name = "transylvanian coat" + desc = "What is a spessman? A miserable little pile of secrets." + icon_state = "draculacoat" + item_state = "draculacoat" + +/* + * Winter Coats + */ + +/obj/item/clothing/suit/hooded/wintercoat + name = "winter coat" + desc = "A heavy jacket made from 'synthetic' animal furs." + icon_state = "wintercoat" + item_state = "coatwinter" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0) + allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) + + sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi') + +/obj/item/clothing/head/hooded/winterhood + name = "winter hood" + desc = "A hood attached to a heavy winter jacket." + icon_state = "winterhood" + body_parts_covered = HEAD + cold_protection = HEAD + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + flags = BLOCKHAIR + flags_inv = HIDEEARS + + sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi') + +/obj/item/clothing/suit/hooded/wintercoat/captain + name = "captain's winter coat" + icon_state = "wintercoat_captain" + item_state = "coatcaptain" + armor = list(melee = 25, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0) + allowed = list(/obj/item/gun/energy, /obj/item/reagent_containers/spray/pepper, /obj/item/gun/projectile, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic) + hoodtype = /obj/item/clothing/head/hooded/winterhood/captain + +/obj/item/clothing/head/hooded/winterhood/captain + icon_state = "winterhood_captain" + +/obj/item/clothing/suit/hooded/wintercoat/security + name = "security winter coat" + icon_state = "wintercoat_sec" + item_state = "coatsecurity" + armor = list(melee = 10, bullet = 10, laser = 10, energy = 5, bomb = 15, bio = 0, rad = 0) + allowed = list(/obj/item/gun/energy, /obj/item/reagent_containers/spray/pepper, /obj/item/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic) + hoodtype = /obj/item/clothing/head/hooded/winterhood/security + +/obj/item/clothing/head/hooded/winterhood/security + icon_state = "winterhood_sec" + +/obj/item/clothing/suit/hooded/wintercoat/medical + name = "medical winter coat" + icon_state = "wintercoat_med" + item_state = "coatmedical" + allowed = list(/obj/item/analyzer, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer,/obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 50, rad = 0) + hoodtype = /obj/item/clothing/head/hooded/winterhood/medical + +/obj/item/clothing/head/hooded/winterhood/medical + icon_state = "winterhood_med" + +/obj/item/clothing/suit/hooded/wintercoat/science + name = "science winter coat" + icon_state = "wintercoat_sci" + item_state = "coatscience" + allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer,/obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 10, bio = 0, rad = 0) + hoodtype = /obj/item/clothing/head/hooded/winterhood/science + +/obj/item/clothing/head/hooded/winterhood/science + icon_state = "winterhood_sci" + +/obj/item/clothing/suit/hooded/wintercoat/engineering + name = "engineering winter coat" + icon_state = "wintercoat_engi" + item_state = "coatengineer" + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 20) + allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/t_scanner, /obj/item/rcd) + hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering + +/obj/item/clothing/head/hooded/winterhood/engineering + icon_state = "winterhood_engi" + +/obj/item/clothing/suit/hooded/wintercoat/engineering/atmos + name = "atmospherics winter coat" + icon_state = "wintercoat_atmos" + item_state = "coatatmos" + hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering/atmos + +/obj/item/clothing/head/hooded/winterhood/engineering/atmos + icon_state = "winterhood_atmos" + +/obj/item/clothing/suit/hooded/wintercoat/hydro + name = "hydroponics winter coat" + icon_state = "wintercoat_hydro" + item_state = "coathydro" + allowed = list(/obj/item/reagent_containers/spray, /obj/item/plant_analyzer, /obj/item/seeds, /obj/item/reagent_containers/glass/bottle, /obj/item/hatchet, /obj/item/storage/bag/plants) + hoodtype = /obj/item/clothing/head/hooded/winterhood/hydro + +/obj/item/clothing/head/hooded/winterhood/hydro + icon_state = "winterhood_hydro" + +/obj/item/clothing/suit/hooded/wintercoat/cargo + name = "cargo winter coat" + icon_state = "wintercoat_cargo" + item_state = "coatcargo" + hoodtype = /obj/item/clothing/head/hooded/winterhood/cargo + +/obj/item/clothing/head/hooded/winterhood/cargo + icon_state = "winterhood_cargo" + +/obj/item/clothing/suit/hooded/wintercoat/miner + name = "mining winter coat" + icon_state = "wintercoat_miner" + item_state = "coatminer" + allowed = list(/obj/item/pickaxe, /obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) + armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + hoodtype = /obj/item/clothing/head/hooded/winterhood/miner + +/obj/item/clothing/head/hooded/winterhood/miner + icon_state = "winterhood_miner" + + +/* + * Misc + */ + +//hoodies +/obj/item/clothing/suit/hooded/hoodie + name = "black hoodie" + desc = "It's a hoodie. It has a hood. Most hoodies do." + icon_state = "black_hoodie" + item_state = "blueshieldcoat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen) + hoodtype = /obj/item/clothing/head/hooded/hood + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/head/hooded/hood + name = "black hood" + desc = "A hood attached to a hoodie." + icon_state = "blackhood" + body_parts_covered = HEAD + cold_protection = HEAD + flags = BLOCKHAIR + flags_inv = HIDEEARS + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/head.dmi' + ) + +/obj/item/clothing/head/hooded/hood/blue + icon_state = "bluehood" + +/obj/item/clothing/head/hooded/hood/white + icon_state = "whitehood" + +/obj/item/clothing/suit/hooded/hoodie/blue + name = "blue hoodie" + icon_state = "blue_hoodie" + hoodtype = /obj/item/clothing/head/hooded/hood/blue + +/obj/item/clothing/suit/hooded/hoodie/mit + name = "Martian Institute of Technology hoodie" + desc = "A hoodie proudly worn by students and graduates alike, has the letters 'MIT' on the back." + icon_state = "mit_hoodie" + hoodtype = /obj/item/clothing/head/hooded/hood + +/obj/item/clothing/suit/hooded/hoodie/cut + name = "Canaan University of Technology hoodie" + desc = "A bright hoodie with the Canaan University of Technology logo on the front." + icon_state = "cut_hoodie" + hoodtype = /obj/item/clothing/head/hooded/hood/white + +/obj/item/clothing/suit/hooded/hoodie/lam + name = "Lunar Academy of Medicine hoodie" + desc = "A bright hoodie with the Lunar Academy of Medicine logo on the back." + icon_state = "lam_hoodie" + hoodtype = /obj/item/clothing/head/hooded/hood/white + +/obj/item/clothing/suit/hooded/hoodie/nt + name = "Nanotrasen hoodie" + desc = "A blue hoodie with the Nanotrasen logo on the back." + icon_state = "nt_hoodie" + hoodtype = /obj/item/clothing/head/hooded/hood/blue + +/obj/item/clothing/suit/hooded/hoodie/tp + name = "Tharsis Polytech hoodie" + desc = "A dark hoodie with the Tharsis Polytech logo on the back." + icon_state = "tp_hoodie" + hoodtype = /obj/item/clothing/head/hooded/hood + +/obj/item/clothing/suit/straight_jacket + name = "straight jacket" + desc = "A suit that completely restrains the wearer." + icon_state = "straight_jacket" + item_state = "straight_jacket" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL + flags_size = ONESIZEFITSALL + strip_delay = 60 + breakouttime = 3000 + +/obj/item/clothing/suit/ianshirt + name = "worn shirt" + desc = "A worn out, curiously comfortable t-shirt with a picture of Ian. You wouldn't go so far as to say it feels like being hugged when you wear it but it's pretty close. Good for sleeping in." + icon_state = "ianshirt" + item_state = "ianshirt" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + + + +//pyjamas +//originally intended to be pinstripes >.> + +/obj/item/clothing/under/bluepyjamas + name = "blue pyjamas" + desc = "Slightly old-fashioned sleepwear." + icon_state = "blue_pyjamas" + item_state = "blue_pyjamas" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS + +/obj/item/clothing/under/redpyjamas + name = "red pyjamas" + desc = "Slightly old-fashioned sleepwear." + icon_state = "red_pyjamas" + item_state = "red_pyjamas" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS + +//coats + +/obj/item/clothing/suit/leathercoat + name = "leather coat" + desc = "A long, thick black leather coat." + icon_state = "leathercoat" + item_state = "leathercoat" + burn_state = FIRE_PROOF + +/obj/item/clothing/suit/browncoat + name = "brown leather coat" + desc = "A long, brown leather coat." + icon_state = "browncoat" + item_state = "browncoat" + +/obj/item/clothing/suit/neocoat + name = "black coat" + desc = "A flowing, black coat." + icon_state = "neocoat" + item_state = "neocoat" + +/obj/item/clothing/suit/browntrenchcoat + name = "brown trench coat" + desc = "It makes you stand out. Just the opposite of why it's typically worn. Nice try trying to blend in while wearing it." + icon_state = "brtrenchcoat" + item_state = "brtrenchcoat" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/blacktrenchcoat + name = "black trench coat" + desc = "That shade of black just makes you look a bit more evil. Good for those mafia types." + icon_state = "bltrenchcoat" + item_state = "bltrenchcoat" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +//trackjackets + +/obj/item/clothing/suit/tracksuit + name = "black tracksuit" + desc = "Lightweight and stylish. What else could a man ask of his tracksuit?" + icon_state = "trackjacket_open" + item_state = "bltrenchcoat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + ignore_suitadjust = 0 + suit_adjusted = 1 + actions_types = list(/datum/action/item_action/openclose) + adjust_flavour = "unzip" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/tracksuit/green + name = "green tracksuit" + icon_state = "trackjacketgreen_open" + +/obj/item/clothing/suit/tracksuit/red + name = "red tracksuit" + icon_state = "trackjacketred_open" + +/obj/item/clothing/suit/tracksuit/white + name = "white tracksuit" + icon_state = "trackjacketwhite_open" + +//actual suits + +/obj/item/clothing/suit/creamsuit + name = "cream suit" + desc = "A cream coloured, genteel suit." + icon_state = "creamsuit" + item_state = "creamsuit" + +/obj/item/clothing/under/stripper/mankini + name = "the mankini" + desc = "No honest man would wear this abomination" + icon_state = "mankini" + item_color = "mankini" + +/obj/item/clothing/suit/jacket/miljacket + name = "olive military jacket" + desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in olive." + icon_state = "militaryjacket" + item_state = "militaryjacket" + ignore_suitadjust = 1 + actions_types = list() + adjust_flavour = null + allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter,/obj/item/gun/projectile/automatic/pistol,/obj/item/gun/projectile/revolver,/obj/item/gun/projectile/revolver/detective) + +/obj/item/clothing/suit/jacket/miljacket/navy + name = "navy military jacket" + desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in navy blue." + icon_state = "navy_jacket" + +/obj/item/clothing/suit/jacket/miljacket/desert + name = "desert military jacket" + desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in desert beige." + icon_state = "desert_jacket" + +/obj/item/clothing/suit/jacket/miljacket/white + name = "white military jacket" + desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in snow white." + icon_state = "white_jacket" + +/obj/item/clothing/suit/xenos + name = "xenos suit" + desc = "A suit made out of chitinous alien hide." + icon_state = "xenos" + item_state = "xenos_helm" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + flags_size = ONESIZEFITSALL + +//swimsuit +/obj/item/clothing/under/swimsuit/ + +/obj/item/clothing/under/swimsuit/black + name = "black swimsuit" + desc = "An oldfashioned black swimsuit." + icon_state = "swim_black" + item_color = "swim_black" + +/obj/item/clothing/under/swimsuit/blue + name = "blue swimsuit" + desc = "An oldfashioned blue swimsuit." + icon_state = "swim_blue" + item_color = "swim_blue" + +/obj/item/clothing/under/swimsuit/purple + name = "purple swimsuit" + desc = "An oldfashioned purple swimsuit." + icon_state = "swim_purp" + item_color = "swim_purp" + +/obj/item/clothing/under/swimsuit/green + name = "green swimsuit" + desc = "An oldfashioned green swimsuit." + icon_state = "swim_green" + item_color = "swim_green" + +/obj/item/clothing/under/swimsuit/red + name = "red swimsuit" + desc = "An oldfashioned red swimsuit." + icon_state = "swim_red" + item_color = "swim_red" + +/obj/item/clothing/suit/storage/mercy_hoodie + name = "mercy robe" + desc = "A soft white robe made of a synthetic fiber that provides improved protection against biohazards. Possessing multiple overlapping layers, yet light enough to allow complete freedom of movement, it denotes its wearer as a master physician." + icon_state = "mercy_hoodie" + item_state = "mercy_hoodie" + w_class = WEIGHT_CLASS_BULKY + gas_transfer_coefficient = 0.01 + permeability_coefficient = 0.01 + flags_size = ONESIZEFITSALL + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + allowed = list(/obj/item/tank/emergency_oxygen,/obj/item/pen,/obj/item/flashlight/pen) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL + +/obj/item/clothing/head/mercy_hood + name = "Mercy Hood" + desc = "A soft white hood made of a synthetic fiber that provides improved protection against biohazards. Its elegant design allows a clear field of vision." + icon_state = "mercy_hood" + item_state = "mercy_hood" + permeability_coefficient = 0.01 + flags = BLOCKHAIR + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES + +/obj/item/clothing/suit/jacket + name = "bomber jacket" + desc = "Aviators not included." + icon_state = "bomber" + item_state = "bomber" + ignore_suitadjust = 0 + allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter) + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + actions_types = list(/datum/action/item_action/zipper) + adjust_flavour = "unzip" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/jacket/pilot + name = "security bomber jacket" + desc = "A stylish and worn-in armoured black bomber jacket emblazoned with the NT Security crest on the left breast. Looks rugged." + icon_state = "bombersec" + item_state = "bombersec" + ignore_suitadjust = 0 + //Inherited from Security armour. + allowed = list(/obj/item/gun/energy,/obj/item/reagent_containers/spray/pepper,/obj/item/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/flashlight/seclite,/obj/item/melee/classic_baton/telescopic,/obj/item/kitchen/knife/combat) + heat_protection = UPPER_TORSO|LOWER_TORSO + min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT + max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT + strip_delay = 60 + put_on_delay = 40 + flags_size = ONESIZEFITSALL + armor = list(melee = 25, bullet = 15, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) + //End of inheritance from Security armour. + +/obj/item/clothing/suit/jacket/leather + name = "leather jacket" + desc = "Pompadour not included." + icon_state = "leatherjacket" + ignore_suitadjust = 1 + actions_types = list() + adjust_flavour = null + burn_state = FIRE_PROOF + +/obj/item/clothing/suit/jacket/leather/overcoat + name = "leather overcoat" + desc = "That's a damn fine coat." + icon_state = "leathercoat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS + cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS + +/obj/item/clothing/suit/officercoat + name = "Clown Officer's Coat" + desc = "A classy clown officer's overcoat, also designed by Hugo Boss." + icon_state = "officersuit" + item_state = "officersuit" + ignore_suitadjust = 0 + actions_types = list(/datum/action/item_action/button) + adjust_flavour = "unbutton" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/soldiercoat + name = "Clown Soldier's Coat" + desc = "An overcoat for the clown soldier, to keep him warm during those cold winter nights on the front." + icon_state = "soldiersuit" + item_state = "soldiersuit" + ignore_suitadjust = 0 + actions_types = list(/datum/action/item_action/button) + adjust_flavour = "unbutton" + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + +/obj/item/clothing/suit/toggle/owlwings + name = "owl cloak" + desc = "A soft brown cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive the ladies mad." + icon_state = "owl_wings" + item_state = "owl_wings" + body_parts_covered = ARMS + armor = list(melee = 5, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + allowed = list(/obj/item/gun/energy,/obj/item/reagent_containers/spray/pepper,/obj/item/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/flashlight/seclite) + actions_types = list(/datum/action/item_action/toggle_wings) + + +/obj/item/clothing/suit/toggle/owlwings/griffinwings + name = "griffon cloak" + desc = "A plush white cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive your captives mad." + icon_state = "griffin_wings" + item_state = "griffin_wings" + +/obj/item/clothing/suit/toggle/attack_self() + if(icon_state == initial(icon_state)) + icon_state = icon_state + "_t" + item_state = icon_state + "_t" + else + icon_state = initial(icon_state) + item_state = initial(item_state) + usr.update_inv_wear_suit() + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + +/obj/item/clothing/suit/lordadmiral + name = "Lord Admiral's Coat" + desc = "You'll be the Ruler of the King's Navy in no time." + icon_state = "lordadmiral" + item_state = "lordadmiral" + allowed = list (/obj/item/gun) + +/obj/item/clothing/suit/fluff/noble_coat + name = "noble coat" + desc = "The livid blues, purples and greens are awesome enough to evoke a visceral response in you; it is not dissimilar to indigestion." + icon_state = "noble_coat" + item_state = "noble_coat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + + +///Advanced Protective Suit, AKA, God Mode in wearable form. + +/obj/item/clothing/suit/advanced_protective_suit + name = "Advanced Protective Suit" + desc = "An incredibly advanced and complex suit; it has so many buttons and dials as to be incomprehensible." + icon_state = "bomb" + item_state = "bomb" + actions_types = list(/datum/action/item_action/toggle) + gas_transfer_coefficient = 0.01 + permeability_coefficient = 0.01 + flags = STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|HEAD + armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100) + cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + heat_protection = UPPER_TORSO | LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + slowdown = -10 + siemens_coefficient = 0 + var/on = 0 + +/obj/item/clothing/suit/advanced_protective_suit/Destroy() + if(on) + on = 0 + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/clothing/suit/advanced_protective_suit/ui_action_click() + if(on) + on = 0 + to_chat(usr, "You turn the suit's special processes off.") + else + on = 1 + to_chat(usr, "You turn the suit's special processes on.") + START_PROCESSING(SSobj, src) + + +/obj/item/clothing/suit/advanced_protective_suit/IsReflect() + return (on) + +/obj/item/clothing/suit/advanced_protective_suit/process() + if(on) + var/mob/living/carbon/human/user = src.loc + if(user && ishuman(user) && (user.wear_suit == src)) + if(user.reagents.get_reagent_amount("stimulants") < 15) + user.reagents.add_reagent("stimulants", 15) + if(user.reagents.get_reagent_amount("adminordrazine") < 15) + user.reagents.add_reagent("adminordrazine", 15) + if(user.reagents.get_reagent_amount("nanites") < 15) + user.reagents.add_reagent("nanites", 15) + if(user.reagents.get_reagent_amount("syndicate_nanites") < 15) + user.reagents.add_reagent("syndicate_nanites", 15) + else + STOP_PROCESSING(SSobj, src) + +//Syndicate Chaplain Robe (WOLOLO!) +/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe + description_antag = "This robe is made of reinforced fibers, granting it superior protection. The robes also wirelessly generate power for the neurotransmitter in the linked missionary staff while being worn." + armor = list(melee = 10, bullet = 10, laser = 5, energy = 5, bomb = 0, bio = 0, rad = 15) + var/obj/item/nullrod/missionary_staff/linked_staff = null + +/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/Destroy() + if(linked_staff) //delink on destruction + linked_staff.robes = null + linked_staff = null + STOP_PROCESSING(SSobj, src) //probably is cleared in a parent call already, but just in case we're gonna do it here + return ..() + +/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/equipped(mob/living/carbon/human/H, slot) + if(!istype(H) || slot != slot_wear_suit) + STOP_PROCESSING(SSobj, src) + return + else + START_PROCESSING(SSobj, src) + +/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/process() + if(!linked_staff) //if we don't have a linked staff, the rest of this is useless + return + + if(!ishuman(loc)) //if we somehow try to process while not on a human, remove ourselves from processing and return + STOP_PROCESSING(SSobj, src) + return + + var/mob/living/carbon/human/H = loc + + if(linked_staff.faith >= 100) //if the linked staff is fully recharged, do nothing + return + + if(!linked_staff in range(3, get_turf(src))) //staff won't charge at range (to prevent it from being handed off / stolen and used) + if(prob(10)) //10% chance per process should avoid being too spammy, can tweak if it ends up still being too frequent. + to_chat(H, "Your staff is unable to charge at this range. Get closer!") + return + + linked_staff.faith += 5 + if(linked_staff.faith >= 100) //if this charge puts the staff at or above full, notify the wearer + to_chat(H, "Faith renewed; ready to convert new followers.") + +/obj/item/clothing/suit/tailcoat + name = "victorian tailcoat" + desc = "A fancy victorian tailcoat." + icon_state = "tailcoat" + item_state = "tailcoat" + +/obj/item/clothing/suit/victcoat + name = "ladies victorian coat" + desc = "A fancy victorian coat." + icon_state = "ladiesvictoriancoat" + item_state = "ladiesvictoriancoat" + +/obj/item/clothing/suit/victcoat/red + name = "ladies red victorian coat" + icon_state = "ladiesredvictoriancoat" + item_state = "ladiesredvictoriancoat" + +//Mantles! +/obj/item/clothing/suit/mantle + name = "mantle" + desc = "A heavy quilted mantle, for keeping your shoulders warm and stylish." + icon_state = "mantle" + item_state = "mantle" + body_parts_covered = UPPER_TORSO|ARMS + cold_protection = UPPER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + +/obj/item/clothing/suit/mantle/regal + name = "regal shawl" + desc = "A fancy shawl for nobility, made from high quality materials." + icon_state = "regal_mantle" + item_state = "regal_mantle" + +/obj/item/clothing/suit/mantle/old + name = "old wrap" + desc = "A tattered fabric wrap, faded over the years. Smells faintly of cigars." + icon_state = "old_mantle" + item_state = "old_mantle" + +/obj/item/clothing/suit/ghost_sheet + name = "ghost sheet" + desc = "The hands float by themselves, so it's extra spooky." + icon_state = "ghost_sheet" + item_state = "ghost_sheet" + throwforce = 0 + throw_speed = 1 + throw_range = 2 + w_class = WEIGHT_CLASS_TINY + flags = BLOCKHAIR + flags_inv = HIDEGLOVES|HIDEEARS|HIDEFACE diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index 871eab23d3b..576b3e6c552 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -6,7 +6,8 @@ /obj/item/clothing/suit/space/hardsuit/Destroy() if(helmet) helmet.suit = null - qdel(helmet) + QDEL_NULL(helmet) + QDEL_NULL(jetpack) return ..() /obj/item/clothing/head/helmet/space/hardsuit/Destroy() diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index 6bfd40ad0ad..81c6d15562a 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -88,6 +88,9 @@ item_state = "sexyclown" item_color = "sexyclown" +/obj/item/clothing/under/rank/clown/nodrop + flags = NODROP + /obj/item/clothing/under/rank/head_of_personnel desc = "It's a jumpsuit worn by someone who works in the position of \"Head of Personnel\"." name = "head of personnel's jumpsuit" @@ -208,6 +211,8 @@ item_color = "mime" flags_size = ONESIZEFITSALL +/obj/item/clothing/under/mime/nodrop + flags = NODROP /obj/item/clothing/under/rank/miner desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty." diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 91527f2dd19..c277345a440 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -890,3 +890,10 @@ item_color = "hawaiianblue" flags_size = ONESIZEFITSALL +/obj/item/clothing/under/misc/durathread + name = "durathread jumpsuit" + desc = "A jumpsuit made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "durathread" + item_state = "durathread" + item_color = "durathread" + armor = list(melee = 10, bullet = 0, laser = 10, energy = 0, bomb = 5, bio = 0, rad = 0) \ No newline at end of file diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index ea5e4a652aa..e05e31c297f 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -1,7 +1,26 @@ /datum/personal_crafting var/busy var/viewing_category = 1 //typical powergamer starting on the Weapons tab - var/list/categories = list(CAT_WEAPON,CAT_AMMO,CAT_ROBOT,CAT_FOOD,CAT_MISC,CAT_PRIMAL) + var/viewing_subcategory = 1 + var/list/categories = list( + CAT_WEAPONRY, + CAT_ROBOT, + CAT_MISC, + CAT_PRIMAL, + CAT_FOOD, + CAT_CLOTHING) + var/list/subcategories = list( + list( //Weapon subcategories + CAT_WEAPON, + CAT_AMMO), + CAT_NONE, //Robot subcategories + CAT_NONE, //Misc subcategories + CAT_NONE, //Tribal subcategories + list( //Food subcategories + CAT_CAKE, + CAT_SUSHI, + CAT_SANDWICH), + CAT_CLOTHING) //Clothing subcategories var/display_craftable_only = FALSE var/display_compact = TRUE @@ -22,11 +41,14 @@ /datum/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents) + contents = contents["other"] main_loop: for(var/A in R.reqs) var/needed_amount = R.reqs[A] for(var/B in contents) if(ispath(B, A)) + if (R.blacklist.Find(B)) + continue if(contents[B] >= R.reqs[A]) continue main_loop else @@ -56,45 +78,47 @@ if(AM.flags_2 & HOLOGRAM_2) continue . += AM + for(var/slot in list(slot_r_store, slot_l_store)) + . += user.get_item_by_slot(slot) /datum/personal_crafting/proc/get_surroundings(mob/user) . = list() + .["other"] = list() for(var/obj/item/I in get_environment(user)) if(I.flags_2 & HOLOGRAM_2) continue if(istype(I, /obj/item/stack)) var/obj/item/stack/S = I - .[I.type] += S.amount + .["other"][I.type] += S.amount else if(istype(I, /obj/item/reagent_containers)) var/obj/item/reagent_containers/RC = I - if(RC.container_type & OPENCONTAINER) + if(RC.is_drainable()) for(var/datum/reagent/A in RC.reagents.reagent_list) - .[A.type] += A.volume - .[I.type] += 1 + .["other"][A.type] += A.volume + .["other"][I.type] += 1 /datum/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents) if(!R.tools.len) - return 1 + return TRUE var/list/possible_tools = list() for(var/obj/item/I in user.contents) if(istype(I, /obj/item/storage)) for(var/obj/item/SI in I.contents) possible_tools += SI.type possible_tools += I.type - possible_tools += contents + possible_tools |= contents["other"] main_loop: for(var/A in R.tools) for(var/I in possible_tools) if(ispath(I,A)) continue main_loop - return 0 - return 1 + return FALSE + return TRUE /datum/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R) - for(var/A in R.parts) var/list/contents = get_surroundings(user) var/send_feedback = 1 if(check_contents(R, contents)) @@ -108,6 +132,8 @@ var/list/parts = del_reqs(R, user) var/atom/movable/I = new R.result (get_turf(user.loc)) I.CheckParts(parts, R) + if(isitem(I)) + user.put_in_hands(I) if(send_feedback) feedback_add_details("object_crafted","[I.type]") return 0 @@ -173,6 +199,7 @@ RGNT.volume += RG.volume RGNT.data += RG.data qdel(RG) + RC.on_reagent_change() else surroundings -= RC else if(ispath(A, /obj/item/stack)) @@ -195,7 +222,7 @@ else data = S.amount S = locate(S.type) in Deletion - S.amount += data + S.add(data) surroundings -= S else var/atom/movable/I @@ -241,11 +268,19 @@ /datum/personal_crafting/ui_data(mob/user) var/list/data = list() + var/list/subs = list() + var/cur_subcategory = CAT_NONE var/cur_category = categories[viewing_category] + if(islist(subcategories[viewing_category])) + subs = subcategories[viewing_category] + cur_subcategory = subs[viewing_subcategory] data["busy"] = busy data["prev_cat"] = categories[prev_cat()] + data["prev_subcat"] = subs[prev_subcat()] data["category"] = cur_category + data["subcategory"] = cur_subcategory data["next_cat"] = categories[next_cat()] + data["next_subcat"] = subs[next_subcat()] data["display_craftable_only"] = display_craftable_only data["display_compact"] = display_compact @@ -254,7 +289,11 @@ var/list/cant_craft = list() for(var/rec in GLOB.crafting_recipes) var/datum/crafting_recipe/R = rec - if(R.category != cur_category) + + if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this. + continue + + if((R.category != cur_category) || (R.subcategory != cur_subcategory)) continue if(check_contents(R, surroundings)) can_craft += list(build_recipe_data(R)) @@ -269,41 +308,54 @@ return if(href_list["make"]) - var/datum/crafting_recipe/TR = locate(href_list["make"]) - busy = 1 + var/datum/crafting_recipe/TR = locate(href_list["make"]) in GLOB.crafting_recipes + busy = TRUE SSnanoui.update_uis(src) var/fail_msg = construct_item(usr, TR) if(!fail_msg) to_chat(usr, "[TR.name] constructed.") else to_chat(usr, "Construction failed[fail_msg]") - busy = 0 + busy = FALSE SSnanoui.update_uis(src) if(href_list["forwardCat"]) - viewing_category = next_cat() - to_chat(usr, "Category is now [categories[viewing_category]].") + viewing_category = next_cat(FALSE) . = TRUE if(href_list["backwardCat"]) - viewing_category = prev_cat() - to_chat(usr, "Category is now [categories[viewing_category]].") + viewing_category = prev_cat(FALSE) + . = TRUE + if(href_list["forwardSubCat"]) + viewing_subcategory = next_subcat() + . = TRUE + if(href_list["backwardSubCat"]) + viewing_subcategory = prev_subcat() . = TRUE if(href_list["toggle_recipes"]) display_craftable_only = !display_craftable_only - to_chat(usr, "You will now [display_craftable_only ? "only see recipes you can craft":"see all recipes"].") . = TRUE if(href_list["toggle_compact"]) display_compact = !display_compact - to_chat(usr, "Crafting menu is now [display_compact? "compact" : "full size"].") . = TRUE SSnanoui.update_uis(src) //Next works nicely with modular arithmetic -/datum/personal_crafting/proc/next_cat() +//Next works nicely with modular arithmetic +/datum/personal_crafting/proc/next_cat(readonly = TRUE) + if (!readonly) + viewing_subcategory = 1 . = viewing_category % categories.len + 1 +/datum/personal_crafting/proc/next_subcat() + if(islist(subcategories[viewing_category])) + var/list/subs = subcategories[viewing_category] + . = viewing_subcategory % subs.len + 1 + + //Previous can go fuck itself -/datum/personal_crafting/proc/prev_cat() +/datum/personal_crafting/proc/prev_cat(readonly = TRUE) + if (!readonly) + viewing_subcategory = 1 if(viewing_category == categories.len) . = viewing_category-1 else @@ -311,6 +363,18 @@ if(. <= 0) . = categories.len +/datum/personal_crafting/proc/prev_subcat() + if(islist(subcategories[viewing_category])) + var/list/subs = subcategories[viewing_category] + if(viewing_subcategory == subs.len) + . = viewing_subcategory-1 + else + . = viewing_subcategory % subs.len - 1 + if(. <= 0) + . = subs.len + else + . = null + /datum/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R) var/list/data = list() data["name"] = R.name @@ -334,9 +398,19 @@ data["catalyst_text"] = catalyst_text for(var/a in R.tools) - var/atom/A = a //cheat-typecast - tool_text += " [R.tools[A]] [initial(A.name)]," + if(ispath(a, /obj/item)) + var/obj/item/b = a + tool_text += " [initial(b.name)]," + else + tool_text += " [a]," tool_text = replacetext(tool_text, ",", "", -1) data["tool_text"] = tool_text - return data \ No newline at end of file + return data + +//Mind helpers + +/datum/mind/proc/teach_crafting_recipe(R) + if(!learned_recipes) + learned_recipes = list() + learned_recipes |= R \ No newline at end of file diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 58338efea61..126e9f30b31 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -1,19 +1,15 @@ /datum/crafting_recipe var/name = "" //in-game display name var/reqs[] = list() //type paths of items consumed associated with how many are needed + var/blacklist[] = list() //type paths of items explicitly not allowed as an ingredient var/result //type path of item resulting from this craft var/tools[] = list() //type paths of items needed but not consumed var/time = 30 //time in deciseconds var/parts[] = list() //type paths of items that will be placed in the result var/chem_catalysts[] = list() //like tools but for reagents - var/category = CAT_NONE // Recipe category - var/roundstart_enabled = TRUE //Set to FALSE if you don't want a particular crafting recipe to be available all the time - -/datum/crafting_recipe/proc/AdjustChems(var/obj/resultobj as obj) - //This proc is to replace the make_food proc of recipes from microwaves and such that are being converted to table crafting recipes. - //Use it to handle the removal of reagents after the food has been created (like removing toxins from a salad made with ambrosia) - //If a recipe does not require it's chems adjusted, don't bother declaring this for the recipe, as it will call this placeholder - return + var/category = CAT_NONE //where it shows up in the crafting UI + var/subcategory = CAT_NONE + var/always_availible = TRUE //Set to FALSE if it needs to be learned first. /datum/crafting_recipe/IED name = "IED" @@ -24,7 +20,8 @@ /obj/item/reagent_containers/food/drinks/cans = 1) parts = list(/obj/item/reagent_containers/food/drinks/cans = 1) time = 15 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/molotov name = "Molotov" @@ -33,7 +30,8 @@ /obj/item/reagent_containers/food/drinks/bottle = 1) parts = list(/obj/item/reagent_containers/food/drinks/bottle = 1) time = 40 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/stunprod name = "Stunprod" @@ -42,7 +40,8 @@ /obj/item/stack/rods = 1, /obj/item/assembly/igniter = 1) time = 40 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/bola name = "Bola" @@ -50,7 +49,8 @@ reqs = list(/obj/item/restraints/handcuffs/cable = 1, /obj/item/stack/sheet/metal = 6) time = 20//15 faster than crafting them by hand! - category= CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/ed209 name = "ED209" @@ -144,7 +144,8 @@ /obj/item/weldingtool = 1) tools = list(/obj/item/screwdriver) time = 10 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/meteorshot name = "Meteorshot Shell" @@ -154,7 +155,8 @@ /obj/item/stock_parts/manipulator = 2) tools = list(/obj/item/screwdriver) time = 5 - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/pulseslug name = "Pulse Slug Shell" @@ -164,7 +166,8 @@ /obj/item/stock_parts/micro_laser/ultra = 1) tools = list(/obj/item/screwdriver) time = 5 - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/dragonsbreath name = "Dragonsbreath Shell" @@ -173,7 +176,8 @@ /datum/reagent/phosphorus = 5,) tools = list(/obj/item/screwdriver) time = 5 - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/frag12 name = "FRAG-12 Shell" @@ -184,7 +188,8 @@ /datum/reagent/facid = 5,) tools = list(/obj/item/screwdriver) time = 5 - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/ionslug name = "Ion Scatter Shell" @@ -194,7 +199,8 @@ /obj/item/stock_parts/subspace/crystal = 1) tools = list(/obj/item/screwdriver) time = 5 - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/improvisedslug name = "Improvised Shotgun Shell" @@ -205,7 +211,8 @@ /datum/reagent/fuel = 10) tools = list(/obj/item/screwdriver) time = 5 - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/improvisedslugoverload name = "Overload Improvised Shell" @@ -215,7 +222,8 @@ /datum/reagent/plasma_dust = 20) tools = list(/obj/item/screwdriver) time = 5 - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/laserslug name = "Laser Slug Shell" @@ -225,7 +233,8 @@ /obj/item/stock_parts/micro_laser/high = 1) tools = list(/obj/item/screwdriver) time = 5 - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/ishotgun name = "Improvised Shotgun" @@ -236,7 +245,8 @@ /obj/item/stack/packageWrap = 5,) tools = list(/obj/item/screwdriver) time = 100 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/chainsaw name = "Chainsaw" @@ -246,7 +256,8 @@ /obj/item/stack/sheet/plasteel = 1) tools = list(/obj/item/weldingtool) time = 50 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/spear name = "Spear" @@ -255,7 +266,8 @@ /obj/item/shard = 1, /obj/item/stack/rods = 1) time = 40 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/spooky_camera name = "Camera Obscura" @@ -296,7 +308,8 @@ reqs = list(/obj/item/stack/sheet/wood = 1, /obj/item/stack/cable_coil = 5) tools = list(/obj/item/kitchen/knife) // Gotta carve the wood into handles - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/makeshift_bolt name = "Makeshift Bolt" @@ -304,7 +317,8 @@ time = 5 reqs = list(/obj/item/stack/rods = 1) tools = list(/obj/item/weldingtool) - category = CAT_AMMO + category = CAT_WEAPONRY + subcategory = CAT_AMMO /datum/crafting_recipe/crossbow name = "Powered Crossbow" @@ -316,7 +330,8 @@ /obj/item/stack/sheet/wood = 5) tools = list(/obj/item/weldingtool, /obj/item/screwdriver) - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/glove_balloon name = "Latex Glove Balloon" @@ -361,7 +376,8 @@ ) parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2) time = 30 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/chemical_payload2 name = "Chemical Payload (gibtonite)" @@ -373,7 +389,8 @@ ) parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2) time = 50 - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/toxins_payload name = "Toxins Payload Casing" @@ -383,7 +400,8 @@ /obj/item/assembly/signaler = 1, /obj/item/stack/sheet/metal = 2 ) - category = CAT_WEAPON + category = CAT_WEAPONRY + subcategory = CAT_WEAPON /datum/crafting_recipe/bonearmor name = "Bone Armor" @@ -552,4 +570,4 @@ /obj/item/grown/log = 2) time = 50 category = CAT_MISC - roundstart_enabled = FALSE + always_availible = FALSE diff --git a/code/modules/crafting/tailoring.dm b/code/modules/crafting/tailoring.dm new file mode 100644 index 00000000000..a46e509001c --- /dev/null +++ b/code/modules/crafting/tailoring.dm @@ -0,0 +1,145 @@ +/datum/crafting_recipe/durathread_vest + name = "Durathread Vest" + result = /obj/item/clothing/suit/armor/vest/durathread + reqs = list(/obj/item/stack/sheet/durathread = 5, + /obj/item/stack/sheet/leather = 4) + time = 50 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_helmet + name = "Durathread Helmet" + result = /obj/item/clothing/head/helmet/durathread + reqs = list(/obj/item/stack/sheet/durathread = 4, + /obj/item/stack/sheet/leather = 5) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_jumpsuit + name = "Durathread Jumpsuit" + result = /obj/item/clothing/under/misc/durathread + reqs = list(/obj/item/stack/sheet/durathread = 4) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_beret + name = "Durathread Beret" + result = /obj/item/clothing/head/beret/durathread + reqs = list(/obj/item/stack/sheet/durathread = 2) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_beanie + name = "Durathread Beanie" + result = /obj/item/clothing/head/beanie/durathread + reqs = list(/obj/item/stack/sheet/durathread = 2) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_bandana + name = "Durathread Bandana" + result = /obj/item/clothing/mask/bandana/durathread + reqs = list(/obj/item/stack/sheet/durathread = 1) + time = 25 + category = CAT_CLOTHING + +/datum/crafting_recipe/fannypack + name = "Fannypack" + result = /obj/item/storage/belt/fannypack + reqs = list(/obj/item/stack/sheet/cloth = 2, + /obj/item/stack/sheet/leather = 1) + time = 20 + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsunsec + name = "Security HUDsunglasses" + result = /obj/item/clothing/glasses/hud/security/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/security = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsunsecremoval + name = "Security HUD removal" + result = /obj/item/clothing/glasses/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsunmed + name = "Medical HUDsunglasses" + result = /obj/item/clothing/glasses/hud/health/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/health = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsunmedremoval + name = "Medical HUD removal" + result = /obj/item/clothing/glasses/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/health/sunglasses = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsundiag + name = "Diagnostic HUDsunglasses" + result = /obj/item/clothing/glasses/hud/diagnostic/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/diagnostic = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsundiagremoval + name = "Diagnostic HUD removal" + result = /obj/item/clothing/glasses/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/diagnostic/sunglasses = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/beergoggles + name = "Beer Goggles" + result = /obj/item/clothing/glasses/sunglasses/reagent + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/science = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING + +/datum/crafting_recipe/beergogglesremoval + name = "Beer Goggles removal" + result = /obj/item/clothing/glasses/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/sunglasses/reagent = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/ghostsheet + name = "Ghost Sheet" + result = /obj/item/clothing/suit/ghost_sheet + time = 5 + tools = list(/obj/item/wirecutters) + reqs = list(/obj/item/bedsheet = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/cowboyboots + name = "Cowboy Boots" + result = /obj/item/clothing/shoes/cowboy + reqs = list(/obj/item/stack/sheet/leather = 2) + time = 45 + category = CAT_CLOTHING + +/datum/crafting_recipe/lizardboots + name = "Lizard Skin Boots" + result = /obj/effect/spawner/lootdrop/lizardboots + reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1, /obj/item/stack/sheet/leather = 1) + time = 60 + category = CAT_CLOTHING diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index b7f395afce0..c1acd1e3d38 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -178,7 +178,7 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "book_berner_1" -/obj/item/clothing/glasses/sunglasses/fake/fluff/kaki //Rapidvalj: Kakicharakiti +/obj/item/clothing/glasses/sunglasses_fake/fluff/kaki //Rapidvalj: Kakicharakiti name = "broken thermonocle" desc = "A weathered Vox thermonocle, doesn't seem to work anymore." icon_state = "thermoncle" @@ -903,9 +903,9 @@ desc = "A green hoodie with the Nanotrasen logo on the back. It looks weathered." icon = 'icons/obj/custom_items.dmi' icon_state = "linda_hoodie" - hoodtype = /obj/item/clothing/head/hood/fluff/linda + hoodtype = /obj/item/clothing/head/hooded/hood/fluff/linda -/obj/item/clothing/head/hood/fluff/linda //Epic_Charger: Linda Clark +/obj/item/clothing/head/hooded/hood/fluff/linda //Epic_Charger: Linda Clark icon_state = "greenhood" /obj/item/clothing/suit/hooded/hoodie/hylo //Hylocereus: Sam Aria @@ -913,9 +913,9 @@ desc = "A soft, cozy longline hoodie. It looks old and worn, but well cared for. There's no label, but a series of dates and names is penned on a scrap of fabric sewn on the inside of the left side of the chest - 'Sam Aria' is scrawled atop them all, next to the words 'Please Remember'." icon = 'icons/obj/custom_items.dmi' icon_state = "sam_hoodie" - hoodtype = /obj/item/clothing/head/hood/hylo + hoodtype = /obj/item/clothing/head/hooded/hood/hylo -/obj/item/clothing/head/hood/hylo +/obj/item/clothing/head/hooded/hood/hylo icon = 'icons/obj/custom_items.dmi' icon_state = "sam_hood" @@ -925,9 +925,9 @@ body_parts_covered = HEAD|UPPER_TORSO|LOWER_TORSO|LEGS|ARMS icon = 'icons/obj/custom_items.dmi' icon_state = "skeleton_suit" - hoodtype = /obj/item/clothing/head/hood/fluff/skeleton + hoodtype = /obj/item/clothing/head/hooded/hood/fluff/skeleton -/obj/item/clothing/head/hood/fluff/skeleton +/obj/item/clothing/head/hooded/hood/fluff/skeleton icon = 'icons/obj/custom_items.dmi' icon_state = "skeleton_hood" @@ -973,18 +973,18 @@ desc = "A velvety smooth black winter coat with white and red stripes on the side." icon = 'icons/obj/custom_items.dmi' icon_state = "xantholne_wintercoat" - hoodtype = /obj/item/clothing/head/hood/fluff/xantholne + hoodtype = /obj/item/clothing/head/hooded/hood/fluff/xantholne body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) -/obj/item/clothing/head/hood/fluff/xantholne // Xantholne: Meex Zwichsnicrur +/obj/item/clothing/head/hooded/hood/fluff/xantholne // Xantholne: Meex Zwichsnicrur name = "black winter hood" desc = "A black hood attached to a stripped winter coat." icon = 'icons/obj/custom_items.dmi' icon_state = "xantholne_winterhood" body_parts_covered = HEAD - flags = NODROP|BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEEARS /obj/item/clothing/suit/hooded/hoodie/fluff/xydonus //Xydonus: Rsik Ugsharki Atan | Based off of the bomber jacket, but with a hood slapped on (for allowed suit storage) @@ -993,18 +993,18 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "xydonus_jacket" ignore_suitadjust = 0 - hoodtype = /obj/item/clothing/head/hood/fluff/xydonus + hoodtype = /obj/item/clothing/head/hooded/hood/fluff/xydonus body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter) -/obj/item/clothing/head/hood/fluff/xydonus +/obj/item/clothing/head/hooded/hood/fluff/xydonus name = "custom fit hood" desc = "A hood with some horns glued to them, or something like that. Custom fit for a Unathi's head shape." icon = 'icons/obj/custom_items.dmi' icon_state = "xydonus_bomberhood" body_parts_covered = HEAD - flags = NODROP|BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEEARS /obj/item/clothing/suit/fluff/pineapple //Pineapple Salad: Dan Jello @@ -1039,17 +1039,17 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "shesicoat" item_state = "shesicoat" - hoodtype = /obj/item/clothing/head/hood/fluff/shesi + hoodtype = /obj/item/clothing/head/hooded/hood/fluff/shesi body_parts_covered = UPPER_TORSO|LOWER_TORSO cold_protection = UPPER_TORSO|LOWER_TORSO -/obj/item/clothing/head/hood/fluff/shesi //MrSynnester : Shesi Skaklas +/obj/item/clothing/head/hooded/hood/fluff/shesi //MrSynnester : Shesi Skaklas name = "custom made winter hood" desc = "A custom made winter coat hood. Looks comfy." icon = 'icons/obj/custom_items.dmi' icon_state = "shesicoat_hood2" body_parts_covered = HEAD - flags = NODROP|BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEEARS /obj/item/clothing/suit/jacket/dtx //AffectedArc07: DTX @@ -1212,16 +1212,16 @@ //////////// Sets //////////// // Fox P McCloud: Fox McCloud -/obj/item/clothing/suit/jacket/fluff/fox +/obj/item/clothing/suit/storage/fox name = "Aeronautics Jacket" desc = "An aviator styled jacket made from a peculiar material; this one seems very old." icon = 'icons/obj/custom_items.dmi' icon_state = "fox_jacket" item_state = "fox_jacket" - ignore_suitadjust = TRUE - actions_types = list() - adjust_flavour = null - sprite_sheets = null + allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/projectile/automatic/pistol, /obj/item/gun/projectile/revolver, /obj/item/gun/projectile/revolver/detective) + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT /obj/item/clothing/under/fluff/fox name = "Aeronautics Jumpsuit" @@ -1232,6 +1232,12 @@ item_color = "fox_suit" displays_id = FALSE //still appears on examine; this is pure fluff. +/obj/item/clothing/suit/storage/fox/miljacket_desert + name = "rugged military jacket" + desc = "A rugged brown military jacket with a stylized 'A' embroidered on the back. It seems very old, yet is in near mint condition. Has a tag on the inside collar signed 'Fox McCloud'." + icon_state = "fox_coat" + item_color = "fox_coat" + /obj/item/toy/plushie/fluff/fox name = "orange fox plushie" desc = "A cute, soft, fuzzy, fluffy, and cuddly plushie. This has a small tag on it that is signed 'Fox McCloud'." @@ -1262,12 +1268,6 @@ /obj/item/toy/plushie/fluff/fox/ui_action_click() change_color() -/obj/item/clothing/suit/jacket/miljacket/desert/fox - name = "rugged military jacket" - desc = "A rugged brown military jacket with a stylized 'A' embroidered on the back. It seems very old, yet is in near mint condition. Has a tag on the inside collar signed 'Fox McCloud'." - icon = 'icons/obj/custom_items.dmi' - icon_state = "fox_coat" - item_color = "fox_coat" // TheFlagbearer: Willow Walker /obj/item/clothing/under/fluff/arachno_suit diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index 595eace858e..e0dd80a1e6e 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -240,9 +240,7 @@ log transactions if(amount > 10000) // prevent crashes to_chat(usr, "The ATM's screen flashes, 'Maximum single withdrawl limit reached, defaulting to 10,000.'") amount = 10000 - authenticated_account.money -= amount withdraw_arbitrary_sum(amount) - authenticated_account.charge(amount, null, "Credit withdrawal", machine_id, authenticated_account.owner_name) else to_chat(usr, "[bicon(src)]You don't have enough funds to do that!") diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 67881662db5..8467c709f5e 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -1,6 +1,6 @@ /datum/event/grid_check //NOTE: Times are measured in master controller ticks! announceWhen = 5 - + /datum/event/grid_check/setup() endWhen = rand(30,120) @@ -12,7 +12,7 @@ if(!M.client || !is_station_level(T.z)) continue SEND_SOUND(M, S) - + /datum/event/grid_check/announce() event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg') @@ -45,11 +45,6 @@ continue if(C.cell) C.cell.charge = 0 - for(var/obj/machinery/power/P in GLOB.machines) - var/area/current_area = get_area(P) - if((current_area.type in skipped_areas_apc) || (current_area.type in skipped_areas) || !is_station_level(P.z)) - continue - P.malfunction = TRUE /proc/power_restore(var/announce = 1) var/list/skipped_areas = list(/area/turret_protected/ai) @@ -72,8 +67,6 @@ S.input_attempt = S.last_input_attempt S.update_icon() S.power_change() - for(var/obj/machinery/power/P in GLOB.machines) - P.malfunction = FALSE /proc/power_restore_quick(var/announce = 1) if(announce) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 9199d8ca3bd..a7f9feb1c16 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -137,7 +137,7 @@ if(prob(50)) ChangeTurf(baseturf) -/turf/simulated/floor/vines/ChangeTurf(turf/open/floor/T) +/turf/simulated/floor/vines/ChangeTurf(turf/simulated/floor/T) . = ..() //Do this *after* the turf has changed as qdel in spacevines will call changeturf again if it hasn't for(var/obj/structure/spacevine/SV in src) diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index e931db813cf..6293e72e689 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -12,7 +12,7 @@ var/apply_method = "swallow" var/transfer_efficiency = 1.0 var/instant_application = 0 //if we want to bypass the forcedfeed delay - var/taste = TRUE//whether you can taste eating from this + var/can_taste = TRUE//whether you can taste eating from this var/antable = TRUE // Will ants come near it? var/ant_location = null var/ant_timer = null diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index b0ac9d20d6c..bebef085297 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -89,6 +89,7 @@ basename = "personal pizza" snack_overlays = 0 top = 0 + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) /obj/item/reagent_containers/food/snacks/customizable/pasta name = "spaghetti" @@ -107,6 +108,7 @@ basename = "bread" snack_overlays = 0 top = 0 + tastes = list("bread" = 10) /obj/item/reagent_containers/food/snacks/customizable/cook/pie name = "pie" @@ -116,6 +118,7 @@ basename = "pie" snack_overlays = 0 top = 0 + tastes = list("pie" = 1) /obj/item/reagent_containers/food/snacks/customizable/cook/cake name = "cake" @@ -125,6 +128,7 @@ basename = "cake" snack_overlays = 0 top = 0 + tastes = list("cake" = 1) /obj/item/reagent_containers/food/snacks/customizable/cook/jelly name = "jelly" @@ -152,6 +156,7 @@ basename = "kebab" snack_overlays = 0 top = 0 + tastes = list("meat" = 3, "metal" = 1) /obj/item/reagent_containers/food/snacks/customizable/cook/salad name = "salad" @@ -161,6 +166,7 @@ basename = "salad" snack_overlays = 0 top = 0 + tastes = list("leaves" = 1) /obj/item/reagent_containers/food/snacks/customizable/cook/waffles name = "waffles" @@ -170,6 +176,7 @@ basename = "waffles" snack_overlays = 0 top = 0 + tastes = list("waffles" = 1) /obj/item/reagent_containers/food/snacks/customizable/candy/cookie name = "cookie" @@ -179,6 +186,7 @@ basename = "cookie" snack_overlays = 0 top = 0 + tastes = list("cookie" = 1) /obj/item/reagent_containers/food/snacks/customizable/candy/cotton name = "flavored cotton candy" @@ -308,6 +316,7 @@ snack_overlays = 0 trash = /obj/item/trash/bowl top = 0 + tastes = list("soup" = 1) /obj/item/reagent_containers/food/snacks/customizable/burger name = "burger bun" @@ -316,6 +325,7 @@ baseicon = "burgercustom" basename = "burger" toptype = new /obj/item/reagent_containers/food/snacks/bun() + tastes = list("bun" = 4) /obj/item/reagent_containers/food/snacks/customizable/attackby(obj/item/I, mob/user, params) if(contents.len > sandwich_limit) diff --git a/code/modules/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm index 0746f37d113..57fd36393b5 100644 --- a/code/modules/food_and_drinks/food/foods/baked_goods.dm +++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm @@ -12,6 +12,7 @@ bitesize = 3 filling_color = "#FFD675" list_reagents = list("nutriment" = 20, "oculine" = 10, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) /obj/item/reagent_containers/food/snacks/carrotcakeslice name = "carrot cake slice" @@ -19,6 +20,8 @@ icon_state = "carrotcake_slice" trash = /obj/item/trash/plate filling_color = "#FFD675" + tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) + /obj/item/reagent_containers/food/snacks/sliceable/braincake name = "brain cake" @@ -29,6 +32,7 @@ filling_color = "#E6AEDB" bitesize = 3 list_reagents = list("protein" = 10, "nutriment" = 10, "mannitol" = 10, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1) /obj/item/reagent_containers/food/snacks/braincakeslice name = "brain cake slice" @@ -36,6 +40,7 @@ icon_state = "braincakeslice" trash = /obj/item/trash/plate filling_color = "#E6AEDB" + tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1) /obj/item/reagent_containers/food/snacks/sliceable/cheesecake name = "cheese cake" @@ -46,6 +51,7 @@ filling_color = "#FAF7AF" bitesize = 3 list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("cake" = 4, "cream cheese" = 3) /obj/item/reagent_containers/food/snacks/cheesecakeslice name = "cheese cake slice" @@ -53,6 +59,7 @@ icon_state = "cheesecake_slice" trash = /obj/item/trash/plate filling_color = "#FAF7AF" + tastes = list("cake" = 4, "cream cheese" = 3) /obj/item/reagent_containers/food/snacks/sliceable/plaincake name = "vanilla cake" @@ -63,6 +70,7 @@ bitesize = 3 filling_color = "#F7EDD5" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("cake" = 5, "vanilla" = 1, "sweetness" = 2) /obj/item/reagent_containers/food/snacks/plaincakeslice name = "vanilla cake slice" @@ -70,6 +78,7 @@ icon_state = "plaincake_slice" trash = /obj/item/trash/plate filling_color = "#F7EDD5" + tastes = list("cake" = 5, "vanilla" = 1, "sweetness" = 2) /obj/item/reagent_containers/food/snacks/sliceable/orangecake name = "orange cake" @@ -80,6 +89,7 @@ bitesize = 3 filling_color = "#FADA8E" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2) /obj/item/reagent_containers/food/snacks/orangecakeslice name = "orange cake slice" @@ -87,6 +97,7 @@ icon_state = "orangecake_slice" trash = /obj/item/trash/plate filling_color = "#FADA8E" + tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2) /obj/item/reagent_containers/food/snacks/sliceable/bananacake name = "banana cake" @@ -97,6 +108,7 @@ bitesize = 3 filling_color = "#FADA8E" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 2, "banana" = 2) /obj/item/reagent_containers/food/snacks/bananacakeslice name = "banana cake slice" @@ -104,6 +116,7 @@ icon_state = "bananacake_slice" trash = /obj/item/trash/plate filling_color = "#FADA8E" + tastes = list("cake" = 5, "sweetness" = 2, "banana" = 2) /obj/item/reagent_containers/food/snacks/sliceable/limecake name = "lime cake" @@ -114,6 +127,7 @@ slices_num = 5 filling_color = "#CBFA8E" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) /obj/item/reagent_containers/food/snacks/limecakeslice name = "lime cake slice" @@ -121,6 +135,7 @@ icon_state = "limecake_slice" trash = /obj/item/trash/plate filling_color = "#CBFA8E" + tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) /obj/item/reagent_containers/food/snacks/sliceable/lemoncake name = "lemon cake" @@ -131,6 +146,7 @@ bitesize = 3 filling_color = "#FAFA8E" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) /obj/item/reagent_containers/food/snacks/lemoncakeslice name = "lemon cake slice" @@ -138,6 +154,7 @@ icon_state = "lemoncake_slice" trash = /obj/item/trash/plate filling_color = "#FAFA8E" + tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) /obj/item/reagent_containers/food/snacks/sliceable/chocolatecake name = "chocolate cake" @@ -148,6 +165,7 @@ bitesize = 3 filling_color = "#805930" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) /obj/item/reagent_containers/food/snacks/chocolatecakeslice name = "chocolate cake slice" @@ -155,6 +173,7 @@ icon_state = "chocolatecake_slice" trash = /obj/item/trash/plate filling_color = "#805930" + tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) /obj/item/reagent_containers/food/snacks/sliceable/birthdaycake name = "birthday cake" @@ -165,6 +184,7 @@ filling_color = "#FFD6D6" bitesize = 3 list_reagents = list("nutriment" = 20, "sprinkles" = 10, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 1) /obj/item/reagent_containers/food/snacks/birthdaycakeslice name = "birthday cake slice" @@ -172,6 +192,7 @@ icon_state = "birthdaycakeslice" trash = /obj/item/trash/plate filling_color = "#FFD6D6" + tastes = list("cake" = 5, "sweetness" = 1) /obj/item/reagent_containers/food/snacks/sliceable/applecake name = "apple cake" @@ -182,6 +203,7 @@ bitesize = 3 filling_color = "#EBF5B8" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1) /obj/item/reagent_containers/food/snacks/applecakeslice name = "apple cake slice" @@ -189,6 +211,7 @@ icon_state = "applecakeslice" trash = /obj/item/trash/plate filling_color = "#EBF5B8" + tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1) ////////////////////// @@ -202,6 +225,7 @@ bitesize = 1 filling_color = "#DBC94F" list_reagents = list("nutriment" = 1, "sugar" = 3, "hot_coco" = 5 ) + tastes = list("cookie" = 1, "crunchy chocolate" = 1) /obj/item/reagent_containers/food/snacks/fortunecookie name = "fortune cookie" @@ -210,12 +234,14 @@ filling_color = "#E8E79E" list_reagents = list("nutriment" = 3) trash = /obj/item/paper/fortune + tastes = list("cookie" = 1) /obj/item/reagent_containers/food/snacks/sugarcookie name = "sugar cookie" desc = "Just like your little sister used to make." icon_state = "sugarcookie" list_reagents = list("nutriment" = 1, "sugar" = 3) + tastes = list("sweetness" = 1) ////////////////////// @@ -230,6 +256,7 @@ filling_color = "#FBFFB8" bitesize = 3 list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) + tastes = list("pie" = 1) /obj/item/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) ..() @@ -245,6 +272,7 @@ filling_color = "#948051" bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) + tastes = list("pie" = 1, "meat" = 1) /obj/item/reagent_containers/food/snacks/tofupie name = "tofu-pie" @@ -254,6 +282,7 @@ filling_color = "#FFFEE0" bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) + tastes = list("pie" = 1, "tofu" = 1) /obj/item/reagent_containers/food/snacks/amanita_pie name = "amanita pie" @@ -262,6 +291,7 @@ filling_color = "#FFCCCC" bitesize = 4 list_reagents = list("nutriment" = 6, "amanitin" = 3, "psilocybin" = 1, "vitamin" = 4) + tastes = list("pie" = 1, "mushroom" = 1) /obj/item/reagent_containers/food/snacks/plump_pie name = "plump pie" @@ -270,6 +300,7 @@ filling_color = "#B8279B" bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) + tastes = list("pie" = 1, "mushroom" = 1) /obj/item/reagent_containers/food/snacks/plump_pie/New() ..() @@ -285,6 +316,8 @@ trash = /obj/item/trash/plate filling_color = "#43DE18" list_reagents = list("nutriment" = 10, "vitamin" = 2) + tastes = list("pie" = 1, "meat" = 1, "acid" = 1) + /obj/item/reagent_containers/food/snacks/applepie name = "apple pie" @@ -293,6 +326,8 @@ filling_color = "#E0EDC5" bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) + tastes = list("pie" = 1, "apple" = 1) + /obj/item/reagent_containers/food/snacks/cherrypie name = "cherry pie" @@ -301,6 +336,7 @@ filling_color = "#FF525A" bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) + tastes = list("pie" = 1, "cherries" = 1) /obj/item/reagent_containers/food/snacks/sliceable/pumpkinpie name = "pumpkin pie" @@ -311,6 +347,7 @@ bitesize = 3 filling_color = "#F5B951" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("pie" = 1, "pumpkin" = 1) /obj/item/reagent_containers/food/snacks/pumpkinpieslice name = "pumpkin pie slice" @@ -318,7 +355,7 @@ icon_state = "pumpkinpieslice" trash = /obj/item/trash/plate filling_color = "#F5B951" - + tastes = list("pie" = 1, "pumpkin" = 1) ////////////////////// // Donuts // @@ -333,6 +370,7 @@ var/extra_reagent = null filling_color = "#D2691E" var/randomized_sprinkles = 1 + tastes = list("donut" = 1) /obj/item/reagent_containers/food/snacks/donut/New() ..() @@ -353,6 +391,7 @@ name = "chaos donut" desc = "Like life, it never quite tastes the same." bitesize = 10 + tastes = list("donut" = 3, "chaos" = 1) /obj/item/reagent_containers/food/snacks/donut/chaos/New() ..() @@ -369,6 +408,7 @@ desc = "You jelly?" icon_state = "jdonut1" extra_reagent = "berryjuice" + tastes = list("jelly" = 1, "donut" = 3) /obj/item/reagent_containers/food/snacks/donut/jelly/New() ..() @@ -403,6 +443,7 @@ icon_state = "muffin" filling_color = "#E0CF9B" list_reagents = list("nutriment" = 6) + tastes = list("muffin" = 1) /obj/item/reagent_containers/food/snacks/berryclafoutis name = "berry clafoutis" @@ -411,6 +452,8 @@ trash = /obj/item/trash/plate bitesize = 3 list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2) + tastes = list("pie" = 1, "blackberries" = 1) + /obj/item/reagent_containers/food/snacks/poppypretzel name = "poppy pretzel" @@ -418,6 +461,7 @@ icon_state = "poppypretzel" filling_color = "#916E36" list_reagents = list("nutriment" = 5) + tastes = list("pretzel" = 1) /obj/item/reagent_containers/food/snacks/plumphelmetbiscuit name = "plump helmet biscuit" @@ -425,6 +469,7 @@ icon_state = "phelmbiscuit" filling_color = "#CFB4C4" list_reagents = list("nutriment" = 5) + tastes = list("mushroom" = 1, "biscuit" = 1) /obj/item/reagent_containers/food/snacks/plumphelmetbiscuit/New() ..() @@ -441,6 +486,8 @@ filling_color = "#FFFF00" bitesize = 3 list_reagents = list("nutriment" = 8, "gold" = 5, "vitamin" = 4) + tastes = list("pie" = 1, "apple" = 1, "expensive metal" = 1) + /obj/item/reagent_containers/food/snacks/cracker name = "cracker" @@ -449,3 +496,4 @@ bitesize = 1 filling_color = "#F5DEB8" list_reagents = list("nutriment" = 1) + tastes = list("cracker" = 1) diff --git a/code/modules/food_and_drinks/food/foods/bread.dm b/code/modules/food_and_drinks/food/foods/bread.dm index c841f8d65fa..d888a532c01 100644 --- a/code/modules/food_and_drinks/food/foods/bread.dm +++ b/code/modules/food_and_drinks/food/foods/bread.dm @@ -11,6 +11,7 @@ slices_num = 5 filling_color = "#FF7575" list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) + tastes = list("bread" = 10, "meat" = 10) /obj/item/reagent_containers/food/snacks/meatbreadslice name = "meatbread slice" @@ -27,6 +28,7 @@ slices_num = 5 filling_color = "#8AFF75" list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) + tastes = list("bread" = 10, "acid" = 10) /obj/item/reagent_containers/food/snacks/xenomeatbreadslice name = "xenomeatbread slice" @@ -42,6 +44,7 @@ slice_path = /obj/item/reagent_containers/food/snacks/spidermeatbreadslice slices_num = 5 list_reagents = list("protein" = 20, "nutriment" = 10, "toxin" = 15, "vitamin" = 5) + tastes = list("bread" = 10, "cobwebs" = 5) /obj/item/reagent_containers/food/snacks/spidermeatbreadslice name = "spider meat bread slice" @@ -58,6 +61,7 @@ slices_num = 5 filling_color = "#EDE5AD" list_reagents = list("banana" = 20, "nutriment" = 20) + tastes = list("bread" = 10) /obj/item/reagent_containers/food/snacks/bananabreadslice name = "Banana-nut bread slice" @@ -65,6 +69,7 @@ icon_state = "bananabreadslice" trash = /obj/item/trash/plate filling_color = "#EDE5AD" + tastes = list("bread" = 10) /obj/item/reagent_containers/food/snacks/sliceable/tofubread name = "Tofubread" @@ -74,6 +79,7 @@ slices_num = 5 filling_color = "#F7FFE0" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("bread" = 10, "tofu" = 10) /obj/item/reagent_containers/food/snacks/tofubreadslice name = "Tofubread slice" @@ -90,6 +96,7 @@ slices_num = 6 filling_color = "#FFE396" list_reagents = list("nutriment" = 10) + tastes = list("bread" = 10) /obj/item/reagent_containers/food/snacks/breadslice name = "Bread slice" @@ -98,6 +105,7 @@ trash = /obj/item/trash/plate filling_color = "#D27332" list_reagents = list("nutriment" = 2, "bread" = 5) + tastes = list("bread" = 10) /obj/item/reagent_containers/food/snacks/sliceable/creamcheesebread name = "Cream Cheese Bread" @@ -107,6 +115,7 @@ slices_num = 5 filling_color = "#FFF896" list_reagents = list("nutriment" = 20, "vitamin" = 5) + tastes = list("bread" = 10, "cheese" = 10) /obj/item/reagent_containers/food/snacks/creamcheesebreadslice name = "Cream Cheese Bread slice" @@ -115,6 +124,7 @@ trash = /obj/item/trash/plate filling_color = "#FFF896" list_reagents = list("nutriment" = 4, "vitamin" = 1) + tastes = list("bread" = 10, "cheese" = 10) ////////////////////// @@ -127,6 +137,8 @@ icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "bun" list_reagents = list("nutriment" = 1) + tastes = list("bun" = 1) + /obj/item/reagent_containers/food/snacks/flatbread name = "flatbread" @@ -134,6 +146,7 @@ icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "flatbread" list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bread" = 2) /obj/item/reagent_containers/food/snacks/baguette name = "baguette" @@ -142,6 +155,7 @@ filling_color = "#E3D796" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bread" = 2) /obj/item/reagent_containers/food/snacks/twobread name = "Two Bread" @@ -150,6 +164,7 @@ filling_color = "#DBCC9A" bitesize = 3 list_reagents = list("nutriment" = 2, "vitamin" = 2) + tastes = list("bread" = 2) /obj/item/reagent_containers/food/snacks/jelliedtoast name = "Jellied Toast" @@ -158,6 +173,7 @@ trash = /obj/item/trash/plate filling_color = "#B572AB" bitesize = 3 + tastes = list("toast" = 1, "jelly" = 1) /obj/item/reagent_containers/food/snacks/jelliedtoast/cherry list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2) @@ -173,6 +189,7 @@ filling_color = "#FF00F7" bitesize = 4 list_reagents = list("nutriment" = 8, "psilocybin" = 2, "vitamin" = 2) + tastes = list("waffle" = 1, "mushrooms" = 1) /obj/item/reagent_containers/food/snacks/waffles name = "waffles" diff --git a/code/modules/food_and_drinks/food/foods/candy.dm b/code/modules/food_and_drinks/food/foods/candy.dm index 299b60cc8fa..aeab2b52128 100644 --- a/code/modules/food_and_drinks/food/foods/candy.dm +++ b/code/modules/food_and_drinks/food/foods/candy.dm @@ -12,6 +12,7 @@ desc = "It's placeholder flavored. This shouldn't be seen." icon = 'icons/obj/food/candy.dmi' icon_state = "candy" + tastes = list("candy" = 1) // *********************************************************** // Candy Ingredients / Flavorings / Byproduct @@ -23,6 +24,7 @@ icon_state = "chocolatebar" filling_color = "#7D5F46" list_reagents = list("nutriment" = 2, "chocolate" = 4) + tastes = list("chocolate" = 1) /obj/item/reagent_containers/food/snacks/candy/caramel name = "caramel" @@ -107,6 +109,7 @@ icon_state = "candycorn" filling_color = "#FFFCB0" list_reagents = list("nutriment" = 4, "sugar" = 2) + tastes = list("candy corn" = 1) // *********************************************************** // Candy Products (plain / unflavored) @@ -130,6 +133,7 @@ bitesize = 3 junkiness = 25 list_reagents = list("nutriment" = 1, "chocolate" = 1) + tastes = list("chocolate" = 1) /obj/item/reagent_containers/food/snacks/candy/candycane @@ -177,6 +181,8 @@ icon_state = "candy_cash" filling_color = "#302000" list_reagents = list("nutriment" = 2, "chocolate" = 4) + tastes = list("chocolate" = 1) + /obj/item/reagent_containers/food/snacks/candy/coin name = "chocolate coin" @@ -185,6 +191,8 @@ filling_color = "#302000" bitesize = 3 list_reagents = list("nutriment" = 2, "chocolate" = 4) + tastes = list("chocolate" = 1) + /obj/item/reagent_containers/food/snacks/candy/gum name = "bubblegum" diff --git a/code/modules/food_and_drinks/food/foods/desserts.dm b/code/modules/food_and_drinks/food/foods/desserts.dm index ff99efd07be..9e8ded0bd1b 100644 --- a/code/modules/food_and_drinks/food/foods/desserts.dm +++ b/code/modules/food_and_drinks/food/foods/desserts.dm @@ -10,6 +10,7 @@ icon_state = "icecream_cone" bitesize = 3 list_reagents = list("nutriment" = 1, "sugar" = 1) + tastes = list("ice cream" = 1) /obj/item/reagent_containers/food/snacks/icecream/New() ..() @@ -61,6 +62,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#FFFBDB" list_reagents = list("nutriment" = 7, "vitamin" = 2) + tastes = list("rice" = 1, "sweetness" = 1) /obj/item/reagent_containers/food/snacks/spacylibertyduff name = "Spacy Liberty Duff" @@ -70,6 +72,7 @@ filling_color = "#42B873" bitesize = 3 list_reagents = list("nutriment" = 6, "psilocybin" = 6) + tastes = list("jelly" = 1, "mushroom" = 1) /obj/item/reagent_containers/food/snacks/amanitajelly name = "Amanita Jelly" @@ -79,6 +82,7 @@ filling_color = "#ED0758" bitesize = 3 list_reagents = list("nutriment" = 6, "amanitin" = 6, "psilocybin" = 3) + tastes = list("jelly" = 1, "mushroom" = 1) /obj/item/reagent_containers/food/snacks/candiedapple name = "Candied Apple" @@ -87,6 +91,7 @@ filling_color = "#F21873" bitesize = 3 list_reagents = list("nutriment" = 3, "sugar" = 2) + tastes = list("apple" = 2, "sweetness" = 2) /obj/item/reagent_containers/food/snacks/mint name = "mint" diff --git a/code/modules/food_and_drinks/food/foods/ethnic.dm b/code/modules/food_and_drinks/food/foods/ethnic.dm index 9404992f5eb..0a160967858 100644 --- a/code/modules/food_and_drinks/food/foods/ethnic.dm +++ b/code/modules/food_and_drinks/food/foods/ethnic.dm @@ -9,6 +9,7 @@ icon_state = "taco" bitesize = 3 list_reagents = list("nutriment" = 7, "vitamin" = 1) + tastes = list("taco" = 4, "meat" = 2, "cheese" = 2, "lettuce" = 1) /obj/item/reagent_containers/food/snacks/burrito name = "burrito" @@ -17,6 +18,8 @@ trash = /obj/item/trash/plate filling_color = "#A36A1F" list_reagents = list("nutriment" = 4, "vitamin" = 1) + tastes = list("torilla" = 2, "meat" = 3) + /obj/item/reagent_containers/food/snacks/chimichanga name = "chimichanga" @@ -34,6 +37,7 @@ filling_color = "#A36A1F" bitesize = 4 list_reagents = list("nutriment" = 8, "capsaicin" = 6) + tastes = list("hot peppers" = 1, "meat" = 3, "cheese" = 1, "sour cream" = 1) /obj/item/reagent_containers/food/snacks/cornchips name = "corn chips" @@ -55,6 +59,7 @@ icon_state = "chinese1" junkiness = 25 list_reagents = list("nutriment" = 1, "beans" = 3, "msg" = 4, "sugar" = 2) + tastes = list("noodle" = 1, "vegetables" = 1) /obj/item/reagent_containers/food/snacks/chinese/sweetsourchickenball name = "sweet & sour chicken balls" @@ -62,6 +67,7 @@ icon_state = "chickenball" junkiness = 25 list_reagents = list("nutriment" = 2, "msg" = 4, "sugar" = 2) + tastes = list("chicken" = 1, "sweetness" = 1) /obj/item/reagent_containers/food/snacks/chinese/tao name = "Admiral Yamamoto carp" @@ -69,6 +75,7 @@ icon_state = "chinese2" junkiness = 25 list_reagents = list("nutriment" = 1, "protein" = 1, "msg" = 4, "sugar" = 4) + tastes = list("chicken" = 1) /obj/item/reagent_containers/food/snacks/chinese/newdles name = "chinese newdles" @@ -76,6 +83,7 @@ icon_state = "chinese3" junkiness = 25 list_reagents = list("nutriment" = 1, "msg" = 4, "sugar" = 3) + tastes = list("noodles" = 1) /obj/item/reagent_containers/food/snacks/chinese/rice name = "fried rice" @@ -83,6 +91,7 @@ icon_state = "chinese4" junkiness = 20 list_reagents = list("nutriment" = 1, "rice" = 3, "msg" = 4, "sugar" = 2) + tastes = list("rice" = 1) ////////////////////// @@ -96,6 +105,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#F0F2E4" list_reagents = list("nutriment" = 5) + tastes = list("custard" = 1) /obj/item/reagent_containers/food/snacks/yakiimo name = "yaki imo" @@ -104,6 +114,7 @@ trash = /obj/item/trash/plate list_reagents = list("nutriment" = 5, "vitamin" = 4) filling_color = "#8B1105" + tastes = list("sweet potato" = 1) ////////////////////// diff --git a/code/modules/food_and_drinks/food/foods/ingredients.dm b/code/modules/food_and_drinks/food/foods/ingredients.dm index 7dda7c0a1c0..8ab0ba3c5ce 100644 --- a/code/modules/food_and_drinks/food/foods/ingredients.dm +++ b/code/modules/food_and_drinks/food/foods/ingredients.dm @@ -10,6 +10,7 @@ filling_color = "#FFFEE0" bitesize = 3 list_reagents = list("plantmatter" = 2) + tastes = list("tofu" = 1) /obj/item/reagent_containers/food/snacks/fried_tofu name = "fried tofu" @@ -18,6 +19,7 @@ filling_color = "#FFFEE0" bitesize = 3 list_reagents = list("plantmatter" = 3) + tastes = list("tofu" = 1) /obj/item/reagent_containers/food/snacks/soydope name = "soy dope" @@ -26,6 +28,7 @@ trash = /obj/item/trash/plate filling_color = "#C4BF76" list_reagents = list("nutriment" = 2) + tastes = list("soy" = 1) ////////////////////// @@ -40,12 +43,14 @@ slices_num = 5 filling_color = "#FFF700" list_reagents = list("nutriment" = 15, "vitamin" = 5, "cheese" = 20) + tastes = list("cheese" = 1) /obj/item/reagent_containers/food/snacks/cheesewedge name = "cheese wedge" desc = "A wedge of delicious Cheddar. The cheese wheel it was cut from can't have gone far." icon_state = "cheesewedge" filling_color = "#FFF700" + tastes = list("cheese" = 1) /obj/item/reagent_containers/food/snacks/weirdcheesewedge name = "weird cheese" @@ -66,6 +71,7 @@ filling_color = "#E0D7C5" bitesize = 6 list_reagents = list("plantmatter" = 3, "vitamin" = 1) + tastes = list("mushroom" = 1) /obj/item/reagent_containers/food/snacks/tomatomeat name = "tomato slice" @@ -74,18 +80,21 @@ filling_color = "#DB0000" bitesize = 6 list_reagents = list("protein" = 2) + tastes = list("tomato" = 1) /obj/item/reagent_containers/food/snacks/watermelonslice name = "watermelon slice" desc = "A slice of watery goodness." icon_state = "watermelonslice" filling_color = "#FF3867" + tastes = list("watermelon" = 1) /obj/item/reagent_containers/food/snacks/pineappleslice name = "pineapple slices" desc = "Rings of pineapple." icon_state = "pineappleslice" filling_color = "#e5b437" + tastes = list("pineapple" = 1) ////////////////////// @@ -98,6 +107,7 @@ icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "dough" list_reagents = list("nutriment" = 6) + tastes = list("dough" = 1) // Dough + rolling pin = flat dough /obj/item/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user, params) @@ -120,6 +130,8 @@ slice_path = /obj/item/reagent_containers/food/snacks/doughslice slices_num = 3 list_reagents = list("nutriment" = 6) + tastes = list("dough" = 1) + /obj/item/reagent_containers/food/snacks/doughslice name = "dough slice" @@ -127,6 +139,7 @@ icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "doughslice" list_reagents = list("nutriment" = 1) + tastes = list("dough" = 1) ///cookies by Ume @@ -138,6 +151,8 @@ desc = "The base for tasty cookies." icon_state = "cookiedough" list_reagents = list("nutriment" = 5, "sugar" = 5) + tastes = list("dough" = 1, "sugar" = 1) + /obj/item/reagent_containers/food/snacks/cookiedough/update_icon() if(flat) @@ -193,6 +208,7 @@ icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "unbaked_cookies_choco" list_reagents = list("nutriment" = 5, "sugar" = 5, "chocolate" = 5) + tastes = list("dough" = 1, "sugar" = 1, "chocolate" = 1) ////////////////////// // Chocolate // @@ -204,6 +220,7 @@ icon_state = "chocolatebar" filling_color = "#7D5F46" list_reagents = list("nutriment" = 2, "sugar" = 2, "cocoa" = 2) + tastes = list("chocolate" = 1) ///Chocolate crumbles/pile /obj/item/reagent_containers/food/snacks/chocolatebar/attackby(obj/item/I, mob/user, params) @@ -224,6 +241,7 @@ icon_state = "cocoa" filling_color = "#7D5F46" list_reagents = list("chocolate" = 5) + tastes = list("chocolate" = 1) ////////////////////// @@ -236,3 +254,4 @@ icon = 'icons/obj/wizard.dmi' icon_state = "ectoplasm" list_reagents = list("ectoplasm" = 10) + tastes = list("spookiness" = 1) diff --git a/code/modules/food_and_drinks/food/foods/junkfood.dm b/code/modules/food_and_drinks/food/foods/junkfood.dm index 3fa20f0d1c3..ad174fcaddd 100644 --- a/code/modules/food_and_drinks/food/foods/junkfood.dm +++ b/code/modules/food_and_drinks/food/foods/junkfood.dm @@ -12,6 +12,7 @@ filling_color = "#E8C31E" junkiness = 20 list_reagents = list("nutriment" = 1, "sodiumchloride" = 1, "sugar" = 3) + tastes = list("crisps" = 1) /obj/item/reagent_containers/food/snacks/sosjerky name = "Scaredy's Private Reserve Beef Jerky" @@ -21,6 +22,7 @@ filling_color = "#631212" junkiness = 25 list_reagents = list("protein" = 1, "sugar" = 3) + tastes = list("chewy beef" = 1) /obj/item/reagent_containers/food/snacks/pistachios name = "pistachios" @@ -30,6 +32,7 @@ filling_color = "#BAD145" junkiness = 20 list_reagents = list("plantmatter" = 2, "sodiumchloride" = 1, "sugar" = 4) + tastes = list("pistachios" = 1) /obj/item/reagent_containers/food/snacks/no_raisin name = "4no Raisins" @@ -39,6 +42,7 @@ filling_color = "#343834" junkiness = 25 list_reagents = list("plantmatter" = 2, "sugar" = 4) + tastes = list("dried raisins" = 1) /obj/item/reagent_containers/food/snacks/spacetwinkie name = "Space Twinkie" @@ -47,6 +51,7 @@ filling_color = "#FFE591" junkiness = 25 list_reagents = list("sugar" = 4) + tastes = list("twinkies" = 1) /obj/item/reagent_containers/food/snacks/cheesiehonkers name = "Cheesie Honkers" @@ -56,6 +61,7 @@ filling_color = "#FFA305" junkiness = 25 list_reagents = list("nutriment" = 1, "fake_cheese" = 2, "sugar" = 3) + tastes = list("cheese" = 1, "crisps" = 2) /obj/item/reagent_containers/food/snacks/syndicake name = "Syndi-Cakes" @@ -65,6 +71,7 @@ trash = /obj/item/trash/syndi_cakes bitesize = 3 list_reagents = list("nutriment" = 4, "salglu_solution" = 5) + tastes = list("sweetness" = 3, "cake" = 1) /obj/item/reagent_containers/food/snacks/tastybread name = "bread tube" @@ -74,6 +81,7 @@ filling_color = "#A66829" junkiness = 20 list_reagents = list("nutriment" = 2, "sugar" = 4) + tastes = list("bread" = 1) ////////////////////// diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm index d19a88fcea8..8e667bab885 100644 --- a/code/modules/food_and_drinks/food/foods/meat.dm +++ b/code/modules/food_and_drinks/food/foods/meat.dm @@ -11,6 +11,7 @@ filling_color = "#FF1C1C" bitesize = 3 list_reagents = list("protein" = 3) + tastes = list("meat" = 1) /obj/item/reagent_containers/food/snacks/meat/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/kitchen/knife) || istype(W, /obj/item/scalpel)) @@ -30,6 +31,7 @@ name = "-meat" var/subjectname = "" var/subjectjob = null + tastes = list("tender meat" = 1) /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct name = "meat product" @@ -83,6 +85,7 @@ filling_color = "#DB0000" bitesize = 3 list_reagents = list("protein" = 12, "morphine" = 5, "vitamin" = 2) + tastes = list("meat" = 1, "salmon" = 1) /obj/item/reagent_containers/food/snacks/xenomeat name = "meat" @@ -91,6 +94,7 @@ filling_color = "#43DE18" bitesize = 6 list_reagents = list("protein" = 3, "vitamin" = 1) + tastes = list("meat" = 1, "acid" = 1) /obj/item/reagent_containers/food/snacks/spidermeat name = "spider meat" @@ -98,6 +102,7 @@ icon_state = "spidermeat" bitesize = 3 list_reagents = list("protein" = 3, "toxin" = 3, "vitamin" = 1) + tastes = list("cobwebs" = 1) /obj/item/reagent_containers/food/snacks/lizardmeat name = "mutant lizard meat" @@ -106,30 +111,35 @@ filling_color = "#43DE18" bitesize = 3 list_reagents = list("protein" = 3, "toxin" = 3) + tastes = list("tough meat" = 1) /obj/item/reagent_containers/food/snacks/spiderleg name = "spider leg" desc = "A still twitching leg of a giant spider. You don't really want to eat this, do you?" icon_state = "spiderleg" list_reagents = list("protein" = 2, "toxin" = 2) + tastes = list("cobwebs" = 1, "creepy motion" = 1) /obj/item/reagent_containers/food/snacks/raw_bacon name = "raw bacon" desc = "God's gift to man in uncooked form." icon_state = "raw_bacon" list_reagents = list("nutriment" = 1, "porktonium" = 10) + tastes = list("bacon" = 1) /obj/item/reagent_containers/food/snacks/spidereggs name = "spider eggs" desc = "A cluster of juicy spider eggs. A great side dish for when you don't care about your health." icon_state = "spidereggs" list_reagents = list("protein" = 2, "toxin" = 2) + tastes = list("cobwebs" = 1, "spider juice" = 1) /obj/item/reagent_containers/food/snacks/goliath name = "goliath meat" desc = "A slab of goliath meat. It's not very edible now, but it cooks great in lava." icon_state = "goliathmeat" list_reagents = list("protein" = 3, "toxin" = 5) + tastes = list("tough meat" = 1) /obj/item/reagent_containers/food/snacks/goliath/burn() visible_message("[src] finishes cooking!") @@ -148,12 +158,14 @@ filling_color = "#7A3D11" bitesize = 3 list_reagents = list("nutriment" = 5) + tastes = list("meat" = 1) /obj/item/reagent_containers/food/snacks/bacon name = "bacon" desc = "It looks crispy and tastes amazing! Mmm... Bacon." icon_state = "bacon" list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4) + tastes = list("bacon" = 1) /obj/item/reagent_containers/food/snacks/telebacon name = "tele bacon" @@ -161,6 +173,7 @@ icon_state = "bacon" var/obj/item/radio/beacon/bacon/baconbeacon list_reagents = list("nutriment" = 4, "porktonium" = 10) + tastes = list("bacon" = 1) /obj/item/reagent_containers/food/snacks/telebacon/New() ..() @@ -178,6 +191,7 @@ icon_state = "meatball" filling_color = "#DB0000" list_reagents = list("protein" = 4, "vitamin" = 1) + tastes = list("meat" = 1) /obj/item/reagent_containers/food/snacks/sausage name = "sausage" @@ -185,6 +199,7 @@ icon_state = "sausage" filling_color = "#DB0000" list_reagents = list("protein" = 6, "vitamin" = 1, "porktonium" = 10) + tastes = list("meat" = 1) /obj/item/reagent_containers/food/snacks/cutlet name = "cutlet" @@ -192,6 +207,7 @@ icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "cutlet" list_reagents = list("protein" = 2) + tastes = list("meat" = 1) /obj/item/reagent_containers/food/snacks/spidereggsham name = "green eggs and ham" @@ -200,6 +216,7 @@ trash = /obj/item/trash/plate bitesize = 4 list_reagents = list("nutriment" = 6) + tastes = list("cobwebs" = 1, "the colour green" = 1) /obj/item/reagent_containers/food/snacks/boiledspiderleg name = "boiled spider leg" @@ -208,6 +225,7 @@ trash = /obj/item/trash/plate bitesize = 3 list_reagents = list("nutriment" = 3, "capsaicin" = 2) + tastes = list("cobwebs" = 1, "hot peppers" = 1) /obj/item/reagent_containers/food/snacks/wingfangchu name = "wing fang chu" @@ -216,6 +234,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#43DE18" list_reagents = list("nutriment" = 6, "soysauce" = 5, "vitamin" = 2) + tastes = list("soy" = 1) /obj/item/reagent_containers/food/snacks/goliath_steak name = "goliath steak" @@ -224,6 +243,7 @@ icon_state = "goliathsteak" trash = null list_reagents = list("protein" = 6, "vitamin" = 2) + tastes = list("meat" = 1) ////////////////////// // Cubes // @@ -238,6 +258,7 @@ var/faction var/datum/species/monkey_type = /datum/species/monkey list_reagents = list("nutriment" = 2) + tastes = list("the jungle" = 1, "bananas" = 1) /obj/item/reagent_containers/food/snacks/monkeycube/water_act(volume, temperature, source, method = TOUCH) . = ..() @@ -294,6 +315,8 @@ icon_state = "egg" filling_color = "#FDFFD1" list_reagents = list("protein" = 1, "egg" = 5) + tastes = list("egg" = 1) + /obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) ..() @@ -367,6 +390,7 @@ filling_color = "#FFDF78" bitesize = 1 list_reagents = list("nutriment" = 3, "egg" = 5) + tastes = list("egg" = 1, "salt" = 1, "pepper" = 1) /obj/item/reagent_containers/food/snacks/boiledegg name = "boiled egg" @@ -390,6 +414,7 @@ filling_color = "#FFF9A8" list_reagents = list("nutriment" = 8, "vitamin" = 1) bitesize = 1 + tastes = list("egg" = 1, "cheese" = 1) /obj/item/reagent_containers/food/snacks/benedict name = "eggs benedict" @@ -397,6 +422,7 @@ icon_state = "benedict" bitesize = 3 list_reagents = list("nutriment" = 6, "egg" = 3, "vitamin" = 4) + tastes = list("egg" = 1, "bacon" = 1, "bun" = 1) ////////////////////// @@ -409,6 +435,7 @@ icon_state = "hotdog" bitesize = 3 list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3) + tastes = list("bun" = 3, "meat" = 2) /obj/item/reagent_containers/food/snacks/meatbun name = "meat bun" @@ -416,6 +443,7 @@ icon_state = "meatbun" bitesize = 6 list_reagents = list("nutriment" = 6, "vitamin" = 2) + tastes = list("bun" = 3, "meat" = 2) /obj/item/reagent_containers/food/snacks/sliceable/turkey name = "turkey" @@ -424,6 +452,7 @@ slice_path = /obj/item/reagent_containers/food/snacks/turkeyslice slices_num = 6 list_reagents = list("protein" = 24, "nutriment" = 18, "vitamin" = 5) + tastes = list("turkey" = 2, "stuffing" = 2) /obj/item/reagent_containers/food/snacks/turkeyslice name = "turkey serving" @@ -431,6 +460,7 @@ icon_state = "turkeyslice" trash = /obj/item/trash/plate filling_color = "#B97A57" + tastes = list("turkey" = 1) /obj/item/reagent_containers/food/snacks/organ name = "organ" diff --git a/code/modules/food_and_drinks/food/foods/misc.dm b/code/modules/food_and_drinks/food/foods/misc.dm index 4845fe4d608..1fcd4a52c18 100644 --- a/code/modules/food_and_drinks/food/foods/misc.dm +++ b/code/modules/food_and_drinks/food/foods/misc.dm @@ -10,6 +10,7 @@ trash = /obj/item/trash/plate filling_color = "#4D2F5E" list_reagents = list("nutriment" = 6, "vitamin" = 2) + tastes = list("eggplant" = 2, "cheese" = 2) /obj/item/reagent_containers/food/snacks/soylentgreen name = "soylent green" @@ -18,6 +19,7 @@ trash = /obj/item/trash/waffles filling_color = "#B8E6B5" list_reagents = list("nutriment" = 10, "vitamin" = 1) + tastes = list("waffles" = 7, "people" = 1) /obj/item/reagent_containers/food/snacks/soylentviridians name = "soylent virdians" @@ -26,6 +28,7 @@ trash = /obj/item/trash/waffles filling_color = "#E6FA61" list_reagents = list("nutriment" = 10, "vitamin" = 1) + tastes = list("waffles" = 10) /obj/item/reagent_containers/food/snacks/monkeysdelight name = "monkey's delight" @@ -35,6 +38,7 @@ filling_color = "#5C3C11" bitesize = 6 list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5) + tastes = list("banana" = 1, "the jungle" = 1) /obj/item/reagent_containers/food/snacks/dionaroast name = "roast diona" @@ -43,6 +47,7 @@ trash = /obj/item/trash/plate filling_color = "#75754B" list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2, "vitamin" = 4) + tastes = list("chewy vegetables" = 1) /obj/item/reagent_containers/food/snacks/tofurkey name = "tofurkey" @@ -51,6 +56,7 @@ filling_color = "#FFFEE0" bitesize = 3 list_reagents = list("nutriment" = 12, "ether" = 3) + tastes = list("tofu" = 1) ////////////////////// @@ -65,6 +71,7 @@ filling_color = "#468C00" bitesize = 3 list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6) + tastes = list("divinity" = 1, "lettuce" = 1) /obj/item/reagent_containers/food/snacks/herbsalad name = "herb salad" @@ -74,6 +81,7 @@ filling_color = "#76B87F" bitesize = 3 list_reagents = list("nutriment" = 8, "vitamin" = 2) + tastes = list("lettuce" = 1, "apple" = 1) /obj/item/reagent_containers/food/snacks/validsalad name = "valid salad" @@ -83,6 +91,7 @@ filling_color = "#76B87F" bitesize = 3 list_reagents = list("nutriment" = 8, "salglu_solution" = 5, "vitamin" = 2) + tastes = list("fried potato" = 1, "lettuce" = 1, "meat" = 1, "valids" = 1) ////////////////////// @@ -95,6 +104,7 @@ icon_state = "donkpocket" filling_color = "#DEDEAB" list_reagents = list("nutriment" = 4) + tastes = list("meat" = 2, "dough" = 2, "laziness" = 1) /obj/item/reagent_containers/food/snacks/warmdonkpocket name = "warm Donk-pocket" @@ -102,6 +112,7 @@ icon_state = "donkpocket" filling_color = "#DEDEAB" list_reagents = list("nutriment" = 4) + tastes = list("meat" = 2, "dough" = 2, "laziness" = 1) /obj/item/reagent_containers/food/snacks/warmdonkpocket/Post_Consume(mob/living/M) M.reagents.add_reagent("omnizine", 15) @@ -140,6 +151,7 @@ icon_state = "boiledrorocore" bitesize = 3 list_reagents = list("slimejelly" = 5) + tastes = list("jelly" = 3) /obj/item/reagent_containers/food/snacks/popcorn name = "Popcorn" @@ -150,6 +162,7 @@ filling_color = "#FFFAD4" bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 list_reagents = list("nutriment" = 2) + tastes = list("popcorn" = 3, "butter" = 1) /obj/item/reagent_containers/food/snacks/popcorn/New() ..() diff --git a/code/modules/food_and_drinks/food/foods/pasta.dm b/code/modules/food_and_drinks/food/foods/pasta.dm index 77bfb0728ca..41de9f4f565 100644 --- a/code/modules/food_and_drinks/food/foods/pasta.dm +++ b/code/modules/food_and_drinks/food/foods/pasta.dm @@ -10,6 +10,7 @@ icon_state = "spaghetti" filling_color = "#EDDD00" list_reagents = list("nutriment" = 1, "vitamin" = 1) + tastes = list("raw pasta" = 1) /obj/item/reagent_containers/food/snacks/macaroni name = "macaroni twists" @@ -18,6 +19,7 @@ icon_state = "macaroni" filling_color = "#EDDD00" list_reagents = list("nutriment" = 1, "vitamin" = 1) + tastes = list("raw pasta" = 1) ////////////////////// @@ -32,6 +34,7 @@ trash = /obj/item/trash/plate filling_color = "#FCEE81" list_reagents = list("nutriment" = 2, "vitamin" = 1) + tastes = list("pasta" = 1) /obj/item/reagent_containers/food/snacks/pastatomato name = "spaghetti" @@ -42,6 +45,7 @@ filling_color = "#DE4545" bitesize = 4 list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) + tastes = list("pasta" = 1, "tomato" = 1) /obj/item/reagent_containers/food/snacks/meatballspaghetti name = "spaghetti & meatballs" @@ -51,6 +55,7 @@ trash = /obj/item/trash/plate filling_color = "#DE4545" list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4) + tastes = list("pasta" = 1, "tomato" = 1, "meat" = 1) /obj/item/reagent_containers/food/snacks/spesslaw name = "Spesslaw" @@ -59,6 +64,7 @@ icon_state = "spesslaw" filling_color = "#DE4545" list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6) + tastes = list("pasta" = 1, "tomato" = 1, "meat" = 2) /obj/item/reagent_containers/food/snacks/macncheese name = "mac n cheese" @@ -68,10 +74,12 @@ icon_state = "macncheese" filling_color = "#ffe45d" list_reagents = list("nutriment" = 5, "vitamin" = 2, "cheese" = 4) + tastes = list("pasta" = 1, "cheese" = 1, "comfort" = 1) /obj/item/reagent_containers/food/snacks/lasagna name = "Lasagna" icon_state = "lasagna" - desc = "Tajarans loves to eat this, for some reason." + desc = "Tajara love to eat this, for some reason." filling_color = "#E18712" list_reagents = list("nutriment" = 10, "msg" = 3, "vitamin" = 4, "tomatojuice" = 10) + tastes = list("pasta" = 1, "cheese" = 1, "tomato" = 1, "meat" = 1) diff --git a/code/modules/food_and_drinks/food/foods/pizza.dm b/code/modules/food_and_drinks/food/foods/pizza.dm index cbe7342b74b..e1290d9148a 100644 --- a/code/modules/food_and_drinks/food/foods/pizza.dm +++ b/code/modules/food_and_drinks/food/foods/pizza.dm @@ -7,6 +7,7 @@ icon = 'icons/obj/food/pizza.dmi' slices_num = 6 filling_color = "#BAA14C" + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) /obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita name = "margherita pizza" @@ -22,6 +23,7 @@ icon_state = "pizzamargheritaslice" filling_color = "#BAA14C" list_reagents = list("nutriment" = 5) + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) /obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza name = "meat pizza" @@ -29,6 +31,7 @@ icon_state = "meatpizza" slice_path = /obj/item/reagent_containers/food/snacks/meatpizzaslice list_reagents = list("protein" = 30, "tomatojuice" = 6, "vitamin" = 8) + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1) /obj/item/reagent_containers/food/snacks/meatpizzaslice name = "meat pizza slice" @@ -36,6 +39,7 @@ icon = 'icons/obj/food/pizza.dmi' icon_state = "meatpizzaslice" filling_color = "#BAA14C" + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1) /obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza name = "mushroom pizza" @@ -43,6 +47,8 @@ icon_state = "mushroompizza" slice_path = /obj/item/reagent_containers/food/snacks/mushroompizzaslice list_reagents = list("plantmatter" = 30, "vitamin" = 5) + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "mushroom" = 1) + /obj/item/reagent_containers/food/snacks/mushroompizzaslice name = "mushroom pizza slice" @@ -50,6 +56,7 @@ icon = 'icons/obj/food/pizza.dmi' icon_state = "mushroompizzaslice" filling_color = "#BAA14C" + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "mushroom" = 1) /obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza name = "vegetable pizza" @@ -57,6 +64,8 @@ icon_state = "vegetablepizza" slice_path = /obj/item/reagent_containers/food/snacks/vegetablepizzaslice list_reagents = list("plantmatter" = 25, "tomatojuice" = 6, "oculine" = 12, "vitamin" = 5) + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "carrot" = 1, "vegetables" = 1) + /obj/item/reagent_containers/food/snacks/vegetablepizzaslice name = "vegetable pizza slice" @@ -64,6 +73,7 @@ icon = 'icons/obj/food/pizza.dmi' icon_state = "vegetablepizzaslice" filling_color = "#BAA14C" + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "carrot" = 1, "vegetables" = 1) /obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza name = "Hawaiian pizza" @@ -71,6 +81,7 @@ icon_state = "hawaiianpizza" //NEEDED slice_path = /obj/item/reagent_containers/food/snacks/hawaiianpizzaslice list_reagents = list("protein" = 15, "tomatojuice" = 6, "plantmatter" = 20, "pineapplejuice" = 6, "vitamin" = 5) + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "pineapple" = 1) /obj/item/reagent_containers/food/snacks/hawaiianpizzaslice name = "Hawaiian pizza slice" @@ -78,6 +89,7 @@ icon = 'icons/obj/food/pizza.dmi' icon_state = "hawaiianpizzaslice" filling_color = "#e5b437" + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "pineapple" = 1) /obj/item/reagent_containers/food/snacks/sliceable/pizza/macpizza name = "mac n cheese pizza" @@ -86,6 +98,7 @@ slice_path = /obj/item/reagent_containers/food/snacks/macpizzaslice list_reagents = list("nutriment" = 40, "vitamin" = 5) //More nutriment because carbs, but it's not any more vitaminicious filling_color = "#ffe45d" + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 2, "pasta" = 1) /obj/item/reagent_containers/food/snacks/macpizzaslice name = "mac n cheese pizza slice" @@ -93,6 +106,7 @@ icon = 'icons/obj/food/pizza.dmi' icon_state = "macpizzaslice" filling_color = "#ffe45d" + tastes = list("crust" = 1, "tomato" = 1, "cheese" = 2, "pasta" = 1) ////////////////////// diff --git a/code/modules/food_and_drinks/food/foods/sandwiches.dm b/code/modules/food_and_drinks/food/foods/sandwiches.dm index 43f1b31df0e..216e56af9f9 100644 --- a/code/modules/food_and_drinks/food/foods/sandwiches.dm +++ b/code/modules/food_and_drinks/food/foods/sandwiches.dm @@ -10,6 +10,7 @@ filling_color = "#F2B6EA" bitesize = 3 list_reagents = list("nutriment" = 6, "prions" = 10, "vitamin" = 1) + tastes = list("bun" = 4, "brains" = 2) /obj/item/reagent_containers/food/snacks/ghostburger name = "ghost burger" @@ -18,6 +19,7 @@ filling_color = "#FFF2FF" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "ectoplasm" = 2) /obj/item/reagent_containers/food/snacks/human var/hname = "" @@ -30,6 +32,7 @@ icon_state = "hburger" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "tender meat" = 2) /obj/item/reagent_containers/food/snacks/cheeseburger name = "cheeseburger" @@ -37,6 +40,7 @@ icon_state = "cheeseburger" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "meat" = 1, "cheese" = 1) /obj/item/reagent_containers/food/snacks/monkeyburger name = "burger" @@ -45,6 +49,7 @@ filling_color = "#D63C3C" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "meat" = 1, "the jungle" = 1) /obj/item/reagent_containers/food/snacks/tofuburger name = "tofu burger" @@ -53,6 +58,7 @@ filling_color = "#FFFEE0" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "tofu" = 4) /obj/item/reagent_containers/food/snacks/roburger name = "roburger" @@ -61,6 +67,7 @@ filling_color = "#CCCCCC" bitesize = 3 list_reagents = list("nutriment" = 6, "nanomachines" = 10, "vitamin" = 1) + tastes = list("bun" = 4, "lettuce" = 2, "sludge" = 1) /obj/item/reagent_containers/food/snacks/roburgerbig name = "roburger" @@ -70,6 +77,7 @@ volume = 120 bitesize = 3 list_reagents = list("nutriment" = 6, "nanomachines" = 70, "vitamin" = 5) + tastes = list("bun" = 4, "lettuce" = 2, "sludge" = 2) /obj/item/reagent_containers/food/snacks/xenoburger name = "xenoburger" @@ -78,6 +86,7 @@ filling_color = "#43DE18" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "acid" = 4) /obj/item/reagent_containers/food/snacks/clownburger name = "clown burger" @@ -86,6 +95,7 @@ filling_color = "#FF00FF" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "banana" = 1, "magic" = 2) /obj/item/reagent_containers/food/snacks/mimeburger name = "mime burger" @@ -94,6 +104,7 @@ filling_color = "#FFFFFF" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "silence" = 2) /obj/item/reagent_containers/food/snacks/baseballburger name = "home run baseball burger" @@ -102,6 +113,7 @@ filling_color = "#CD853F" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4) /obj/item/reagent_containers/food/snacks/spellburger name = "spell burger" @@ -110,6 +122,7 @@ filling_color = "#D505FF" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "magic" = 2) /obj/item/reagent_containers/food/snacks/bigbiteburger name = "BigBite burger" @@ -118,6 +131,7 @@ filling_color = "#E3D681" bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) + tastes = list("bun" = 4, "meat" = 2, "cheese" = 2, "type two diabetes" = 10) /obj/item/reagent_containers/food/snacks/superbiteburger name = "SuperBite burger" @@ -126,6 +140,7 @@ filling_color = "#CCA26A" bitesize = 7 list_reagents = list("nutriment" = 40, "vitamin" = 5) + tastes = list("bun" = 4, "meat" = 2, "cheese" = 2, "type two diabetes" = 10) /obj/item/reagent_containers/food/snacks/jellyburger name = "jelly burger" @@ -133,6 +148,7 @@ icon_state = "jellyburger" filling_color = "#B572AB" bitesize = 3 + tastes = list("bun" = 4, "jelly" = 2) /obj/item/reagent_containers/food/snacks/jellyburger/slime list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1) @@ -152,6 +168,7 @@ trash = /obj/item/trash/plate filling_color = "#D9BE29" list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("meat" = 2, "cheese" = 1, "bread" = 2, "lettuce" = 1) /obj/item/reagent_containers/food/snacks/toastedsandwich name = "toasted sandwich" @@ -160,6 +177,7 @@ trash = /obj/item/trash/plate filling_color = "#D9BE29" list_reagents = list("nutriment" = 6, "carbon" = 2) + tastes = list("toast" = 1) /obj/item/reagent_containers/food/snacks/grilledcheese name = "grilled cheese sandwich" @@ -168,6 +186,7 @@ trash = /obj/item/trash/plate filling_color = "#D9BE29" list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value? + tastes = list("toast" = 1, "grilled cheese" = 1) /obj/item/reagent_containers/food/snacks/jellysandwich name = "jelly sandwich" @@ -176,6 +195,7 @@ trash = /obj/item/trash/plate filling_color = "#9E3A78" bitesize = 3 + tastes = list("toast" = 1, "jelly" = 1) /obj/item/reagent_containers/food/snacks/jellysandwich/slime list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2) @@ -188,9 +208,11 @@ desc = "Something seems to be wrong with this, you can't quite figure what. Maybe it's his moustache." icon_state = "notasandwich" list_reagents = list("nutriment" = 6, "vitamin" = 6) + tastes = list("nothing suspicious" = 1) /obj/item/reagent_containers/food/snacks/wrap name = "egg wrap" desc = "The precursor to Pigs in a Blanket." icon_state = "wrap" list_reagents = list("nutriment" = 5) + tastes = list("egg" = 1) diff --git a/code/modules/food_and_drinks/food/foods/seafood.dm b/code/modules/food_and_drinks/food/foods/seafood.dm index 9e4407d9602..007af8f6eb9 100644 --- a/code/modules/food_and_drinks/food/foods/seafood.dm +++ b/code/modules/food_and_drinks/food/foods/seafood.dm @@ -7,6 +7,7 @@ filling_color = "#FFDEFE" bitesize = 6 list_reagents = list("protein" = 3, "carpotoxin" = 2, "vitamin" = 2) + tastes = list("white fish" = 1) /obj/item/reagent_containers/food/snacks/salmonmeat name = "raw salmon" @@ -16,6 +17,7 @@ filling_color = "#FFDEFE" bitesize = 6 list_reagents = list("protein" = 3, "vitamin" = 2) + tastes = list("raw salmon" = 1) /obj/item/reagent_containers/food/snacks/salmonsteak name = "salmon steak" @@ -26,6 +28,7 @@ filling_color = "#7A3D11" bitesize = 3 list_reagents = list("nutriment" = 4, "vitamin" = 2) + tastes = list("cooked salmon" = 1) /obj/item/reagent_containers/food/snacks/catfishmeat name = "raw catfish" @@ -35,6 +38,7 @@ filling_color = "#FFDEFE" bitesize = 6 list_reagents = list("protein" = 3, "vitamin" = 2) + tastes = list("catfish" = 1) /obj/item/reagent_containers/food/snacks/fishfingers name = "fish fingers" @@ -44,6 +48,7 @@ filling_color = "#FFDEFE" bitesize = 1 list_reagents = list("nutriment" = 4) + tastes = list("fish" = 1, "bread" = 1) /obj/item/reagent_containers/food/snacks/fishburger name = "Fillet-O-Carp sandwich" @@ -53,6 +58,7 @@ filling_color = "#FFDEFE" bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) + tastes = list("bun" = 4, "fish" = 4) /obj/item/reagent_containers/food/snacks/cubancarp name = "Cuban carp" @@ -63,6 +69,7 @@ filling_color = "#E9ADFF" bitesize = 3 list_reagents = list("nutriment" = 6, "capsaicin" = 1) + tastes = list("fish" = 4, "batter" = 1, "hot peppers" = 1) /obj/item/reagent_containers/food/snacks/fishandchips name = "fish and chips" @@ -72,6 +79,7 @@ filling_color = "#E3D796" bitesize = 3 list_reagents = list("nutriment" = 6) + tastes = list("fish" = 1, "chips" = 1) /obj/item/reagent_containers/food/snacks/sashimi name = "carp sashimi" @@ -80,6 +88,7 @@ icon_state = "sashimi" bitesize = 3 list_reagents = list("nutriment" = 6, "capsaicin" = 5) + tastes = list("raw carp" = 1, "hot peppers" = 1) /obj/item/reagent_containers/food/snacks/fried_shrimp name = "fried shrimp" @@ -88,6 +97,7 @@ icon_state = "shrimp_fried" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("shrimp" = 1, "bread crumbs" = 1) /obj/item/reagent_containers/food/snacks/boiled_shrimp name = "boiled shrimp" @@ -96,6 +106,7 @@ icon_state = "shrimp_cooked" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("shrimp" = 1) /obj/item/reagent_containers/food/snacks/shrimp_skewer name = "shrimp skewer" @@ -105,6 +116,7 @@ icon_state = "shrimpskewer" bitesize = 3 list_reagents = list("nutriment" = 8) + tastes = list("shrimp" = 4) /obj/item/reagent_containers/food/snacks/fish_skewer name = "fish skewer" @@ -114,6 +126,7 @@ icon_state = "fishskewer" bitesize = 3 list_reagents = list("protein" = 6, "vitamin" = 4) + tastes = list("shrimp" = 1, "batter" = 1) /obj/item/reagent_containers/food/snacks/sliceable/Ebi_maki name = "ebi makiroll" @@ -124,6 +137,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8) + tastes = list("shrimp" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Ebi name = "ebi sushi" @@ -132,6 +146,7 @@ icon_state = "sushi_Ebi" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("shrimp" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/Ikura_maki name = "ikura makiroll" @@ -142,6 +157,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8, "protein" = 4) + tastes = list("salmon roe" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Ikura name = "ikura sushi" @@ -150,16 +166,18 @@ icon_state = "sushi_Ikura" bitesize = 3 list_reagents = list("nutriment" = 2, "protein" = 1) + tastes = list("salmon roe" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/Sake_maki name = "sake makiroll" - desc = "A large unsliced roll of Ebi Sushi." + desc = "A large unsliced roll of Sake Sushi." icon = 'icons/obj/food/seafood.dmi' icon_state = "Sake_maki" slice_path = /obj/item/reagent_containers/food/snacks/sushi_Sake slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8) + tastes = list("raw salmon" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Sake name = "sake sushi" @@ -168,6 +186,7 @@ icon_state = "sushi_Sake" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("raw salmon" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/SmokedSalmon_maki name = "smoked salmon makiroll" @@ -178,6 +197,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8) + tastes = list("smoked salmon" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_SmokedSalmon name = "smoked salmon sushi" @@ -186,6 +206,7 @@ icon_state = "sushi_SmokedSalmon" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("smoked salmon" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/Tamago_maki name = "tamago makiroll" @@ -196,6 +217,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8) + tastes = list("egg" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Tamago name = "tamago sushi" @@ -204,6 +226,7 @@ icon_state = "sushi_Tamago" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("egg" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/Inari_maki name = "inari makiroll" @@ -214,6 +237,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8) + tastes = list("fried tofu" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Inari name = "inari sushi" @@ -222,6 +246,7 @@ icon_state = "sushi_Inari" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("fried tofu" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/Masago_maki name = "masago makiroll" @@ -232,6 +257,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8, "protein" = 4) + tastes = list("goldfish roe" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Masago name = "masago sushi" @@ -240,6 +266,7 @@ icon_state = "sushi_Masago" bitesize = 3 list_reagents = list("nutriment" = 2, "protein" = 1) + tastes = list("goldfish roe" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/Tobiko_maki name = "tobiko makiroll" @@ -250,6 +277,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8, "protein" = 4) + tastes = list("shark roe" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Tobiko name = "tobiko sushi" @@ -258,6 +286,7 @@ icon_state = "sushi_Masago" bitesize = 3 list_reagents = list("nutriment" = 2, "protein" = 1) + tastes = list("shark roe" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/TobikoEgg_maki name = "tobiko and egg makiroll" @@ -268,6 +297,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8, "protein" = 4) + tastes = list("shark roe" = 1, "rice" = 1, "egg" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_TobikoEgg name = "tobiko and egg sushi" @@ -276,6 +306,7 @@ icon_state = "sushi_TobikoEgg" bitesize = 3 list_reagents = list("nutriment" = 2, "protein" = 1) + tastes = list("shark roe" = 1, "rice" = 1, "egg" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sliceable/Tai_maki name = "tai makiroll" @@ -286,6 +317,7 @@ slices_num = 4 bitesize = 3 list_reagents = list("nutriment" = 8) + tastes = list("catfish" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Tai name = "tai sushi" @@ -294,6 +326,7 @@ icon_state = "sushi_Tai" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("catfish" = 1, "rice" = 1, "seaweed" = 1) /obj/item/reagent_containers/food/snacks/sushi_Unagi name = "unagi sushi" @@ -302,3 +335,4 @@ icon_state = "sushi_Hokki" bitesize = 3 list_reagents = list("nutriment" = 2) + tastes = list("grilled eel" = 1, "seaweed" = 1) diff --git a/code/modules/food_and_drinks/food/foods/side_dishes.dm b/code/modules/food_and_drinks/food/foods/side_dishes.dm index ec562d4e8bb..e90bf4827cf 100644 --- a/code/modules/food_and_drinks/food/foods/side_dishes.dm +++ b/code/modules/food_and_drinks/food/foods/side_dishes.dm @@ -9,6 +9,7 @@ icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "rawsticks" list_reagents = list("plantmatter" = 3) + tastes = list("raw potatoes" = 1) ////////////////////// @@ -22,6 +23,7 @@ trash = /obj/item/trash/plate filling_color = "#EDDD00" list_reagents = list("nutriment" = 4) + tastes = list("fries" = 3, "salt" = 1) /obj/item/reagent_containers/food/snacks/cheesyfries name = "cheesy fries" @@ -30,6 +32,7 @@ trash = /obj/item/trash/plate filling_color = "#EDDD00" list_reagents = list("nutriment" = 6) + tastes = list("fries" = 3, "cheese" = 1) /obj/item/reagent_containers/food/snacks/tatortot name = "tator tot" @@ -37,6 +40,7 @@ icon_state = "tatortot" list_reagents = list("nutriment" = 4) filling_color = "FFD700" + tastes = list("fried potato" = 3, "valids" = 1) /obj/item/reagent_containers/food/snacks/onionrings name = "onion rings" @@ -45,6 +49,7 @@ list_reagents = list("nutriment" = 3) filling_color = "#C0C9A0" gender = PLURAL + tastes = list("onion" = 3, "batter" = 1) /obj/item/reagent_containers/food/snacks/carrotfries name = "carrot fries" @@ -53,6 +58,7 @@ trash = /obj/item/trash/plate filling_color = "#FAA005" list_reagents = list("plantmatter" = 3, "oculine" = 3, "vitamin" = 2) + tastes = list("carrots" = 3, "salt" = 1) ////////////////////// @@ -64,6 +70,7 @@ desc = "Musical fruit in a slightly less musical container." icon_state = "beans" list_reagents = list("nutriment" = 10, "beans" = 10, "vitamin" = 3) + tastes = list("beans" = 1) /obj/item/reagent_containers/food/snacks/mashed_potatoes //mashed taters name = "mashed potatoes" @@ -72,6 +79,7 @@ trash = /obj/item/trash/plate filling_color = "#D6D9C1" list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10, "vitamin" = 2) + tastes = list("mashed potato" = 3, "gravy" = 1) /obj/item/reagent_containers/food/snacks/stuffing name = "stuffing" @@ -79,6 +87,7 @@ icon_state = "stuffing" filling_color = "#C9AC83" list_reagents = list("nutriment" = 3) + tastes = list("bread crumbs" = 1, "herbs" = 1) /obj/item/reagent_containers/food/snacks/loadedbakedpotato name = "loaded baked potato" @@ -86,6 +95,7 @@ icon_state = "loadedbakedpotato" filling_color = "#9C7A68" list_reagents = list("nutriment" = 6) + tastes = list("potato" = 1, "cheese" = 1, "herbs" = 1) /obj/item/reagent_containers/food/snacks/boiledrice name = "boiled rice" @@ -94,6 +104,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#FFFBDB" list_reagents = list("nutriment" = 5, "vitamin" = 1) + tastes = list("rice" = 1) /obj/item/reagent_containers/food/snacks/roastparsnip @@ -103,3 +114,5 @@ trash = /obj/item/trash/plate list_reagents = list("nutriment" = 3, "vitamin" = 4) filling_color = "#FF5500" + tastes = list("parsnip" = 1) + diff --git a/code/modules/food_and_drinks/food/foods/soups.dm b/code/modules/food_and_drinks/food/foods/soups.dm index 586912d1f79..6d725037742 100644 --- a/code/modules/food_and_drinks/food/foods/soups.dm +++ b/code/modules/food_and_drinks/food/foods/soups.dm @@ -11,6 +11,7 @@ filling_color = "#785210" bitesize = 5 list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + tastes = list("meatball" = 1) /obj/item/reagent_containers/food/snacks/slimesoup name = "slime soup" @@ -19,6 +20,7 @@ filling_color = "#C4DBA0" bitesize = 5 list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4) + tastes = list("slime" = 1) /obj/item/reagent_containers/food/snacks/bloodsoup name = "tomato soup" @@ -27,6 +29,7 @@ filling_color = "#FF0000" bitesize = 5 list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4) + tastes = list("iron" = 1) /obj/item/reagent_containers/food/snacks/clownstears name = "clown's tears" @@ -35,6 +38,7 @@ filling_color = "#C4FBFF" bitesize = 5 list_reagents = list("nutriment" = 4, "banana" = 5, "water" = 5, "vitamin" = 8) + tastes = list("a bad joke" = 1) /obj/item/reagent_containers/food/snacks/vegetablesoup name = "vegetable soup" @@ -44,6 +48,7 @@ filling_color = "#AFC4B5" bitesize = 5 list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + tastes = list("vegetables" = 1) /obj/item/reagent_containers/food/snacks/nettlesoup name = "nettle soup" @@ -53,6 +58,7 @@ filling_color = "#AFC4B5" bitesize = 5 list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + tastes = list("nettles" = 1) /obj/item/reagent_containers/food/snacks/mysterysoup name = "mystery soup" @@ -61,6 +67,7 @@ var/extra_reagent = null bitesize = 5 list_reagents = list("nutriment" = 6) + tastes = list("chaos" = 1) /obj/item/reagent_containers/food/snacks/mysterysoup/New() ..() @@ -75,6 +82,7 @@ filling_color = "#D1F4FF" bitesize = 5 list_reagents = list("water" = 10) + tastes = list("wishes" = 1) /obj/item/reagent_containers/food/snacks/wishsoup/New() ..() @@ -91,6 +99,7 @@ filling_color = "#D92929" bitesize = 5 list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3) + tastes = list("tomato" = 1) /obj/item/reagent_containers/food/snacks/milosoup name = "milosoup" @@ -99,6 +108,7 @@ trash = /obj/item/trash/snack_bowl bitesize = 5 list_reagents = list("nutriment" = 7, "vitamin" = 2) + tastes = list("milo" = 1) /obj/item/reagent_containers/food/snacks/mushroomsoup name = "chantrelle soup" @@ -108,6 +118,7 @@ filling_color = "#E386BF" bitesize = 5 list_reagents = list("nutriment" = 8, "vitamin" = 4) + tastes = list("mushroom" = 1) /obj/item/reagent_containers/food/snacks/beetsoup name = "beet soup" @@ -117,6 +128,7 @@ bitesize = 5 filling_color = "#FAC9FF" list_reagents = list("nutriment" = 7, "vitamin" = 2) + tastes = list("beet" = 1) /obj/item/reagent_containers/food/snacks/beetsoup/New() ..() @@ -134,6 +146,7 @@ filling_color = "#9E673A" bitesize = 7 list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5) + tastes = list("tomato" = 1, "carrot" = 1) /obj/item/reagent_containers/food/snacks/stewedsoymeat name = "stewed soy meat" @@ -141,6 +154,7 @@ icon_state = "stewedsoymeat" trash = /obj/item/trash/plate list_reagents = list("nutriment" = 8) + tastes = list("soy" = 1, "vegetables" = 1) ////////////////////// @@ -155,6 +169,7 @@ filling_color = "#FF3C00" bitesize = 5 list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2) + tastes = list("hot peppers" = 1, "tomato" = 1) /obj/item/reagent_containers/food/snacks/coldchili name = "cold chili" @@ -164,3 +179,4 @@ trash = /obj/item/trash/snack_bowl bitesize = 5 list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2) + tastes = list("tomato" = 1, "mint" = 1) \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index b1cd3f091ff..3839c977a86 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -16,9 +16,21 @@ var/cooktype[0] var/cooked_type = null //for microwave cooking. path of the resulting item after microwaving var/total_w_class = 0 //for the total weight an item of food can carry + var/list/tastes // for example list("crisps" = 2, "salt" = 1) +/obj/item/reagent_containers/food/snacks/add_initial_reagents() + if(tastes && tastes.len) + if(list_reagents) + for(var/rid in list_reagents) + var/amount = list_reagents[rid] + if(rid == "nutriment" || rid == "vitamin" || rid == "protein" || rid == "plantmatter") + reagents.add_reagent(rid, amount, tastes.Copy()) + else + reagents.add_reagent(rid, amount) + else + ..() - //Placeholder for effect that trigger on eating that aren't tied to reagents. +//Placeholder for effect that trigger on eating that aren't tied to reagents. /obj/item/reagent_containers/food/snacks/proc/On_Consume(mob/M, mob/user) if(!user) return @@ -153,11 +165,13 @@ C.adjustFireLoss(-5) qdel(src) G.last_eaten = world.time + G.taste(reagents) else M.visible_message("[M] takes a bite of [src].","You take a bite of [src].") playsound(loc,'sound/items/eatfood.ogg', rand(10,50), 1) bitecount++ G.last_eaten = world.time + G.taste(reagents) else if(ismouse(M)) var/mob/living/simple_animal/mouse/N = M to_chat(N, text("You nibble away at [src].")) @@ -166,6 +180,7 @@ //N.emote("nibbles away at the [src]") N.adjustBruteLoss(-1) N.adjustFireLoss(-1) + N.taste(reagents) /obj/item/reagent_containers/food/snacks/sliceable/examine(mob/user) . = ..() diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm index ba9a67fee43..a0988951855 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm @@ -17,6 +17,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sandwich category = CAT_FOOD + subcategory = CAT_SANDWICH /datum/crafting_recipe/slimesandwich name = "Slime Jelly Sandwich" @@ -26,6 +27,7 @@ ) result = /obj/item/reagent_containers/food/snacks/jellysandwich/slime category = CAT_FOOD + subcategory = CAT_SANDWICH /datum/crafting_recipe/cherrysandwich name = "Cherry Jelly Sandwich" @@ -35,6 +37,7 @@ ) result = /obj/item/reagent_containers/food/snacks/jellysandwich/cherry category = CAT_FOOD + subcategory = CAT_SANDWICH /datum/crafting_recipe/slimeburger name = "Slime Jelly Burger" @@ -44,6 +47,7 @@ ) result = /obj/item/reagent_containers/food/snacks/jellyburger/slime category = CAT_FOOD + subcategory = CAT_SANDWICH /datum/crafting_recipe/jellyburger name = "Cherry Jelly Burger" @@ -53,6 +57,7 @@ ) result = /obj/item/reagent_containers/food/snacks/jellyburger/cherry category = CAT_FOOD + subcategory = CAT_SANDWICH /datum/crafting_recipe/baseballburger name = "Home run baseball burger" @@ -62,6 +67,7 @@ ) result = /obj/item/reagent_containers/food/snacks/baseballburger category = CAT_FOOD + subcategory = CAT_SANDWICH /datum/crafting_recipe/notasandwich name = "not-a-sandwich" @@ -71,7 +77,7 @@ ) result = /obj/item/reagent_containers/food/snacks/notasandwich category = CAT_FOOD - + subcategory = CAT_SANDWICH /datum/crafting_recipe/sushi_Ebi name = "Ebi Sushi" @@ -81,6 +87,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_Ebi category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/Ebi_maki name = "Ebi Makiroll" @@ -91,6 +98,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/Ebi_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/sushi_Ikura name = "Ikura Sushi" @@ -100,6 +108,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_Ikura category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/Ikura_maki name = "Ikura Makiroll" @@ -110,6 +119,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/Ikura_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/sushi_Inari name = "Inari Sushi" @@ -119,6 +129,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_Inari category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/Inari_maki name = "Inari Makiroll" @@ -129,6 +140,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/Inari_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/sushi_Sake name = "Sake Sushi" @@ -138,6 +150,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_Sake category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/Sake_maki name = "Sake Makiroll" @@ -148,6 +161,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/Sake_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/sushi_SmokedSalmon name = "Smoked Salmon Sushi" @@ -157,6 +171,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_SmokedSalmon category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/SmokedSalmon_maki name = "Smoked Salmon Makiroll" @@ -167,6 +182,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/SmokedSalmon_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/sushi_Masago name = "Masago Sushi" @@ -176,6 +192,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_Masago category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/Masago_maki name = "Masago Makiroll" @@ -186,6 +203,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/Masago_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/sushi_Tobiko name = "Tobiko Sushi" @@ -195,6 +213,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_Tobiko category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/Tobiko_maki name = "Tobiko Makiroll" @@ -205,6 +224,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/Tobiko_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/sushi_TobikoEgg name = "Tobiko and Egg Sushi" @@ -214,6 +234,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_TobikoEgg category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/TobikoEgg_maki name = "Tobiko Makiroll" @@ -224,6 +245,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/TobikoEgg_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/Sake_maki name = "Sake Makiroll" @@ -234,6 +256,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/TobikoEgg_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/sushi_Tai name = "Tai Sushi" @@ -243,6 +266,7 @@ ) result = /obj/item/reagent_containers/food/snacks/sushi_Tai category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/Tai_maki name = "Tai Makiroll" @@ -253,6 +277,7 @@ tools = list(/obj/item/kitchen/sushimat) result = /obj/item/reagent_containers/food/snacks/sliceable/Tai_maki category = CAT_FOOD + subcategory = CAT_SUSHI /datum/crafting_recipe/food @@ -271,4 +296,5 @@ /datum/reagent/teslium = 1, ) result = /mob/living/simple_animal/pet/cat/cak - category = CAT_FOOD \ No newline at end of file + category = CAT_FOOD + subcategory = CAT_CAKE //Cat! Haha, get it? CAT? GET IT? We get it - Love Felines -Foxes are better \ No newline at end of file diff --git a/code/modules/holiday/christmas.dm b/code/modules/holiday/christmas.dm index ea608e35e4d..047c8ce069e 100644 --- a/code/modules/holiday/christmas.dm +++ b/code/modules/holiday/christmas.dm @@ -6,8 +6,10 @@ new /obj/item/a_gift(T) for(var/mob/living/simple_animal/pet/corgi/Ian/Ian in GLOB.mob_list) Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian)) - GLOB.crafting_recipes += new /datum/crafting_recipe/snowman -//The following spawn is necessary as both the timer and the shuttle systems initialise after the events system does, so we can't add stuff to the shuttle system as it doesn't exist yet and we can't use a timer + for(var/datum/crafting_recipe/snowman/S in GLOB.crafting_recipes) + S.always_availible = TRUE + break + //The following spawn is necessary as both the timer and the shuttle systems initialise after the events system does, so we can't add stuff to the shuttle system as it doesn't exist yet and we can't use a timer spawn(60 SECONDS) var/datum/supply_packs/xmas = SSshuttle.supply_packs["[/datum/supply_packs/misc/snow_machine]"] xmas.special_enabled = TRUE diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm index 9f4dbb7315d..e701406897c 100644 --- a/code/modules/hydroponics/fermenting_barrel.dm +++ b/code/modules/hydroponics/fermenting_barrel.dm @@ -32,8 +32,8 @@ data["alcohol_perc"] = G.wine_power if(G.wine_flavor) data["tastes"] = list(G.wine_flavor = 1) - // else // Stub - Will implement when we port over tg's better taste system - I'd rather get the barrel in first. - // data["tastes"] = list(G.tastes[1] = 1) + else + data["tastes"] = list(G.tastes[1] = 1) reagents.add_reagent("fruit_wine", amount, data) qdel(G) playsound(src, 'sound/effects/bubbles.ogg', 50, TRUE) diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 361c305bb8d..63d21bced03 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -20,6 +20,9 @@ /obj/item/reagent_containers/food/snacks/grown/New(newloc, var/obj/item/seeds/new_seed = null) ..() + if(!tastes) + tastes = list("[name]" = 1) + if(new_seed) seed = new_seed.Copy() else if(ispath(seed)) @@ -68,7 +71,7 @@ if(!isturf(loc) || !(locate(/obj/structure/table) in loc) && !(locate(/obj/machinery/optable) in loc) && !(locate(/obj/item/storage/bag/tray) in loc)) to_chat(user, "You cannot slice [src] here! You need a table or at least a tray to do it.") - return TRUE + return TRUE var/slices_lost = 0 if(!inaccurate) diff --git a/code/modules/hydroponics/grown/ambrosia.dm b/code/modules/hydroponics/grown/ambrosia.dm index a2085eafaee..1223dd9dba7 100644 --- a/code/modules/hydroponics/grown/ambrosia.dm +++ b/code/modules/hydroponics/grown/ambrosia.dm @@ -7,6 +7,7 @@ slot_flags = SLOT_HEAD filling_color = "#008000" bitesize_mod = 2 + tastes = list("ambrosia" = 1) // Ambrosia Vulgaris /obj/item/seeds/ambrosia @@ -52,6 +53,7 @@ filling_color = "#008B8B" origin_tech = "biotech=4;materials=3" wine_power = 0.5 + tastes = list("ambrosia deus" = 1) //Ambrosia Gaia /obj/item/seeds/ambrosia/gaia @@ -78,6 +80,7 @@ seed = /obj/item/seeds/ambrosia/gaia wine_power = 0.7 wine_flavor = "the earthmother's blessing" + tastes = list("ambrosia gaia" = 1) // Ambrosia Cruciatus /obj/item/seeds/ambrosia/cruciatus @@ -88,4 +91,5 @@ /obj/item/reagent_containers/food/snacks/grown/ambrosia/cruciatus seed = /obj/item/seeds/ambrosia/cruciatus - wine_power = 0.7 \ No newline at end of file + wine_power = 0.7 + tastes = list("ambrosia cruciatus" = 1) \ No newline at end of file diff --git a/code/modules/hydroponics/grown/apple.dm b/code/modules/hydroponics/grown/apple.dm index 67948c4beb9..1344a8c39b0 100644 --- a/code/modules/hydroponics/grown/apple.dm +++ b/code/modules/hydroponics/grown/apple.dm @@ -23,6 +23,7 @@ icon_state = "apple" filling_color = "#FF4500" bitesize = 100 // Always eat the apple in one bite + tastes = list("apple" = 1) distill_reagent = "hcider" // Posioned Apple diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index dd56ade79be..dc78ff71335 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -24,6 +24,7 @@ filling_color = "#FFFF00" bitesize = 5 distill_reagent = "bananahonk" + tastes = list("banana" = 1) /obj/item/reagent_containers/food/snacks/grown/banana/suicide_act(mob/user) user.visible_message("[user] is aiming the [name] at [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide.") diff --git a/code/modules/hydroponics/grown/beans.dm b/code/modules/hydroponics/grown/beans.dm index 3649e84b869..206d0984c3d 100644 --- a/code/modules/hydroponics/grown/beans.dm +++ b/code/modules/hydroponics/grown/beans.dm @@ -25,6 +25,7 @@ icon_state = "soybeans" filling_color = "#F0E68C" bitesize_mod = 2 + tastes = list("soybean" = 1) wine_power = 0.2 // Koibean @@ -47,4 +48,5 @@ icon_state = "koibeans" filling_color = "#F0E68C" bitesize_mod = 2 + tastes = list("koi" = 1) wine_power = 0.4 \ No newline at end of file diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm index 8e740719fbf..d4161b0a87e 100644 --- a/code/modules/hydroponics/grown/berries.dm +++ b/code/modules/hydroponics/grown/berries.dm @@ -25,6 +25,7 @@ gender = PLURAL filling_color = "#FF00FF" bitesize_mod = 2 + tastes = list("berry" = 1) distill_reagent = "gin" // Poison Berries @@ -46,6 +47,7 @@ icon_state = "poisonberrypile" filling_color = "#C71585" distill_reagent = null + tastes = list("poison-berry" = 1) wine_power = 0.35 // Death Berries @@ -69,6 +71,7 @@ icon_state = "deathberrypile" filling_color = "#708090" distill_reagent = null + tastes = list("death-berry" = 1) wine_power = 0.5 // Glow Berries @@ -96,6 +99,7 @@ light_color = "#006622" distill_reagent = null wine_power = 0.6 + tastes = list("glow-berry" = 1) wine_flavor = "warmth" // Cherries @@ -127,6 +131,7 @@ filling_color = "#FF0000" bitesize_mod = 2 wine_power = 0.3 + tastes = list("cherry" = 1) // Blue Cherries /obj/item/seeds/cherry/blue @@ -148,6 +153,7 @@ filling_color = "#6495ED" bitesize_mod = 2 wine_power = 0.5 + tastes = list("blue cherry" = 1) // Grapes /obj/item/seeds/grape @@ -179,6 +185,7 @@ filling_color = "#FF1493" bitesize_mod = 2 distill_reagent = "wine" + tastes = list("grapes" = 1) // Green Grapes /obj/item/seeds/grape/green @@ -197,4 +204,5 @@ name = "bunch of green grapes" icon_state = "greengrapes" filling_color = "#7FFF00" + tastes = list("green grape" = 1) distill_reagent = "cognac" diff --git a/code/modules/hydroponics/grown/cannabis.dm b/code/modules/hydroponics/grown/cannabis.dm index ed05d7a6954..274a1f1e084 100644 --- a/code/modules/hydroponics/grown/cannabis.dm +++ b/code/modules/hydroponics/grown/cannabis.dm @@ -93,6 +93,7 @@ icon_state = "cannabis" filling_color = "#00FF00" bitesize_mod = 2 + tastes = list("cannabis" = 1) wine_power = 0.2 diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm index e864687a551..89b462a19e1 100644 --- a/code/modules/hydroponics/grown/cereals.dm +++ b/code/modules/hydroponics/grown/cereals.dm @@ -20,6 +20,7 @@ gender = PLURAL icon_state = "wheat" filling_color = "#F0E68C" + tastes = list("wheat" = 1) bitesize_mod = 2 distill_reagent = "beer" @@ -40,6 +41,7 @@ gender = PLURAL icon_state = "oat" filling_color = "#556B2F" + tastes = list("oat" = 1) bitesize_mod = 2 distill_reagent = "ale" @@ -62,6 +64,7 @@ icon_state = "rice" filling_color = "#FAFAD2" bitesize_mod = 2 + tastes = list("rice" = 1) distill_reagent = "sake" //Meatwheat - grows into synthetic meat @@ -83,6 +86,7 @@ filling_color = rgb(150, 0, 0) bitesize_mod = 2 seed = /obj/item/seeds/wheat/meat + tastes = list("meatwheat" = 1) can_distill = FALSE /obj/item/reagent_containers/food/snacks/grown/meatwheat/attack_self(mob/living/user) diff --git a/code/modules/hydroponics/grown/chili.dm b/code/modules/hydroponics/grown/chili.dm index 5f4621eff16..1a2b5142e37 100644 --- a/code/modules/hydroponics/grown/chili.dm +++ b/code/modules/hydroponics/grown/chili.dm @@ -25,6 +25,7 @@ icon_state = "chilipepper" filling_color = "#FF0000" bitesize_mod = 2 + tastes = list("chili" = 1) wine_power = 0.2 // Ice Chili @@ -50,6 +51,7 @@ filling_color = "#0000CD" bitesize_mod = 2 origin_tech = "biotech=4" + tastes = list("chilli" = 1) wine_power = 0.3 // Ghost Chili @@ -76,4 +78,5 @@ filling_color = "#F8F8FF" bitesize_mod = 4 origin_tech = "biotech=4;magnets=5" + tastes = list("ghost chili" = 1) wine_power = 0.5 diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index b6e4a36d164..38e4104c4a7 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -30,6 +30,7 @@ desc = "It's so sour, your face will twist." icon_state = "lime" filling_color = "#00FF00" + tastes = list("lime" = 1) distill_reagent = "triple_sec" // Orange @@ -56,6 +57,7 @@ name = "orange" desc = "It's an tangy fruit." icon_state = "orange" + tastes = list("orange" = 1) filling_color = "#FFA500" // Lemon @@ -81,6 +83,7 @@ name = "lemon" desc = "When life gives you lemons, make lemonade." icon_state = "lemon" + tastes = list("lemonade" = 1) filling_color = "#FFD700" // Combustible lemon @@ -107,6 +110,7 @@ icon_state = "firelemon" bitesize_mod = 2 wine_power = 0.7 + tastes = list("burning lemon" = 1) wine_flavor = "fire" /obj/item/reagent_containers/food/snacks/grown/firelemon/attack_self(mob/living/user) diff --git a/code/modules/hydroponics/grown/cocoa_vanilla.dm b/code/modules/hydroponics/grown/cocoa_vanilla.dm index 745aa006498..744300d9daa 100644 --- a/code/modules/hydroponics/grown/cocoa_vanilla.dm +++ b/code/modules/hydroponics/grown/cocoa_vanilla.dm @@ -25,6 +25,7 @@ icon_state = "cocoapod" filling_color = "#FFD700" bitesize_mod = 2 + tastes = list("cocoa" = 1) distill_reagent = "creme_de_cacao" // Vanilla Pod @@ -45,4 +46,5 @@ desc = "Fattening... Mmmmm... vanilla." icon_state = "vanillapod" filling_color = "#FFD700" + tastes = list("vanilla" = 1) distill_reagent = "vanilla" //Takes longer, but you can get even more vanilla from it. \ No newline at end of file diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm index dca121d1acb..cf7c185c147 100644 --- a/code/modules/hydroponics/grown/corn.dm +++ b/code/modules/hydroponics/grown/corn.dm @@ -24,6 +24,7 @@ filling_color = "#FFFF00" trash = /obj/item/grown/corncob bitesize_mod = 2 + tastes = list("corn" = 1) distill_reagent = "whiskey" wine_power = 0.4 diff --git a/code/modules/hydroponics/grown/cotton.dm b/code/modules/hydroponics/grown/cotton.dm new file mode 100644 index 00000000000..3fa4247f578 --- /dev/null +++ b/code/modules/hydroponics/grown/cotton.dm @@ -0,0 +1,79 @@ +/obj/item/seeds/cotton + name = "pack of cotton seeds" + desc = "A pack of seeds that'll grow into a cotton plant. Assistants make good free labor if neccesary." + icon_state = "seed-cotton" + species = "cotton" + plantname = "Cotton" + icon_harvest = "cotton-harvest" + product = /obj/item/grown/cotton + lifespan = 35 + endurance = 25 + maturation = 15 + production = 1 + yield = 2 + potency = 50 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing.dmi' + icon_dead = "cotton-dead" + mutatelist = list(/obj/item/seeds/cotton/durathread) + +/obj/item/grown/cotton + seed = /obj/item/seeds/cotton + name = "cotton bundle" + desc = "A fluffy bundle of cotton." + icon_state = "cotton" + force = 0 + throwforce = 0 + w_class = WEIGHT_CLASS_TINY + throw_speed = 2 + throw_range = 3 + attack_verb = list("pomfed") + var/cotton_type = /obj/item/stack/sheet/cotton + var/cotton_name = "raw cotton" + +/obj/item/grown/cotton/attack_self(mob/user) + user.show_message("You pull some [cotton_name] out of the [name]!", 1) + var/seed_modifier = 0 + if(seed) + seed_modifier = round(seed.potency / 25) + var/obj/item/stack/cotton = new cotton_type(user.loc, 1 + seed_modifier) + var/old_cotton_amount = cotton.amount + for(var/obj/item/stack/ST in user.loc) + if(ST != cotton && istype(ST, cotton_type) && ST.amount < ST.max_amount) + ST.attackby(cotton, user) + if(cotton.amount > old_cotton_amount) + to_chat(user, "You add the newly-formed [cotton_name] to the stack. It now contains [cotton.amount] [cotton_name].") + qdel(src) + +//reinforced mutated variant +/obj/item/seeds/cotton/durathread + name = "pack of durathread seeds" + desc = "A pack of seeds that'll grow into an extremely durable thread that could easily rival plasteel if woven properly." + icon_state = "seed-durathread" + species = "durathread" + plantname = "Durathread" + icon_harvest = "durathread-harvest" + product = /obj/item/grown/cotton/durathread + lifespan = 80 + endurance = 50 + maturation = 15 + production = 1 + yield = 2 + potency = 50 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing.dmi' + icon_dead = "cotton-dead" + +/obj/item/grown/cotton/durathread + seed = /obj/item/seeds/cotton/durathread + name = "durathread bundle" + desc = "A tough bundle of durathread, good luck unraveling this." + icon_state = "durathread" + force = 5 + throwforce = 5 + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 2 + throw_range = 3 + attack_verb = list("bashed", "battered", "bludgeoned", "whacked") + cotton_type = /obj/item/stack/sheet/cotton/durathread + cotton_name = "raw durathread" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/eggplant.dm b/code/modules/hydroponics/grown/eggplant.dm index b9244bfd3ec..2ed28f76226 100644 --- a/code/modules/hydroponics/grown/eggplant.dm +++ b/code/modules/hydroponics/grown/eggplant.dm @@ -22,6 +22,7 @@ icon_state = "eggplant" filling_color = "#800080" bitesize_mod = 2 + tastes = list("eggplant" = 1) wine_power = 0.2 // Egg-Plant @@ -43,4 +44,5 @@ trash = /obj/item/reagent_containers/food/snacks/egg filling_color = "#F8F8FF" bitesize_mod = 2 + tastes = list("egg-plant" = 1) distill_reagent = "eggnog" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm index 2b5817788a6..d662a77e08a 100644 --- a/code/modules/hydroponics/grown/flowers.dm +++ b/code/modules/hydroponics/grown/flowers.dm @@ -25,6 +25,7 @@ slot_flags = SLOT_HEAD filling_color = "#FF6347" bitesize_mod = 3 + tastes = list("poppy" = 1) distill_reagent = "vermouth" // Lily @@ -42,6 +43,7 @@ name = "lily" desc = "A beautiful orange flower" icon_state = "lily" + tastes = list("lily" = 1) filling_color = "#FFA500" // Geranium @@ -59,6 +61,7 @@ name = "geranium" desc = "A beautiful blue flower" icon_state = "geranium" + tastes = list("geranium" = 1) filling_color = "#008B8B" @@ -88,6 +91,7 @@ icon_state = "harebell" slot_flags = SLOT_HEAD filling_color = "#E6E6FA" + tastes = list("harebell" = 1) bitesize_mod = 3 distill_reagent = "vermouth" @@ -147,6 +151,7 @@ slot_flags = SLOT_HEAD filling_color = "#E6E6FA" bitesize_mod = 2 + tastes = list("moonflower" = 1) distill_reagent = "absinthe" // Novaflower diff --git a/code/modules/hydroponics/grown/grass_carpet.dm b/code/modules/hydroponics/grown/grass_carpet.dm index c45899a310b..dee15bf75b2 100644 --- a/code/modules/hydroponics/grown/grass_carpet.dm +++ b/code/modules/hydroponics/grown/grass_carpet.dm @@ -27,6 +27,7 @@ bitesize_mod = 2 var/stacktype = /obj/item/stack/tile/grass var/tile_coefficient = 0.02 // 1/50 + tastes = list("grass" = 1) wine_power = 0.15 /obj/item/reagent_containers/food/snacks/grown/grass/attack_self(mob/user) @@ -66,4 +67,5 @@ desc = "The textile industry's dark secret." icon_state = "carpetclump" stacktype = /obj/item/stack/tile/carpet + tastes = list("carpet" = 1) can_distill = FALSE diff --git a/code/modules/hydroponics/grown/herbals.dm b/code/modules/hydroponics/grown/herbals.dm index 07734aa268f..6a0ad441ad3 100644 --- a/code/modules/hydroponics/grown/herbals.dm +++ b/code/modules/hydroponics/grown/herbals.dm @@ -17,6 +17,7 @@ desc = "Mash to turn into a poultice." icon_state = "tea_astra_leaves" color = "#378C61" + tastes = list("comfrey" = 1) bitesize_mod = 2 /obj/item/reagent_containers/food/snacks/grown/comfrey/attack_self(mob/user) @@ -43,6 +44,7 @@ desc = "Mash to turn into a poultice." icon_state = "ambrosiavulgaris" color = "#4CC5C7" + tastes = list("aloe" = 1) bitesize_mod = 2 /obj/item/reagent_containers/food/snacks/grown/aloe/attack_self(mob/user) diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm index 64b84649770..41ce7ae957e 100644 --- a/code/modules/hydroponics/grown/kudzu.dm +++ b/code/modules/hydroponics/grown/kudzu.dm @@ -95,4 +95,5 @@ icon_state = "kudzupod" filling_color = "#6B8E23" bitesize_mod = 2 + tastes = list("kudzu" = 1) wine_power = 0.2 diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index ed7608e21b9..09952a2a405 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -24,6 +24,7 @@ dried_type = null w_class = WEIGHT_CLASS_NORMAL filling_color = "#008000" + tastes = list("watermelon" = 1) bitesize_mod = 3 wine_power = 0.4 @@ -47,4 +48,5 @@ filling_color = "#FFD700" dried_type = null wine_power = 0.7 //Water to wine, baby. + tastes = list("melon" = 1, "divinity" = 1) wine_flavor = "divinity" diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index 0d60c7d864f..f2adfab0f20 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -53,6 +53,7 @@ icon_state = "cabbage" filling_color = "#90EE90" bitesize_mod = 2 + tastes = list("cabbage" = 1) wine_power = 0.2 @@ -79,6 +80,7 @@ icon_state = "sugarcane" filling_color = "#FFD700" bitesize_mod = 2 + tastes = list("sugarcane" = 1) distill_reagent = "rum" @@ -109,6 +111,7 @@ icon_state = "gatfruit" origin_tech = "combat=6" trash = /obj/item/gun/projectile/revolver + tastes = list("2nd amendment" = 1, "freedom" = 1) bitesize_mod = 2 wine_power = 0.9 //It burns going down, too. @@ -131,6 +134,7 @@ filling_color = rgb(20, 20, 20) seed = /obj/item/seeds/cherry/bomb bitesize_mod = 2 + tastes = list("cherry" = 1, "explosion" = 1) volume = 125 //Gives enough room for the black powder at max potency wine_power = 0.8 diff --git a/code/modules/hydroponics/grown/mushrooms.dm b/code/modules/hydroponics/grown/mushrooms.dm index 14c4b2a252a..68331c664c9 100644 --- a/code/modules/hydroponics/grown/mushrooms.dm +++ b/code/modules/hydroponics/grown/mushrooms.dm @@ -28,6 +28,7 @@ name = "reishi" desc = "Ganoderma lucidum: A special fungus known for its medicinal and stress relieving properties." icon_state = "reishi" + tastes = list("reishi" = 1) filling_color = "#FF4500" @@ -55,6 +56,7 @@ name = "fly amanita" desc = "Amanita Muscaria: Learn poisonous mushrooms by heart. Only pick mushrooms you know." icon_state = "amanita" + tastes = list("amanita" = 1) filling_color = "#FF0000" @@ -85,6 +87,7 @@ desc = "Amanita Virosa: Deadly poisonous basidiomycete fungus filled with alpha amanitin." icon_state = "angel" filling_color = "#C0C0C0" + tastes = list("destroying angel" = 1) wine_power = 0.6 @@ -112,6 +115,7 @@ icon_state = "libertycap" filling_color = "#DAA520" wine_power = 0.8 + tastes = list("liberty-cap" = 1) wine_flavor = "freedom" @@ -139,6 +143,7 @@ desc = "Plumus Hellmus: Plump, soft and s-so inviting~" icon_state = "plumphelmet" filling_color = "#9370DB" + tastes = list("plump helmet" = 1, "dwarven hardiness" = 1) distill_reagent = "manlydorf" @@ -166,6 +171,7 @@ icon_state = "walkingmushroom" filling_color = "#9370DB" origin_tech = "biotech=4;programming=5" + tastes = list("walking mushroom" = 1, "motion" = 1) can_distill = FALSE /obj/item/reagent_containers/food/snacks/grown/mushroom/walkingmushroom/attack_self(mob/user) @@ -205,6 +211,7 @@ name = "chanterelle cluster" desc = "Cantharellus Cibarius: These jolly yellow little shrooms sure look tasty!" icon_state = "chanterelle" + tastes = list("chanterelle" = 1) filling_color = "#FFA500" @@ -238,6 +245,7 @@ var/effect_path = /obj/structure/glowshroom origin_tech = "biotech=4;plasmatech=6" light_color = "#006622" + tastes = list("warmth" = 1, "light" = 1, "glowshroom" = 1) wine_power = 0.5 /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/attack_self(mob/user) @@ -287,6 +295,7 @@ effect_path = /obj/structure/glowshroom/glowcap origin_tech = "biotech=4;powerstorage=6;plasmatech=4" light_color = "#8E0300" + tastes = list("warmth" = 1, "light" = 1, "glowscap" = 1) wine_power = 0.6 wine_flavor = "warmth" @@ -311,6 +320,7 @@ name = "fungus" desc = "A fungus ideal for making antibacterials." icon_state = "angel" + tastes = list("fungus" = 1) color = "#4f4331" //Shadowshroom @@ -335,5 +345,6 @@ icon_state = "shadowshroom" effect_path = /obj/structure/glowshroom/shadowshroom origin_tech = "biotech=4;plasmatech=4;magnets=4" + tastes = list("strange coldness" = 1, "shadowshroom" = 1) wine_power = 0.6 wine_flavor = "strange coldness" diff --git a/code/modules/hydroponics/grown/onion.dm b/code/modules/hydroponics/grown/onion.dm index e39548d9e7c..597d5c70660 100644 --- a/code/modules/hydroponics/grown/onion.dm +++ b/code/modules/hydroponics/grown/onion.dm @@ -24,6 +24,7 @@ filling_color = "#C0C9A0" bitesize_mod = 2 slice_path = /obj/item/reagent_containers/food/snacks/onion_slice + tastes = list("onion" = 1, "pungentness" = 1) slices_num = 2 wine_power = 0.2 wine_flavor = "pungentness" @@ -45,6 +46,7 @@ icon_state = "onion_red" filling_color = "#C29ACF" slice_path = /obj/item/reagent_containers/food/snacks/onion_slice/red + tastes = list("red onion" = 1, "pungentness" = 3) wine_power = 0.6 wine_flavor = "powerful pungentness" @@ -54,6 +56,7 @@ icon_state = "onionslice" list_reagents = list("plantmatter" = 5, "vitamin" = 2) filling_color = "#C0C9A0" + tastes = list("onion" = 1, "pungentness" = 1) gender = PLURAL cooked_type = /obj/item/reagent_containers/food/snacks/onionrings @@ -62,4 +65,5 @@ desc = "They shine like exceptionally low quality amethyst." icon_state = "onionslice_red" filling_color = "#C29ACF" + tastes = list("red onion" = 1, "pungentness" = 3) list_reagents = list("plantmatter" = 5, "vitamin" = 2, "onionjuice" = 2.5) \ No newline at end of file diff --git a/code/modules/hydroponics/grown/peanut.dm b/code/modules/hydroponics/grown/peanut.dm index 2a02754d4fc..52b74ab795b 100644 --- a/code/modules/hydroponics/grown/peanut.dm +++ b/code/modules/hydroponics/grown/peanut.dm @@ -22,4 +22,5 @@ name = "patch of peanuts" desc = "Best avoided if you have spess allergies." icon_state = "peanuts" + tastes = list("peanut" = 1, "nuttiness" = 1) gender = PLURAL \ No newline at end of file diff --git a/code/modules/hydroponics/grown/pineapple.dm b/code/modules/hydroponics/grown/pineapple.dm index 589f9456bc2..4a2975fae42 100644 --- a/code/modules/hydroponics/grown/pineapple.dm +++ b/code/modules/hydroponics/grown/pineapple.dm @@ -25,4 +25,5 @@ filling_color = "#e5b437" w_class = WEIGHT_CLASS_NORMAL bitesize_mod = 3 + tastes = list("pineapple" = 1) wine_power = 0.4 \ No newline at end of file diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm index 655cb6d69bd..c02b8f72119 100644 --- a/code/modules/hydroponics/grown/potato.dm +++ b/code/modules/hydroponics/grown/potato.dm @@ -24,6 +24,7 @@ desc = "Boil 'em! Mash 'em! Stick 'em in a stew!" icon_state = "potato" filling_color = "#E9967A" + tastes = list("potato" = 1) bitesize = 100 distill_reagent = "vodka" @@ -33,6 +34,7 @@ desc = "Slices of neatly cut potato." icon_state = "potato_wedges" filling_color = "#E9967A" + tastes = list("potato" = 1) bitesize = 100 distill_reagent = "sbiten" @@ -64,4 +66,5 @@ seed = /obj/item/seeds/potato/sweet name = "sweet potato" desc = "It's sweet." + tastes = list("sweet potato" = 1) icon_state = "sweetpotato" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm index f05a6847dc2..aa7030bc6db 100644 --- a/code/modules/hydroponics/grown/pumpkin.dm +++ b/code/modules/hydroponics/grown/pumpkin.dm @@ -23,6 +23,7 @@ icon_state = "pumpkin" filling_color = "#FFA500" bitesize_mod = 2 + tastes = list("pumpkin" = 1) wine_power = 0.2 /obj/item/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/W as obj, mob/user as mob, params) @@ -53,4 +54,5 @@ icon_state = "blumpkin" filling_color = "#87CEFA" bitesize_mod = 2 + tastes = list("blumpkin" = 1) wine_power = 0.5 diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index c8145033545..3aaa8d87041 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -88,7 +88,7 @@ make_podman = 0 if(make_podman) //all conditions met! - var/mob/living/carbon/human/diona/podman = new /mob/living/carbon/human/diona(parent.loc) + var/mob/living/carbon/human/pod_diona/podman = new /mob/living/carbon/human/pod_diona(parent.loc) if(realName) podman.real_name = realName mind.transfer_to(podman) diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm index 35bb5ee195c..56fee727a20 100644 --- a/code/modules/hydroponics/grown/root.dm +++ b/code/modules/hydroponics/grown/root.dm @@ -21,6 +21,7 @@ icon_state = "carrot" filling_color = "#FFA500" bitesize_mod = 2 + tastes = list("carrot" = 1) wine_power = 0.3 /obj/item/reagent_containers/food/snacks/grown/carrot/wedges @@ -60,16 +61,17 @@ desc = "Closely related to carrots." icon_state = "parsnip" bitesize_mod = 2 + tastes = list("parsnip" = 1) wine_power = 0.35 // White-Beet /obj/item/seeds/whitebeet - name = "pack of white-beet seeds" + name = "pack of white beet seeds" desc = "These seeds grow into sugary beet producing plants." icon_state = "seed-whitebeet" species = "whitebeet" - plantname = "White-Beet Plants" + plantname = "White Beet Plants" product = /obj/item/reagent_containers/food/snacks/grown/whitebeet lifespan = 60 endurance = 50 @@ -81,11 +83,12 @@ /obj/item/reagent_containers/food/snacks/grown/whitebeet seed = /obj/item/seeds/whitebeet - name = "white-beet" - desc = "You can't beat white-beet." + name = "white beet" + desc = "You can't beat white beet." icon_state = "whitebeet" filling_color = "#F4A460" bitesize_mod = 2 + tastes = list("white beet" = 1) wine_power = 0.4 // Red Beet @@ -94,7 +97,7 @@ desc = "These seeds grow into red beet producing plants." icon_state = "seed-redbeet" species = "redbeet" - plantname = "Red-Beet Plants" + plantname = "Red Beet Plants" product = /obj/item/reagent_containers/food/snacks/grown/redbeet lifespan = 60 endurance = 50 @@ -109,5 +112,6 @@ name = "red beet" desc = "You can't beat red beet." icon_state = "redbeet" + tastes = list("red beet" = 1) bitesize_mod = 2 wine_power = 0.6 diff --git a/code/modules/hydroponics/grown/tea_coffee.dm b/code/modules/hydroponics/grown/tea_coffee.dm index 1139c03cad5..cec0a8598e0 100644 --- a/code/modules/hydroponics/grown/tea_coffee.dm +++ b/code/modules/hydroponics/grown/tea_coffee.dm @@ -21,6 +21,7 @@ name = "Tea Aspera tips" desc = "These aromatic tips of the tea plant can be dried to make tea." icon_state = "tea_aspera_leaves" + tastes = list("tea leaves" = 1) filling_color = "#008000" can_distill = FALSE @@ -28,6 +29,7 @@ /obj/item/seeds/tea/astra name = "pack of tea astra seeds" icon_state = "seed-teaastra" + desc = "These seeds grow into Tea Astra, a more potent variant of tea" species = "teaastra" plantname = "Tea Astra Plant" product = /obj/item/reagent_containers/food/snacks/grown/tea/astra @@ -38,7 +40,9 @@ /obj/item/reagent_containers/food/snacks/grown/tea/astra seed = /obj/item/seeds/tea/astra name = "Tea Astra tips" + desc = "Knock away your fatigue!" icon_state = "tea_astra_leaves" + tastes = list("tea leaves" = 1, "pure energy" = 1) filling_color = "#4582B4" @@ -67,6 +71,7 @@ desc = "Dry them out to make coffee." icon_state = "coffee_arabica" filling_color = "#DC143C" + tastes = list("coffee beans" = 1) bitesize_mod = 2 distill_reagent = "kahlua" @@ -86,4 +91,5 @@ seed = /obj/item/seeds/coffee/robusta name = "coffee robusta beans" desc = "Increases robustness by 37 percent!" + tastes = list("coffee beans" = 1, "robustness" = 1) icon_state = "coffee_robusta" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/tobacco.dm b/code/modules/hydroponics/grown/tobacco.dm index 95333bba31a..09d7d484f53 100644 --- a/code/modules/hydroponics/grown/tobacco.dm +++ b/code/modules/hydroponics/grown/tobacco.dm @@ -20,6 +20,7 @@ name = "tobacco leaves" desc = "Dry them out to make some smokes." icon_state = "tobacco_leaves" + tastes = list("tobacco" = 1) filling_color = "#008000" distill_reagent = "creme_de_menthe" //Menthol, I guess. @@ -40,5 +41,6 @@ name = "space tobacco leaves" desc = "Dry them out to make some space-smokes." icon_state = "stobacco_leaves" + tastes = list("space tobacco" = 1) distill_reagent = null wine_power = 0.5 \ No newline at end of file diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm index 58bf18057ad..873b08f151e 100644 --- a/code/modules/hydroponics/grown/tomato.dm +++ b/code/modules/hydroponics/grown/tomato.dm @@ -21,6 +21,7 @@ icon_state = "tomato" splat_type = /obj/effect/decal/cleanable/tomato_smudge filling_color = "#FF6347" + tastes = list("tomato" = 1) bitesize_mod = 2 distill_reagent = "enzyme" @@ -43,6 +44,7 @@ icon_state = "bloodtomato" splat_type = /obj/effect/gibspawner/generic filling_color = "#FF0000" + tastes = list("tomato" = 1, "blood" = 2) origin_tech = "biotech=5" distill_reagent = "bloodymary" @@ -67,6 +69,7 @@ name = "blue-tomato" desc = "I say blue-mah-to, you say blue-mae-to." icon_state = "bluetomato" + tastes = list("bluemato" = 1) splat_type = /obj/effect/decal/cleanable/blood/oil filling_color = "#0000FF" @@ -90,6 +93,7 @@ name = "bluespace tomato" desc = "So lubricated, you might slip through space-time." icon_state = "bluespacetomato" + tastes = list("bluemato" = 1, "taste bud dislocation" = 1) origin_tech = "biotech=4;bluespace=5" distill_reagent = null wine_power = 0.8 diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 899146f160d..45c55f4a7f3 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -86,6 +86,7 @@ name = "hatchet" desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." icon_state = "hatchet" + item_state = "hatchet" flags = CONDUCT force = 12 w_class = WEIGHT_CLASS_TINY @@ -109,6 +110,12 @@ icon_state = "unathiknife" attack_verb = list("ripped", "torn", "cut") +/obj/item/hatchet/wooden + desc = "A crude axe blade upon a short wooden handle." + icon_state = "woodhatchet" + materials = null + flags = NONE + /obj/item/scythe icon_state = "scythe0" name = "scythe" diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 753186831fd..d9e07d96987 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -160,15 +160,23 @@ return result -/obj/item/seeds/proc/prepare_result(var/obj/item/reagent_containers/food/snacks/grown/T) - if(T.reagents) - for(var/reagent_id in reagents_add) - if(reagent_id == "blood") // Hack to make blood in plants always O- - T.reagents.add_reagent(reagent_id, 1 + round(potency * reagents_add[reagent_id], 1), list("blood_type"="O-")) - continue +/obj/item/seeds/proc/prepare_result(obj/item/T) + if(!T.reagents) + CRASH("[T] has no reagents.") - T.reagents.add_reagent(reagent_id, 1 + round(potency * reagents_add[reagent_id]), 1) - return 1 + for(var/rid in reagents_add) + var/amount = 1 + round(potency * reagents_add[rid], 1) + + var/list/data = null + if(rid == "blood") // Hack to make blood in plants always O- + data = list("blood_type" = "O-") + if(rid == "nutriment" || rid == "vitamin" || rid == "protein" || rid == "plantmatter") + // apple tastes of apple. + if(istype(T, /obj/item/reagent_containers/food/snacks/grown)) + var/obj/item/reagent_containers/food/snacks/grown/grown_edible = T + data = grown_edible.tastes.Copy() + + T.reagents.add_reagent(rid, amount, data) /// Setters procs /// diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 47b3fb01501..d340e6069cc 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -209,7 +209,7 @@ if(istype(T, denied_type) || istype(src, T.denied_type)) to_chat(user, "You can't seem to attach [src] to [H]. Maybe remove a few trophies?") return FALSE - if(!user.drop_item()) + if(!user.unEquip(src)) return forceMove(H) H.trophies += src diff --git a/code/modules/mining/equipment/lazarus_injector.dm b/code/modules/mining/equipment/lazarus_injector.dm index dcd0916d876..0f174ff748f 100644 --- a/code/modules/mining/equipment/lazarus_injector.dm +++ b/code/modules/mining/equipment/lazarus_injector.dm @@ -73,9 +73,10 @@ icon = 'icons/obj/mobcap.dmi' icon_state = "mobcap0" w_class = WEIGHT_CLASS_TINY - throw_range = 20 + throw_range = 7 var/mob/living/simple_animal/captured = null var/colorindex = 0 + var/capture_type = SENTIENCE_ORGANIC //So you can't capture boss monsters or robots with it /obj/item/mobcapsule/Destroy() if(captured) @@ -83,26 +84,25 @@ QDEL_NULL(captured) return ..() -/obj/item/mobcapsule/attack(var/atom/A, mob/user, prox_flag) - if(!istype(A, /mob/living/simple_animal) || isbot(A)) - return ..() - capture(A, user) - return 1 +/obj/item/mobcapsule/attack(mob/living/simple_animal/S, mob/user, prox_flag) + if(istype(S) && S.sentience_type == capture_type) + capture(S, user) + return TRUE + return ..() -/obj/item/mobcapsule/proc/capture(var/mob/target, var/mob/U as mob) - var/mob/living/simple_animal/T = target +/obj/item/mobcapsule/proc/capture(mob/living/simple_animal/S, mob/living/M) if(captured) - to_chat(U, "Capture failed!: The capsule already has a mob registered to it!") + to_chat(M, "Capture failed!: The capsule already has a mob registered to it!") else - if(istype(T) && "neutral" in T.faction) - T.forceMove(src) - T.name = "[U.name]'s [initial(T.name)]" - T.cancel_camera() - name = "Lazarus Capsule: [initial(T.name)]" - to_chat(U, "You placed a [T.name] inside the Lazarus Capsule!") - captured = T + if("neutral" in S.faction) + S.forceMove(src) + S.name = "[M.name]'s [initial(S.name)]" + S.cancel_camera() + name = "Lazarus Capsule: [initial(S.name)]" + to_chat(M, "You placed a [S.name] inside the Lazarus Capsule!") + captured = S else - to_chat(U, "You can't capture that mob!") + to_chat(M, "You can't capture that mob!") /obj/item/mobcapsule/throw_impact(atom/A, mob/user) ..() diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 9a88dd50259..015921634fe 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -77,6 +77,7 @@ dir = FULLTILE_WINDOW_DIR max_integrity = 100 fulltile = TRUE + flags = PREVENT_CLICK_UNDER reinf = TRUE heat_resistance = 1600 armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100) @@ -296,7 +297,7 @@ name = "air flow blocker" resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF unacidable = TRUE - invisibility = INVISIBILITY_ABSTRACT + invisibility = INVISIBILITY_ABSTRACT //Signs /obj/structure/sign/mining diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index 9b6bd8c5893..48c4249fd62 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -380,7 +380,7 @@ medsensor.add_hud_to(src) /mob/living/simple_animal/hostile/lightgeist/AttackingTarget() - ..() + . = ..() if(isliving(target) && target != src) var/mob/living/L = target if(L.stat < DEAD) diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm index c8579fbec65..3727c103a64 100644 --- a/code/modules/mining/lavaland/loot/tendril_loot.dm +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -77,6 +77,21 @@ add_fingerprint(M) +//Book of Babel + +/obj/item/book_of_babel + name = "Book of Babel" + desc = "An ancient tome written in countless tongues." + icon = 'icons/obj/library.dmi' + icon_state = "book1" + w_class = 2 + +/obj/item/book_of_babel/attack_self(mob/user) + to_chat(user, "You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.") + user.grant_all_languages() + new /obj/effect/decal/cleanable/ash(get_turf(user)) + qdel(src) + //Potion of Flight: as we do not have the "Angel" species this currently does not work. /obj/item/reagent_containers/glass/bottle/potion @@ -117,6 +132,30 @@ H.emote("scream") ..()*/ +/obj/item/jacobs_ladder + name = "jacob's ladder" + desc = "A celestial ladder that violates the laws of physics." + icon = 'icons/obj/structures.dmi' + icon_state = "ladder00" + +/obj/item/jacobs_ladder/attack_self(mob/user) + var/turf/T = get_turf(src) + var/ladder_x = T.x + var/ladder_y = T.y + to_chat(user, "You unfold the ladder. It extends much farther than you were expecting.") + var/last_ladder = null + for(var/i in 1 to world.maxz) + if(is_admin_level(i) || is_away_level(i)) + continue + var/turf/T2 = locate(ladder_x, ladder_y, i) + last_ladder = new /obj/structure/ladder/unbreakable/jacob(T2, null, last_ladder) + qdel(src) + +// Inherit from unbreakable but don't set ID, to suppress the default Z linkage +/obj/structure/ladder/unbreakable/jacob + name = "jacob's ladder" + desc = "An indestructible celestial ladder that violates the laws of physics." + //Boat /obj/vehicle/lavaboat diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index a2ee237c659..1a0a063e33f 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -18,7 +18,7 @@ if(!add_loot) return - var/loot = rand(1,25) + var/loot = rand(1, 26) switch(loot) if(1) new /obj/item/shared_storage/red(src) @@ -48,7 +48,7 @@ if(11) new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/berserker(src) if(12) - new /obj/item/sord(src) + new /obj/item/jacobs_ladder(src) if(13) new /obj/item/nullrod/scythe/talking(src) if(14) @@ -78,6 +78,8 @@ if(24) new /obj/item/spellbook/oneuse/summonitem(src) if(25) + new /obj/item/book_of_babel(src) + if(26) new /obj/item/borg/upgrade/modkit/lifesteal(src) new /obj/item/bedsheet/cult(src) diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 229b9053ae6..4de84bb70c4 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -37,7 +37,7 @@ new /datum/data/mining_equipment("Lazarus Injector", /obj/item/lazarus_injector, 1000), new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/pickaxe/silver, 1000), new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffel/mining_conscript, 1500), - new /datum/data/mining_equipment("Jetpack", /obj/item/tank/jetpack/carbondioxide/mining, 2000), + new /datum/data/mining_equipment("Jetpack Upgrade", /obj/item/tank/jetpack/suit, 2000), new /datum/data/mining_equipment("Mining Hardsuit", /obj/item/clothing/suit/space/hardsuit/mining, 2000), new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/pickaxe/diamond, 2000), new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index f350633a4c2..b85db884ef5 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -44,8 +44,8 @@ /obj/structure/closet/secure_closet/miner/New() ..() -// new /obj/item/stack/sheet/mineral/sandbags(src, 5) -// new /obj/item/storage/box/emptysandbags(src) + new /obj/item/stack/sheet/mineral/sandbags(src, 5) + new /obj/item/storage/box/emptysandbags(src) new /obj/item/shovel(src) new /obj/item/pickaxe/mini(src) new /obj/item/radio/headset/headset_cargo/mining(src) diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index e7036ad4f2f..5a0c17d9e93 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -15,7 +15,6 @@ a_intent = INTENT_HARM atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 - idle_vision_range = 5 move_to_delay = 10 health = 125 maxHealth = 125 @@ -145,7 +144,7 @@ /mob/living/simple_animal/hostile/mining_drone/proc/SetCollectBehavior() mode = MINEDRONE_COLLECT - idle_vision_range = 9 + vision_range = 9 search_objects = 2 wander = TRUE ranged = FALSE @@ -156,7 +155,7 @@ /mob/living/simple_animal/hostile/mining_drone/proc/SetOffenseBehavior() mode = MINEDRONE_ATTACK - idle_vision_range = 7 + vision_range = 7 search_objects = 0 wander = FALSE ranged = TRUE @@ -192,7 +191,7 @@ for(var/obj/item/stack/ore/O in contents) O.forceMove(drop_location()) -/mob/living/simple_animal/hostile/mining_drone/adjustHealth(amount) +/mob/living/simple_animal/hostile/mining_drone/adjustHealth(amount, updating_health = TRUE) if(mode != MINEDRONE_ATTACK && amount > 0) SetOffenseBehavior() . = ..() diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 57725da8eb2..525421ed186 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -762,6 +762,18 @@ desc = "Bark bark bark." key = "vu" +/datum/language/zombie + name = "Zombie" + desc = "BRAAAAAAINS!" + speech_verb = "moans" + whisper_verb = "mutters" + exclaim_verb = "wails" + colour = "zombie" + key = "zom" + syllables = list("BRAAAAAAAAAAAAAAAAINS", "BRAAINS", "BRAINS") +/mob/proc/grant_all_languages() + for(var/la in GLOB.all_languages) + add_language(la) #undef SCRAMBLE_CACHE_LEN diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 82b98a3732e..21662714653 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -213,7 +213,6 @@ swap_hand() /mob/living/carbon/proc/help_shake_act(mob/living/carbon/M) - add_attack_logs(M, src, "Shaked", ATKLOG_ALL) if(health >= HEALTH_THRESHOLD_CRIT) if(src == M && ishuman(src)) check_self_for_injuries() @@ -222,6 +221,7 @@ M.visible_message("[M] shakes [src], but [p_they()] [p_do()] not respond. Probably suffering from SSD.", \ "You shake [src], but [p_theyre()] unresponsive. Probably suffering from SSD.") if(lying) // /vg/: For hugs. This is how update_icon figgers it out, anyway. - N3X15 + add_attack_logs(M, src, "Shaked", ATKLOG_ALL) if(ishuman(src)) var/mob/living/carbon/human/H = src if(H.w_uniform) @@ -1000,7 +1000,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, else if(!forceFed(toEat, user, fullness)) return 0 - consume(toEat, bitesize_override, taste = toEat.taste) + consume(toEat, bitesize_override, can_taste_container = toEat.can_taste) score_foodeaten++ return 1 @@ -1051,7 +1051,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /*TO DO - If/when stomach organs are introduced, override this at the human level sending the item to the stomach so that different stomachs can handle things in different ways VB*/ -/mob/living/carbon/proc/consume(var/obj/item/reagent_containers/food/toEat, var/bitesize_override, var/taste = TRUE) +/mob/living/carbon/proc/consume(var/obj/item/reagent_containers/food/toEat, var/bitesize_override, var/can_taste_container = TRUE) var/this_bite = bitesize_override ? bitesize_override : toEat.bitesize if(!toEat.reagents) return @@ -1060,8 +1060,8 @@ so that different stomachs can handle things in different ways VB*/ if(toEat.consume_sound) playsound(loc, toEat.consume_sound, rand(10,50), 1) if(toEat.reagents.total_volume) - if(taste) - taste_reagents(toEat.reagents) + if(can_taste_container) + taste(toEat.reagents) var/fraction = min(this_bite/toEat.reagents.total_volume, 1) toEat.reagents.reaction(src, toEat.apply_type, fraction) toEat.reagents.trans_to(src, this_bite*toEat.transfer_efficiency) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 7b8790076ce..c583d9873b6 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -16,7 +16,7 @@ /mob/living/carbon/water_act(volume, temperature, source, method = TOUCH) . = ..() - if(volume > 10) //anything over 10 volume will make the mob wetter. + if(volume > 10) // Anything over 10 volume will make the mob wetter. wetlevel = min(wetlevel + 1,5) /mob/living/carbon/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 219ba9ca9eb..c23db2f5501 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -858,14 +858,10 @@ playsound(loc, 'sound/effects/snap.ogg', 50, 1) if("fart", "farts") - if(locate(/obj/item/storage/bible) in get_turf(src)) - to_chat(viewers(src), "[src] farts on the Bible!") - var/image/cross = image('icons/obj/storage.dmi', "bible") - var/adminbfmessage = "[bicon(cross)] Bible Fart: [key_name(src, 1)] ([ADMIN_QUE(src,"?")]) ([ADMIN_PP(src,"PP")]) ([ADMIN_VV(src,"VV")]) ([ADMIN_SM(src,"SM")]) ([admin_jump_link(src)]) (CA) (SMITE):" - for(var/client/X in GLOB.admins) - if(check_rights(R_EVENT, 0, X.mob)) - to_chat(X, adminbfmessage) - else + var/farted_on_thing = FALSE + for(var/atom/A in get_turf(src)) + farted_on_thing += A.fart_act(src) + if(!farted_on_thing) message = "[src] [pick("passes wind", "farts")]." m_type = 2 @@ -947,7 +943,7 @@ for(var/mob/M in GLOB.dead_mob_list) if(!M.client) - continue + continue if(isnewplayer(M)) continue diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 4aef44444e9..1862fe5cffa 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -390,7 +390,7 @@ S = H.glasses return !istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/security) && S && S.read_only if("medical") - return istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.glasses, /obj/item/clothing/glasses/hud/health/health_advanced) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical) + return istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical) else return 0 else if(isrobot(M) || isAI(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0cd4b176e0b..b3d320de913 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -34,9 +34,6 @@ handcrafting = new() - var/mob/M = src - faction |= "\ref[M]" //what - // Set up DNA. if(dna) dna.ready_dna(src) @@ -106,6 +103,9 @@ /mob/living/carbon/human/diona/Initialize(mapload) ..(mapload, /datum/species/diona) +/mob/living/carbon/human/pod_diona/Initialize(mapload) + ..(mapload, /datum/species/diona/pod) + /mob/living/carbon/human/machine/Initialize(mapload) ..(mapload, /datum/species/machine) @@ -165,7 +165,11 @@ show_stat_emergency_shuttle_eta() if(client.statpanel == "Status") - if(locate(/obj/item/assembly/health) in src) + var/total_user_contents = GetAllContents() // cache it + if(locate(/obj/item/gps) in total_user_contents) + var/turf/T = get_turf(src) + stat(null, "GPS: [COORD(T)]") + if(locate(/obj/item/assembly/health) in total_user_contents) stat(null, "Health: [health]") if(internal) if(!internal.air_contents) @@ -849,7 +853,7 @@ return var/read = 0 var/perpname = get_visible_name(TRUE) - + for(var/datum/data/record/E in data_core.general) if(E.fields["name"] == perpname) for(var/datum/data/record/R in data_core.medical) @@ -1096,17 +1100,22 @@ var/limb_path = organ_data["path"] var/obj/item/organ/external/O = new limb_path(temp_holder) if(H.get_limb_by_name(O.name)) //Check to see if the user already has an limb with the same name as the 'missing limb'. If they do, skip regrowth. - continue //In an example, this will prevent duplication of the mob's right arm if the mob is a Human and they have a Diona right arm, since, - //while the limb with the name 'right_arm' the mob has may not be listed in their species' bodyparts definition, it is still viable and has the appropriate limb name. + continue //In an example, this will prevent duplication of the mob's right arm if the mob is a Human and they have a Diona right arm, since, + //while the limb with the name 'right_arm' the mob has may not be listed in their species' bodyparts definition, it is still viable and has the appropriate limb name. else O = new limb_path(H) //Create the limb on the player. O.owner = H H.bodyparts |= H.bodyparts_by_name[O.limb_name] + if(O.body_part == HEAD) //They're sprouting a fresh head so lets hook them up with their genetic stuff so their new head looks like the original. + H.UpdateAppearance() //Replacing lost organs with the species default. temp_holder = new /mob/living/carbon/human() - for(var/index in H.dna.species.has_organ) - var/organ = H.dna.species.has_organ[index] + var/list/species_organs = H.dna.species.has_organ.Copy() //Compile a list of species organs and tack on the mutantears afterward. + if(H.dna.species.mutantears) + species_organs["ears"] = H.dna.species.mutantears + for(var/index in species_organs) + var/organ = species_organs[index] if(!(organ in types_of_int_organs)) //If the mob is missing this particular organ... var/obj/item/organ/internal/I = new organ(temp_holder) //Create the organ inside our holder so we can check it before implantation. if(H.get_organ_slot(I.slot)) //Check to see if the user already has an organ in the slot the 'missing organ' belongs to. If they do, skip implantation. @@ -1470,12 +1479,12 @@ var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) var/obj/item/organ/internal/cyberimp/eyes/eye_implant = get_int_organ(/obj/item/organ/internal/cyberimp/eyes) if(istype(dna.species) && dna.species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', dna.species.eyes) + var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', dna.species.eyes) if(eye_implant) //Eye implants override native DNA eye colo(u)r eyes_icon = eye_implant.generate_icon() else if(eyes) eyes_icon = eyes.generate_icon() - else + else //Error 404: Eyes not found! eyes_icon.Blend("#800000", ICON_ADD) return eyes_icon @@ -1484,8 +1493,8 @@ var/obj/item/organ/external/head/head_organ = get_organ("head") var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style] var/icon/hair = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - var/mutable_appearance/MA = mutable_appearance(get_icon_difference(get_eyecon(), hair), layer = LIGHTING_LAYER + 1) - MA.plane = LIGHTING_PLANE + var/mutable_appearance/MA = mutable_appearance(get_icon_difference(get_eyecon(), hair), layer = ABOVE_LIGHTING_LAYER) + MA.plane = ABOVE_LIGHTING_PLANE return MA //Cut the hair's pixels from the eyes icon so eyes covered by bangs stay hidden even while on a higher layer. /*Used to check if eyes should shine in the dark. Returns the image of the eyes on the layer where they will appear to shine. @@ -1886,12 +1895,6 @@ Eyes need to have significantly high darksight to shine unless the mob has the X .["Make superhero"] = "?_src_=vars;makesuper=[UID()]" . += "---" -/mob/living/carbon/human/get_taste_sensitivity() - if(dna.species) - return dna.species.taste_sensitivity - else - return 1 - /mob/living/carbon/human/proc/special_post_clone_handling() if(mind && mind.assigned_role == "Cluwne") //HUNKE your suffering never stops makeCluwne() diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index e106d214fd3..762df8d3b8b 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -202,6 +202,16 @@ amount = amount * dna.species.tox_mod . = ..() +/mob/living/carbon/human/adjustStaminaLoss(amount, updating = TRUE) + if(dna.species && amount > 0) + amount = amount * dna.species.stamina_mod + . = ..() + +/mob/living/carbon/human/setStaminaLoss(amount, updating = TRUE) + if(dna.species && amount > 0) + amount = amount * dna.species.stamina_mod + . = ..() + //////////////////////////////////////////// //Returns a list of damaged organs @@ -334,56 +344,5 @@ This function restores all organs. //Handle BRUTE and BURN damage handle_suit_punctures(damagetype, damage) - - blocked = (100 - blocked) / 100 - if(blocked <= 0) - return 0 - - var/obj/item/organ/external/organ = null - if(isorgan(def_zone)) - organ = def_zone - else - if(!def_zone) - def_zone = ran_zone(def_zone) - organ = get_organ(check_zone(def_zone)) - if(!organ) - return 0 - - damage = damage * blocked - - switch(damagetype) - if(BRUTE) - damageoverlaytemp = 20 - if(dna.species) - damage = damage * dna.species.brute_mod - - if(organ.receive_damage(damage, 0, sharp, used_weapon)) - UpdateDamageIcon() - - if(LAssailant && ishuman(LAssailant)) //superheros still get the comical hit markers - var/mob/living/carbon/human/H = LAssailant - if(H.mind && H.mind in (SSticker.mode.superheroes || SSticker.mode.supervillains || SSticker.mode.greyshirts)) - var/list/attack_bubble_recipients = list() - var/mob/living/user - for(var/mob/O in viewers(user, src)) - if(O.client && O.has_vision(information_only=TRUE)) - attack_bubble_recipients.Add(O.client) - spawn(0) - var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1) - dmgIcon.pixel_x = (!lying) ? rand(-3,3) : rand(-11,12) - dmgIcon.pixel_y = (!lying) ? rand(-11,9) : rand(-10,1) - flick_overlay(dmgIcon, attack_bubble_recipients, 9) - - - if(BURN) - damageoverlaytemp = 20 - - if(dna.species) - damage = damage * dna.species.burn_mod - - if(organ.receive_damage(0, damage, sharp, used_weapon)) - UpdateDamageIcon() - - // Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life(). - updatehealth("apply damage") - return 1 + //Handle species apply_damage procs + return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, sharp, used_weapon) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 925e979c11d..b6bf5b34bac 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -11,10 +11,11 @@ //Do we have a working jetpack? var/obj/item/tank/jetpack/thrust - if(istype(back,/obj/item/tank/jetpack)) + if(istype(back, /obj/item/tank/jetpack)) thrust = back - else if(istype(s_store,/obj/item/tank/jetpack)) - thrust = s_store + else if(istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) + var/obj/item/clothing/suit/space/hardsuit/C = wear_suit + thrust = C.jetpack else if(istype(back,/obj/item/rig)) var/obj/item/rig/rig = back for(var/obj/item/rig_module/maneuvering_jets/module in rig.installed_modules) @@ -63,7 +64,8 @@ else //No oldFP or it's a different kind of blood S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP) - createFootprintsFrom(shoes, dir, T) + if(S.bloody_shoes[S.blood_state] > BLOOD_LOSS_IN_SPREAD) + createFootprintsFrom(shoes, dir, T) update_inv_shoes() else if(hasfeet) if(bloody_feet && bloody_feet[blood_state]) @@ -72,7 +74,8 @@ return else bloody_feet[blood_state] = max(0, bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP) - createFootprintsFrom(src, dir, T) + if(bloody_feet[blood_state] > BLOOD_LOSS_IN_SPREAD) + createFootprintsFrom(src, dir, T) update_inv_shoes() //End bloody footprints if(S) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d6c667b1b74..fe048fb8137 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -14,7 +14,6 @@ handle_heartbeat() handle_drunk() dna.species.handle_life(src) - if(!client) dna.species.handle_npc(src) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index 438d3386948..dbb7b8731fc 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -50,10 +50,12 @@ var/oxy_mod = 1 // Oxy damage reduction/amplification var/clone_mod = 1 // Clone damage reduction/amplification var/brain_mod = 1 // Brain damage damage reduction/amplification + var/stamina_mod = 1 var/stun_mod = 1 // If a species is more/less impacated by stuns/weakens/paralysis - + var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster + var/armor = 0 // overall defense for the race... or less defense, if it's negative. var/blood_damage_type = OXY //What type of damage does this species take if it's low on blood? - + var/obj/item/mutanthands var/total_health = 100 var/punchdamagelow = 0 //lowest possible punch damage var/punchdamagehigh = 9 //highest possible punch damage @@ -63,8 +65,6 @@ var/ventcrawler = 0 //Determines if the mob can go through the vents. var/has_fine_manipulation = 1 // Can use small items. - var/mob/living/list/ignored_by = list() // list of mobs that will ignore this species - var/list/allowed_consumed_mobs = list() //If a species can consume mobs, put the type of mobs it can consume here. var/list/species_traits = list() @@ -307,6 +307,63 @@ /datum/species/proc/handle_death(mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). return +/datum/species/proc/spec_death(gibbed, mob/living/carbon/human/C) + return + +/datum/species/proc/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, mob/living/carbon/human/H, sharp = 0, obj/used_weapon = null) + blocked = (100 - blocked) / 100 + if(blocked <= 0) + return 0 + + var/obj/item/organ/external/organ = null + if(isorgan(def_zone)) + organ = def_zone + else + if(!def_zone) + def_zone = ran_zone(def_zone) + organ = H.get_organ(check_zone(def_zone)) + if(!organ) + return 0 + + damage = damage * blocked + + switch(damagetype) + if(BRUTE) + H.damageoverlaytemp = 20 + damage = damage * brute_mod + + if(organ.receive_damage(damage, 0, sharp, used_weapon)) + H.UpdateDamageIcon() + + if(H.LAssailant && ishuman(H.LAssailant)) //superheros still get the comical hit markers + var/mob/living/carbon/human/A = H.LAssailant + if(A.mind && A.mind in (SSticker.mode.superheroes || SSticker.mode.supervillains || SSticker.mode.greyshirts)) + var/list/attack_bubble_recipients = list() + var/mob/living/user + for(var/mob/O in viewers(user, src)) + if(O.client && O.has_vision(information_only=TRUE)) + attack_bubble_recipients.Add(O.client) + spawn(0) + var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1) + dmgIcon.pixel_x = (!H.lying) ? rand(-3,3) : rand(-11,12) + dmgIcon.pixel_y = (!H.lying) ? rand(-11,9) : rand(-10,1) + flick_overlay(dmgIcon, attack_bubble_recipients, 9) + + + if(BURN) + H.damageoverlaytemp = 20 + damage = damage * burn_mod + + if(organ.receive_damage(0, damage, sharp, used_weapon)) + H.UpdateDamageIcon() + + // Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life(). + H.updatehealth("apply damage") + return 1 + +/datum/species/proc/spec_stun(mob/living/carbon/human/H,amount) + return + /datum/species/proc/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) return @@ -733,8 +790,8 @@ It'll return null if the organ doesn't correspond, so include null checks when u H.sync_lighting_plane_alpha() /datum/species/proc/water_act(mob/living/carbon/human/M, volume, temperature, source, method = TOUCH) - if(abs(temperature - M.bodytemperature) > 10) //If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately - M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling + if(abs(temperature - M.bodytemperature) > 10) // If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately. + M.bodytemperature = (temperature + M.bodytemperature) * 0.5 // Approximation for gradual heating or cooling. /datum/species/proc/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) //return TRUE if hit, FALSE if stopped/reflected/etc return TRUE diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm index bccbeb6c5a7..518ee94f8f0 100644 --- a/code/modules/mob/living/carbon/human/species/diona.dm +++ b/code/modules/mob/living/carbon/human/species/diona.dm @@ -7,21 +7,11 @@ speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16] speech_chance = 20 unarmed_type = /datum/unarmed_attack/diona - //primitive_form = "Nymph" - slowdown = 5 remains_type = /obj/effect/decal/cleanable/ash - - warning_low_pressure = 50 - hazard_low_pressure = -1 - - cold_level_1 = 50 - cold_level_2 = -1 - cold_level_3 = -1 - - heat_level_1 = 300 - heat_level_2 = 340 - heat_level_3 = 400 + burn_mod = 1.25 + heatmod = 1.5 + var/pod = FALSE //did they come from a pod? If so, they're stronger than normal Diona. blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ @@ -31,16 +21,14 @@ even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ water and other radiation." - species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN) - dies_at_threshold = TRUE + species_traits = list(IS_PLANT) clothing_flags = HAS_SOCKS default_hair_colour = "#000000" has_gender = FALSE - dietflags = 0 //Diona regenerate nutrition in light and water, no diet necessary - taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE + dietflags = DIET_HERB //Diona regenerate nutrition in light and water, no diet necessary, but if they must, they eat other plants *scream + taste_sensitivity = TASTE_SENSITIVITY_DULL skinned_type = /obj/item/stack/sheet/wood - body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not blood_color = "#004400" flesh_color = "#907E4A" butt_sprite = "diona" @@ -49,6 +37,7 @@ has_organ = list( "nutrient channel" = /obj/item/organ/internal/liver/diona, + "respiratory vacuoles" = /obj/item/organ/internal/lungs/diona, "neural strata" = /obj/item/organ/internal/heart/diona, "receptor node" = /obj/item/organ/internal/eyes/diona, //Default darksight of 2. "gas bladder" = /obj/item/organ/internal/brain/diona, @@ -85,29 +74,47 @@ ..() H.gender = NEUTER -/datum/species/diona/handle_life(mob/living/carbon/human/H) - H.radiation = Clamp(H.radiation, 0, 100) //We have to clamp this first, then decrease it, or there's a few edge cases of massive heals if we clamp and decrease at the same time. - var/rads = H.radiation / 25 - H.radiation = max(H.radiation-rads, 0) - H.nutrition = min(H.nutrition+rads, NUTRITION_LEVEL_WELL_FED+10) - H.adjustBruteLoss(-(rads)) - H.adjustToxLoss(-(rads)) +/datum/species/diona/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) + if(R.id == "glyphosate" || R.id == "atrazine") + H.adjustToxLoss(3) //Deal aditional damage + return TRUE + return ..() +/datum/species/diona/handle_life(mob/living/carbon/human/H) + if(H.stat == DEAD) + return var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing if(isturf(H.loc)) //else, there's considered to be no light var/turf/T = H.loc - light_amount = min(T.get_lumcount() * 10, 5) //hardcapped so it's not abused by having a ton of flashlights - H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10) + light_amount = min(1, T.get_lumcount()) - 0.5 + if(light_amount > 0) + H.clear_alert("nolight") + else + H.throw_alert("nolight", /obj/screen/alert/nolight) + H.nutrition += light_amount * 10 + if(H.nutrition > NUTRITION_LEVEL_ALMOST_FULL) + H.nutrition = NUTRITION_LEVEL_ALMOST_FULL + if(light_amount > 0.2 && !H.suiciding) //if there's enough light, heal + if(!pod && H.health <= 0) + return + H.adjustBruteLoss(-1) + H.adjustFireLoss(-1) + H.adjustToxLoss(-1) + H.adjustOxyLoss(-1) - if(light_amount > 0) - H.clear_alert("nolight") - else - H.throw_alert("nolight", /obj/screen/alert/nolight) - - if((light_amount >= 5) && !H.suiciding) //if there's enough light, heal - - H.adjustBruteLoss(-(light_amount/2)) - H.adjustFireLoss(-(light_amount/4)) - if(H.nutrition < NUTRITION_LEVEL_STARVING+50) - H.take_overall_damage(10,0) + if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) + H.adjustBruteLoss(2) ..() + +/datum/species/diona/pod //Same name and everything; we want the same limitations on them; we just want their regeneration to kick in at all times and them to have special factions + pod = TRUE + +/datum/species/diona/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.faction |= "plants" + C.faction |= "vines" + +/datum/species/diona/pod/on_species_loss(mob/living/carbon/C) + . = ..() + C.faction -= "plants" + C.faction -= "vines" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index c1e416a8a48..9d74e7e2130 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -251,28 +251,44 @@ attack_verb = list("smash") attack_sound = 'sound/effects/meteorimpact.ogg' -//More resistant to burn damage -//Add ashstorm resistance if we ever port lavaland +//More resistant to burn damage and immune to ashstorm /datum/species/golem/titanium name = "Titanium Golem" golem_colour = rgb(255, 255, 255) skinned_type = /obj/item/stack/ore/titanium - info_text = "As a Titanium Golem, you are resistant to burn damage." + info_text = "As a Titanium Golem, you are resistant to burn damage and immune to ash storms." burn_mod = 0.3 prefix = "Titanium" special_names = list("Dioxide") -//Even more resistant to burn damage -//Add ashstorm and lava resistance if we ever port lavaland +/datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.weather_immunities |= "ash" + +/datum/species/golem/titanium/on_species_loss(mob/living/carbon/C) + . = ..() + C.weather_immunities -= "ash" + +//Even more resistant to burn damage and immune to ashstorms and lava /datum/species/golem/plastitanium name = "Plastitanium Golem" golem_colour = rgb(136, 136, 136) skinned_type = /obj/item/stack/ore/titanium - info_text = "As a Plastitanium Golem, you are very resistant to burn damage." + info_text = "As a Plastitanium Golem, you are very resistant to burn damage and immune to both ash storms and lava." burn_mod = 0.15 prefix = "Plastitanium" special_names = null +/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.weather_immunities |= "lava" + C.weather_immunities |= "ash" + +/datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C) + . = ..() + C.weather_immunities -= "ash" + C.weather_immunities -= "lava" + //Fast and regenerates... but can only speak like an abductor /datum/species/golem/alloy name = "Alien Alloy Golem" @@ -357,10 +373,12 @@ /datum/species/golem/uranium/handle_life(mob/living/carbon/human/H) for(var/mob/living/L in range(2, H)) - if(isgolem(H)) - continue - to_chat(L, "You are enveloped by a soft green glow emanating from [H].") - L.apply_effect(10, IRRADIATE) + if(ishuman(L)) + var/mob/living/carbon/human/I = L + if(!(RADIMMUNE in I.dna.species.species_traits)) + L.apply_effect(10, IRRADIATE) + if(prob(25)) //reduce spam + to_chat(L, "You are enveloped by a soft green glow emanating from [H].") ..() //Ventcrawler @@ -592,7 +610,7 @@ punchdamagehigh = 0 punchstunthreshold = 1 //Harmless and can't stun skinned_type = /obj/item/stack/ore/bananium - info_text = "As a Bananium Golem, you are made for pranking. Your body emits natural honks, and you can barely even hurt people when punching them. Your skin also bleeds banana peels when damaged." + info_text = "As a Bananium Golem, you are made for pranking. Your body emits natural honks, and punching people will just harmlessly honk them. Your skin also bleeds banana peels when damaged." prefix = "Bananium" special_names = null unarmed_type = /datum/unarmed_attack/golem/bananium @@ -610,6 +628,12 @@ H.mutations.Add(COMIC) H.equip_to_slot_or_del(new /obj/item/reagent_containers/food/drinks/bottle/bottleofbanana(H), slot_r_store) H.equip_to_slot_or_del(new /obj/item/bikehorn(H), slot_l_store) + H.AddComponent(/datum/component/waddling) + +/datum/species/golem/bananium/on_species_loss(mob/living/carbon/C) + . = ..() + GET_COMPONENT_FROM(waddling, /datum/component/waddling, C) + waddling.Destroy() /datum/species/golem/bananium/get_random_name() var/clown_name = pick(GLOB.clown_names) diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm index 3b8bbe34ffb..fd8fc09fd4d 100644 --- a/code/modules/mob/living/carbon/human/species/grey.dm +++ b/code/modules/mob/living/carbon/human/species/grey.dm @@ -40,15 +40,15 @@ . = ..() if(method == TOUCH) + if(H.wear_mask) + to_chat(H, "Your [H.wear_mask] protects you from the acid!") + return + + if(H.head) + to_chat(H, "Your [H.wear_mask] protects you from the acid!") + return + if(volume > 25) - if(H.wear_mask) - to_chat(H, "Your [H.wear_mask] protects you from the acid!") - return - - if(H.head) - to_chat(H, "Your [H.wear_mask] protects you from the acid!") - return - if(prob(75)) H.take_organ_damage(5, 10) H.emote("scream") @@ -65,9 +65,6 @@ H.adjustFireLoss(min(max(4, (volume - 10) * 2), 20)) H.emote("scream") to_chat(H, "The water stings[volume < 10 ? " you, but isn't concentrated enough to harm you" : null]!") - if(volume >= 10) - H.adjustFireLoss(min(max(4, (volume - 10) * 2), 20)) - H.emote("scream") /datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H) var/translator_pref = H.client.prefs.speciesprefs diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index b75132c7bc6..e4ba4349202 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -116,7 +116,7 @@ if("Chief Engineer") O = new /datum/outfit/plasmaman/ce - if("Atmospheric Technician") + if("Life Support Specialist") O = new /datum/outfit/plasmaman/atmospherics if("Mime") diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm index fb7fd2ebda1..b21002e7225 100644 --- a/code/modules/mob/living/carbon/human/species/shadow.dm +++ b/code/modules/mob/living/carbon/human/species/shadow.dm @@ -8,8 +8,6 @@ unarmed_type = /datum/unarmed_attack/claws - ignored_by = list(/mob/living/simple_animal/hostile/faithless) - blood_color = "#CCCCCC" flesh_color = "#AAAAAA" has_organ = list( @@ -51,12 +49,14 @@ if(grant_vision_toggle) vision_toggle = new vision_toggle.Grant(H) + H.faction |= "faithless" /datum/species/shadow/on_species_loss(mob/living/carbon/human/H) ..() if(grant_vision_toggle && vision_toggle) H.vision_type = null vision_toggle.Remove(H) + H.faction -= "faithless" /datum/species/shadow/handle_life(mob/living/carbon/human/H) var/light_amount = 0 diff --git a/code/modules/mob/living/carbon/human/species/zombies.dm b/code/modules/mob/living/carbon/human/species/zombies.dm new file mode 100644 index 00000000000..6ff30c54a67 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/zombies.dm @@ -0,0 +1,91 @@ +#define REGENERATION_DELAY 60 // After taking damage, how long it takes for automatic regeneration to begin + +/datum/species/zombie + // 1spooky + name = "High-Functioning Zombie" + name_plural = "High-Functioning Zombies" + icobase = 'icons/mob/human_races/r_zombie.dmi' + deform = 'icons/mob/human_races/r_def_zombie.dmi' + dies_at_threshold = TRUE + language = "Zombie" + species_traits = list(NO_BLOOD,NOZOMBIE,NOTRANSSTING,NO_BREATHE, RADIMMUNE, NO_SCAN) + var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg') + warning_low_pressure = 50 + hazard_low_pressure = 0 + flesh_color = "#00FF00" // for green examine text + bodyflags = HAS_SKIN_COLOR + dietflags = DIET_CARN + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, + "ears" = /obj/item/organ/internal/ears, + "zombie_infection" = /obj/item/organ/internal/zombie_infection) + + +/datum/species/zombie/infectious + name = "Infectious Zombie" + mutanthands = /obj/item/zombie_hand + icobase = 'icons/mob/human_races/r_zombie.dmi' + deform = 'icons/mob/human_races/r_def_zombie.dmi' + armor = 20 // 120 damage to KO a zombie, which kills it + speedmod = 1.6 + default_language = "Zombie" + var/heal_rate = 1 + var/regen_cooldown = 0 + +/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H, amount) + . = min(20, amount) + +/datum/species/zombie/infectious/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, sharp = 0, obj/used_weapon = null) + . = ..() + if(damage) + regen_cooldown = world.time + REGENERATION_DELAY + +/datum/species/zombie/infectious/handle_life(mob/living/carbon/human/C) + . = ..() + //Zombies never actually die, they just fall down until they regenerate enough to rise back up. + //They must be restrained, beheaded or gibbed to stop being a threat. + if(regen_cooldown < world.time) + var/heal_amt = heal_rate + if(C.InCritical()) + heal_amt *= 2 + C.heal_overall_damage(heal_amt,heal_amt) + C.adjustToxLoss(-heal_amt) + if(!C.InCritical() && prob(4)) + playsound(C, pick(spooks), 50, TRUE, 10) + +//Congrats you somehow died so hard you stopped being a zombie +/datum/species/zombie/infectious/spec_death(gibbed, mob/living/carbon/C) + . = ..() + var/obj/item/organ/internal/zombie_infection/infection + infection = C.get_organ_slot("zombie_infection") + if(infection) + qdel(infection) + +/datum/species/zombie/infectious/on_species_gain(mob/living/carbon/human/C, datum/species/old_species) + . = ..() + // Deal with the source of this zombie corruption + // Infection organ needs to be handled separately from mutant_organs + // because it persists through species transitions + if(mutanthands) + C.drop_l_hand() + C.drop_r_hand() + C.put_in_hands(new mutanthands()) + C.put_in_hands(new mutanthands()) + var/obj/item/organ/internal/zombie_infection/infection + infection = C.get_organ_slot("zombie_infection") + if(!infection) + infection = new() + infection.insert(C) + +/datum/species/zombie/infectious/on_species_loss(mob/living/carbon/human/C, datum/species/old_species) + QDEL_NULL(C.r_hand) + QDEL_NULL(C.l_hand) + return ..() + +#undef REGENERATION_DELAY diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index 379eb183292..818e15f26e8 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -5,21 +5,29 @@ . = ..() /mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0) - if(dna.species) + if(dna.species.stun_mod) amount = amount * dna.species.stun_mod + else + amount = dna.species.spec_stun(src,amount) return ..() /mob/living/carbon/human/SetWeakened(amount, updating = 1, force = 0) - if(dna.species) + if(dna.species.stun_mod) amount = amount * dna.species.stun_mod + else + amount = dna.species.spec_stun(src,amount) return ..() /mob/living/carbon/human/SetParalysis(amount, updating = 1, force = 0) - if(dna.species) + if(dna.species.stun_mod) amount = amount * dna.species.stun_mod + else + amount = dna.species.spec_stun(src,amount) return ..() /mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE) - if(dna.species) + if(dna.species.stun_mod) amount = amount * dna.species.stun_mod - return ..() \ No newline at end of file + else + amount = dna.species.spec_stun(src,amount) + return ..() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index a682a61d68d..05dfbd0e302 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -1022,9 +1022,9 @@ var/global/list/damage_icon_parts = list() t_state = r_hand.icon_state var/mutable_appearance/standing - if(r_hand.sprite_sheets && r_hand.sprite_sheets[dna.species.name]) + if(r_hand.sprite_sheets_inhand && r_hand.sprite_sheets_inhand[dna.species.name]) t_state = "[t_state]_r" - standing = mutable_appearance(r_hand.sprite_sheets[dna.species.name], "[t_state]", layer = -R_HAND_LAYER) + standing = mutable_appearance(r_hand.sprite_sheets_inhand[dna.species.name], "[t_state]", layer = -R_HAND_LAYER) else standing = mutable_appearance(r_hand.righthand_file, "[t_state]", layer = -R_HAND_LAYER) standing = center_image(standing, r_hand.inhand_x_dimension, r_hand.inhand_y_dimension) @@ -1041,9 +1041,9 @@ var/global/list/damage_icon_parts = list() t_state = l_hand.icon_state var/mutable_appearance/standing - if(l_hand.sprite_sheets && l_hand.sprite_sheets[dna.species.name]) + if(l_hand.sprite_sheets_inhand && l_hand.sprite_sheets_inhand[dna.species.name]) t_state = "[t_state]_l" - standing = mutable_appearance(l_hand.sprite_sheets[dna.species.name], "[t_state]", layer = -L_HAND_LAYER) + standing = mutable_appearance(l_hand.sprite_sheets_inhand[dna.species.name], "[t_state]", layer = -L_HAND_LAYER) else standing = mutable_appearance(l_hand.lefthand_file, "[t_state]", layer = -L_HAND_LAYER) standing = center_image(standing, l_hand.inhand_x_dimension, l_hand.inhand_y_dimension) diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index 38dadbbbfa7..ddab7eae1ee 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -510,13 +510,15 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 /mob/living/carbon/slime/toggle_throw_mode() return -/mob/living/carbon/slime/proc/apply_water() - adjustToxLoss(rand(15,20)) - if(!client) - if(Target) // Like cats - Target = null - ++Discipline - return +/mob/living/carbon/slime/water_act(volume, temperature, source, method = TOUCH) + . = ..() + + var/water_damage = rand(10, 15) * volume + adjustToxLoss(water_damage) + + if(!client && Target && volume >= 3) + Target = null + ++Discipline /mob/living/carbon/slime/can_use_vents() if(Victim) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 57c67f5fd61..cd20656254f 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -2,6 +2,7 @@ . = ..() var/datum/atom_hud/data/human/medical/advanced/medhud = huds[DATA_HUD_MEDICAL_ADVANCED] medhud.add_to_hud(src) + faction += "\ref[src]" /mob/living/prepare_huds() ..() @@ -256,10 +257,10 @@ death() to_chat(src, "You have given up life and succumbed to death.") - + /mob/living/proc/InCritical() return (health < HEALTH_THRESHOLD_CRIT && health > HEALTH_THRESHOLD_DEAD && stat == UNCONSCIOUS) - + /mob/living/ex_act(severity) ..() @@ -916,44 +917,6 @@ if(pulling && !(pulling in orange(1))) stop_pulling() -/mob/living/proc/get_taste_sensitivity() - return 1 - -/mob/living/proc/taste_reagents(datum/reagents/tastes) - if(!get_taste_sensitivity())//this also works for IPCs and stuff that returns 0 here - return - - var/do_not_taste_at_all = 1//so we don't spam with recent tastes - - var/taste_sum = 0 - var/list/taste_list = list()//associative list so we can stack stuff that tastes the same - var/list/final_taste_list = list()//final list of taste strings - - for(var/datum/reagent/R in tastes.reagent_list) - taste_sum += R.volume * R.taste_strength - if(!R.taste_message)//set to null; no taste, like water - continue - taste_list[R.taste_message] += R.volume * R.taste_strength - - for(var/R in taste_list) - if(recent_tastes[R] && (world.time - recent_tastes[R] < 12 SECONDS)) - continue - - do_not_taste_at_all = 0//something was fresh enough to taste; could still be bland enough to be unrecognizable - - if(taste_list[R] / taste_sum >= 0.15 / get_taste_sensitivity())//we return earlier if the proc returns a 0; won't break the universe - final_taste_list += R - recent_tastes[R] = world.time - - if(do_not_taste_at_all) - return //no message spam - - if(final_taste_list.len == 0)//too many reagents - none meet their thresholds - to_chat(src, "You can't really make out what you're tasting...") - return - - to_chat(src, "You can taste [english_list(final_taste_list)].") - /mob/living/proc/update_z(new_z) // 1+ to register, null to unregister if(registered_z != new_z) if(registered_z) diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index b49aa82625c..2eca24104cd 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -70,6 +70,13 @@ if(!silent && !isnull(usr)) log_and_message_admins("cleared the supplied laws of [src]") +/mob/living/silicon/proc/clear_zeroth_law(var/silent = FALSE) + throw_alert("newlaw", /obj/screen/alert/newlaw) + laws_sanity_check() + laws.clear_zeroth_laws() + if(!silent && !isnull(usr)) + log_and_message_admins("cleared the zeroth law of [src]") + /mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws) var/prefix = "" if(MAIN_CHANNEL == lawchannel) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 636df89885d..20f6155ba0f 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -1,10 +1,26 @@ +/mob/living/simple_animal/attackby(obj/item/O, mob/living/user) + if(can_collar && !collar && istype(O, /obj/item/clothing/accessory/petcollar)) + var/obj/item/clothing/accessory/petcollar/C = O + if(user.drop_item()) + C.forceMove(src) + collar = C + collar.equipped(src) + regenerate_icons() + to_chat(usr, "You put \the [C] around \the [src]'s neck.") + if(C.tagname) + name = C.tagname + real_name = C.tagname + return + else + return ..() + /mob/living/simple_animal/attack_hand(mob/living/carbon/human/M) ..() switch(M.a_intent) if(INTENT_HELP) if(health > 0) - visible_message("[M] [response_help] [src].") + visible_message("[M] [response_help] [src].", "[M] [response_help] you.") playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) if(INTENT_GRAB) @@ -12,12 +28,12 @@ if(INTENT_HARM, INTENT_DISARM) M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - visible_message("[M] [response_harm] [src]!") + visible_message("[M] [response_harm] [src]!", "[M] [response_harm] you!") playsound(loc, attacked_sound, 25, 1, -1) attack_threshold_check(harm_intent_damage) add_attack_logs(M, src, "Melee attacked with fists") updatehealth() - return 1 + return TRUE /mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) if(user.a_intent == INTENT_HARM) @@ -39,10 +55,11 @@ /mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L) if(..()) //successful larva bite - var/damage = rand(5, 10) if(stat != DEAD) - L.amount_grown = min(L.amount_grown + damage, L.max_grown) - attack_threshold_check(damage) + var/damage = rand(5, 10) + . = attack_threshold_check(damage) + if(.) + L.amount_grown = min(L.amount_grown + damage, L.max_grown) /mob/living/simple_animal/attack_animal(mob/living/simple_animal/M) if(..()) @@ -51,21 +68,57 @@ /mob/living/simple_animal/attack_slime(mob/living/carbon/slime/M) ..() - var/damage = rand(1, 3) - + var/damage = rand(15, 25) if(M.is_adult) - damage = rand(20, 40) - else - damage = rand(5, 35) - + damage = rand(20, 35) attack_threshold_check(damage) - return -/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE) - if(damage <= force_threshold || !damage_coeff[damagetype]) - visible_message("[src] looks unharmed.") +/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = "melee") + var/temp_damage = damage + if(!damage_coeff[damagetype]) + temp_damage = 0 else - apply_damage(damage, damagetype) + temp_damage *= damage_coeff[damagetype] + + if(temp_damage >= 0 && temp_damage <= force_threshold) + visible_message("[src] looks unharmed.") + return FALSE + else + apply_damage(damage, damagetype, null, getarmor(null, armorcheck)) + return TRUE + +/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj) + if(!Proj) + return + apply_damage(Proj.damage, Proj.damage_type) + Proj.on_hit(src, 0) + return FALSE + +/mob/living/simple_animal/ex_act(severity, origin) + if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) + return + ..() + var/bomb_armor = getarmor(null, "bomb") + switch(severity) + if(1) + if(prob(bomb_armor)) + adjustBruteLoss(500) + else + gib() + return + if(2) + var/bloss = 60 + if(prob(bomb_armor)) + bloss = bloss / 1.5 + adjustBruteLoss(bloss) + if(3) + var/bloss = 30 + if(prob(bomb_armor)) + bloss = bloss / 1.5 + adjustBruteLoss(bloss) + +/mob/living/simple_animal/blob_act(obj/structure/blob/B) + adjustBruteLoss(20) /mob/living/simple_animal/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) if(!no_effect && !visual_effect_icon && melee_damage_upper) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 4793b91dee6..76f88220eda 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -241,10 +241,10 @@ else to_chat(user, "[src] is in pristine condition.") -/mob/living/simple_animal/bot/adjustHealth(amount) +/mob/living/simple_animal/bot/adjustHealth(amount, updating_health = TRUE) if(amount > 0 && prob(10)) new /obj/effect/decal/cleanable/blood/oil(loc) - return ..(amount) + . = ..() /mob/living/simple_animal/bot/updatehealth(reason = "none given") ..(reason) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index d5fabe96be4..3a26265466b 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -217,7 +217,7 @@ /mob/living/simple_animal/hostile/construct/builder/Found(atom/A) //what have we found here? - if(istype(A, /mob/living/simple_animal/hostile/construct)) //is it a construct? + if(isconstruct(A)) //is it a construct? var/mob/living/simple_animal/hostile/construct/C = A if(C.health < C.maxHealth) //is it hurt? let's go heal it if it is return 1 @@ -236,7 +236,7 @@ ..() if(isliving(target)) var/mob/living/L = target - if(istype(L, /mob/living/simple_animal/hostile/construct) && L.health >= L.maxHealth) //is this target an unhurt construct? stop trying to heal it + if(isconstruct(L) && L.health >= L.maxHealth) //is this target an unhurt construct? stop trying to heal it LoseTarget() return 0 if(L.health <= melee_damage_lower+melee_damage_upper) //ey bucko you're hurt as fuck let's go hit you @@ -245,7 +245,7 @@ /mob/living/simple_animal/hostile/construct/builder/Aggro() ..() - if(istype(target, /mob/living/simple_animal/hostile/construct)) //oh the target is a construct no need to flee + if(isconstruct(target)) //oh the target is a construct no need to flee retreat_distance = null minimum_distance = 1 @@ -256,7 +256,7 @@ /mob/living/simple_animal/hostile/construct/builder/hostile //actually hostile, will move around, hit things, heal other constructs AIStatus = AI_ON - environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP + environment_smash = ENVIRONMENT_SMASH_STRUCTURES //only token destruction, don't smash the cult wall NO STOP /////////////////////////////Behemoth///////////////////////// diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm new file mode 100644 index 00000000000..6899b40bea0 --- /dev/null +++ b/code/modules/mob/living/simple_animal/damage_procs.dm @@ -0,0 +1,37 @@ + +/mob/living/simple_animal/proc/adjustHealth(amount, updating_health = TRUE) + if(status_flags & GODMODE) + return FALSE + var/oldbruteloss = bruteloss + bruteloss = Clamp(bruteloss + amount, 0, maxHealth) + if(oldbruteloss == bruteloss) + updating_health = FALSE + . = STATUS_UPDATE_NONE + else + . = STATUS_UPDATE_HEALTH + if(updating_health) + updatehealth() + +/mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE) + if(damage_coeff[BRUTE]) + return adjustHealth(amount * damage_coeff[BRUTE], updating_health) + +/mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE) + if(damage_coeff[BURN]) + return adjustHealth(amount * damage_coeff[BURN], updating_health) + +/mob/living/simple_animal/adjustOxyLoss(amount, updating_health = TRUE) + if(damage_coeff[OXY]) + return adjustHealth(amount * damage_coeff[OXY], updating_health) + +/mob/living/simple_animal/adjustToxLoss(amount, updating_health = TRUE) + if(damage_coeff[TOX]) + return adjustHealth(amount * damage_coeff[TOX], updating_health) + +/mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE) + if(damage_coeff[CLONE]) + return adjustHealth(amount * damage_coeff[CLONE], updating_health) + +/mob/living/simple_animal/adjustStaminaLoss(amount, updating_health = TRUE) + if(damage_coeff[STAMINA]) + return ..(amount*damage_coeff[STAMINA], updating_health) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 4dea368ad5e..928cd9789da 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -94,26 +94,27 @@ new cat_type(loc) -/mob/living/simple_animal/pet/cat/handle_automated_action() +/mob/living/simple_animal/pet/cat/Life() ..() - if(prob(1)) - custom_emote(1, pick("stretches out for a belly rub.", "wags its tail.", "lies down.")) - icon_state = "[icon_living]_rest" - resting = 1 - update_canmove() - else if (prob(1)) - custom_emote(1, pick("sits down.", "crouches on its hind legs.", "looks alert.")) - icon_state = "[icon_living]_sit" - resting = 1 - update_canmove() - else if (prob(1)) - if (resting) - custom_emote(1, pick("gets up and meows.", "walks around.", "stops resting.")) - icon_state = "[icon_living]" - resting = 0 + make_babies() + + +/mob/living/simple_animal/pet/cat/handle_automated_action() + if(!stat && !buckled) + if(prob(1)) + custom_emote(1, pick("stretches out for a belly rub.", "wags its tail.", "lies down.")) + StartResting() + else if(prob(1)) + custom_emote(1, pick("sits down.", "crouches on its hind legs.", "looks alert.")) + icon_state = "[icon_living]_sit" + resting = TRUE update_canmove() - else - custom_emote(1, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat.")) + else if(prob(1)) + if(resting) + custom_emote(1, pick("gets up and meows.", "walks around.", "stops resting.")) + StopResting() + else + custom_emote(1, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat.")) //MICE! if(eats_mice && isturf(loc) && !incapacitated()) @@ -128,10 +129,9 @@ if(T.cooldown < (world.time - 400)) custom_emote(1, "bats \the [T] around with its paw!") T.cooldown = world.time - make_babies() /mob/living/simple_animal/pet/cat/handle_automated_movement() - ..() + . = ..() if(!stat && !resting && !buckled) turns_since_scan++ if(turns_since_scan > 5) diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index d8f09f4cb78..c6a572e9679 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -451,9 +451,8 @@ response_harm = "kicks" gold_core_spawnable = CHEM_MOB_SPAWN_INVALID -/mob/living/simple_animal/pet/corgi/Ian/Life() - ..() - +/mob/living/simple_animal/pet/corgi/Ian/handle_automated_movement() + . = ..() //Feeding, chasing food, FOOOOODDDD if(!resting && !buckled) turns_since_scan++ @@ -580,9 +579,10 @@ /mob/living/simple_animal/pet/corgi/Lisa/Life() ..() - make_babies() +/mob/living/simple_animal/pet/corgi/Lisa/handle_automated_movement() + . = ..() if(!resting && !buckled) if(prob(1)) custom_emote(1, pick("dances around.","chases her tail.")) @@ -651,15 +651,16 @@ /mob/living/simple_animal/pet/corgi/Ian/borgi/Life(seconds, times_fired) ..() - if(emagged && prob(25)) - var/mob/living/carbon/target = locate() in view(10,src) - if(target) - shootAt(target) - //spark for no reason if(prob(5)) do_sparks(3, 1, src) +/mob/living/simple_animal/pet/corgi/Ian/borgi/handle_automated_action() + if(emagged && prob(25)) + var/mob/living/carbon/target = locate() in view(10, src) + if(target) + shootAt(target) + /mob/living/simple_animal/pet/corgi/Ian/borgi/death(gibbed) // Only execute the below if we successfully died . = ..(gibbed) diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index 94ecb71703b..1456e2f70fb 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -17,8 +17,6 @@ stop_automated_movement = 1 friendly = "pinches" ventcrawler = 2 - var/obj/item/inventory_head - var/obj/item/inventory_mask can_hide = 1 can_collar = 1 gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY @@ -32,11 +30,6 @@ var/east_vs_west = pick(4, 8) if(Process_Spacemove(east_vs_west)) Move(get_step(src, east_vs_west), east_vs_west) - turns_since_move = 0 - -/mob/living/simple_animal/crab/Life(seconds, times_fired) - . = ..() - regenerate_icons() //COFFEE! SQUEEEEEEEEE! /mob/living/simple_animal/crab/Coffee diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index bdb479997dc..0c9aa96728c 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -34,12 +34,11 @@ . = ..() /mob/living/simple_animal/hostile/retaliate/goat/Destroy() - qdel(udder) - udder = null + QDEL_NULL(udder) return ..() /mob/living/simple_animal/hostile/retaliate/goat/handle_automated_movement() - ..() + . = ..() //chance to go crazy and start wacking stuff if(!enemies.len && prob(1)) Retaliate() @@ -49,14 +48,13 @@ LoseTarget() visible_message("[src] calms down.") - if(stat == CONSCIOUS) - eat_plants() - if(!pulledby) - for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) - var/step = get_step(src, direction) - if(step) - if(locate(/obj/structure/spacevine) in step || locate(/obj/structure/glowshroom) in step) - Move(step, get_dir(src, step)) + eat_plants() + if(!pulledby) + for(var/direction in shuffle(list(1, 2, 4, 8, 5, 6, 9, 10))) + var/step = get_step(src, direction) + if(step) + if(locate(/obj/structure/spacevine) in step || locate(/obj/structure/glowshroom) in step) + Move(step, get_dir(src, step)) /mob/living/simple_animal/hostile/retaliate/goat/Life(seconds, times_fired) . = ..() @@ -94,8 +92,8 @@ say("Nom") /mob/living/simple_animal/hostile/retaliate/goat/AttackingTarget() - ..() - if(isdiona(target)) + . = ..() + if(. && isdiona(target)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/NB = pick(H.bodyparts) H.visible_message("[src] takes a big chomp out of [H]!", "[src] takes a big chomp out of your [NB.name]!") diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 2c9cbc355f7..ec9cb5cd884 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -56,28 +56,19 @@ visible_message("[src] chews through [C].") /mob/living/simple_animal/mouse/handle_automated_speech() - ..() - if(prob(speak_chance)) - for(var/mob/M in view()) - M << squeak_sound - -/mob/living/simple_animal/mouse/Life(seconds, times_fired) - . = ..() - if(stat == UNCONSCIOUS) - if(ckey || prob(1)) - stat = CONSCIOUS - icon_state = "mouse_[mouse_color]" - wander = 1 - else if(prob(5)) - emote("snuffles") - -/mob/living/simple_animal/mouse/Life() ..() - if(prob(0.5) && !ckey) - stat = UNCONSCIOUS - icon_state = "mouse_[mouse_color]_sleep" - wander = 0 - speak_chance = 0 + if(prob(speak_chance) && !incapacitated()) + playsound(src, squeak_sound, 100, 1) + +/mob/living/simple_animal/mouse/handle_automated_movement() + . = ..() + if(resting) + if(prob(1)) + StopResting() + else if(prob(5)) + custom_emote(2, "snuffles") + else if(prob(0.5)) + StartResting() /mob/living/simple_animal/mouse/New() ..() @@ -119,7 +110,7 @@ desc = "It's toast." death() -/mob/living/simple_animal/mouse/death(gibbed) +/mob/living/simple_animal/mouse/death(gibbed) // Only execute the below if we successfully died playsound(src, squeak_sound, 40, 1) . = ..(gibbed) diff --git a/code/modules/mob/living/simple_animal/friendly/pug.dm b/code/modules/mob/living/simple_animal/friendly/pug.dm index 36ce34094a0..c7b52928e8a 100644 --- a/code/modules/mob/living/simple_animal/friendly/pug.dm +++ b/code/modules/mob/living/simple_animal/friendly/pug.dm @@ -19,13 +19,12 @@ see_in_dark = 5 gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY -/mob/living/simple_animal/pet/pug/Life() - ..() - +/mob/living/simple_animal/pet/pug/handle_automated_movement() + . = ..() if(!resting && !buckled) if(prob(1)) custom_emote(1, pick("chases its tail.")) spawn(0) - for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) + for(var/i in list(1, 2, 4, 8, 4, 2, 1, 2, 4, 8, 4, 2, 1, 2, 4, 8, 4, 2)) dir = i - sleep(1) + sleep(1) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 0aa148eb031..52f149f0775 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -158,7 +158,8 @@ if(istype(target, /obj/effect/decal/cleanable)) visible_message("\The [src] cleans up \the [target].") qdel(target) - return + return TRUE var/atom/movable/M = target M.clean_blood() visible_message("\The [src] polishes \the [target].") + return TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/bat.dm b/code/modules/mob/living/simple_animal/hostile/bat.dm index 2d16dcb3095..fdb05a51fd9 100644 --- a/code/modules/mob/living/simple_animal/hostile/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/bat.dm @@ -22,6 +22,9 @@ attacktext = "bites" attack_sound = 'sound/weapons/bite.ogg' + emote_taunt = list("flutters") + taunt_chance = 20 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 @@ -39,11 +42,6 @@ /mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0) return ..() //No drifting in space for space carp! //original comments do not steal -/mob/living/simple_animal/hostile/scarybat/FindTarget() - . = ..() - if(.) - custom_emote(1, "flutters towards [.]") - /mob/living/simple_animal/hostile/scarybat/Found(var/atom/A)//This is here as a potential override to pick a specific target if available if(istype(A) && A == owner) return 0 diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 8b814076720..cf084086ae7 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -137,12 +137,13 @@ if(target == beehome) var/obj/structure/beebox/BB = target forceMove(BB) + toggle_ai(AI_IDLE) target = null wanted_objects -= beehometypecache //so we don't attack beeboxes when not going home return //no don't attack the goddamm box else - ..() - if(isliving(target) && (!client || a_intent == INTENT_HARM)) + . = ..() + if(. && isliving(target) && (!client || a_intent == INTENT_HARM)) var/mob/living/L = target if(L.reagents) if(beegent) @@ -222,8 +223,8 @@ //leave pollination for the peasent bees /mob/living/simple_animal/hostile/poison/bees/queen/AttackingTarget() - ..() - if(beegent && isliving(target)) + . = ..() + if(. && beegent && isliving(target)) var/mob/living/L = target beegent.reaction_mob(L, TOUCH) L.reagents.add_reagent(beegent.id, rand(1, 5)) @@ -283,6 +284,14 @@ QDEL_NULL(queen) return ..() +/mob/living/simple_animal/hostile/poison/bees/consider_wakeup() + if(beehome && loc == beehome) // If bees are chilling in their nest, they're not actively looking for targets + idle = min(100, ++idle) + if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM)) + toggle_ai(AI_ON) + forceMove(beehome.drop_location()) + else + ..() //Syndicate Bees /mob/living/simple_animal/hostile/poison/bees/syndi @@ -327,8 +336,8 @@ return TRUE /mob/living/simple_animal/hostile/poison/bees/syndi/AttackingTarget() - ..() - if(target && isliving(target)) + . = ..() + if(. && target && isliving(target)) var/mob/living/L = target if(L.stat) LoseTarget() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 299677804e2..48021ad2593 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -10,6 +10,8 @@ response_help = "pets the" response_disarm = "gently pushes aside the" response_harm = "hits the" + emote_taunt = list("gnashes") + taunt_chance = 30 speed = 0 maxHealth = 25 health = 25 @@ -50,14 +52,9 @@ /mob/living/simple_animal/hostile/carp/Process_Spacemove(var/movement_dir = 0) return 1 //No drifting in space for space carp! //original comments do not steal -/mob/living/simple_animal/hostile/carp/FindTarget() - . = ..() - if(.) - custom_emote(1, "gnashes at [.]!") - /mob/living/simple_animal/hostile/carp/AttackingTarget() - ..() - if(ishuman(target)) + . = ..() + if(. && ishuman(target)) var/mob/living/carbon/human/H = target H.adjustStaminaLoss(8) diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index f668312e88d..2b736ee7641 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -19,6 +19,8 @@ attacktext = "grips" attack_sound = 'sound/hallucinations/growl1.ogg' speak_emote = list("growls") + emote_taunt = list("wails") + taunt_chance = 25 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 @@ -29,14 +31,9 @@ /mob/living/simple_animal/hostile/faithless/Process_Spacemove(var/movement_dir = 0) return 1 -/mob/living/simple_animal/hostile/faithless/FindTarget() - . = ..() - if(.) - custom_emote(1, "wails at [.]!") - /mob/living/simple_animal/hostile/faithless/AttackingTarget() - ..() - if(iscarbon(target)) + . = ..() + if(. && iscarbon(target)) var/mob/living/carbon/C = target if(prob(12)) C.Weaken(3) diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index f28aed9dae8..258a1f1abe7 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -40,8 +40,8 @@ /mob/living/simple_animal/hostile/poison/giant_spider/AttackingTarget() // This is placed here, NOT on /poison, because the other subtypes of /poison/ already override AttackingTarget() completely, and as such it would do nothing but confuse people there. - ..() - if(venom_per_bite > 0 && iscarbon(target) && (!client || a_intent == INTENT_HARM)) + . = ..() + if(. && venom_per_bite > 0 && iscarbon(target) && (!client || a_intent == INTENT_HARM)) var/mob/living/carbon/C = target var/inject_target = pick("chest", "head") if(C.can_inject(null, 0, inject_target, 0)) @@ -76,19 +76,20 @@ venom_per_bite = 10 move_to_delay = 5 -/mob/living/simple_animal/hostile/poison/giant_spider/hunter/handle_automated_movement() - if(AIStatus == AI_IDLE && !busy) +/mob/living/simple_animal/hostile/poison/giant_spider/handle_automated_movement() //Hacky and ugly. + . = ..() + if(AIStatus == AI_IDLE) //1% chance to skitter madly away if(prob(1)) stop_automated_movement = 1 - Goto(pick(orange(20, src)), move_to_delay) + Goto(pick(urange(20, src, 1)), move_to_delay) spawn(50) stop_automated_movement = 0 walk(src,0) else ..() -/mob/living/simple_animal/hostile/poison/giant_spider/nurse/proc/GiveUp(var/C) +/mob/living/simple_animal/hostile/poison/giant_spider/nurse/proc/GiveUp(C) spawn(100) if(busy == MOVING_TO_TARGET) if(cocoon_target == C && get_dist(src,cocoon_target) > 1) @@ -96,13 +97,13 @@ busy = 0 stop_automated_movement = 0 -/mob/living/simple_animal/hostile/poison/giant_spider/nurse/handle_automated_movement() - if(AIStatus == AI_IDLE) +/mob/living/simple_animal/hostile/poison/giant_spider/nurse/handle_automated_movement() //Hacky and ugly. + if(..()) var/list/can_see = view(src, 10) if(!busy && prob(30)) //30% chance to stop wandering and do something - //first, check for potential food nearby to cocoon + //first, check for potential food nearby to cocoon for(var/mob/living/C in can_see) - if(C.stat && !istype(C,/mob/living/simple_animal/hostile/poison/giant_spider)) + if(C.stat && !istype(C, /mob/living/simple_animal/hostile/poison/giant_spider) && !C.anchored) cocoon_target = C busy = MOVING_TO_TARGET Goto(C, move_to_delay) @@ -122,7 +123,7 @@ for(var/obj/O in can_see) if(O.anchored) continue - if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery)) + if(isitem(O) || isstructure(O) || ismachinery(O)) cocoon_target = O busy = MOVING_TO_TARGET stop_automated_movement = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 1ef6f06259f..1d37f04312d 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -36,11 +36,11 @@ for(var/mob/living/L in T) if(L == src || L == A) continue - if(faction_check(L) && !attack_same) + if(faction_check_mob(L) && !attack_same) return visible_message("[src] [ranged_message] at [A]!") throw_at(A, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE) - ranged_cooldown = world.time + ranged_cooldown_time + ranged_cooldown = world.time + ranged_cooldown_time /mob/living/simple_animal/hostile/headcrab/proc/Zombify(mob/living/carbon/human/H) if(!H.check_death_method()) diff --git a/code/modules/mob/living/simple_animal/hostile/headslug.dm b/code/modules/mob/living/simple_animal/hostile/headslug.dm index e2fc98c483f..a14ed91aa8f 100644 --- a/code/modules/mob/living/simple_animal/hostile/headslug.dm +++ b/code/modules/mob/living/simple_animal/hostile/headslug.dm @@ -36,16 +36,14 @@ else if(mind) // Let's make this a feature egg.origin = mind for(var/obj/item/organ/internal/I in src) - I.loc = egg + I.forceMove(egg) visible_message("[src] plants something in [victim]'s flesh!", \ "We inject our egg into [victim]'s body!") egg_lain = 1 /mob/living/simple_animal/hostile/headslug/AttackingTarget() - if(egg_lain) - target.attack_animal(src) - return - if(iscarbon(target) && !issmall(target)) + . = ..() + if(. && !egg_lain && iscarbon(target) && !issmall(target)) // Changeling egg can survive in aliens! var/mob/living/carbon/C = target if(C.stat == DEAD) @@ -54,10 +52,7 @@ return Infect(target) to_chat(src, "With our egg laid, our death approaches rapidly...") - spawn(100) - death() - return - target.attack_animal(src) + addtimer(CALLBACK(src, .proc/death), 100) /obj/item/organ/internal/body_egg/changeling_egg name = "changeling egg" diff --git a/code/modules/mob/living/simple_animal/hostile/hellhound.dm b/code/modules/mob/living/simple_animal/hostile/hellhound.dm index f3e110d0099..40318b914bc 100644 --- a/code/modules/mob/living/simple_animal/hostile/hellhound.dm +++ b/code/modules/mob/living/simple_animal/hostile/hellhound.dm @@ -42,19 +42,16 @@ whisper_action.Grant(src) /mob/living/simple_animal/hostile/hellhound/handle_automated_action() - . = ..() + if(!..()) + return if(resting) if(!wants_to_rest()) custom_emote(1, "growls, and gets up.") playsound(get_turf(src), 'sound/hallucinations/growl2.ogg', 50, 1) - icon_state = "[icon_living]" - resting = 0 - update_canmove() + StopResting() else if(wants_to_rest()) custom_emote(1, "lays down, and starts to lick their wounds.") - icon_state = "[icon_resting]" - resting = 1 - update_canmove() + StartResting() /mob/living/simple_animal/hostile/hellhound/examine(mob/user) . = ..() @@ -97,7 +94,7 @@ /mob/living/simple_animal/hostile/hellhound/AttackingTarget() . = ..() - if(ishuman(target) && (!client || a_intent == INTENT_HARM)) + if(. && ishuman(target) && (!client || a_intent == INTENT_HARM)) special_aoe() /mob/living/simple_animal/hostile/hellhound/attackby(obj/item/C, mob/user, params) diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index 9695cacccd8..30572f19158 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -36,7 +36,7 @@ /mob/living/simple_animal/hostile/hivebot/rapid ranged = 1 - rapid = 1 + rapid = 3 retreat_distance = 5 minimum_distance = 5 diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index a96c78d09d6..41ed10288c3 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -2,60 +2,60 @@ faction = list("hostile") stop_automated_movement_when_pulled = 0 obj_damage = 40 - environment_smash = 1 //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls + environment_smash = ENVIRONMENT_SMASH_STRUCTURES //Bitflags. Set to ENVIRONMENT_SMASH_STRUCTURES to break closets,tables,racks, etc; ENVIRONMENT_SMASH_WALLS for walls; ENVIRONMENT_SMASH_RWALLS for rwalls var/atom/target - var/ranged = 0 - var/rapid = 0 - var/projectiletype + var/ranged = FALSE + var/rapid = 0 //How many shots per volley. + var/rapid_fire_delay = 2 //Time between rapid fire shots + + var/dodging = FALSE + var/approaching_target = FALSE //We should dodge now + var/in_melee = FALSE //We should sidestep now + var/dodge_prob = 30 + var/sidestep_per_cycle = 1 //How many sidesteps per npcpool cycle when in melee + + var/projectiletype //set ONLY it and NULLIFY casingtype var, if we have ONLY projectile var/projectilesound - var/casingtype + var/casingtype //set ONLY it and NULLIFY projectiletype, if we have projectile IN CASING var/move_to_delay = 3 //delay for the automated movement. var/list/friends = list() + var/list/emote_taunt = list() + var/taunt_chance = 0 + + var/rapid_melee = 1 //Number of melee attacks between each npc pool tick. Spread evenly. + var/melee_queue_distance = 4 //If target is close enough start preparing to hit them if we have rapid_melee enabled + var/ranged_message = "fires" //Fluff text for ranged mobs - var/ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat. var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance + //These vars are related to how mobs locate and target var/robust_searching = 0 //By default, mobs have a simple searching method, set this to 1 for the more scrutinous searching (stat_attack, stat_exclusive, etc), should be disabled on most mobs var/vision_range = 9 //How big of an area to search for targets in, a vision of 9 attempts to find targets as soon as they walk into screen view var/aggro_vision_range = 9 //If a mob is aggro, we search in this radius. Defaults to 9 to keep in line with original simple mob aggro radius - var/idle_vision_range = 9 //If a mob is just idling around, it's vision range is limited to this. Defaults to 9 to keep in line with original simple mob aggro radius var/search_objects = 0 //If we want to consider objects when searching around, set this to 1. If you want to search for objects while also ignoring mobs until hurt, set it to 2. To completely ignore mobs, even when attacked, set it to 3 - var/list/wanted_objects = list() //A list of objects that will be checked against to attack, should we have search_objects enabled - var/stat_attack = 0 //Mobs with stat_attack to 1 will attempt to attack things that are unconscious, Mobs with stat_attack set to 2 will attempt to attack the dead. - var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses - var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction - - //typecache of things this mob will attack in DestroySurroundings() if it has environment_smash - var/list/environment_target_typecache = list( - /obj/machinery/door/window, - /obj/structure/window, - /obj/structure/closet, - /obj/structure/table, - /obj/structure/grille, - /obj/structure/girder, - /obj/structure/rack, - /obj/structure/computerframe, - /obj/machinery/constructable_frame, - /obj/structure/barricade) //turned into a typecache in New() + var/search_objects_timer_id //Timer for regaining our old search_objects value after being attacked + var/search_objects_regain_time = 30 //the delay between being attacked and gaining our old search_objects value back + var/list/wanted_objects = list() //A typecache of objects types that will be checked against to attack, should we have search_objects enabled + var/stat_attack = CONSCIOUS //Mobs with stat_attack to UNCONSCIOUS will attempt to attack things that are unconscious, Mobs with stat_attack set to DEAD will attempt to attack the dead. + var/stat_exclusive = FALSE //Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack DEAD means they will only attack corpses + var/attack_same = 0 //Set us to 1 to allow us to attack our own faction var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such - var/list/emote_taunt = list() - var/taunt_chance = 0 + var/attack_all_objects = FALSE //if true, equivalent to having a wanted_objects list containing ALL objects. var/lose_patience_timer_id //id for a timer to call LoseTarget(), used to stop mobs fixating on a target they can't reach var/lose_patience_timeout = 300 //30 seconds by default, so there's no major changes to AI behaviour, beyond actually bailing if stuck forever - var/attack_all_objects = FALSE //if true, equivalent to having a wanted_objects list containing ALL objects. +/mob/living/simple_animal/hostile/Initialize(mapload) + . = ..() -/mob/living/simple_animal/hostile/New() - ..() if(!targets_from) targets_from = src - environment_target_typecache = typecacheof(environment_target_typecache) wanted_objects = typecacheof(wanted_objects) /mob/living/simple_animal/hostile/Destroy() @@ -73,16 +73,46 @@ if(AIStatus == AI_OFF) return 0 var/list/possible_targets = ListTargets() //we look around for potential targets and make it a list for later use. + if(environment_smash) EscapeConfinement() if(AICanContinue(possible_targets)) - DestroySurroundings() + if(!QDELETED(target) && !targets_from.Adjacent(target)) + DestroyPathToTarget() if(!MoveToTarget(possible_targets)) //if we lose our target if(AIShouldSleep(possible_targets)) // we try to acquire a new one toggle_ai(AI_IDLE) // otherwise we go idle return 1 +/mob/living/simple_animal/hostile/handle_automated_movement() + . = ..() + if(dodging && target && in_melee && isturf(loc) && isturf(target.loc)) + var/datum/cb = CALLBACK(src,.proc/sidestep) + if(sidestep_per_cycle > 1) //For more than one just spread them equally - this could changed to some sensible distribution later + var/sidestep_delay = SSnpcpool.wait / sidestep_per_cycle + for(var/i in 1 to sidestep_per_cycle) + addtimer(cb, (i - 1) * sidestep_delay) + else //Otherwise randomize it to make the players guessing. + addtimer(cb,rand(1, SSnpcpool.wait)) + +/mob/living/simple_animal/hostile/proc/sidestep() + if(!target || !isturf(target.loc) || !isturf(loc) || stat == DEAD) + return + var/target_dir = get_dir(src, target) + + var/static/list/cardinal_sidestep_directions = list(-90, -45, 0, 45, 90) + var/static/list/diagonal_sidestep_directions = list(-45, 0, 45) + var/chosen_dir = 0 + if (target_dir & (target_dir - 1)) + chosen_dir = pick(diagonal_sidestep_directions) + else + chosen_dir = pick(cardinal_sidestep_directions) + if(chosen_dir) + chosen_dir = turn(target_dir, chosen_dir) + Move(get_step(src, chosen_dir)) + face_atom(target) //Looks better if they keep looking at you when dodging + /mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user) if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client && user) FindTarget(list(user), 1) @@ -97,7 +127,6 @@ //////////////HOSTILE MOB TARGETTING AND AGGRESSION//////////// - /mob/living/simple_animal/hostile/proc/ListTargets()//Step 1, find out what we can see if(!search_objects) . = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide @@ -108,7 +137,11 @@ if(can_see(targets_from, HM, vision_range)) . += HM else - . = oview(vision_range, targets_from) + . = list() // The following code is only very slightly slower than just returning oview(vision_range, targets_from), but it saves us much more work down the line, particularly when bees are involved + for(var/obj/A in oview(vision_range, targets_from)) + . += A + for(var/mob/A in oview(vision_range, targets_from)) + . += A /mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about . = list() @@ -153,59 +186,61 @@ var/chosen_target = pick(Targets)//Pick the remaining targets (if any) at random return chosen_target -/mob/living/simple_animal/hostile/CanAttack(var/atom/the_target)//Can we actually attack a possible target? - if(!the_target) - return 0 - if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it - return 0 +// Please do not add one-off mob AIs here, but override this function for your mob +/mob/living/simple_animal/hostile/CanAttack(atom/the_target)//Can we actually attack a possible target? + if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids + return FALSE + + if(ismob(the_target)) //Target is in godmode, ignore it. + var/mob/M = the_target + if(M.status_flags & GODMODE) + return FALSE + + if(see_invisible < the_target.invisibility) //Target's invisible to us, forget it + return FALSE if(search_objects < 2) if(isliving(the_target)) var/mob/living/L = the_target - var/faction_check = faction_check(L) + var/faction_check = faction_check_mob(L) if(robust_searching) - if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive == 1) - return 0 - if(faction_check && !attack_same || !faction_check && attack_same == 2) - return 0 - if(L in friends) - return 0 - else - if(L.stat) - return 0 if(faction_check && !attack_same) - return 0 - return 1 + return FALSE + if(L.stat > stat_attack) + return FALSE + if(L in friends) + return FALSE + else + if((faction_check && !attack_same) || L.stat) + return FALSE + return TRUE - if(ishuman(the_target)) - var/mob/living/carbon/human/H = the_target - if(is_type_in_list(src, H.dna.species.ignored_by)) - return 0 - - if(istype(the_target, /obj/mecha)) + if(ismecha(the_target)) var/obj/mecha/M = the_target if(M.occupant)//Just so we don't attack empty mechs if(CanAttack(M.occupant)) - return 1 + return TRUE - if(istype(the_target, /obj/spacepod)) + if(isspacepod(the_target)) var/obj/spacepod/S = the_target - if(S.pilot) //Just so we don't attack empty pods + if(S.pilot)//Just so we don't attack empty pods if(CanAttack(S.pilot)) - return 1 + return TRUE if(istype(the_target, /obj/machinery/porta_turret)) var/obj/machinery/porta_turret/P = the_target if(P.faction in faction) - return 0 + return FALSE if(!P.raised) //Don't attack invincible turrets - return 0 + return FALSE if(P.stat & BROKEN) //Or turrets that are already broken - return 0 - return 1 + return FALSE + return TRUE + if(isobj(the_target)) - if(attack_all_objects || is_type_in_list(the_target, wanted_objects)) - return 1 - return 0 + if(attack_all_objects || is_type_in_typecache(the_target, wanted_objects)) + return TRUE + + return FALSE /mob/living/simple_animal/hostile/proc/GiveTarget(new_target)//Step 4, give us our selected target target = new_target @@ -215,19 +250,39 @@ Aggro() return 1 -/mob/living/simple_animal/hostile/proc/MoveToTarget(var/list/possible_targets)//Step 5, handle movement between us and our target +//What we do after closing in +/mob/living/simple_animal/hostile/proc/MeleeAction(patience = TRUE) + if(rapid_melee > 1) + var/datum/callback/cb = CALLBACK(src, .proc/CheckAndAttack) + var/delay = SSnpcpool.wait / rapid_melee + for(var/i in 1 to rapid_melee) + addtimer(cb, (i - 1)*delay) + else + AttackingTarget() + if(patience) + GainPatience() + +/mob/living/simple_animal/hostile/proc/CheckAndAttack() + if(target && targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from) && !incapacitated()) + AttackingTarget() + +/mob/living/simple_animal/hostile/proc/MoveToTarget(list/possible_targets)//Step 5, handle movement between us and our target stop_automated_movement = 1 if(!target || !CanAttack(target)) LoseTarget() return 0 if(target in possible_targets) - if(target.z != z) + var/turf/T = get_turf(src) + if(target.z != T.z) LoseTarget() return 0 var/target_distance = get_dist(targets_from,target) if(ranged) //We ranged? Shoot at em if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown OpenFire(target) + if(!Process_Spacemove()) //Drifting + walk(src,0) + return 1 if(retreat_distance != null) //If we have a retreat distance, check if we need to run from our target if(target_distance <= retreat_distance) //If target's closer than our retreat distance, run walk_away(src,target,retreat_distance,move_to_delay) @@ -237,8 +292,11 @@ Goto(target,move_to_delay,minimum_distance) if(target) if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack - AttackingTarget() - GainPatience() + MeleeAction() + else + if(rapid_melee > 1 && target_distance <= melee_queue_distance) + MeleeAction(FALSE) + in_melee = FALSE //If we're just preparing to strike do not enter sidestep mode return 1 return 0 if(environment_smash) @@ -256,14 +314,18 @@ return 0 /mob/living/simple_animal/hostile/proc/Goto(target, delay, minimum_distance) + if(target == src.target) + approaching_target = TRUE + else + approaching_target = FALSE walk_to(src, target, minimum_distance, delay) -/mob/living/simple_animal/hostile/adjustHealth(damage) +/mob/living/simple_animal/hostile/adjustHealth(damage, updating_health = TRUE) . = ..() if(!ckey && !stat && search_objects < 3 && damage > 0)//Not unconscious, and we don't ignore mobs if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight - search_objects = 0 target = null + LoseSearchObjects() if(AIStatus != AI_ON && AIStatus != AI_OFF) toggle_ai(AI_ON) FindTarget() @@ -271,7 +333,9 @@ FindTarget() /mob/living/simple_animal/hostile/proc/AttackingTarget() - target.attack_animal(src) + SEND_SIGNAL(src, COMSIG_HOSTILE_ATTACKINGTARGET, target) + in_melee = TRUE + return target.attack_animal(src) /mob/living/simple_animal/hostile/proc/Aggro() vision_range = aggro_vision_range @@ -281,11 +345,13 @@ /mob/living/simple_animal/hostile/proc/LoseAggro() stop_automated_movement = 0 - vision_range = idle_vision_range + vision_range = initial(vision_range) taunt_chance = initial(taunt_chance) /mob/living/simple_animal/hostile/proc/LoseTarget() target = null + approaching_target = FALSE + in_melee = FALSE walk(src, 0) LoseAggro() @@ -302,8 +368,7 @@ do_alert_animation(src) playsound(loc, 'sound/machines/chime.ogg', 50, 1, -1) for(var/mob/living/simple_animal/hostile/M in oview(distance, targets_from)) - var/list/L = M.faction&faction - if(L.len) + if(faction_check_mob(M, TRUE)) if(M.AIStatus == AI_OFF) return else @@ -323,21 +388,18 @@ return visible_message("[src] [ranged_message] at [A]!") - if(rapid) - spawn(1) - Shoot(A) - spawn(4) - Shoot(A) - spawn(6) - Shoot(A) + + if(rapid > 1) + var/datum/callback/cb = CALLBACK(src, .proc/Shoot, A) + for(var/i in 1 to rapid) + addtimer(cb, (i - 1)*rapid_fire_delay) else Shoot(A) ranged_cooldown = world.time + ranged_cooldown_time /mob/living/simple_animal/hostile/proc/Shoot(atom/targeted_atom) - if(targeted_atom == targets_from.loc || targeted_atom == targets_from) + if( QDELETED(targeted_atom) || targeted_atom == targets_from.loc || targeted_atom == targets_from ) return - var/turf/startloc = get_turf(targets_from) if(casingtype) var/obj/item/ammo_casing/casing = new casingtype(startloc) @@ -354,32 +416,70 @@ if(AIStatus != AI_ON)//Don't want mindless mobs to have their movement screwed up firing in space newtonian_move(get_dir(targeted_atom, targets_from)) P.original = targeted_atom + P.preparePixelProjectile(targeted_atom, get_turf(targeted_atom), src) P.fire() return P -/mob/living/simple_animal/hostile/proc/DestroySurroundings() +/mob/living/simple_animal/hostile/proc/CanSmashTurfs(turf/T) + return iswallturf(T) || ismineralturf(T) + +/mob/living/simple_animal/hostile/Move(atom/newloc, dir , step_x , step_y) + if(dodging && approaching_target && prob(dodge_prob) && moving_diagonally == 0 && isturf(loc) && isturf(newloc)) + return dodge(newloc, dir) + else + return ..() + +/mob/living/simple_animal/hostile/proc/dodge(moving_to,move_direction) + //Assuming we move towards the target we want to swerve toward them to get closer + var/cdir = turn(move_direction, 45) + var/ccdir = turn(move_direction, -45) + dodging = FALSE + . = Move(get_step(loc,pick(cdir,ccdir))) + if(!.)//Can't dodge there so we just carry on + . = Move(moving_to,move_direction) + dodging = TRUE + +/mob/living/simple_animal/hostile/proc/DestroyObjectsInDirection(direction) + var/turf/T = get_step(targets_from, direction) + if(QDELETED(T)) + return + if(T.Adjacent(targets_from)) + if(CanSmashTurfs(T)) + T.attack_animal(src) + return + for(var/obj/O in T.contents) + if(!O.Adjacent(targets_from)) + continue + if((ismachinery(O) || isstructure(O)) && O.density && environment_smash >= ENVIRONMENT_SMASH_STRUCTURES && !O.IsObscured()) + O.attack_animal(src) + return + +/mob/living/simple_animal/hostile/proc/DestroyPathToTarget() + if(environment_smash) + EscapeConfinement() + var/dir_to_target = get_dir(targets_from, target) + var/dir_list = list() + if(dir_to_target in diagonals) //it's diagonal, so we need two directions to hit + for(var/direction in cardinal) + if(direction & dir_to_target) + dir_list += direction + else + dir_list += dir_to_target + for(var/direction in dir_list) //now we hit all of the directions we got in this fashion, since it's the only directions we should actually need + DestroyObjectsInDirection(direction) + +/mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with megafauna destroying everything around them if(environment_smash) EscapeConfinement() for(var/dir in cardinal) - var/turf/T = get_step(targets_from, dir) - if(iswallturf(T) || ismineralturf(T)) - if(T.Adjacent(targets_from)) - T.attack_animal(src) - for(var/a in T) - var/atom/A = a - if(!A.Adjacent(targets_from)) - continue - if(is_type_in_typecache(A, environment_target_typecache)) - A.attack_animal(src) - return + DestroyObjectsInDirection(dir) /mob/living/simple_animal/hostile/proc/EscapeConfinement() if(buckled) buckled.attack_animal(src) if(!isturf(targets_from.loc) && targets_from.loc != null)//Did someone put us in something? - var/atom/A = get_turf(targets_from) + var/atom/A = targets_from.loc A.attack_animal(src)//Bang on it till we get out - return /mob/living/simple_animal/hostile/proc/FindHidden() if(istype(target.loc, /obj/structure/closet) || istype(target.loc, /obj/machinery/disposal) || istype(target.loc, /obj/machinery/sleeper) || istype(target.loc, /obj/machinery/bodyscanner) || istype(target.loc, /obj/machinery/recharge_station)) @@ -420,9 +520,23 @@ LosePatience() lose_patience_timer_id = addtimer(CALLBACK(src, .proc/LoseTarget), lose_patience_timeout, TIMER_STOPPABLE) + /mob/living/simple_animal/hostile/proc/LosePatience() deltimer(lose_patience_timer_id) + +//These two procs handle losing and regaining search_objects when attacked by a mob +/mob/living/simple_animal/hostile/proc/LoseSearchObjects() + search_objects = 0 + deltimer(search_objects_timer_id) + search_objects_timer_id = addtimer(CALLBACK(src, .proc/RegainSearchObjects), search_objects_regain_time, TIMER_STOPPABLE) + + +/mob/living/simple_animal/hostile/proc/RegainSearchObjects(value) + if(!value) + value = initial(search_objects) + search_objects = value + /mob/living/simple_animal/hostile/consider_wakeup() ..() var/list/tlist @@ -455,4 +569,4 @@ if(isturf(M.loc)) . += M else if(M.loc.type in hostile_machines) - . += M.loc + . += M.loc \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index 9ed59fb4ab5..29739a9d867 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -46,8 +46,8 @@ /mob/living/simple_animal/hostile/illusion/AttackingTarget() - ..() - if(istype(target, /mob/living) && prob(multiply_chance)) + . = ..() + if(. && isliving(target) && prob(multiply_chance)) var/mob/living/L = target if(L.stat == DEAD) return diff --git a/code/modules/mob/living/simple_animal/hostile/jungle_animals.dm b/code/modules/mob/living/simple_animal/hostile/jungle_animals.dm index e34a5e0cb08..797beb9b11b 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle_animals.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle_animals.dm @@ -23,6 +23,9 @@ pixel_x = -16 see_in_dark = 8 + emote_taunt = list("nashes") + taunt_chance = 20 + harm_intent_damage = 8 melee_damage_lower = 15 melee_damage_upper = 15 @@ -33,18 +36,13 @@ var/stalk_tick_delay = 3 gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE -/mob/living/simple_animal/hostile/panther/FindTarget(var/list/possible_targets) +/mob/living/simple_animal/hostile/panther/AttackingTarget() . = ..() if(.) - emote("nashes at [.]") - -/mob/living/simple_animal/hostile/panther/AttackingTarget() - . =..() - var/mob/living/L = . - if(istype(L)) - if(prob(15)) - L.Weaken(3) - L.visible_message("\the [src] knocks down \the [L]!") + if(prob(15) && iscarbon(target)) + var/mob/living/carbon/C = target + C.Weaken(3) + C.visible_message("\the [src] knocks down \the [C]!") //*******// // Snake // @@ -67,6 +65,9 @@ maxHealth = 25 health = 25 + emote_taunt = list("hisses wickedly") + taunt_chance = 20 + harm_intent_damage = 2 melee_damage_lower = 3 melee_damage_upper = 10 @@ -77,13 +78,9 @@ var/stalk_tick_delay = 3 gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE -/mob/living/simple_animal/hostile/snake/FindTarget() - . = ..() - if(.) - emote("hisses wickedly") - /mob/living/simple_animal/hostile/snake/AttackingTarget() . =..() - var/mob/living/L = . - if(istype(L)) - L.apply_damage(rand(3,12), TOX) + if(.) + if(iscarbon(target)) + var/mob/living/carbon/C = target + C.apply_damage(rand(3, 12), TOX) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index d45e6f6ead8..05bdf9c76a6 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -34,7 +34,7 @@ Difficulty: Medium move_to_delay = 3 projectiletype = /obj/item/projectile/kinetic/miner projectilesound = 'sound/weapons/kenetic_accel.ogg' - ranged = 1 + ranged = TRUE ranged_cooldown_time = 16 pixel_x = -16 crusher_loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator, /obj/item/crusher_trophy/miner_eye) @@ -47,8 +47,12 @@ Difficulty: Medium var/dashing = FALSE var/dash_cooldown = 15 var/guidance = FALSE + var/transform_stop_attack = FALSE // stops the blood drunk miner from attacking after transforming his weapon until the next attack chain deathmessage = "falls to the ground, decaying into glowing particles." death_sound = "bodyfall" + attack_action_types = list(/datum/action/innate/megafauna_attack/dash, + /datum/action/innate/megafauna_attack/kinetic_accelerator, + /datum/action/innate/megafauna_attack/transform_weapon) /obj/item/gps/internal/miner icon_state = null @@ -56,13 +60,52 @@ Difficulty: Medium desc = "The sweet blood, oh, it sings to me." invisibility = 100 -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance - guidance = TRUE - -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter/AttackingTarget() +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Initialize(mapload) . = ..() - if(. && prob(12)) - INVOKE_ASYNC(src, .proc/dash) + miner_saw = new(src) + internal_gps = new/obj/item/gps/internal/miner(src) + + // Add a zone selection UI; otherwise the mob can't melee attack properly. + zone_sel = new /obj/screen/zone_sel() + +/datum/action/innate/megafauna_attack/dash + name = "Dash To Target" + icon_icon = 'icons/mob/actions/actions.dmi' + button_icon_state = "sniper_zoom" + chosen_message = "You are now dashing to your target." + chosen_attack_num = 1 + +/datum/action/innate/megafauna_attack/kinetic_accelerator + name = "Fire Kinetic Accelerator" + icon_icon = 'icons/obj/guns/energy.dmi' + button_icon_state = "kineticgun" + chosen_message = "You are now shooting your kinetic accelerator." + chosen_attack_num = 2 + +/datum/action/innate/megafauna_attack/transform_weapon + name = "Transform Weapon" + icon_icon = 'icons/obj/lavaland/artefacts.dmi' + button_icon_state = "cleaving_saw" + chosen_message = "You are now transforming your weapon." + chosen_attack_num = 3 + +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/OpenFire() + if(client) + switch(chosen_attack) + if(1) + dash(target) + if(2) + shoot_ka() + if(3) + transform_weapon() + return + + Goto(target, move_to_delay, minimum_distance) + if(get_dist(src, target) > MINER_DASH_RANGE && dash_cooldown <= world.time) + dash_attack() + else + shoot_ka() + transform_weapon() /obj/item/melee/energy/cleaving_saw/miner //nerfed saw because it is very murdery force = 6 @@ -79,15 +122,7 @@ Difficulty: Medium icon_state = "ka_tracer" range = MINER_DASH_RANGE -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Initialize() - . = ..() - miner_saw = new(src) - internal_gps = new/obj/item/gps/internal/miner(src) - - // Add a zone selection UI; otherwise the mob can't melee attack properly. - zone_sel = new /obj/screen/zone_sel() - -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/adjustHealth(amount, updating_health = TRUE, forced = FALSE) +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/adjustHealth(amount, updating_health = TRUE) var/adjustment_amount = amount * 0.1 if(world.time + adjustment_amount > next_move) changeNext_move(adjustment_amount) //attacking it interrupts it attacking, but only briefly @@ -104,16 +139,19 @@ Difficulty: Medium return FALSE return ..() -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target) +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity) if(dash()) return return ..() +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/MeleeAction(patience = TRUE) + transform_stop_attack = FALSE + return ..() + /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/AttackingTarget() - if(QDELETED(target)) - return - if(next_move > world.time || !Adjacent(target)) //some cheating - INVOKE_ASYNC(src, .proc/quick_attack_loop) + if(client) + transform_stop_attack = FALSE + if(QDELETED(target) || transform_stop_attack) return face_atom(target) if(isliving(target)) @@ -132,8 +170,6 @@ Difficulty: Medium miner_saw.melee_attack_chain(src, target) if(guidance) adjustHealth(-2) - transform_weapon() - INVOKE_ASYNC(src, .proc/quick_attack_loop) return TRUE /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) @@ -146,16 +182,10 @@ Difficulty: Medium . = ..() if(. && target && !targets_the_same) wander = TRUE - transform_weapon() - INVOKE_ASYNC(src, .proc/quick_attack_loop) -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/OpenFire() - Goto(target, move_to_delay, minimum_distance) - if(get_dist(src, target) > MINER_DASH_RANGE && dash_cooldown <= world.time) - INVOKE_ASYNC(src, .proc/dash, target) - else - shoot_ka() - transform_weapon() +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash_attack() + INVOKE_ASYNC(src, .proc/dash, target) + shoot_ka() /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/shoot_ka() if(ranged_cooldown <= world.time && get_dist(src, target) <= MINER_DASH_RANGE && !Adjacent(target)) @@ -166,21 +196,6 @@ Difficulty: Medium Shoot(target) changeNext_move(CLICK_CD_RANGE) -//I'm still of the belief that this entire proc needs to be wiped from existence. -// do not take my touching of it to be endorsement of it. ~mso -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop() - while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep. - stoplag(1) - sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about - if(QDELETED(target)) - return - if(dashing || next_move > world.time || !Adjacent(target)) - if(dashing && next_move <= world.time) - next_move = world.time + 1 - INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again. - return - AttackingTarget() - /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash(atom/dash_target) if(world.time < dash_cooldown) return @@ -189,7 +204,9 @@ Difficulty: Medium var/turf/own_turf = get_turf(src) if(!QDELETED(dash_target)) self_dist_to_target += get_dist(dash_target, own_turf) - for(var/turf/simulated/O in RANGE_TURFS(MINER_DASH_RANGE, own_turf)) + for(var/turf/O in RANGE_TURFS(MINER_DASH_RANGE, own_turf)) + if(O.density) + continue var/turf_dist_to_target = 0 if(!QDELETED(dash_target)) turf_dist_to_target += get_dist(dash_target, O) @@ -218,26 +235,29 @@ Difficulty: Medium var/turf/step_forward_turf = get_step(own_turf, get_cardinal_dir(own_turf, target_turf)) new /obj/effect/temp_visual/small_smoke/halfsecond(step_back_turf) new /obj/effect/temp_visual/small_smoke/halfsecond(step_forward_turf) - var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc, src) - animate(D, alpha = 0, time = 5) + var/obj/effect/temp_visual/decoy/fading/halfsecond/D = new (own_turf, src) forceMove(step_back_turf) playsound(own_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1) dashing = TRUE alpha = 0 animate(src, alpha = 255, time = 5) - sleep(2) + SLEEP_CHECK_DEATH(2) D.forceMove(step_forward_turf) forceMove(target_turf) playsound(target_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1) - sleep(1) + SLEEP_CHECK_DEATH(1) dashing = FALSE - shoot_ka() return TRUE /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/transform_weapon() if(time_until_next_transform <= world.time) miner_saw.transform_cooldown = 0 miner_saw.transform_weapon(src, TRUE) + if(!miner_saw.active) + rapid_melee = 5 // 4 deci cooldown before changes, npcpool subsystem wait is 20, 20/4 = 5 + else + rapid_melee = 3 // same thing but halved (slightly rounded up) + transform_stop_attack = TRUE icon_state = "miner[miner_saw.active ? "_transformed":""]" icon_living = "miner[miner_saw.active ? "_transformed":""]" time_until_next_transform = world.time + rand(50, 100) @@ -263,4 +283,12 @@ Difficulty: Medium sleep(4) animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags = ANIMATION_PARALLEL) +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance + guidance = TRUE + +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter/AttackingTarget() + . = ..() + if(. && prob(12)) + INVOKE_ASYNC(src, .proc/dash) + #undef MINER_DASH_RANGE \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index ac5e40025c6..5b605551a22 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -122,12 +122,16 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget() if(!charging) - ..() + return ..() /mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance) if(!charging) ..() +/mob/living/simple_animal/hostile/megafauna/bubblegum/MoveToTarget(list/possible_targets) + if(!charging) + ..() + /mob/living/simple_animal/hostile/megafauna/bubblegum/Move() if(charging) new /obj/effect/temp_visual/decoy/fading(loc, src) @@ -195,7 +199,7 @@ Difficulty: Hard . = list() for(var/mob/living/L in targets) var/list/bloodpool = get_pools(get_turf(L), 0) - if(bloodpool.len && (!faction_check(L) || L.stat == DEAD)) + if(bloodpool.len && (!faction_check_mob(L) || L.stat == DEAD)) . += L /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack() @@ -246,7 +250,7 @@ Difficulty: Hard new /obj/effect/temp_visual/bubblegum_hands/leftsmack(T) sleep(2.5) for(var/mob/living/L in T) - if(!faction_check(L)) + if(!faction_check_mob(L)) to_chat(L, "[src] rends you!") playsound(T, attack_sound, 100, 1, -1) var/limb_to_hit = pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg") @@ -262,7 +266,7 @@ Difficulty: Hard new /obj/effect/temp_visual/bubblegum_hands/leftthumb(T) sleep(6) for(var/mob/living/L in T) - if(!faction_check(L)) + if(!faction_check_mob(L)) to_chat(L, "[src] drags you through the blood!") playsound(T, 'sound/misc/enter_blood.ogg', 100, 1, -1) var/turf/targetturf = get_step(src, dir) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 0789d00832d..00f67674546 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -62,14 +62,14 @@ Difficulty: Medium return ..() -/mob/living/simple_animal/hostile/megafauna/dragon/adjustHealth(amount) +/mob/living/simple_animal/hostile/megafauna/dragon/adjustHealth(amount, updating_health = TRUE) if(swooping) - return 0 + return FALSE return ..() /mob/living/simple_animal/hostile/megafauna/dragon/AttackingTarget() if(!swooping) - ..() + return ..() /mob/living/simple_animal/hostile/megafauna/dragon/DestroySurroundings() if(!swooping) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index bb4e9297605..4ed44c616c8 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -123,13 +123,18 @@ Difficulty: Hard adjustHealth(-L.maxHealth*0.5) L.dust() +/mob/living/simple_animal/hostile/megafauna/hierophant/CanAttack(atom/the_target) + . = ..() + if(istype(the_target, /mob/living/simple_animal/hostile/asteroid/hivelordbrood)) //ignore temporary targets in favor of more permanent targets + return FALSE + /*/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target) var/targets_the_same = (new_target == target) . = ..() if(. && target && !targets_the_same) visible_message("\"[pick(target_phrases)]\"")*/ -/mob/living/simple_animal/hostile/megafauna/hierophant/adjustHealth(amount) +/mob/living/simple_animal/hostile/megafauna/hierophant/adjustHealth(amount, updating_health = TRUE) . = ..() if(src && amount > 0 && !blinking) wander = TRUE @@ -140,7 +145,7 @@ Difficulty: Hard if(target && isliving(target)) spawn(0) melee_blast(get_turf(target)) //melee attacks on living mobs produce a 3x3 blast - ..() + return ..() /mob/living/simple_animal/hostile/megafauna/hierophant/DestroySurroundings() if(!blinking) @@ -536,7 +541,7 @@ Difficulty: Hard /obj/effect/temp_visual/hierophant/blast/proc/do_damage(turf/T) for(var/mob/living/L in T.contents - hit_things) //find and damage mobs... hit_things += L - if((friendly_fire_check && caster && caster.faction_check(L)) || L.stat == DEAD) + if((friendly_fire_check && caster && caster.faction_check_mob(L)) || L.stat == DEAD) continue if(L.client) flash_color(L.client, "#660099", 1) @@ -551,7 +556,7 @@ Difficulty: Hard for(var/obj/mecha/M in T.contents - hit_things) //and mechs. hit_things += M if(M.occupant) - if(friendly_fire_check && caster && caster.faction_check(M.occupant)) + if(friendly_fire_check && caster && caster.faction_check_mob(M.occupant)) continue to_chat(M.occupant, "Your [M.name] is struck by a [name]!") playsound(M,'sound/weapons/sear.ogg', 50, 1, -4) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 027bbb60a14..d26400bceca 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -46,7 +46,6 @@ Difficulty: Medium loot = list(/obj/item/stack/sheet/bone = 3) vision_range = 13 elimination = 1 - idle_vision_range = 13 appearance_flags = 0 mouse_opacity = MOUSE_OPACITY_ICON stat_attack = 1 // Overriden from /tg/ - otherwise Legion starts chasing its minions @@ -56,8 +55,8 @@ Difficulty: Medium internal_gps = new/obj/item/gps/internal/legion(src) /mob/living/simple_animal/hostile/megafauna/legion/AttackingTarget() - ..() - if(ishuman(target)) + . = ..() + if(. && ishuman(target)) var/mob/living/L = target if(L.stat == UNCONSCIOUS) var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new(loc) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index f57559d549a..20df360a51a 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -18,19 +18,8 @@ damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) minbodytemp = 0 maxbodytemp = INFINITY + vision_range = 5 aggro_vision_range = 18 - idle_vision_range = 5 - environment_target_typecache = list( - /obj/machinery/door/window, - /obj/structure/window, - /obj/structure/closet, - /obj/structure/table, - /obj/structure/grille, - /obj/structure/girder, - /obj/structure/rack, - /obj/structure/barricade, - /obj/machinery/field, - /obj/machinery/power/emitter) var/list/crusher_loot var/medal_type var/score_type = BOSS_SCORE @@ -43,10 +32,15 @@ mob_size = MOB_SIZE_LARGE layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway + var/chosen_attack = 1 // chosen attack num + var/list/attack_action_types = list() /mob/living/simple_animal/hostile/megafauna/New() ..() apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + for(var/action_type in attack_action_types) + var/datum/action/innate/megafauna_attack/attack_action = new action_type() + attack_action.Grant(src) /mob/living/simple_animal/hostile/megafauna/Destroy() QDEL_NULL(internal_gps) @@ -70,8 +64,8 @@ loot = crusher_loot /mob/living/simple_animal/hostile/megafauna/AttackingTarget() - ..() - if(isliving(target)) + . = ..() + if(. && isliving(target)) var/mob/living/L = target if(L.stat != DEAD) if(!client && ranged && ranged_cooldown <= world.time) @@ -124,3 +118,21 @@ SSmedals.SetScore(BOSS_SCORE, C, 1) SSmedals.SetScore(score_type, C, 1) return TRUE + +/datum/action/innate/megafauna_attack + name = "Megafauna Attack" + icon_icon = 'icons/mob/actions/actions_animal.dmi' + button_icon_state = "" + var/mob/living/simple_animal/hostile/megafauna/M + var/chosen_message + var/chosen_attack_num = 0 + +/datum/action/innate/megafauna_attack/Grant(mob/living/L) + if(istype(L, /mob/living/simple_animal/hostile/megafauna)) + M = L + return ..() + return FALSE + +/datum/action/innate/megafauna_attack/Activate() + M.chosen_attack = chosen_attack_num + to_chat(M, chosen_message) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm index fa2479bb658..5a1d10edfb2 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm @@ -81,7 +81,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa new createtype(loc) -/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/adjustHealth(amount, updating_health = TRUE, forced = FALSE) +/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/adjustHealth(amount, updating_health = TRUE) . = ..() if(. > 0 && world.time > call_help_cooldown) call_help_cooldown = world.time + call_help_cooldown_amt diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 5c26fe1ba57..57277dc2d74 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -17,7 +17,9 @@ melee_damage_upper = 12 attacktext = "attacks" attack_sound = 'sound/weapons/bite.ogg' + emote_taunt = list("growls") speak_emote = list("creaks") + taunt_chance = 30 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 @@ -29,11 +31,6 @@ gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE del_on_death = 1 -/mob/living/simple_animal/hostile/mimic/FindTarget() - . = ..() - if(.) - custom_emote(1, "growls at [.]") - /mob/living/simple_animal/hostile/mimic/emp_act(severity) if(is_electronic) switch(severity) @@ -56,7 +53,7 @@ for(var/obj/item/I in loc) I.loc = src -/mob/living/simple_animal/hostile/mimic/crate/DestroySurroundings() +/mob/living/simple_animal/hostile/mimic/crate/DestroyPathToTarget() ..() if(prob(90)) icon_state = "[initial(icon_state)]open" @@ -77,15 +74,19 @@ . = ..() if(.) icon_state = initial(icon_state) + if(prob(15) && iscarbon(target)) + var/mob/living/carbon/C = target + C.Weaken(2) + C.visible_message("\The [src] knocks down \the [C]!", "\The [src] knocks you down!") /mob/living/simple_animal/hostile/mimic/crate/proc/trigger() if(!attempt_open) visible_message("[src] starts to move!") attempt_open = 1 -/mob/living/simple_animal/hostile/mimic/crate/adjustHealth(damage) +/mob/living/simple_animal/hostile/mimic/crate/adjustHealth(amount, updating_health = TRUE) trigger() - ..(damage) + . = ..() /mob/living/simple_animal/hostile/mimic/crate/LoseTarget() ..() @@ -96,18 +97,10 @@ var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate for(var/obj/O in src) - O.loc = C + O.forceMove(C) // due to `del_on_death` return ..() -/mob/living/simple_animal/hostile/mimic/crate/AttackingTarget() - . =..() - var/mob/living/L = . - if(istype(L)) - if(prob(15)) - L.Weaken(2) - L.visible_message("\the [src] knocks down \the [L]!") - var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window) /mob/living/simple_animal/hostile/mimic/copy @@ -191,14 +184,11 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca ..() /mob/living/simple_animal/hostile/mimic/copy/AttackingTarget() - ..() - if(knockdown_people) - if(iscarbon(target)) - var/mob/living/carbon/C = target - if(prob(15)) - C.Weaken(2) - C.visible_message("\The [src] knocks down \the [C]!", \ - "\The [src] knocks you down!") + . = ..() + if(knockdown_people && . && prob(15) && iscarbon(target)) + var/mob/living/carbon/C = target + C.Weaken(2) + C.visible_message("\The [src] knocks down \the [C]!", "\The [src] knocks you down!") /mob/living/simple_animal/hostile/mimic/copy/Aggro() ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm index ad8dcf44699..f960471d510 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm @@ -26,8 +26,8 @@ a_intent = INTENT_HARM speak_emote = list("chitters") attack_sound = 'sound/weapons/bladeslice.ogg' + vision_range = 2 aggro_vision_range = 9 - idle_vision_range = 2 turns_per_move = 5 loot = list(/obj/item/stack/ore/diamond{layer = 4.1}, /obj/item/stack/ore/diamond{layer = 4.1}) @@ -41,13 +41,10 @@ flag = "energy" temperature = 50 -/mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(var/new_target) +/mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(new_target) if(..()) //we have a target - if(isliving(target)) - var/mob/living/L = target - if(L.bodytemperature > 261) - L.bodytemperature = 261 - visible_message("The [src.name]'s stare chills [L.name] to the bone!") + if(isliving(target) && !target.Adjacent(targets_from) && ranged_cooldown <= world.time)//No more being shot at point blank or spammed with RNG beams + OpenFire(target) /mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity) switch(severity) diff --git a/code/modules/mob/living/simple_animal/hostile/mining/goldgrub.dm b/code/modules/mob/living/simple_animal/hostile/mining/goldgrub.dm index cd73868a9e7..9066b84b5f6 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/goldgrub.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/goldgrub.dm @@ -8,8 +8,8 @@ icon_dead = "Goldgrub_dead" icon_gib = "syndicate_gib" vision_range = 2 + vision_range = 2 aggro_vision_range = 9 - idle_vision_range = 2 move_to_delay = 5 friendly = "harmlessly rolls into" maxHealth = 45 @@ -48,14 +48,13 @@ retreat_distance = 10 minimum_distance = 10 if(will_burrow) - spawn(chase_time) - Burrow() + addtimer(CALLBACK(src, .proc/Burrow), chase_time) /mob/living/simple_animal/hostile/asteroid/goldgrub/AttackingTarget() if(istype(target, /obj/item/stack/ore)) EatOre(target) return - ..() + return ..() /mob/living/simple_animal/hostile/asteroid/goldgrub/proc/EatOre(var/atom/targeted_ore) for(var/obj/item/stack/ore/O in get_turf(targeted_ore)) @@ -69,13 +68,13 @@ /mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Burrow()//Begin the chase to kill the goldgrub in time if(!stat) - visible_message("The [src.name] buries into the ground, vanishing from sight!") + visible_message("The [name] buries into the ground, vanishing from sight!") qdel(src) /mob/living/simple_animal/hostile/asteroid/goldgrub/bullet_act(obj/item/projectile/P) visible_message("The [P.name] was repelled by [src.name]'s girth!") return -/mob/living/simple_animal/hostile/asteroid/goldgrub/adjustHealth(damage) - idle_vision_range = 9 +/mob/living/simple_animal/hostile/asteroid/goldgrub/adjustHealth(amount, updating_health = TRUE) + vision_range = 9 . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining/goliath.dm index dae7a688cb3..323976003b8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/goliath.dm @@ -11,7 +11,6 @@ mouse_opacity = MOUSE_OPACITY_OPAQUE move_to_delay = 40 ranged = TRUE - ranged_cooldown = 2 //By default, start the Goliath with his cooldown off so that people can run away quickly on first sight ranged_cooldown_time = 120 friendly = "wails at" speak_emote = list("bellows") @@ -26,8 +25,8 @@ attacktext = "pulverizes" attack_sound = 'sound/weapons/punch1.ogg' throw_message = "does nothing to the rocky hide of the" + vision_range = 5 aggro_vision_range = 9 - idle_vision_range = 5 move_force = MOVE_FORCE_VERY_STRONG move_resist = MOVE_FORCE_VERY_STRONG pull_force = MOVE_FORCE_VERY_STRONG @@ -54,6 +53,8 @@ /mob/living/simple_animal/hostile/asteroid/goliath/OpenFire() var/tturf = get_turf(target) + if(!isturf(tturf)) + return if(get_dist(src, target) <= 7)//Screen range check, so you can't get tentacle'd offscreen visible_message("The [src.name] digs its tentacles under [target.name]!") new /obj/effect/temp_visual/goliath_tentacle/original(tturf, src) @@ -61,10 +62,10 @@ icon_state = icon_aggro pre_attack = FALSE -/mob/living/simple_animal/hostile/asteroid/goliath/adjustHealth(damage) - ranged_cooldown-- +/mob/living/simple_animal/hostile/asteroid/goliath/adjustHealth(amount, updating_health = TRUE) + ranged_cooldown -= 10 handle_preattack() - ..() + . = ..() /mob/living/simple_animal/hostile/asteroid/goliath/Aggro() vision_range = aggro_vision_range @@ -188,4 +189,4 @@ /obj/effect/temp_visual/goliath_tentacle/proc/retract() icon_state = "Goliath_tentacle_retract" deltimer(timerid) - timerid = QDEL_IN(src, 5) + timerid = QDEL_IN(src, 7) diff --git a/code/modules/mob/living/simple_animal/hostile/mining/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining/gutlunch.dm index 6e5c840a401..23a900c1519 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/gutlunch.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/gutlunch.dm @@ -30,7 +30,7 @@ stop_automated_movement_when_pulled = TRUE stat_exclusive = TRUE robust_searching = TRUE - search_objects = TRUE + search_objects = 3 del_on_death = TRUE loot = list(/obj/effect/decal/cleanable/blood/gibs) deathmessage = "is pulped into bugmash." @@ -38,7 +38,7 @@ animal_species = /mob/living/simple_animal/hostile/asteroid/gutlunch childtype = list(/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck = 45, /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen = 55) - wanted_objects = list(/obj/effect/decal/cleanable/blood/gibs) + wanted_objects = list(/obj/effect/decal/cleanable/blood/gibs, /obj/item/organ/internal) var/obj/item/udder/gutlunch/udder = null /mob/living/simple_animal/hostile/asteroid/gutlunch/New() @@ -61,16 +61,37 @@ udder.milkAnimal(O, user) regenerate_icons() else - ..() + return ..() + +/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(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // 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_mob(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/AttackingTarget() - if(is_type_in_typecache(target, wanted_objects)) //we eats + if(is_type_in_typecache(target,wanted_objects)) //we eats udder.generateMilk() regenerate_icons() visible_message("[src] slurps up [target].") qdel(target) - return - ..() + return ..() /obj/item/udder/gutlunch name = "nutrient sac" diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm index 43d239c59ce..30dd6783717 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm @@ -11,8 +11,8 @@ move_to_delay = 14 ranged = 1 vision_range = 5 + vision_range = 5 aggro_vision_range = 9 - idle_vision_range = 5 speed = 3 maxHealth = 75 health = 75 @@ -44,6 +44,7 @@ /mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget() OpenFire() + return TRUE /mob/living/simple_animal/hostile/asteroid/hivelord/spawn_crusher_loot() loot += crusher_loot //we don't butcher @@ -361,7 +362,7 @@ if("Cultist") uniform = /obj/item/clothing/under/roman suit = /obj/item/clothing/suit/hooded/cultrobes - head = /obj/item/clothing/head/culthood + head = /obj/item/clothing/head/hooded/culthood suit_store = /obj/item/tome r_pocket = /obj/item/restraints/legcuffs/bola/cult l_pocket = /obj/item/melee/cultblade/dagger diff --git a/code/modules/mob/living/simple_animal/hostile/mining/mining.dm b/code/modules/mob/living/simple_animal/hostile/mining/mining.dm index 434869c1d6d..ba4f00503e1 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/mining.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/mining.dm @@ -28,12 +28,14 @@ /mob/living/simple_animal/hostile/asteroid/Aggro() ..() - icon_state = icon_aggro + if(vision_range != aggro_vision_range) + icon_state = icon_aggro /mob/living/simple_animal/hostile/asteroid/LoseAggro() ..() - if(stat == CONSCIOUS) - icon_state = icon_living + if(stat == DEAD) + return + icon_state = icon_living /mob/living/simple_animal/hostile/asteroid/bullet_act(var/obj/item/projectile/P)//Reduces damage from most projectiles to curb off-screen kills if(!stat) diff --git a/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm index c6bc205627e..e910bac7ca3 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm @@ -17,6 +17,8 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 maxbodytemp = INFINITY + move_resist = INFINITY + anchored = TRUE loot = list(/obj/effect/collapse, /obj/structure/closet/crate/necropolis/tendril) del_on_death = 1 var/gps = null @@ -76,4 +78,4 @@ mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril) /mob/living/simple_animal/hostile/spawner/lavaland/legion - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril) \ No newline at end of file + mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm deleted file mode 100644 index efc18895141..00000000000 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ /dev/null @@ -1,225 +0,0 @@ -/mob/living/simple_animal/hostile/asteroid/ - vision_range = 2 - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - unsuitable_atmos_damage = 15 - faction = list("mining") - weather_immunities = list("lava","ash") - obj_damage = 30 - environment_smash = 2 - minbodytemp = 0 - heat_damage_per_tick = 20 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "strikes" - status_flags = 0 - a_intent = INTENT_HARM - var/throw_message = "bounces off of" - var/icon_aggro = null // for swapping to when we get aggressive - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - mob_size = MOB_SIZE_LARGE - -/mob/living/simple_animal/hostile/asteroid/Aggro() - ..() - icon_state = icon_aggro - -/mob/living/simple_animal/hostile/asteroid/LoseAggro() - ..() - if(stat == CONSCIOUS) - icon_state = icon_living - -/mob/living/simple_animal/hostile/asteroid/bullet_act(var/obj/item/projectile/P)//Reduces damage from most projectiles to curb off-screen kills - if(!stat) - Aggro() - if(P.damage < 30 && P.damage_type != BRUTE) - P.damage = (P.damage / 3) - visible_message("The [P] has a reduced effect on [src]!") - ..() - -/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM)//No floor tiling them to death, wiseguy - if(istype(AM, /obj/item)) - var/obj/item/T = AM - if(!stat) - Aggro() - if(T.throwforce <= 20) - visible_message("The [T.name] [src.throw_message] [src.name]!") - return - ..() - -/mob/living/simple_animal/hostile/asteroid/basilisk - name = "basilisk" - desc = "A territorial beast, covered in a thick shell that absorbs energy. Its stare causes victims to freeze from the inside." - icon = 'icons/mob/animal.dmi' - icon_state = "Basilisk" - icon_living = "Basilisk" - icon_aggro = "Basilisk_alert" - icon_dead = "Basilisk_dead" - icon_gib = "syndicate_gib" - move_to_delay = 20 - projectiletype = /obj/item/projectile/temp/basilisk - projectilesound = 'sound/weapons/pierce.ogg' - ranged = 1 - ranged_message = "stares" - ranged_cooldown_time = 30 - throw_message = "does nothing against the hard shell of" - vision_range = 2 - speed = 3 - maxHealth = 200 - health = 200 - harm_intent_damage = 5 - obj_damage = 60 - melee_damage_lower = 12 - melee_damage_upper = 12 - attacktext = "bites into" - a_intent = INTENT_HARM - speak_emote = list("chitters") - attack_sound = 'sound/weapons/bladeslice.ogg' - aggro_vision_range = 9 - idle_vision_range = 2 - turns_per_move = 5 - loot = list(/obj/item/stack/ore/diamond{layer = 4.1}, - /obj/item/stack/ore/diamond{layer = 4.1}) - -/obj/item/projectile/temp/basilisk - name = "freezing blast" - icon_state = "ice_2" - damage = 0 - damage_type = BURN - nodamage = 1 - flag = "energy" - temperature = 50 - -/mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(var/new_target) - if(..()) //we have a target - if(isliving(target)) - var/mob/living/L = target - if(L.bodytemperature > 261) - L.bodytemperature = 261 - visible_message("The [src.name]'s stare chills [L.name] to the bone!") - -/mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity) - switch(severity) - if(1.0) - gib() - if(2.0) - adjustBruteLoss(140) - if(3.0) - adjustBruteLoss(110) - -/mob/living/simple_animal/hostile/asteroid/goliath - name = "goliath" - desc = "A massive beast that uses long tentacles to ensare its prey, threatening them is not advised under any conditions." - icon = 'icons/mob/animal.dmi' - icon_state = "Goliath" - icon_living = "Goliath" - icon_aggro = "Goliath_alert" - icon_dead = "Goliath_dead" - icon_gib = "syndicate_gib" - attack_sound = 'sound/weapons/punch4.ogg' - mouse_opacity = MOUSE_OPACITY_OPAQUE - move_to_delay = 40 - ranged = 1 - ranged_cooldown = 2 //By default, start the Goliath with his cooldown off so that people can run away quickly on first sight - ranged_cooldown_time = 120 - friendly = "wails at" - speak_emote = list("bellows") - vision_range = 4 - speed = 3 - maxHealth = 300 - health = 300 - harm_intent_damage = 1 //Only the manliest of men can kill a Goliath with only their fists. - obj_damage = 100 - melee_damage_lower = 25 - melee_damage_upper = 25 - attacktext = "pulverizes" - attack_sound = 'sound/weapons/punch1.ogg' - throw_message = "does nothing to the rocky hide of the" - aggro_vision_range = 9 - idle_vision_range = 5 - move_force = MOVE_FORCE_VERY_STRONG - move_resist = MOVE_FORCE_VERY_STRONG - pull_force = MOVE_FORCE_VERY_STRONG - var/pre_attack = 0 - loot = list(/obj/item/stack/sheet/animalhide/goliath_hide{layer = ABOVE_MOB_LAYER}) - -/mob/living/simple_animal/hostile/asteroid/goliath/Life() - ..() - handle_preattack() - -/mob/living/simple_animal/hostile/asteroid/goliath/proc/handle_preattack() - if(ranged_cooldown <= world.time + ranged_cooldown_time * 0.25 && !pre_attack) - pre_attack++ - if(!pre_attack || stat || AIStatus == AI_IDLE) - return - icon_state = "Goliath_preattack" - -/mob/living/simple_animal/hostile/asteroid/goliath/revive() - move_force = MOVE_FORCE_VERY_STRONG - move_resist = MOVE_FORCE_VERY_STRONG - pull_force = MOVE_FORCE_VERY_STRONG - ..() - -/mob/living/simple_animal/hostile/asteroid/goliath/OpenFire() - var/tturf = get_turf(target) - if(get_dist(src, target) <= 7)//Screen range check, so you can't get tentacle'd offscreen - visible_message("The [src.name] digs its tentacles under [target.name]!") - new /obj/effect/goliath_tentacle/original(tturf) - ranged_cooldown = world.time + ranged_cooldown_time - icon_state = icon_aggro - pre_attack = 0 - return - -/mob/living/simple_animal/hostile/asteroid/goliath/adjustHealth(damage) - ranged_cooldown-- - handle_preattack() - ..() - -/mob/living/simple_animal/hostile/asteroid/goliath/Aggro() - vision_range = aggro_vision_range - handle_preattack() - if(icon_state != icon_aggro) - icon_state = icon_aggro - return - -/obj/effect/goliath_tentacle/ - name = "Goliath tentacle" - icon = 'icons/mob/animal.dmi' - icon_state = "Goliath_tentacle" - var/latched = 0 - -/obj/effect/goliath_tentacle/New() - var/turftype = get_turf(src) - if(istype(turftype, /turf/simulated/mineral)) - var/turf/simulated/mineral/M = turftype - M.gets_drilled() - spawn(20) - Trip() - -/obj/effect/goliath_tentacle/original - -/obj/effect/goliath_tentacle/original/New() - for(var/obj/effect/goliath_tentacle/original/O in loc)//No more GG NO RE from 2+ goliaths simultaneously tentacling you - if(O != src) - qdel(src) - var/list/directions = cardinal.Copy() - var/counter - for(counter = 1, counter <= 3, counter++) - var/spawndir = pick(directions) - directions -= spawndir - var/turf/T = get_step(src,spawndir) - new /obj/effect/goliath_tentacle(T) - ..() - - -/obj/effect/goliath_tentacle/proc/Trip() - for(var/mob/living/M in src.loc) - M.Stun(5) - M.adjustBruteLoss(rand(10,15)) - latched = 1 - if(src && M) - visible_message("The [src.name] grabs hold of [M.name]!") - if(!latched) - qdel(src) - else - spawn(50) - qdel(src) diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 59c23953e6b..ce044284a26 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -61,21 +61,42 @@ health = maxHealth ..() -/mob/living/simple_animal/hostile/mushroom/adjustHealth(damage)//Possibility to flee from a fight just to make it more visually interesting +/mob/living/simple_animal/hostile/mushroom/CanAttack(atom/the_target) // Mushroom-specific version of CanAttack to handle stupid attack_same = 2 crap so we don't have to do it for literally every single simple_animal/hostile because this shit never gets spawned + if(!the_target || isturf(the_target) || istype(the_target, /atom/movable/lighting_object)) + 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_mob(L) && attack_same == 2) + return FALSE + if(L.stat > stat_attack) + return FALSE + + return TRUE + + return FALSE + +/mob/living/simple_animal/hostile/mushroom/adjustHealth(amount, updating_health = TRUE)//Possibility to flee from a fight just to make it more visually interesting if(!retreat_distance && prob(33)) retreat_distance = 5 - spawn(30) - retreat_distance = null - ..() + addtimer(CALLBACK(src, .proc/stop_retreat), 30) + . = ..() -/mob/living/simple_animal/hostile/mushroom/attack_animal(var/mob/living/L) +/mob/living/simple_animal/hostile/mushroom/proc/stop_retreat() + retreat_distance = null + +/mob/living/simple_animal/hostile/mushroom/attack_animal(mob/living/L) if(istype(L, /mob/living/simple_animal/hostile/mushroom) && stat == DEAD) var/mob/living/simple_animal/hostile/mushroom/M = L if(faint_ticker < 2) - M.visible_message("[M] chews a bit on [src].") + M.visible_message("[M] chews a bit on [src].") faint_ticker++ - return - M.visible_message("[M] devours [src]!") + return TRUE + M.visible_message("[M] devours [src]!") var/level_gain = (powerlevel - M.powerlevel) if(level_gain >= -1 && !bruised && !M.ckey)//Player shrooms can't level up to become robust gods. if(level_gain < 1)//So we still gain a level if two mushrooms were the same level @@ -83,7 +104,8 @@ M.LevelUp(level_gain) M.adjustBruteLoss(-M.maxHealth) qdel(src) - ..() + return TRUE + return ..() /mob/living/simple_animal/hostile/mushroom/revive() ..() diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm index 108daa031df..34a224ca5ce 100644 --- a/code/modules/mob/living/simple_animal/hostile/pirate.dm +++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm @@ -36,7 +36,7 @@ icon_dead = "piratemelee_dead" projectilesound = 'sound/weapons/laser.ogg' ranged = 1 - rapid = 1 + rapid = 2 retreat_distance = 5 minimum_distance = 5 projectiletype = /obj/item/projectile/beam diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm index 709a238346a..bd3314d1453 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm @@ -7,7 +7,7 @@ icon_living = "drone3" icon_dead = "drone_dead" ranged = 1 - rapid = 1 + rapid = 3 speak_chance = 5 turns_per_move = 3 response_help = "pokes the" diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm index 2e3718cd800..d3bf35671e2 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm @@ -1,20 +1,20 @@ /mob/living/simple_animal/hostile/retaliate var/list/enemies = list() -/mob/living/simple_animal/hostile/retaliate/Found(var/atom/A) +/mob/living/simple_animal/hostile/retaliate/Found(atom/A) if(isliving(A)) var/mob/living/L = A if(!L.stat) return L else enemies -= L - else if(istype(A, /obj/mecha)) + else if(ismecha(A)) var/obj/mecha/M = A if(M.occupant) return A - else if(istype(A, /obj/spacepod)) - var/obj/spacepod/M = A - if(M.pilot) + else if(isspacepod(A)) + var/obj/spacepod/S = A + if(S.pilot) return A /mob/living/simple_animal/hostile/retaliate/ListTargets() @@ -25,48 +25,32 @@ return see /mob/living/simple_animal/hostile/retaliate/proc/Retaliate() - ..() - var/list/around = view(src, 7) + var/list/around = view(src, vision_range) for(var/atom/movable/A in around) if(A == src) continue if(isliving(A)) var/mob/living/M = A - var/faction_check = 0 - for(var/F in faction) - if(F in M.faction) - faction_check = 1 - break - if(faction_check && attack_same || !faction_check) + if(faction_check_mob(M) && attack_same || !faction_check_mob(M)) enemies |= M - else if(istype(A, /obj/mecha)) + else if(ismecha(A)) var/obj/mecha/M = A if(M.occupant) enemies |= M enemies |= M.occupant - else if(istype(A, /obj/spacepod)) - var/obj/spacepod/M = A - if(M.pilot) - enemies |= M - enemies |= M.pilot + else if(isspacepod(A)) + var/obj/spacepod/S = A + if(S.pilot) + enemies |= S + enemies |= S.pilot for(var/mob/living/simple_animal/hostile/retaliate/H in around) - var/retaliate_faction_check = 0 - for(var/F in faction) - if(F in H.faction) - retaliate_faction_check = 1 - break - if(retaliate_faction_check && !attack_same && !H.attack_same) + if(faction_check_mob(H) && !attack_same && !H.attack_same) H.enemies |= enemies return 0 -/mob/living/simple_animal/hostile/retaliate/adjustHealth(damage) - ..(damage) - Retaliate() - -/mob/living/simple_animal/hostile/retaliate/DestroySurroundings() - for(var/dir in cardinal) // North, South, East, West - var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir)) - if(istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table)) - obstacle.attack_animal(src) +/mob/living/simple_animal/hostile/retaliate/adjustHealth(amount, updating_health = TRUE) + . = ..() + if(amount > 0 && stat == CONSCIOUS) + Retaliate() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm index f9516739e6f..d80e68b7542 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm @@ -35,6 +35,9 @@ maxHealth = 20 health = 20 + emote_taunt = list("wails") + taunt_chance = 20 + harm_intent_damage = 10 melee_damage_lower = 2 melee_damage_upper = 3 @@ -51,11 +54,6 @@ /mob/living/simple_animal/hostile/retaliate/ghost/Process_Spacemove(var/check_drift = 0) return 1 -/mob/living/simple_animal/hostile/retaliate/ghost/FindTarget() - . = ..() - if(.) - custom_emote(1, "wails at [.]") - /mob/living/simple_animal/hostile/retaliate/ghost/Life(seconds, times_fired) if(target) invisibility = pick(0,0,60,invisibility) diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index a4f7cce2f51..0c5f2647ae8 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -33,6 +33,7 @@ ranged = 1 retreat_distance = 5 minimum_distance = 5 + projectilesound = 'sound/weapons/gunshots/gunshot.ogg' casingtype = /obj/item/ammo_casing/a357 loot = list(/obj/effect/mob_spawn/human/corpse/russian/ranged, /obj/item/gun/projectile/revolver/mateba) diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm new file mode 100644 index 00000000000..011c47b2c24 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -0,0 +1,49 @@ +/mob/living/simple_animal/hostile/skeleton + name = "reanimated skeleton" + desc = "A real bonefied skeleton, doesn't seem like it wants to socialize." + icon = 'icons/mob/animal.dmi' + icon_state = "skeleton" + icon_living = "skeleton" + turns_per_move = 5 + speak_emote = list("rattles") + emote_see = list("rattles") + a_intent = INTENT_HARM + maxHealth = 40 + health = 40 + speed = 1 + harm_intent_damage = 5 + melee_damage_lower = 15 + melee_damage_upper = 15 + minbodytemp = 0 + maxbodytemp = 1500 + healable = FALSE //they're skeletons how would bruise packs help them?? + attacktext = "slashes" + attack_sound = 'sound/hallucinations/growl1.ogg' + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + unsuitable_atmos_damage = 10 + robust_searching = 1 + stat_attack = UNCONSCIOUS + gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE + faction = list("skeleton") + see_in_dark = 8 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + deathmessage = "collapses into a pile of bones!" + del_on_death = TRUE + loot = list(/obj/effect/decal/remains/human) + +/mob/living/simple_animal/hostile/skeleton/eskimo + name = "undead eskimo" + desc = "The reanimated remains of some poor traveler." + icon_state = "eskimo" + icon_living = "eskimo" + maxHealth = 55 + health = 55 + weather_immunities = list("snow") + gold_core_spawnable = CHEM_MOB_SPAWN_INVALID + melee_damage_lower = 17 + melee_damage_upper = 20 + deathmessage = "collapses into a pile of bones, its gear falling to the floor!" + loot = list(/obj/effect/decal/remains/human, + /obj/item/twohanded/spear, + /obj/item/clothing/shoes/winterboots, + /obj/item/clothing/suit/hooded/wintercoat) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm index 93e03e8279e..fd569984920 100644 --- a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm +++ b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm @@ -118,8 +118,9 @@ //Try to move onto target's turf and eat them /mob/living/simple_animal/hostile/spaceWorm/wormHead/AttackingTarget() - ..() - attemptToEat(target) + . = ..() + if(.) + attemptToEat(target) //Attempt to eat things we bump into, Mobs, Walls, Clowns /mob/living/simple_animal/hostile/spaceWorm/wormHead/Bump(atom/obstacle) diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 2e1e7508e1c..b32cae64675 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -36,7 +36,6 @@ see_in_dark = 8 vision_range = 12 aggro_vision_range = 12 - idle_vision_range = 12 search_objects = 1 // So that it can see through walls @@ -87,11 +86,11 @@ if(can_be_seen(get_turf(loc))) if(client) to_chat(src, "You cannot attack, there are eyes on you!") - return + return FALSE else - ..() + return ..() -/mob/living/simple_animal/hostile/statue/DestroySurroundings() +/mob/living/simple_animal/hostile/statue/DestroyPathToTarget() if(!can_be_seen(get_turf(loc))) ..() diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 8cbef64d34b..f380d85be34 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -135,6 +135,8 @@ LoseTarget() /mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/handle_automated_action() + if(!..()) + return if(seen_enemy) aggro_cycles++ if(alert_on_timeout && !raised_alert && aggro_cycles >= 60) @@ -159,14 +161,13 @@ continue if(depotarea.list_includes(body, depotarea.dead_list)) continue - if(faction_check(body)) + if(faction_check_mob(body)) continue say("Target [body]... terminated.") depotarea.list_add(body, depotarea.dead_list) pointed(body) else scan_cycles++ - ..() /mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/proc/raise_alert(var/reason) if(istype(depotarea) && (!raised_alert || seen_revived_enemy) && !depotarea.used_self_destruct) @@ -190,7 +191,7 @@ /mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/CanPass(atom/movable/mover, turf/target, height=0) if(isliving(mover)) var/mob/living/blocker = mover - if(faction_check(blocker)) + if(faction_check_mob(blocker)) return 1 return ..(mover, target, height) @@ -256,11 +257,12 @@ /mob/living/simple_animal/hostile/syndicate/ranged ranged = 1 - rapid = 1 + rapid = 2 retreat_distance = 5 minimum_distance = 5 icon_state = "syndicateranged" icon_living = "syndicateranged" + projectilesound = 'sound/weapons/gunshots/gunshot.ogg' casingtype = /obj/item/ammo_casing/c45 loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier, /obj/item/gun/projectile/automatic/c20r) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm index 6db08d392ed..50049af0a2e 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm @@ -19,7 +19,8 @@ ventcrawler = 1 idle_ventcrawl_chance = 0 ai_playercontrol_allowtype = 0 - rapid = 1 + ai_type = TS_AI_AGGRESSIVE + rapid = 3 canlay = 1000 spider_tier = TS_TIER_5 projectiletype = /obj/item/projectile/terrorqueenspit/empress diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm index 98556c63d34..91e70dd837d 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm @@ -58,7 +58,7 @@ visible_message("[src] retracts its fangs a little.") melee_damage_lower = melee_damage_lower_rage1 melee_damage_upper = melee_damage_upper_rage1 - ..() + return ..() /obj/structure/spider/terrorweb/red diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm index 999405df2d8..7e90867e783 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm @@ -11,7 +11,6 @@ layer = 2.75 health = 3 var/stillborn = FALSE - faction = list("terrorspiders") var/spider_myqueen = null var/spider_mymother = null var/goto_mother = FALSE @@ -169,10 +168,8 @@ if(!grow_as) grow_as = pick(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green) var/mob/living/simple_animal/hostile/poison/terror_spider/S = new grow_as(loc) - S.faction = faction S.spider_myqueen = spider_myqueen S.spider_mymother = spider_mymother - S.master_commander = master_commander S.enemies = enemies qdel(src) @@ -186,10 +183,8 @@ var/obj/structure/spider/eggcluster/terror_eggcluster/C = new /obj/structure/spider/eggcluster/terror_eggcluster(get_turf(src)) C.spiderling_type = lay_type C.spiderling_number = lay_number - C.faction = faction C.spider_myqueen = spider_myqueen C.spider_mymother = src - C.master_commander = master_commander C.enemies = enemies if(spider_growinstantly) C.amount_grown = 250 @@ -202,7 +197,6 @@ desc = "A cluster of tiny spider eggs. They pulse with a strong inner life, and appear to have sharp thorns on the sides." icon_state = "eggs" var/spider_growinstantly = 0 - faction = list("terrorspiders") var/spider_myqueen = null var/spider_mymother = null var/spiderling_type = null @@ -244,10 +238,8 @@ var/obj/structure/spider/spiderling/terror_spiderling/S = new /obj/structure/spider/spiderling/terror_spiderling(get_turf(src)) if(spiderling_type) S.grow_as = spiderling_type - S.faction = faction S.spider_myqueen = spider_myqueen S.spider_mymother = spider_mymother - S.master_commander = master_commander S.enemies = enemies if(spider_growinstantly) S.amount_grown = 250 diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index 251ba27cf05..f84ec5f90d7 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -92,7 +92,7 @@ var/global/list/ts_spiderling_list = list() var/degenerate = 0 // if 1, they slowly degen until they all die off. Used by high-level abilities only. // Vision - idle_vision_range = 10 + vision_range = 10 aggro_vision_range = 10 see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE @@ -361,7 +361,7 @@ var/global/list/ts_spiderling_list = list() to_chat(T, "TerrorSense: [msgtext]") /mob/living/simple_animal/hostile/poison/terror_spider/proc/CheckFaction() - if(faction.len != 1 || (!("terrorspiders" in faction)) || master_commander != null) + if(faction.len != 2 || (!("terrorspiders" in faction)) || master_commander != null) to_chat(src, "Your connection to the hive mind has been severed!") log_runtime(EXCEPTION("Terror spider with incorrect faction list at: [atom_loc_line(src)]")) gib() diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 508e2934cf6..78f79dfc3b2 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -24,6 +24,8 @@ attacktext = "bites" attack_sound = 'sound/weapons/bite.ogg' speak_emote = list("pines") + emote_taunt = list("growls") + taunt_chance = 20 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 @@ -34,15 +36,10 @@ deathmessage = "is hacked into pieces!" del_on_death = 1 -/mob/living/simple_animal/hostile/tree/FindTarget() - . = ..() - if(.) - custom_emote(1, "growls at [.]") - /mob/living/simple_animal/hostile/tree/AttackingTarget() - . =..() - var/mob/living/L = . - if(istype(L)) + . = ..() + if(. && iscarbon(target)) + var/mob/living/carbon/C = target if(prob(15)) - L.Weaken(3) - L.visible_message("\the [src] knocks down \the [L]!") \ No newline at end of file + C.Weaken(3) + C.visible_message("\the [src] knocks down \the [C]!") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 52ec406fcbd..c8e6b8c5d8e 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -90,7 +90,7 @@ if(grasping.len < max_grasps) grasping: for(var/mob/living/L in view(grasp_range, src)) - if(L == src || faction_check(L) || (L in grasping) || L == target) + if(L == src || faction_check_mob(L) || (L in grasping) || L == target) continue for(var/t in getline(src,L)) for(var/a in t) @@ -105,6 +105,12 @@ /mob/living/simple_animal/hostile/venus_human_trap/OpenFire(atom/the_target) + for(var/turf/T in getline(src,target)) + if (T.density) + return + for(var/obj/O in T) + if(O.density) + return var/dist = get_dist(src,the_target) Beam(the_target, "vine", time=dist*2, maxdistance=dist+2, beam_type=/obj/effect/ebeam/vine) the_target.attack_animal(src) diff --git a/code/modules/mob/living/simple_animal/hostile/winter_mobs.dm b/code/modules/mob/living/simple_animal/hostile/winter_mobs.dm index f96ebabf014..d8fba34296b 100644 --- a/code/modules/mob/living/simple_animal/hostile/winter_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/winter_mobs.dm @@ -117,7 +117,7 @@ maxHealth = 250 health = 250 ranged = 1 - rapid = 1 + rapid = 3 speed = 0 //he's lost some weight from the fighting projectiletype = /obj/item/projectile/ornament retreat_distance = 3 diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 05a3141b17a..b556fa24bec 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -3,15 +3,17 @@ icon = 'icons/mob/animal.dmi' health = 20 maxHealth = 20 + gender = PLURAL //placeholder + universal_understand = 1 + universal_speak = 0 status_flags = CANPUSH var/icon_living = "" var/icon_dead = "" var/icon_resting = "" var/icon_gib = null //We only try to show a gibbing animation if this exists. - - var/healable = 1 + var/flip_on_death = FALSE //Flip the sprite upside down on death. Mostly here for things lacking custom dead sprites. var/list/speak = list() var/speak_chance = 0 @@ -20,7 +22,6 @@ var/turns_per_move = 1 var/turns_since_move = 0 - universal_speak = 0 var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals. var/wander = 1 // Does the mob wander around when idle? var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it. @@ -38,11 +39,13 @@ var/heat_damage_per_tick = 3 //amount of damage applied if animal's body temperature is higher than maxbodytemp var/cold_damage_per_tick = 2 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp + //Healable by medical stacks? Defaults to yes. + var/healable = 1 + //Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above - //LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly var/melee_damage_lower = 0 var/melee_damage_upper = 0 @@ -53,7 +56,7 @@ var/attacktext = "attacks" var/attack_sound = null var/friendly = "nuzzles" //If the mob does no damage with it's attack - var/environment_smash = 0 //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls + var/environment_smash = ENVIRONMENT_SMASH_NONE //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls var/speed = 1 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster var/can_hide = 0 @@ -66,6 +69,7 @@ var/next_scan_time = 0 var/animal_species //Sorry, no spider+corgi buttbabies. + var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against var/gold_core_spawnable = CHEM_MOB_SPAWN_INVALID //if CHEM_MOB_SPAWN_HOSTILE can be spawned by plasma with gold core, CHEM_MOB_SPAWN_FRIENDLY are 'friendlies' spawned with blood var/mob/living/carbon/human/master_commander = null //holding var for determining who own/controls a sentient simple animal (for sentience potions). @@ -73,19 +77,35 @@ var/mob/living/simple_animal/hostile/spawner/nest var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions + var/list/loot = list() //list of things spawned at mob's loc when it dies var/del_on_death = 0 //causes mob to be deleted on death, useful for mobs that spawn lootable corpses - var/attacked_sound = "punch" var/deathmessage = "" var/death_sound = null //The sound played on death + var/allow_movement_on_non_turfs = FALSE + + var/attacked_sound = "punch" + var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever) var/can_have_ai = TRUE //once we have become sentient, we can never go back + var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check. -/mob/living/simple_animal/Initialize() - ..() + //domestication + var/tame = 0 + + var/my_z // I don't want to confuse this with client registered_z + +/mob/living/simple_animal/Initialize(mapload) + . = ..() GLOB.simple_animals[AIStatus] += src + if(gender == PLURAL) + gender = pick(MALE, FEMALE) + if(!real_name) + real_name = name + if(!loc) + stack_trace("Simple animal being instantiated in nullspace") verbs -= /mob/verb/observe if(!can_hide) verbs -= /mob/living/simple_animal/verb/hide @@ -113,27 +133,25 @@ return ..() -/mob/living/simple_animal/Login() - if(src && src.client) - src.client.screen = list() - client.screen += client.void - ..() +/mob/living/simple_animal/examine(mob/user) + . = ..() + if(stat == DEAD) + to_chat(user, "Upon closer examination, [p_they()] appear[p_s()] to be dead.") /mob/living/simple_animal/updatehealth(reason = "none given") ..(reason) health = Clamp(health, 0, maxHealth) med_hud_set_status() -/mob/living/simple_animal/lay_down() +/mob/living/simple_animal/StartResting(updating = 1) ..() - handle_resting_state_icons() + if(icon_resting && stat != DEAD) + icon_state = icon_resting -/mob/living/simple_animal/proc/handle_resting_state_icons() - if(icon_resting) - if(resting && stat != DEAD) - icon_state = icon_resting - else if(stat != DEAD) - icon_state = icon_living +/mob/living/simple_animal/StopResting(updating = 1) + ..() + if(icon_resting && stat != DEAD) + icon_state = icon_living /mob/living/simple_animal/update_stat(reason = "none given") if(status_flags & GODMODE) @@ -146,11 +164,13 @@ create_debug_log("died of damage, trigger reason: [reason]") /mob/living/simple_animal/proc/handle_automated_action() + set waitfor = FALSE return /mob/living/simple_animal/proc/handle_automated_movement() + set waitfor = FALSE if(!stop_automated_movement && wander) - if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc. + if((isturf(loc) || allow_movement_on_non_turfs) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc. turns_since_move++ if(turns_since_move >= turns_per_move) if(!(stop_automated_movement_when_pulled && pulledby)) //Soma animals don't move when pulled @@ -158,11 +178,12 @@ if(Process_Spacemove(anydir)) Move(get_step(src,anydir), anydir) turns_since_move = 0 - return + return 1 -/mob/living/simple_animal/proc/handle_automated_speech() +/mob/living/simple_animal/proc/handle_automated_speech(override) + set waitfor = FALSE if(speak_chance) - if(rand(0,200) < speak_chance) + if(prob(speak_chance) || override) if(speak && speak.len) if((emote_hear && emote_hear.len) || (emote_see && emote_see.len)) var/length = speak.len @@ -200,7 +221,7 @@ var/areatemp = get_temperature(environment) - if(abs(areatemp - bodytemperature) > 40 && !(BREATHLESS in mutations)) + if(abs(areatemp - bodytemperature) > 5 && !(BREATHLESS in mutations)) var/diff = areatemp - bodytemperature diff = diff / 5 bodytemperature += diff @@ -241,30 +262,24 @@ atmos_suitable = 0 if(!atmos_suitable) - adjustBruteLoss(unsuitable_atmos_damage) + adjustHealth(unsuitable_atmos_damage) handle_temperature_damage() /mob/living/simple_animal/proc/handle_temperature_damage() - if(bodytemperature < minbodytemp) - adjustBruteLoss(cold_damage_per_tick) - else if(bodytemperature > maxbodytemp) - adjustBruteLoss(heat_damage_per_tick) + if((bodytemperature < minbodytemp) || (bodytemperature > maxbodytemp)) + adjustHealth(unsuitable_atmos_damage) /mob/living/simple_animal/gib() if(icon_gib) flick(icon_gib, src) if(butcher_results) + var/atom/Tsec = drop_location() for(var/path in butcher_results) - for(var/i = 1; i <= butcher_results[path];i++) - new path(src.loc) + for(var/i in 1 to butcher_results[path]) + new path(Tsec) ..() - -/mob/living/simple_animal/blob_act() - adjustBruteLoss(20) - return - /mob/living/simple_animal/emote(act, m_type = 1, message = null, force) if(stat) return @@ -278,29 +293,13 @@ ..() -/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj) - if(!Proj) - return - if((Proj.damage_type != STAMINA)) - adjustBruteLoss(Proj.damage) - Proj.on_hit(src, 0) - return FALSE +/mob/living/simple_animal/say_quote(message) + var/verb = "says" -/mob/living/simple_animal/attackby(obj/item/O, mob/living/user) - if(can_collar && !collar && istype(O, /obj/item/clothing/accessory/petcollar)) - var/obj/item/clothing/accessory/petcollar/C = O - user.drop_item() - C.forceMove(src) - collar = C - collar.equipped(src) - regenerate_icons() - to_chat(usr, "You put \the [C] around \the [src]'s neck.") - if(C.tagname) - name = C.tagname - real_name = C.tagname - return - else - ..() + if(speak_emote.len) + verb = pick(speak_emote) + + return verb /mob/living/simple_animal/movement_delay() . = ..() @@ -311,21 +310,25 @@ /mob/living/simple_animal/Stat() ..() + if(statpanel("Status")) + stat(null, "Health: [round((health / maxHealth) * 100)]%") + return TRUE - statpanel("Status") - stat(null, "Health: [round((health / maxHealth) * 100)]%") +/mob/living/simple_animal/proc/drop_loot() + if(loot.len) + for(var/i in loot) + new i(loc) /mob/living/simple_animal/death(gibbed) // Only execute the below if we successfully died . = ..() if(!.) return FALSE + flying = FALSE if(nest) nest.spawned_mobs -= src nest = null - if(loot.len) - for(var/i in loot) - new i(loc) + drop_loot() if(!gibbed) if(death_sound) playsound(get_turf(src),death_sound, 200, 1) @@ -334,87 +337,41 @@ else if(!del_on_death) visible_message("\The [src] stops moving...") if(del_on_death) + //Prevent infinite loops if the mob Destroy() is overridden in such + //a manner as to cause a call to death() again + del_on_death = FALSE ghostize() qdel(src) else health = 0 icon_state = icon_dead + if(flip_on_death) + transform = transform.Turn(180) density = 0 - lying = 1 -/mob/living/simple_animal/ex_act(severity) - ..() - switch(severity) - if(1.0) - gib() - return - - if(2.0) - adjustBruteLoss(60) - - - if(3.0) - adjustBruteLoss(30) - -/mob/living/simple_animal/proc/adjustHealth(amount, updating_health = TRUE) - if(status_flags & GODMODE) - return FALSE - var/oldbruteloss = bruteloss - bruteloss = Clamp(bruteloss + amount, 0, maxHealth) - if(oldbruteloss == bruteloss) - updating_health = FALSE - . = STATUS_UPDATE_NONE - else - . = STATUS_UPDATE_HEALTH - if(updating_health) - updatehealth() - -/mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE) - if(damage_coeff[BRUTE]) - return adjustHealth(amount * damage_coeff[BRUTE], updating_health) - -/mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE) - if(damage_coeff[BURN]) - return adjustHealth(amount * damage_coeff[BURN], updating_health) - -/mob/living/simple_animal/adjustOxyLoss(amount, updating_health = TRUE) - if(damage_coeff[OXY]) - return adjustHealth(amount * damage_coeff[OXY], updating_health) - -/mob/living/simple_animal/adjustToxLoss(amount, updating_health = TRUE) - if(damage_coeff[TOX]) - return adjustHealth(amount * damage_coeff[TOX], updating_health) - -/mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE) - if(damage_coeff[CLONE]) - return adjustHealth(amount * damage_coeff[CLONE], updating_health) - -/mob/living/simple_animal/adjustStaminaLoss(amount, updating_health = TRUE) - if(damage_coeff[STAMINA]) - return ..(amount*damage_coeff[STAMINA], updating_health) - -/mob/living/simple_animal/proc/CanAttack(var/atom/the_target) +/mob/living/simple_animal/proc/CanAttack(atom/the_target) if(see_invisible < the_target.invisibility) return FALSE + if(ismob(the_target)) + var/mob/M = the_target + if(M.status_flags & GODMODE) + return FALSE if(isliving(the_target)) var/mob/living/L = the_target if(L.stat != CONSCIOUS) return FALSE - if(istype(the_target, /obj/mecha)) + if(ismecha(the_target)) var/obj/mecha/M = the_target if(M.occupant) return FALSE - if(istype(the_target,/obj/spacepod)) + if(isspacepod(the_target)) var/obj/spacepod/S = the_target if(S.pilot) return FALSE return TRUE /mob/living/simple_animal/handle_fire() - return - -/mob/living/simple_animal/update_fire() - return + return TRUE /mob/living/simple_animal/IgniteMob() return FALSE @@ -422,26 +379,14 @@ /mob/living/simple_animal/ExtinguishMob() return -/mob/living/simple_animal/update_transform() - var/matrix/ntransform = matrix(transform) //aka transform.Copy() - var/changed = 0 - - if(resize != RESIZE_DEFAULT_SIZE) - changed++ - ntransform.Scale(resize) - resize = RESIZE_DEFAULT_SIZE - - if(changed) - animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT) - /mob/living/simple_animal/revive() ..() health = maxHealth + icon = initial(icon) icon_state = icon_living density = initial(density) update_canmove() - - + flying = initial(flying) /mob/living/simple_animal/proc/make_babies() // <3 <3 <3 if(gender != FEMALE || stat || next_scan_time > world.time || !childtype || !animal_species || !SSticker.IsRoundInProgress()) @@ -471,42 +416,6 @@ if(target) return new childspawn(target) -/mob/living/simple_animal/say_quote(var/message) - var/verb = "says" - - if(speak_emote.len) - verb = pick(speak_emote) - - return verb - -/mob/living/simple_animal/update_canmove(delay_action_updates = 0) - if(paralysis || stunned || weakened || stat || resting) - drop_r_hand() - drop_l_hand() - canmove = 0 - else if(buckled) - canmove = 0 - else - canmove = 1 - update_transform() - if(!delay_action_updates) - update_action_buttons_icon() - return canmove - -/mob/living/simple_animal/update_transform() - var/matrix/ntransform = matrix(transform) //aka transform.Copy() - var/changed = 0 - - if(resize != RESIZE_DEFAULT_SIZE) - changed++ - ntransform.Scale(resize) - resize = RESIZE_DEFAULT_SIZE - - if(changed) - animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT) - -/* Inventory */ - /mob/living/simple_animal/show_inv(mob/user as mob) if(!can_collar) return @@ -571,50 +480,39 @@ if(collar) . |= collar.GetAccess() -/* End Inventory */ +/mob/living/simple_animal/update_canmove(delay_action_updates = 0) + if(paralysis || stunned || weakened || stat || resting) + drop_r_hand() + drop_l_hand() + canmove = 0 + else if(buckled) + canmove = 0 + else + canmove = 1 + if(!canmove) + walk(src, 0) //stop mid walk + + update_transform() + if(!delay_action_updates) + update_action_buttons_icon() + return canmove + +/mob/living/simple_animal/update_transform() + var/matrix/ntransform = matrix(transform) //aka transform.Copy() + var/changed = FALSE + + if(resize != RESIZE_DEFAULT_SIZE) + changed = TRUE + ntransform.Scale(resize) + resize = RESIZE_DEFAULT_SIZE + + if(changed) + animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT) /mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion toggle_ai(AI_OFF) can_have_ai = FALSE - return -/mob/living/simple_animal/can_hear() - . = TRUE - -/mob/living/simple_animal/proc/consider_wakeup() - if(pulledby || shouldwakeup) - toggle_ai(AI_ON) - -/mob/living/simple_animal/adjustHealth(amount, updating_health = TRUE, forced = FALSE) - . = ..() - if(!ckey && !stat)//Not unconscious - if(AIStatus == AI_IDLE) - toggle_ai(AI_ON) - -/mob/living/simple_animal/proc/toggle_ai(togglestatus) - if(!can_have_ai && (togglestatus != AI_OFF)) - return - if(AIStatus != togglestatus) - if(togglestatus > 0 && togglestatus < 5) - if(togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF) - var/turf/T = get_turf(src) - if(AIStatus == AI_Z_OFF) - SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src - else - SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src - GLOB.simple_animals[AIStatus] -= src - GLOB.simple_animals[togglestatus] += src - AIStatus = togglestatus - else - stack_trace("Something attempted to set simple animals AI to an invalid state: [togglestatus]") - -/mob/living/simple_animal/onTransitZ(old_z, new_z) - ..() - if(AIStatus == AI_Z_OFF) - SSidlenpcpool.idle_mobs_by_zlevel[old_z] -= src - toggle_ai(initial(AIStatus)) - -// Simple animals will not be given night vision upon death, as that would result in issues when they are revived. /mob/living/simple_animal/grant_death_vision() sight |= SEE_TURFS sight |= SEE_MOBS @@ -641,4 +539,37 @@ return SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT) - sync_lighting_plane_alpha() \ No newline at end of file + sync_lighting_plane_alpha() + +/mob/living/simple_animal/proc/toggle_ai(togglestatus) + if(!can_have_ai && (togglestatus != AI_OFF)) + return + if(AIStatus != togglestatus) + if(togglestatus > 0 && togglestatus < 5) + if(togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF) + var/turf/T = get_turf(src) + if(AIStatus == AI_Z_OFF) + SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src + else + SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src + GLOB.simple_animals[AIStatus] -= src + GLOB.simple_animals[togglestatus] += src + AIStatus = togglestatus + else + stack_trace("Something attempted to set simple animals AI to an invalid state: [togglestatus]") + +/mob/living/simple_animal/proc/consider_wakeup() + if(pulledby || shouldwakeup) + toggle_ai(AI_ON) + +/mob/living/simple_animal/adjustHealth(amount, updating_health = TRUE) + . = ..() + if(!ckey && !stat)//Not unconscious + if(AIStatus == AI_IDLE) + toggle_ai(AI_ON) + +/mob/living/simple_animal/onTransitZ(old_z, new_z) + ..() + if(AIStatus == AI_Z_OFF) + SSidlenpcpool.idle_mobs_by_zlevel[old_z] -= src + toggle_ai(initial(AIStatus)) \ No newline at end of file diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm new file mode 100644 index 00000000000..a403aa39244 --- /dev/null +++ b/code/modules/mob/living/taste.dm @@ -0,0 +1,30 @@ +/mob/living + var/last_taste_time + var/last_taste_text + +/mob/living/proc/get_taste_sensitivity() + return TASTE_SENSITIVITY_NORMAL + +/mob/living/carbon/human/get_taste_sensitivity() + if(dna.species) + return dna.species.taste_sensitivity + else + return TASTE_SENSITIVITY_NORMAL + +// non destructively tastes a reagent container +/mob/living/proc/taste(datum/reagents/from) + if(last_taste_time + 50 < world.time) + var/taste_sensitivity = get_taste_sensitivity() + var/text_output = from.generate_taste_message(taste_sensitivity) + // We dont want to spam the same message over and over again at the + // person. Give it a bit of a buffer. + if(hallucination > 50 && prob(25)) + text_output = pick("spiders","dreams","nightmares","the future","the past","victory",\ + "defeat","pain","bliss","revenge","poison","time","space","death","life","truth","lies","justice","memory",\ + "regrets","your soul","suffering","music","noise","blood","hunger","the american way") + if(text_output != last_taste_text || last_taste_time + 100 < world.time) + to_chat(src, "You can taste [text_output].") + // "something indescribable" -> too many tastes, not enough flavor. + + last_taste_time = world.time + last_taste_text = text_output \ No newline at end of file diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index f5f1924e395..66b4f2f9a16 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -56,9 +56,6 @@ if(abilities) client.verbs |= abilities - if(ishuman(src)) - client.screen += client.void - //HUD updates (antag hud, etc) //readd this mob's HUDs (antag, med, etc) reload_huds() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3c2f9fc732b..c2d16069146 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1234,12 +1234,6 @@ var/list/slot_equipment_priority = list( \ /mob/proc/get_access() return list() //must return list or IGNORE_ACCESS -/mob/proc/faction_check(mob/target) - for(var/F in faction) - if(F in target.faction) - return 1 - return 0 - /mob/proc/create_attack_log(text, collapse = TRUE) LAZYINITLIST(attack_log) create_log_in_list(attack_log, text, collapse, last_log) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 077164be6b7..805d48fdd9f 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -409,12 +409,6 @@ qdel(src) /obj/item/grab/proc/checkvalid(var/mob/attacker, var/mob/prey) //does all the checking for the attack proc to see if a mob can eat another with the grab - if(ishuman(attacker) && (/datum/dna/gene/basic/grant_spell/mattereater in attacker.active_genes)) // MATTER EATER CARES NOT OF YOUR FORM - return 1 - - if(ishuman(attacker) && (FAT in attacker.mutations) && iscarbon(prey) && !isalien(prey)) //Fat people eating carbon mobs but not xenos - return 1 - if(isalien(attacker) && iscarbon(prey)) //Xenomorphs eating carbon mobs return 1 diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 0a0e8422dbf..ec81cc33950 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -113,6 +113,24 @@ return U.sensor_mode return SUIT_SENSOR_OFF +/proc/offer_control(mob/M) + to_chat(M, "Control of your mob has been offered to dead players.") + log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.") + var/minhours = input(usr, "Minimum hours required to play [M]?", "Set Min Hrs", 10) as num + message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts with [minhours] hrs playtime") + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name ? M.real_name : M.name]?", poll_time = 100, min_hours = minhours) + var/mob/dead/observer/theghost = null + + if(LAZYLEN(candidates)) + theghost = pick(candidates) + to_chat(M, "Your mob has been taken over by a ghost!") + message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])") + M.ghostize() + M.key = theghost.key + else + to_chat(M, "There were no ghosts willing to take control.") + message_admins("No ghosts were willing to take control of [key_name_admin(M)])") + /proc/check_zone(zone) if(!zone) return "chest" switch(zone) diff --git a/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm index d4834eccc80..476861861a3 100644 --- a/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm @@ -48,7 +48,7 @@ var/gender = NEUTER //Determines if the accessory will be skipped or included in random hair generations // Restrict some styles to specific species - var/list/species_allowed = list("Human", "Slime People") + var/list/species_allowed = list("Human", "Slime People", "Infectious Zombie", "High-Functioning Zombie") var/list/sprite_sheets = list() //For accessories common across species but need to use 'fitted' sprites (like underwear). e.g. list("Vox" = 'icons/mob/species/vox/iconfile.dmi') var/list/models_allowed = list() //Specifies which, if any, hairstyles or markings can be accessed by which prosthetics. Should equal the manufacturing company name in robolimbs.dm. var/list/heads_allowed = null //Specifies which, if any, alt heads a head marking, hairstyle or facial hair style is compatible with. diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm index 7d40dcc184b..7c691f5093e 100755 --- a/code/modules/pda/PDA.dm +++ b/code/modules/pda/PDA.dm @@ -62,8 +62,8 @@ var/global/list/obj/item/pda/PDAs = list() /* * The Actual PDA */ -/obj/item/pda/New() - ..() +/obj/item/pda/Initialize(mapload) + . = ..() PDAs += src PDAs = sortAtom(PDAs) update_programs() diff --git a/code/modules/pda/cart.dm b/code/modules/pda/cart.dm index b721bef52c4..7b7ec95b0e3 100644 --- a/code/modules/pda/cart.dm +++ b/code/modules/pda/cart.dm @@ -59,9 +59,9 @@ new/datum/data/pda/app/crew_records/security, new/datum/data/pda/app/secbot_control) -/obj/item/cartridge/security/Initialize() +/obj/item/cartridge/security/Initialize(mapload) + . = ..() radio = new /obj/item/integrated_radio/beepsky(src) - ..() /obj/item/cartridge/detective name = "D.E.T.E.C.T. Cartridge" @@ -109,9 +109,9 @@ desc = "A data cartridge with an integrated radio signaler module." programs = list(new/datum/data/pda/app/signaller) -/obj/item/cartridge/signal/Initialize() +/obj/item/cartridge/signal/Initialize(mapload) + . = ..() radio = new /obj/item/integrated_radio/signal(src) - ..() /obj/item/cartridge/signal/toxins name = "Signal Ace 2" @@ -132,9 +132,9 @@ new/datum/data/pda/app/supply, new/datum/data/pda/app/mule_control) -/obj/item/cartridge/quartermaster/Initialize() +/obj/item/cartridge/quartermaster/Initialize(mapload) + . = ..() radio = new /obj/item/integrated_radio/mule(src) - ..() /obj/item/cartridge/head name = "Easy-Record DELUXE" @@ -154,9 +154,9 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/hop/Initialize() +/obj/item/cartridge/hop/Initialize(mapload) + . = ..() radio = new /obj/item/integrated_radio/mule(src) - ..() /obj/item/cartridge/hos name = "R.O.B.U.S.T. DELUXE" @@ -167,9 +167,9 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/hos/Initialize() +/obj/item/cartridge/hos/Initialize(mapload) + . = ..() radio = new /obj/item/integrated_radio/beepsky(src) - ..() /obj/item/cartridge/ce name = "Power-On DELUXE" @@ -205,9 +205,9 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/rd/Initialize() +/obj/item/cartridge/rd/Initialize(mapload) + . = ..() radio = new /obj/item/integrated_radio/signal(src) - ..() /obj/item/cartridge/captain name = "Value-PAK Cartridge" @@ -234,9 +234,9 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/captain/Initialize() +/obj/item/cartridge/captain/Initialize(mapload) + . = ..() radio = new /obj/item/integrated_radio/beepsky(src) - ..() /obj/item/cartridge/supervisor name = "Easy-Record DELUXE" @@ -271,9 +271,9 @@ new/datum/data/pda/app/status_display) -/obj/item/cartridge/centcom/Initialize() +/obj/item/cartridge/centcom/Initialize(mapload) + . = ..() radio = new /obj/item/integrated_radio/beepsky(src) - ..() /obj/item/cartridge/syndicate name = "Detomatix Cartridge" @@ -283,7 +283,8 @@ programs = list(new/datum/data/pda/utility/toggle_door) messenger_plugins = list(new/datum/data/pda/messenger_plugin/virus/detonate) -/obj/item/cartridge/syndicate/New() +/obj/item/cartridge/syndicate/Initialize(mapload) + . = ..() var/datum/data/pda/utility/toggle_door/D = programs[1] if(istype(D)) D.remote_door_id = initial_remote_door_id @@ -321,4 +322,4 @@ my_game.hacked = 1 to_chat(user, "TR4P_M45T3R.mod successfully initialized. ToS violated. User Agreement nullified. Gotta pwn them all.") to_chat(user, "You can now create trapped versions of any mob in your collection that will damage hunters who attempt to capture it.") - description_antag = "This copy of Nano-Mob Hunter GO! has been hacked to allow the creation of trap mobs which will cause any PDA that attempts to capture it to shock anyone holding it. Hacked copies of the game will not trigger the trap." + description_antag = "This copy of Nano-Mob Hunter GO! has been hacked to allow the creation of trap mobs which will cause any PDA that attempts to capture it to shock anyone holding it. Hacked copies of the game will not trigger the trap." \ No newline at end of file diff --git a/code/modules/pda/radio.dm b/code/modules/pda/radio.dm index 7db0ed332d5..a49305598e6 100644 --- a/code/modules/pda/radio.dm +++ b/code/modules/pda/radio.dm @@ -17,13 +17,12 @@ var/on = 0 //Are we currently active?? var/menu_message = "" -/obj/item/integrated_radio/New() - ..() +/obj/item/integrated_radio/Initialize(mapload) + . = ..() if(istype(loc.loc, /obj/item/pda)) hostpda = loc.loc if(bot_filter) - spawn(5) - add_to_radio(bot_filter) + add_to_radio(bot_filter) /obj/item/integrated_radio/Destroy() if(SSradio) @@ -176,7 +175,8 @@ radio_connection = null return ..() -/obj/item/integrated_radio/signal/Initialize() +/obj/item/integrated_radio/signal/Initialize(mapload) + . = ..() if(!SSradio) return if(src.frequency < PUBLIC_LOW_FREQ || src.frequency > PUBLIC_HIGH_FREQ) diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 0ee03a2b272..33741d1475b 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -15,7 +15,6 @@ use_power = NO_POWER_USE idle_power_usage = 0 active_power_usage = 0 - var/malfunction = FALSE /obj/machinery/power/Destroy() disconnect_from_network() @@ -31,7 +30,7 @@ // Non-machines should use add_delayedload(), delayed_surplus(), newavail() /obj/machinery/power/proc/add_avail(amount) - if(powernet && !malfunction) + if(powernet) powernet.newavail += amount return TRUE else diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 7ebc4f4471a..a6a83d07f10 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -158,9 +158,44 @@ to_chat(user, "You need more wires.") return - //build the terminal and link it to the network - make_terminal(user) - terminal.connect_to_network() + if(user.loc == loc) + to_chat(user, "You must not be on the same tile as the [src].") + return + + //Direction the terminal will face to + var/tempDir = get_dir(user, src) + switch(tempDir) + if(NORTHEAST, SOUTHEAST) + tempDir = EAST + if(NORTHWEST, SOUTHWEST) + tempDir = WEST + var/turf/tempLoc = get_step(src, reverse_direction(tempDir)) + if(istype(tempLoc, /turf/space)) + to_chat(user, "You can't build a terminal on space.") + return + else if(istype(tempLoc)) + if(tempLoc.intact) + to_chat(user, "You must remove the floor plating first.") + return + + to_chat(user, "You start adding cable to the [src].") + playsound(loc, C.usesound, 50, 1) + + if(do_after(user, 50, target = src)) + if(!terminal && panel_open) + T = get_turf(user) + var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one + if(prob(50) && electrocute_mob(usr, N, N, 1, TRUE)) //animate the electrocution if uncautious and unlucky + do_sparks(5, 1, src) + return + + C.use(10) // make sure the cable gets used up + user.visible_message(\ + "[user.name] adds the cables and connects the power terminal.",\ + "You add the cables and connect the power terminal.") + + make_terminal(user, tempDir, tempLoc) + terminal.connect_to_network() return //disassembling the terminal @@ -174,18 +209,19 @@ playsound(src.loc, I.usesound, 50, 1) if(do_after(user, 50 * I.toolspeed, target = src)) - if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal, 1, TRUE)) //animate the electrocution if uncautious and unlucky - do_sparks(5, 1, src) - return + if(terminal && panel_open) + if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal, 1, TRUE)) //animate the electrocution if uncautious and unlucky + do_sparks(5, 1, src) + return - //give the wires back and delete the terminal - new /obj/item/stack/cable_coil(T,10) - user.visible_message(\ - "[user.name] cuts the cables and dismantles the power terminal.",\ - "You cut the cables and dismantle the power terminal.") - inputting = 0 //stop inputting, since we have don't have a terminal anymore - qdel(terminal) - return + //give the wires back and delete the terminal + new /obj/item/stack/cable_coil(T,10) + user.visible_message(\ + "[user.name] cuts the cables and dismantles the power terminal.",\ + "You cut the cables and dismantle the power terminal.") + inputting = 0 //stop inputting, since we have don't have a terminal anymore + qdel(terminal) + return //crowbarring it ! default_deconstruction_crowbar(I) @@ -197,6 +233,13 @@ return 1 return 0 +/obj/machinery/power/smes/proc/make_terminal(user, tempDir, tempLoc) + // create a terminal object at the same position as original turf loc + // wires will attach to this + terminal = new /obj/machinery/power/terminal(tempLoc) + terminal.dir = tempDir + terminal.master = src + /obj/machinery/power/smes/Destroy() if(SSticker && SSticker.current_state == GAME_STATE_PLAYING) var/area/area = get_area(src) @@ -299,45 +342,6 @@ update_icon() return -//Will return 1 on failure -/obj/machinery/power/smes/proc/make_terminal(const/mob/user) - if(user.loc == loc) - to_chat(user, "You must not be on the same tile as the [src].") - return 1 - - //Direction the terminal will face to - var/tempDir = get_dir(user, src) - switch(tempDir) - if(NORTHEAST, SOUTHEAST) - tempDir = EAST - if(NORTHWEST, SOUTHWEST) - tempDir = WEST - var/turf/tempLoc = get_step(src, reverse_direction(tempDir)) - if(istype(tempLoc, /turf/space)) - to_chat(user, "You can't build a terminal on space.") - return 1 - else if(istype(tempLoc)) - if(tempLoc.intact) - to_chat(user, "You must remove the floor plating first.") - return 1 - to_chat(user, "You start adding cable to the [src].") - if(do_after(user, 50, target = src)) - var/turf/T = get_turf(user) - var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one - if(prob(50) && electrocute_mob(usr, N, N, 1, TRUE)) //animate the electrocution if uncautious and unlucky - do_sparks(5, 1, src) - return - - user.visible_message(\ - "[user.name] adds the cables and connects the power terminal.",\ - "You add the cables and connect the power terminal.") - - terminal = new /obj/machinery/power/terminal(tempLoc) - terminal.dir = tempDir - terminal.master = src - return 0 - return 1 - /obj/machinery/power/smes/attack_ai(mob/user) add_hiddenprint(user) ui_interact(user) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index eea2c2253e8..fbc29da0391 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -124,12 +124,6 @@ else user.visible_message("[user] fires [src]!", "You fire [src]!", "You hear \a [fire_sound_text]!") - if(weapon_weight >= WEAPON_MEDIUM) - if(user.get_inactive_hand()) - if(prob(15)) - if(user.drop_item()) - user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!") - /obj/item/gun/emp_act(severity) for(var/obj/O in contents) O.emp_act(severity) @@ -174,7 +168,20 @@ to_chat(user, "You need both hands free to fire \the [src]!") return - process_fire(target,user,1,params) + //DUAL WIELDING + var/bonus_spread = 0 + var/loop_counter = 0 + if(ishuman(user) && user.a_intent == INTENT_HARM) + var/mob/living/carbon/human/H = user + for(var/obj/item/gun/G in get_both_hands(H)) + if(G == src || G.weapon_weight >= WEAPON_MEDIUM) + continue + else if(G.can_trigger_gun(user)) + bonus_spread += 24 * G.weapon_weight + loop_counter++ + addtimer(CALLBACK(G, .proc/process_fire, target, user, 1, params, null, bonus_spread), loop_counter) + + process_fire(target,user,1,params, null, bonus_spread) /obj/item/gun/proc/can_trigger_gun(mob/living/user) if(!user.can_use_guns(src)) @@ -184,20 +191,20 @@ return 0 return 1 -obj/item/gun/proc/newshot() +/obj/item/gun/proc/newshot() return -/obj/item/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) +/obj/item/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override, bonus_spread = 0) add_fingerprint(user) if(semicd) return - if(weapon_weight) - if(user.get_inactive_hand()) - recoil = 4 //one-handed kick - else - recoil = initial(recoil) + var/sprd = 0 + var/randomized_gun_spread = 0 + if(spread) + randomized_gun_spread = rand(0,spread) + var/randomized_bonus_spread = rand(0, bonus_spread) if(burst_size > 1) firing_burst = 1 @@ -208,11 +215,10 @@ obj/item/gun/proc/newshot() if( i>1 && !(src in get_both_hands(user))) //for burst firing break if(chambered) - var/sprd = 0 if(randomspread) - sprd = round((rand() - 0.5) * spread) + sprd = round((rand() - 0.5) * (randomized_gun_spread + randomized_bonus_spread)) else - sprd = round((i / burst_size - 0.5) * spread) + sprd = round((i / burst_size - 0.5) * (randomized_gun_spread + randomized_bonus_spread)) if(!chambered.fire(target, user, params, ,suppressed, zone_override, sprd)) shoot_with_empty_chamber(user) break @@ -230,7 +236,8 @@ obj/item/gun/proc/newshot() firing_burst = 0 else if(chambered) - if(!chambered.fire(target, user, params, , suppressed, zone_override, spread)) + sprd = round((pick(1,-1)) * (randomized_gun_spread + randomized_bonus_spread)) + if(!chambered.fire(target, user, params, , suppressed, zone_override, sprd)) shoot_with_empty_chamber(user) return else diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index 36bba8f3112..d9f149b3b17 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -80,7 +80,7 @@ ammo_type = list(/obj/item/ammo_casing/energy/sonic) cell_type = /obj/item/stock_parts/cell/super restricted_species = list(/datum/species/vox/armalis) - sprite_sheets = list("Vox Armalis" = 'icons/mob/species/armalis/held.dmi') + sprite_sheets_inhand = list("Vox Armalis" = 'icons/mob/species/armalis/held.dmi') //Big guns big birds. /obj/item/gun/energy/noisecannon/update_icon() return diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 6e4de3c49fa..3fbfcdaa934 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -21,6 +21,12 @@ /obj/item/gun/energy/emp_act(severity) power_supply.use(round(power_supply.charge / severity)) + if(chambered)//phil235 + if(chambered.BB) + qdel(chambered.BB) + chambered.BB = null + chambered = null + newshot() //phil235 update_icon() /obj/item/gun/energy/get_cell() @@ -34,6 +40,7 @@ power_supply = new(src) power_supply.give(power_supply.maxcharge) update_ammo_types() + on_recharge() if(selfcharge) START_PROCESSING(SSobj, src) update_icon() @@ -67,8 +74,12 @@ if(!external || !external.use(E.e_cost)) //Take power from the borg... return //Note, uses /10 because of shitty mods to the cell system power_supply.give(100) //... to recharge the shot + on_recharge() update_icon() +/obj/item/gun/energy/proc/on_recharge() + newshot() + /obj/item/gun/energy/attack_self(mob/living/user as mob) if(ammo_type.len > 1) select_fire(user) @@ -78,10 +89,6 @@ H.update_inv_l_hand() H.update_inv_r_hand() -/obj/item/gun/energy/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, params) - newshot() //prepare a new shot - ..() - /obj/item/gun/energy/can_shoot() var/obj/item/ammo_casing/energy/shot = ammo_type[select] return power_supply.charge >= shot.e_cost @@ -89,18 +96,20 @@ /obj/item/gun/energy/newshot() if(!ammo_type || !power_supply) return - var/obj/item/ammo_casing/energy/shot = ammo_type[select] - if(power_supply.charge >= shot.e_cost) //if there's enough power in the power_supply cell... - chambered = shot //...prepare a new shot based on the current ammo type selected - chambered.newshot() - return + if(!chambered) + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(power_supply.charge >= shot.e_cost) //if there's enough power in the power_supply cell... + chambered = shot //...prepare a new shot based on the current ammo type selected + if(!chambered.BB) + chambered.newshot() /obj/item/gun/energy/process_chamber() if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired... var/obj/item/ammo_casing/energy/shot = chambered power_supply.use(shot.e_cost)//... drain the power_supply cell + robocharge() chambered = null //either way, released the prepared shot - return + newshot() /obj/item/gun/energy/proc/select_fire(mob/living/user) select++ @@ -111,6 +120,12 @@ fire_delay = shot.delay if(shot.select_name) to_chat(user, "[src] is now set to [shot.select_name].") + if(chambered)//phil235 + if(chambered.BB) + qdel(chambered.BB) + chambered.BB = null + chambered = null + newshot() update_icon() return diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index d214309728e..b93ddefd0d5 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -134,6 +134,7 @@ /obj/item/gun/energy/kinetic_accelerator/proc/reload() power_supply.give(500) + on_recharge() if(!suppressed) playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) else if(isliving(loc)) diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 6cc27a08f09..949ee16fa06 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -79,7 +79,7 @@ slot_flags = null w_class = WEIGHT_CLASS_HUGE ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser) - weapon_weight = WEAPON_MEDIUM + weapon_weight = WEAPON_HEAVY can_flashlight = 0 trigger_guard = TRIGGER_GUARD_NONE ammo_x_offset = 2 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index be60248cded..4499fca3797 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -168,11 +168,13 @@ var/obj/item/stack/sheet/S = A S.use(1) power_supply.give(1000) + on_recharge() to_chat(user, "You insert [A] in [src], recharging it.") else if(istype(A, /obj/item/stack/ore/plasma)) var/obj/item/stack/ore/S = A S.use(1) power_supply.give(500) + on_recharge() to_chat(user, "You insert [A] in [src], recharging it.") else return ..() @@ -251,10 +253,6 @@ /obj/item/gun/energy/printer/emp_act() return -/obj/item/gun/energy/printer/newshot() - ..() - robocharge() - // Instakill Lasers // /obj/item/gun/energy/laser/instakill name = "instakill rifle" diff --git a/code/modules/projectiles/guns/projectile/saw.dm b/code/modules/projectiles/guns/projectile/saw.dm index 9002f12ff35..5b70f2b3282 100644 --- a/code/modules/projectiles/guns/projectile/saw.dm +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -7,7 +7,7 @@ slot_flags = 0 origin_tech = "combat=6;engineering=3;syndicate=6" mag_type = /obj/item/ammo_box/magazine/mm556x45 - weapon_weight = WEAPON_MEDIUM + weapon_weight = WEAPON_HEAVY fire_sound = 'sound/weapons/gunshots/gunshot_mg.ogg' magin_sound = 'sound/weapons/gun_interactions/lmg_magin.ogg' magout_sound = 'sound/weapons/gun_interactions/lmg_magout.ogg' diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 46286bef2af..8b658911b3b 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -11,6 +11,7 @@ mag_type = /obj/item/ammo_box/magazine/internal/shot fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg' var/recentpump = 0 // to prevent spammage + weapon_weight = WEAPON_MEDIUM /obj/item/gun/projectile/shotgun/attackby(obj/item/A, mob/user, params) . = ..() diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index e030c9afb2a..b310ce6d884 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -4,7 +4,7 @@ icon_state = "sniper" item_state = "sniper" recoil = 2 - weapon_weight = WEAPON_MEDIUM + weapon_weight = WEAPON_HEAVY mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_sound = 'sound/weapons/gunshots/gunshot_sniper.ogg' magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg' diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index d5e26182ecc..5dabd8a9db6 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -184,8 +184,10 @@ var/randomize = pick("robot", "slime", "xeno", "human", "animal") switch(randomize) if("robot") + var/path if(prob(30)) - new_mob = new /mob/living/silicon/robot/syndicate(M.loc) + path = pick(typesof(/mob/living/silicon/robot/syndicate)) + new_mob = new path(M.loc) else new_mob = new /mob/living/silicon/robot(M.loc) new_mob.gender = M.gender @@ -193,6 +195,10 @@ new_mob.job = "Cyborg" var/mob/living/silicon/robot/Robot = new_mob Robot.mmi = new /obj/item/mmi(new_mob) + Robot.lawupdate = FALSE + Robot.connected_ai = null + Robot.clear_inherent_laws() + Robot.clear_zeroth_law() if(ishuman(M)) Robot.mmi.transfer_identity(M) //Does not transfer key/client. if("slime") diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index de11cb557a9..41646c114af 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -143,7 +143,6 @@ M.apply_effect((rand(30,80)),IRRADIATE) M.Weaken(5) M.visible_message("[M] writhes in pain as [M.p_their()] vacuoles boil.", "You writhe in pain as your vacuoles boil!", "You hear the crunching of leaves.") - if(prob(35)) if(prob(80)) randmutb(M) domutcheck(M,null) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 69023a3e6e8..9b64161f58b 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -785,6 +785,55 @@ var/const/INGEST = 2 trans_data["viruses"] = temp return trans_data +/datum/reagents/proc/generate_taste_message(minimum_percent = TASTE_SENSITIVITY_NORMAL) + var/list/out = list() + var/list/reagent_tastes = list() //in the form reagent_tastes["descriptor"] = strength + //mobs should get this message when either they cannot taste, the tastes are all too weak for them to detect, or the tastes somehow don't have any strength + var/no_taste_text = "something indescribable" + if(minimum_percent > 100) + return no_taste_text + for(var/datum/reagent/R in reagent_list) + if(!R.taste_mult) + continue + //nutriment carries a list of tastes that originates from the snack food that the nutriment came from + if(istype(R, /datum/reagent/consumable/nutriment)) + var/list/nutriment_taste_data = R.data + for(var/nutriment_taste in nutriment_taste_data) + var/ratio = nutriment_taste_data[nutriment_taste] + var/amount = ratio * R.taste_mult * R.volume + if(nutriment_taste in reagent_tastes) + reagent_tastes[nutriment_taste] += amount + else + reagent_tastes[nutriment_taste] = amount + else + var/taste_desc = R.taste_description + var/taste_amount = R.volume * R.taste_mult + if(taste_desc in reagent_tastes) + reagent_tastes[taste_desc] += taste_amount + else + reagent_tastes[taste_desc] = taste_amount + //deal with percentages + //TODO: may want to sort these from strong to weak + var/total_taste = counterlist_sum(reagent_tastes) + if(total_taste <= 0) + return no_taste_text + for(var/taste_desc in reagent_tastes) + var/percent = (reagent_tastes[taste_desc] / total_taste) * 100 + if(percent < minimum_percent) //the lower the minimum percent, the more sensitive the message is + continue + var/intensity_desc = "a hint of" + if(percent > minimum_percent * 3 && percent != 100) + intensity_desc = "a strong flavor of" + else if(percent > minimum_percent * 2 || percent == 100) + intensity_desc = "" + + if(intensity_desc != "") + out += "[intensity_desc] [taste_desc]" + else + out += "[taste_desc]" + + return english_list(out, no_taste_text) + /////////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index d4199c3dcec..b1aca9820b5 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -26,8 +26,8 @@ var/drink_icon = null var/drink_name = "Glass of ..what?" var/drink_desc = "You can't really tell what this is." - var/taste_strength = 1 //how easy it is to taste - the more the easier - var/taste_message = "bitterness" //life's bitter by default. Cool points for using a span class for when you're tasting LIQUID FUCKING DEATH + var/taste_mult = 1 //how easy it is to taste - the more the easier + var/taste_description = "metaphorical salt" /datum/reagent/Destroy() . = ..() diff --git a/code/modules/reagents/chemistry/reagents/admin.dm b/code/modules/reagents/chemistry/reagents/admin.dm index 0856955da2b..c238c63a8ff 100644 --- a/code/modules/reagents/chemistry/reagents/admin.dm +++ b/code/modules/reagents/chemistry/reagents/admin.dm @@ -6,7 +6,7 @@ color = "#C8A5DC" // rgb: 200, 165, 220 process_flags = ORGANIC | SYNTHETIC //Adminbuse knows no bounds! can_synth = FALSE - taste_message = "admin abuse" + taste_description = "admin abuse" /datum/reagent/medicine/adminordrazine/on_mob_life(mob/living/carbon/M) M.setCloneLoss(0, FALSE) @@ -58,4 +58,4 @@ name = "Nanites" id = "nanites" description = "Nanomachines that aid in rapid cellular regeneration." - taste_message = "nanomachines, son" + taste_description = "nanomachines, son" diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm index 6dde9d2a4ec..5b65a062ea7 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol.dm @@ -8,7 +8,7 @@ color = "#404030" // rgb: 64, 64, 48 var/dizzy_adj = 3 var/alcohol_perc = 1 //percentage of ethanol in a beverage 0.0 - 1.0 - taste_message = "liquid fire" + taste_description = "liquid fire" /datum/reagent/consumable/ethanol/on_mob_life(mob/living/M) M.AdjustDrunk(alcohol_perc) @@ -46,7 +46,7 @@ drink_icon ="beerglass" drink_name = "Beer glass" drink_desc = "A freezing pint of beer" - taste_message = "beer" + taste_description = "beer" /datum/reagent/consumable/ethanol/cider name = "Cider" @@ -58,7 +58,7 @@ drink_icon = "rewriter" drink_name = "Cider" drink_desc = "a refreshing glass of traditional cider" - taste_message = "cider" + taste_description = "cider" /datum/reagent/consumable/ethanol/whiskey name = "Whiskey" @@ -70,7 +70,7 @@ drink_icon = "whiskeyglass" drink_name = "Glass of whiskey" drink_desc = "The silky, smokey whiskey goodness inside the glass makes the drink look very classy." - taste_message = "whiskey" + taste_description = "whiskey" /datum/reagent/consumable/ethanol/specialwhiskey name = "Special Blend Whiskey" @@ -78,7 +78,7 @@ description = "Just when you thought regular station whiskey was good... This silky, amber goodness has to come along and ruin everything." color = "#664300" // rgb: 102, 67, 0 alcohol_perc = 0.5 - taste_message = "class" + taste_description = "class" /datum/reagent/consumable/ethanol/gin name = "Gin" @@ -90,7 +90,7 @@ drink_icon = "ginvodkaglass" drink_name = "Glass of gin" drink_desc = "A crystal clear glass of Griffeater gin." - taste_message = "gin" + taste_description = "gin" /datum/reagent/consumable/ethanol/absinthe name = "Absinthe" @@ -103,7 +103,7 @@ drink_icon = "absinthebottle" drink_name = "Glass of Absinthe" drink_desc = "The green fairy is going to get you now!" - taste_message = "fucking pain" + taste_description = "fucking pain" //copy paste from LSD... shoot me /datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/M) @@ -125,7 +125,7 @@ drink_icon = "glass_brown2" drink_name = "Hooch" drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." - taste_message = "pure resignation" + taste_description = "pure resignation" /datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M) if(M.mind && M.mind.assigned_role == "Assistant") @@ -144,7 +144,7 @@ drink_icon = "rumglass" drink_name = "Glass of Rum" drink_desc = "Now you want to Pray for a pirate suit, don't you?" - taste_message = "rum" + taste_description = "rum" /datum/reagent/consumable/ethanol/rum/overdose_process(mob/living/M, severity) var/update_flags = STATUS_UPDATE_NONE @@ -160,7 +160,7 @@ drink_icon = "mojito" drink_name = "Glass of Mojito" drink_desc = "Fresh from Spesscuba." - taste_message = "mojito" + taste_description = "mojito" /datum/reagent/consumable/ethanol/vodka name = "Vodka" @@ -171,7 +171,7 @@ drink_icon = "ginvodkaglass" drink_name = "Glass of vodka" drink_desc = "The glass contain wodka. Xynta." - taste_message = "vodka" + taste_description = "vodka" /datum/reagent/consumable/ethanol/sake name = "Sake" @@ -182,7 +182,7 @@ drink_icon = "ginvodkaglass" drink_name = "Glass of Sake" drink_desc = "A glass of Sake." - taste_message = "sake" + taste_description = "sake" /datum/reagent/consumable/ethanol/tequila name = "Tequila" @@ -193,7 +193,7 @@ drink_icon = "tequilaglass" drink_name = "Glass of Tequila" drink_desc = "Now all that's missing is the weird colored shades!" - taste_message = "tequila" + taste_description = "tequila" /datum/reagent/consumable/ethanol/vermouth name = "Vermouth" @@ -204,7 +204,7 @@ drink_icon = "vermouthglass" drink_name = "Glass of Vermouth" drink_desc = "You wonder why you're even drinking this straight." - taste_message = "vermouth" + taste_description = "vermouth" /datum/reagent/consumable/ethanol/wine name = "Wine" @@ -216,7 +216,7 @@ drink_icon = "wineglass" drink_name = "Glass of wine" drink_desc = "A very classy looking drink." - taste_message = "wine" + taste_description = "wine" /datum/reagent/consumable/ethanol/cognac name = "Cognac" @@ -228,7 +228,7 @@ drink_icon = "cognacglass" drink_name = "Glass of cognac" drink_desc = "Damn, you feel like some kind of French aristocrat just by holding this." - taste_message = "cognac" + taste_description = "cognac" /datum/reagent/consumable/ethanol/suicider //otherwise known as "I want to get so smashed my liver gives out and I die from alcohol poisoning". name = "Suicider" @@ -240,7 +240,7 @@ drink_icon = "suicider" drink_name = "Suicider" drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." - taste_message = "approaching death" + taste_description = "approaching death" /datum/reagent/consumable/ethanol/ale name = "Ale" @@ -251,7 +251,7 @@ drink_icon = "aleglass" drink_name = "Ale glass" drink_desc = "A freezing pint of delicious Ale" - taste_message = "ale" + taste_description = "ale" /datum/reagent/consumable/ethanol/thirteenloko name = "Thirteen Loko" @@ -265,7 +265,7 @@ drink_icon = "thirteen_loko_glass" drink_name = "Glass of Thirteen Loko" drink_desc = "This is a glass of Thirteen Loko, it appears to be of the highest quality. The drink, not the glass" - taste_message = "party" + taste_description = "party" /datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -290,7 +290,7 @@ drink_icon = "glass_brown" drink_name = "Glass of bilk" drink_desc = "A brew of milk and beer. For those alcoholics who fear osteoporosis." - taste_message = "bilk" + taste_description = "bilk" /datum/reagent/consumable/ethanol/atomicbomb name = "Atomic Bomb" @@ -302,7 +302,7 @@ drink_icon = "atomicbombglass" drink_name = "Atomic Bomb" drink_desc = "Nanotrasen cannot take legal responsibility for your actions after imbibing." - taste_message = "a long, fiery burn" + taste_description = "a long, fiery burn" /datum/reagent/consumable/ethanol/threemileisland name = "THree Mile Island Iced Tea" @@ -314,7 +314,7 @@ drink_icon = "threemileislandglass" drink_name = "Three Mile Island Ice Tea" drink_desc = "A glass of this is sure to prevent a meltdown." - taste_message = "a creeping heat" + taste_description = "a creeping heat" /datum/reagent/consumable/ethanol/goldschlager name = "Goldschlager" @@ -326,7 +326,7 @@ drink_icon = "ginvodkaglass" drink_name = "Glass of goldschlager" drink_desc = "100 proof that teen girls will drink anything with gold in it." - taste_message = "a deep, spicy warmth" + taste_description = "a deep, spicy warmth" /datum/reagent/consumable/ethanol/patron name = "Patron" @@ -338,7 +338,7 @@ drink_icon = "patronglass" drink_name = "Glass of Patron" drink_desc = "Drinking patron in the bar, with all the subpar ladies." - taste_message = "a gift" + taste_description = "a gift" /datum/reagent/consumable/ethanol/gintonic name = "Gin and Tonic" @@ -350,7 +350,7 @@ drink_icon = "gintonicglass" drink_name = "Gin and Tonic" drink_desc = "A mild but still great cocktail. Drink up, like a true Englishman." - taste_message = "bitter medicine" + taste_description = "bitter medicine" /datum/reagent/consumable/ethanol/cuba_libre name = "Cuba Libre" @@ -362,8 +362,8 @@ drink_icon = "cubalibreglass" drink_name = "Cuba Libre" drink_desc = "A classic mix of rum and cola." - taste_message = "fruity alcohol" - taste_message = "liberation" + taste_description = "fruity alcohol" + taste_description = "liberation" /datum/reagent/consumable/ethanol/whiskey_cola name = "Whiskey Cola" @@ -375,7 +375,7 @@ drink_icon = "whiskeycolaglass" drink_name = "Whiskey Cola" drink_desc = "An innocent-looking mixture of cola and Whiskey. Delicious." - taste_message = "whiskey and coke" + taste_description = "whiskey and coke" /datum/reagent/consumable/ethanol/martini name = "Classic Martini" @@ -387,7 +387,7 @@ drink_icon = "martiniglass" drink_name = "Classic Martini" drink_desc = "Damn, the bartender even stirred it, not shook it." - taste_message = "class" + taste_description = "class" /datum/reagent/consumable/ethanol/vodkamartini name = "Vodka Martini" @@ -399,7 +399,7 @@ drink_icon = "martiniglass" drink_name = "Vodka martini" drink_desc ="A bastardisation of the classic martini. Still great." - taste_message = "class and potatoes" + taste_description = "class and potatoes" /datum/reagent/consumable/ethanol/white_russian name = "White Russian" @@ -411,7 +411,7 @@ drink_icon = "whiterussianglass" drink_name = "White Russian" drink_desc = "A very nice looking drink. But that's just, like, your opinion, man." - taste_message = "very creamy alcohol" + taste_description = "very creamy alcohol" /datum/reagent/consumable/ethanol/screwdrivercocktail name = "Screwdriver" @@ -423,7 +423,7 @@ drink_icon = "screwdriverglass" drink_name = "Screwdriver" drink_desc = "A simple, yet superb mixture of Vodka and orange juice. Just the thing for the tired engineer." - taste_message = "a naughty secret" + taste_description = "a naughty secret" /datum/reagent/consumable/ethanol/booger name = "Booger" @@ -435,7 +435,7 @@ drink_icon = "booger" drink_name = "Booger" drink_desc = "Eww..." - taste_message = "a fruity mess" + taste_description = "a fruity mess" /datum/reagent/consumable/ethanol/bloody_mary name = "Bloody Mary" @@ -447,7 +447,7 @@ drink_icon = "bloodymaryglass" drink_name = "Bloody Mary" drink_desc = "Tomato juice, mixed with Vodka and a lil' bit of lime. Tastes like liquid murder." - taste_message = "tomatoes with booze" + taste_description = "tomatoes with booze" /datum/reagent/consumable/ethanol/gargle_blaster name = "Pan-Galactic Gargle Blaster" @@ -459,7 +459,7 @@ drink_icon = "gargleblasterglass" drink_name = "Pan-Galactic Gargle Blaster" drink_desc = "Does... does this mean that Arthur and Ford are on the station? Oh joy." - taste_message = "the number fourty two" + taste_description = "the number fourty two" /datum/reagent/consumable/ethanol/flaming_homer name = "Flaming Moe" @@ -471,7 +471,7 @@ drink_icon = "flamingmoeglass" drink_name = "Flaming Moe" drink_desc = "Happiness is just a Flaming Moe away!" - taste_message = "caramelised booze and sweet, salty medicine" + taste_description = "caramelised booze and sweet, salty medicine" /datum/reagent/consumable/ethanol/brave_bull name = "Brave Bull" @@ -483,7 +483,7 @@ drink_icon = "bravebullglass" drink_name = "Brave Bull" drink_desc = "Tequila and Coffee liquor, brought together in a mouthwatering mixture. Drink up." - taste_message = "sweet alcohol" + taste_description = "sweet alcohol" /datum/reagent/consumable/ethanol/tequila_sunrise name = "Tequila Sunrise" @@ -495,7 +495,7 @@ drink_icon = "tequilasunriseglass" drink_name = "Tequila Sunrise" drink_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..." - taste_message = "fruity alcohol" + taste_description = "fruity alcohol" /datum/reagent/consumable/ethanol/toxins_special name = "Toxins Special" @@ -507,7 +507,7 @@ drink_icon = "toxinsspecialglass" drink_name = "Toxins Special" drink_desc = "Whoah, this thing is on FIRE" - taste_message = "FIRE" + taste_description = "FIRE" /datum/reagent/consumable/ethanol/toxins_special/on_mob_life(mob/living/M) if(M.bodytemperature < 330) @@ -525,7 +525,7 @@ description = "Whiskey-imbued cream, what else would you expect from the Irish." drink_name = "Beepsky Smash" drink_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW." - taste_message = "THE LAW" + taste_description = "THE LAW" /datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/M) var/update_flag = STATUS_UPDATE_NONE @@ -541,7 +541,7 @@ drink_icon = "irishcreamglass" drink_name = "Irish Cream" drink_desc = "It's cream, mixed with whiskey. What else would you expect from the Irish?" - taste_message = "creamy alcohol" + taste_description = "creamy alcohol" /datum/reagent/consumable/ethanol/manly_dorf name = "The Manly Dorf" @@ -553,7 +553,7 @@ drink_icon = "manlydorfglass" drink_name = "The Manly Dorf" drink_desc = "A manly concotion made from Ale and Beer. Intended for true men only." - taste_message = "manliness" + taste_description = "manliness" /datum/reagent/consumable/ethanol/longislandicedtea name = "Long Island Iced Tea" @@ -565,7 +565,7 @@ drink_icon = "longislandicedteaglass" drink_name = "Long Island Iced Tea" drink_desc = "The liquor cabinet, brought together in a delicious mix. Intended for middle-aged alcoholic women only." - taste_message = "fruity alcohol" + taste_description = "fruity alcohol" /datum/reagent/consumable/ethanol/moonshine name = "Moonshine" @@ -577,7 +577,7 @@ drink_icon = "glass_clear" drink_name = "Moonshine" drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." - taste_message = "prohibition" + taste_description = "prohibition" /datum/reagent/consumable/ethanol/b52 name = "B-52" @@ -589,7 +589,7 @@ drink_icon = "b52glass" drink_name = "B-52" drink_desc = "Kahlua, Irish Cream, and congac. You will get bombed." - taste_message = "destruction" + taste_description = "destruction" /datum/reagent/consumable/ethanol/irishcoffee name = "Irish Coffee" @@ -601,7 +601,7 @@ drink_icon = "irishcoffeeglass" drink_name = "Irish Coffee" drink_desc = "Coffee and alcohol. More fun than a Mimosa to drink in the morning." - taste_message = "coffee and booze" + taste_description = "coffee and booze" /datum/reagent/consumable/ethanol/margarita name = "Margarita" @@ -613,7 +613,7 @@ drink_icon = "margaritaglass" drink_name = "Margarita" drink_desc = "On the rocks with salt on the rim. Arriba~!" - taste_message = "daisies" + taste_description = "daisies" /datum/reagent/consumable/ethanol/black_russian name = "Black Russian" @@ -625,7 +625,7 @@ drink_icon = "blackrussianglass" drink_name = "Black Russian" drink_desc = "For the lactose-intolerant. Still as classy as a White Russian." - taste_message = "sweet alcohol" + taste_description = "sweet alcohol" /datum/reagent/consumable/ethanol/manhattan name = "Manhattan" @@ -637,7 +637,7 @@ drink_icon = "manhattanglass" drink_name = "Manhattan" drink_desc = "The Detective's undercover drink of choice. He never could stomach gin..." - taste_message = "a bustling city" + taste_description = "a bustling city" /datum/reagent/consumable/ethanol/manhattan_proj name = "Manhattan Project" @@ -649,7 +649,7 @@ drink_icon = "proj_manhattanglass" drink_name = "Manhattan Project" drink_desc = "A scientist's drink of choice, for thinking how to blow up the station." - taste_message = "the apocalypse" + taste_description = "the apocalypse" /datum/reagent/consumable/ethanol/whiskeysoda name = "Whiskey Soda" @@ -661,7 +661,7 @@ drink_icon = "whiskeysodaglass2" drink_name = "Whiskey Soda" drink_desc = "Ultimate refreshment." - taste_message = "mediocrity" + taste_description = "mediocrity" /datum/reagent/consumable/ethanol/antifreeze name = "Anti-freeze" @@ -673,7 +673,7 @@ drink_icon = "antifreeze" drink_name = "Anti-freeze" drink_desc = "The ultimate refreshment." - taste_message = "poor life choices" + taste_description = "poor life choices" /datum/reagent/consumable/ethanol/antifreeze/on_mob_life(mob/living/M) if(M.bodytemperature < 330) @@ -690,7 +690,7 @@ drink_icon = "b&p" drink_name = "Barefoot" drink_desc = "Barefoot and pregnant" - taste_message = "pregnancy" + taste_description = "pregnancy" /datum/reagent/consumable/ethanol/snowwhite name = "Snow White" @@ -702,7 +702,7 @@ drink_icon = "snowwhite" drink_name = "Snow White" drink_desc = "A cold refreshment." - taste_message = "a poisoned apple" + taste_description = "a poisoned apple" /datum/reagent/consumable/ethanol/demonsblood name = "Demons Blood" @@ -715,7 +715,7 @@ drink_icon = "demonsblood" drink_name = "Demons Blood" drink_desc = "Just looking at this thing makes the hair at the back of your neck stand up." - taste_message = "evil" + taste_description = "evil" /datum/reagent/consumable/ethanol/vodkatonic name = "Vodka and Tonic" @@ -728,7 +728,7 @@ drink_icon = "vodkatonicglass" drink_name = "Vodka and Tonic" drink_desc = "For when a gin and tonic isn't russian enough." - taste_message = "bitter medicine" + taste_description = "bitter medicine" /datum/reagent/consumable/ethanol/ginfizz name = "Gin Fizz" @@ -741,7 +741,7 @@ drink_icon = "ginfizzglass" drink_name = "Gin Fizz" drink_desc = "Refreshingly lemony, deliciously dry." - taste_message = "fizzy alcohol" + taste_description = "fizzy alcohol" /datum/reagent/consumable/ethanol/bahama_mama name = "Bahama mama" @@ -753,7 +753,7 @@ drink_icon = "bahama_mama" drink_name = "Bahama Mama" drink_desc = "Tropic cocktail" - taste_message = "HONK" + taste_description = "HONK" /datum/reagent/consumable/ethanol/singulo name = "Singulo" @@ -766,7 +766,7 @@ drink_icon = "singulo" drink_name = "Singulo" drink_desc = "A blue-space beverage." - taste_message = "infinity" + taste_description = "infinity" /datum/reagent/consumable/ethanol/sbiten name = "Sbiten" @@ -778,7 +778,7 @@ drink_icon = "sbitenglass" drink_name = "Sbiten" drink_desc = "A spicy mix of Vodka and Spice. Very hot." - taste_message = "comforting warmth" + taste_description = "comforting warmth" /datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/M) if(M.bodytemperature < 360) @@ -795,7 +795,7 @@ drink_icon = "devilskiss" drink_name = "Devils Kiss" drink_desc = "Creepy time!" - taste_message = "naughtiness" + taste_description = "naughtiness" /datum/reagent/consumable/ethanol/red_mead name = "Red Mead" @@ -807,7 +807,7 @@ drink_icon = "red_meadglass" drink_name = "Red Mead" drink_desc = "A True Vikings Beverage, though its color is strange." - taste_message = "blood" + taste_description = "blood" /datum/reagent/consumable/ethanol/mead name = "Mead" @@ -820,7 +820,7 @@ drink_icon = "meadglass" drink_name = "Mead" drink_desc = "A Vikings Beverage, though a cheap one." - taste_message = "honey" + taste_description = "honey" /datum/reagent/consumable/ethanol/iced_beer name = "Iced Beer" @@ -832,7 +832,7 @@ drink_icon = "iced_beerglass" drink_name = "Iced Beer" drink_desc = "A beer so frosty, the air around it freezes." - taste_message = "cold beer" + taste_description = "cold beer" /datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/M) if(M.bodytemperature > 270) @@ -849,7 +849,7 @@ drink_icon = "grogglass" drink_name = "Grog" drink_desc = "A fine and cepa drink for Space." - taste_message = "strongly diluted rum" + taste_description = "strongly diluted rum" /datum/reagent/consumable/ethanol/aloe name = "Aloe" @@ -861,7 +861,7 @@ drink_icon = "aloe" drink_name = "Aloe" drink_desc = "Very, very, very good." - taste_message = "healthy skin" + taste_description = "healthy skin" /datum/reagent/consumable/ethanol/andalusia name = "Andalusia" @@ -873,7 +873,7 @@ drink_icon = "andalusia" drink_name = "Andalusia" drink_desc = "A nice, strange named drink." - taste_message = "sweet alcohol" + taste_description = "sweet alcohol" /datum/reagent/consumable/ethanol/alliescocktail name = "Allies Cocktail" @@ -885,7 +885,7 @@ drink_icon = "alliescocktail" drink_name = "Allies cocktail" drink_desc = "A drink made from your allies." - taste_message = "victory" + taste_description = "victory" /datum/reagent/consumable/ethanol/acid_spit name = "Acid Spit" @@ -897,7 +897,7 @@ drink_icon = "acidspitglass" drink_name = "Acid Spit" drink_desc = "A drink from Nanotrasen. Made from live aliens." - taste_message = "PAIN" + taste_description = "PAIN" /datum/reagent/consumable/ethanol/amasec name = "Amasec" @@ -909,7 +909,7 @@ drink_icon = "amasecglass" drink_name = "Amasec" drink_desc = "Always handy before COMBAT!!!" - taste_message = "a stunbaton" + taste_description = "a stunbaton" /datum/reagent/consumable/ethanol/neurotoxin name = "Neuro-toxin" @@ -923,7 +923,7 @@ drink_icon = "neurotoxinglass" drink_name = "Neurotoxin" drink_desc = "A drink that is guaranteed to knock you silly." - taste_message = "brain damageeeEEeee" + taste_description = "brain damageeeEEeee" /datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -945,7 +945,7 @@ drink_icon = "hippiesdelightglass" drink_name = "Hippie's Delight" drink_desc = "A drink enjoyed by people during the 1960's." - taste_message = "colors" + taste_description = "colors" /datum/reagent/consumable/ethanol/hippies_delight/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -983,7 +983,7 @@ drink_icon = "changelingsting" drink_name = "Changeling Sting" drink_desc = "A stingy drink." - taste_message = "a tiny prick" + taste_description = "a tiny prick" /datum/reagent/consumable/ethanol/irishcarbomb name = "Irish Car Bomb" @@ -996,7 +996,7 @@ drink_icon = "irishcarbomb" drink_name = "Irish Car Bomb" drink_desc = "An irish car bomb." - taste_message = "troubles" + taste_description = "troubles" /datum/reagent/consumable/ethanol/syndicatebomb name = "Syndicate Bomb" @@ -1008,7 +1008,7 @@ drink_icon = "syndicatebomb" drink_name = "Syndicate Bomb" drink_desc = "A syndicate bomb." - taste_message = "a job offer" + taste_description = "a job offer" /datum/reagent/consumable/ethanol/erikasurprise name = "Erika Surprise" @@ -1020,7 +1020,7 @@ drink_icon = "erikasurprise" name = "Erika Surprise" drink_desc = "The surprise is, it's green!" - taste_message = "disappointment" + taste_description = "disappointment" /datum/reagent/consumable/ethanol/driestmartini name = "Driest Martini" @@ -1033,7 +1033,7 @@ drink_icon = "driestmartiniglass" drink_name = "Driest Martini" drink_desc = "Only for the experienced. You think you see sand floating in the glass." - taste_message = "dust and ashes" + taste_description = "dust and ashes" /datum/reagent/consumable/ethanol/driestmartini/on_mob_life(mob/living/M) if(current_cycle >= 55 && current_cycle < 115) @@ -1049,7 +1049,7 @@ drink_icon = "kahluaglass" drink_name = "Glass of RR coffee Liquor" drink_desc = "DAMN, THIS THING LOOKS ROBUST" - taste_message = "coffee and alcohol" + taste_description = "coffee and alcohol" /datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1068,7 +1068,7 @@ drink_icon = "ginsonic" drink_name = "Gin and Sonic" drink_desc = "An extremely high amperage drink. Absolutely not for the true Englishman." - taste_message = "SPEED" + taste_description = "SPEED" /datum/reagent/ginsonic/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1095,7 +1095,7 @@ drink_icon = "cognacglass" drink_name = "Glass of applejack" drink_desc = "When cider isn't strong enough, you gotta jack it." - taste_message = "strong cider" + taste_description = "strong cider" /datum/reagent/consumable/ethanol/jackrose name = "Jack Rose" @@ -1106,7 +1106,7 @@ drink_icon = "patronglass" drink_name = "Jack Rose" drink_desc = "Drinking this makes you feel like you belong in a luxury hotel bar during the 1920s." - taste_message = "style" + taste_description = "style" /datum/reagent/consumable/ethanol/drunkenblumpkin name = "Drunken Blumpkin" @@ -1117,7 +1117,7 @@ drink_icon = "drunkenblumpkin" drink_name = "Drunken Blumpkin" drink_desc = "A drink for the drunks" - taste_message = "weirdness" + taste_description = "weirdness" /datum/reagent/consumable/ethanol/eggnog name = "Eggnog" @@ -1129,7 +1129,7 @@ drink_icon = "glass_yellow" drink_name = "Eggnog" drink_desc = "For enjoying the most wonderful time of the year." - taste_message = "christmas spirit" + taste_description = "christmas spirit" /datum/reagent/consumable/ethanol/dragons_breath //inaccessible to players, but here for admin shennanigans name = "Dragon's Breath" @@ -1139,7 +1139,7 @@ color = "#DC0000" alcohol_perc = 1 can_synth = FALSE - taste_message = "LIQUID FUCKING DEATH OH GOD WHAT THE FUCK" + taste_description = "LIQUID FUCKING DEATH OH GOD WHAT THE FUCK" /datum/reagent/consumable/ethanol/dragons_breath/reaction_mob(mob/living/M, method=TOUCH, volume) if(method == INGEST && prob(20)) @@ -1188,7 +1188,7 @@ drink_icon = "synthanolglass" drink_name = "Glass of Synthanol" drink_desc = "The equivalent of alcohol for synthetic crewmembers. They'd find it awful if they had tastebuds too." - taste_message = "motor oil" + taste_description = "motor oil" /datum/reagent/consumable/ethanol/synthanol/on_mob_life(mob/living/M) if(!M.isSynthetic()) @@ -1214,7 +1214,7 @@ drink_icon = "robottearsglass" drink_name = "Glass of Robot Tears" drink_desc = "No robots were hurt in the making of this drink." - taste_message = "existential angst" + taste_description = "existential angst" /datum/reagent/consumable/ethanol/synthanol/trinary name = "Trinary" @@ -1226,7 +1226,7 @@ drink_icon = "trinaryglass" drink_name = "Glass of Trinary" drink_desc = "Colorful drink made for synthetic crewmembers. It doesn't seem like it would taste well." - taste_message = "modem static" + taste_description = "modem static" /datum/reagent/consumable/ethanol/synthanol/servo name = "Servo" @@ -1238,7 +1238,7 @@ drink_icon = "servoglass" drink_name = "Glass of Servo" drink_desc = "Chocolate - based drink made for IPCs. Not sure if anyone's actually tried out the recipe." - taste_message = "motor oil and cocoa" + taste_description = "motor oil and cocoa" /datum/reagent/consumable/ethanol/synthanol/uplink name = "Uplink" @@ -1250,7 +1250,7 @@ drink_icon = "uplinkglass" drink_name = "Glass of Uplink" drink_desc = "An exquisite mix of the finest liquoirs and synthanol. Meant only for synthetics." - taste_message = "a GUI in visual basic" + taste_description = "a GUI in visual basic" /datum/reagent/consumable/ethanol/synthanol/synthnsoda name = "Synth 'n Soda" @@ -1262,7 +1262,7 @@ drink_icon = "synthnsodaglass" drink_name = "Glass of Synth 'n Soda" drink_desc = "Classic drink altered to fit the tastes of a robot. Bad idea to drink if you're made of carbon." - taste_message = "fizzy motor oil" + taste_description = "fizzy motor oil" /datum/reagent/consumable/ethanol/synthanol/synthignon name = "Synthignon" @@ -1274,7 +1274,7 @@ drink_icon = "synthignonglass" drink_name = "Glass of Synthignon" drink_desc = "Someone mixed good wine and robot booze. Romantic, but atrocious." - taste_message = "fancy motor oil" + taste_description = "fancy motor oil" /datum/reagent/consumable/ethanol/fruit_wine name = "Fruit Wine" @@ -1282,7 +1282,7 @@ description = "A wine made from grown plants." color = "#FFFFFF" alcohol_perc = 0.35 - taste_message = "bad coding" + taste_description = "bad coding" can_synth = FALSE var/list/names = list("null fruit" = 1) //Names of the fruits used. Associative list where name is key, value is the percentage of that fruit. var/list/tastes = list("bad coding" = 1) //List of tastes. See above. @@ -1376,7 +1376,7 @@ if(secondary_tastes.len) flavor += ", with a hint of " flavor += english_list(secondary_tastes) - taste_message = flavor + taste_description = flavor if(holder.my_atom) holder.my_atom.on_reagent_change() @@ -1390,4 +1390,4 @@ drink_icon = "glass_brown2" drink_name = "Bacchus' Blessing" drink_desc = "You didn't think it was possible for a liquid to be so utterly revolting. Are you sure about this...?" - taste_message = "a wall of bricks" + taste_description = "a wall of bricks" diff --git a/code/modules/reagents/chemistry/reagents/disease.dm b/code/modules/reagents/chemistry/reagents/disease.dm index 9ce636b466a..27fe0dacc40 100644 --- a/code/modules/reagents/chemistry/reagents/disease.dm +++ b/code/modules/reagents/chemistry/reagents/disease.dm @@ -181,6 +181,7 @@ name = "sucrose agar" id = "sugarvirusfood" color = "#41B0C0" // rgb: 65,176,192 + taste_mult = 1.5 /datum/reagent/medicine/diphenhydramine/diphenhydraminevirusfood name = "virus rations" diff --git a/code/modules/reagents/chemistry/reagents/drink_base.dm b/code/modules/reagents/chemistry/reagents/drink_base.dm index 236da829c73..8f15156753e 100644 --- a/code/modules/reagents/chemistry/reagents/drink_base.dm +++ b/code/modules/reagents/chemistry/reagents/drink_base.dm @@ -4,7 +4,7 @@ description = "Uh, some kind of drink." reagent_state = LIQUID color = "#E78108" // rgb: 231, 129, 8 - taste_message = "something which should not exist" + taste_description = "something which should not exist" var/adj_dizzy = 0 var/adj_drowsy = 0 var/adj_sleepy = 0 diff --git a/code/modules/reagents/chemistry/reagents/drink_cold.dm b/code/modules/reagents/chemistry/reagents/drink_cold.dm index 707aab07b54..ac7adf3eadf 100644 --- a/code/modules/reagents/chemistry/reagents/drink_cold.dm +++ b/code/modules/reagents/chemistry/reagents/drink_cold.dm @@ -1,7 +1,6 @@ /datum/reagent/consumable/drink/cold name = "Cold drink" adj_temp_cool = 5 - taste_message = null /datum/reagent/consumable/drink/cold/tonic name = "Tonic Water" @@ -14,7 +13,7 @@ drink_icon = "glass_clear" drink_name = "Glass of Tonic Water" drink_desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away." - taste_message = "bitterness" + taste_description = "bitterness" /datum/reagent/consumable/drink/cold/sodawater name = "Soda Water" @@ -26,7 +25,7 @@ drink_icon = "glass_clear" drink_name = "Glass of Soda Water" drink_desc = "Soda water. Why not make a scotch and soda?" - taste_message = "fizz" + taste_description = "fizz" /datum/reagent/consumable/drink/cold/ice name = "Ice" @@ -38,7 +37,7 @@ drink_icon = "iceglass" drink_name = "Glass of ice" drink_desc = "Generally, you're supposed to put something else in there too..." - taste_message = "cold" + taste_description = "cold" /datum/reagent/consumable/drink/cold/ice/on_mob_life(mob/living/M) M.bodytemperature = max(M.bodytemperature - 5 * TEMPERATURE_DAMAGE_COEFFICIENT, 0) @@ -54,7 +53,7 @@ drink_icon = "glass_brown" drink_name = "Glass of Space Cola" drink_desc = "A glass of refreshing Space Cola" - taste_message = "cola" + taste_description = "cola" /datum/reagent/consumable/drink/cold/nuka_cola name = "Nuka Cola" @@ -65,7 +64,7 @@ drink_icon = "nuka_colaglass" drink_name = "Nuka Cola" drink_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland" - taste_message = "radioactive cola" + taste_description = "radioactive cola" /datum/reagent/consumable/drink/cold/nuka_cola/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -90,7 +89,7 @@ drink_icon = "Space_mountain_wind_glass" drink_name = "Glass of Space Mountain Wind" drink_desc = "Space Mountain Wind. As you know, there are no mountains in space, only wind." - taste_message = "lime soda" + taste_description = "lime soda" /datum/reagent/consumable/drink/cold/dr_gibb name = "Dr. Gibb" @@ -101,7 +100,7 @@ drink_icon = "dr_gibb_glass" drink_name = "Glass of Dr. Gibb" drink_desc = "Dr. Gibb. Not as dangerous as the name might imply." - taste_message = "cherry soda" + taste_description = "cherry soda" /datum/reagent/consumable/drink/cold/space_up name = "Space-Up" @@ -112,7 +111,7 @@ drink_icon = "space-up_glass" drink_name = "Glass of Space-up" drink_desc = "Space-up. It helps keep your cool." - taste_message = "lemon soda" + taste_description = "lemon soda" /datum/reagent/consumable/drink/cold/lemon_lime name = "Lemon Lime" @@ -120,7 +119,7 @@ id = "lemon_lime" color = "#878F00" // rgb: 135, 40, 0 adj_temp_cool = 8 - taste_message = "citrus soda" + taste_description = "citrus soda" /datum/reagent/consumable/drink/cold/lemonade name = "Lemonade" @@ -130,7 +129,7 @@ drink_icon = "lemonade" drink_name = "Lemonade" drink_desc = "Oh the nostalgia..." - taste_message = "lemonade" + taste_description = "lemonade" /datum/reagent/consumable/drink/cold/kiraspecial name = "Kira Special" @@ -140,7 +139,7 @@ drink_icon = "kiraspecial" drink_name = "Kira Special" drink_desc = "Long live the guy who everyone had mistaken for a girl. Baka!" - taste_message = "citrus soda" + taste_description = "citrus soda" /datum/reagent/consumable/drink/cold/brownstar name = "Brown Star" @@ -151,7 +150,7 @@ drink_icon = "brownstar" drink_name = "Brown Star" drink_desc = "Its not what it sounds like..." - taste_message = "orange soda" + taste_description = "orange soda" /datum/reagent/consumable/drink/cold/milkshake name = "Milkshake" @@ -162,7 +161,7 @@ drink_icon = "milkshake" drink_name = "Milkshake" drink_desc = "Glorious brainfreezing mixture." - taste_message = "milkshake" + taste_description = "milkshake" /datum/reagent/consumable/drink/cold/rewriter name = "Rewriter" @@ -172,7 +171,7 @@ drink_icon = "rewriter" drink_name = "Rewriter" drink_desc = "The secret of the sanctuary of the Librarian..." - taste_message = "coffee...soda?" + taste_description = "coffee...soda?" /datum/reagent/consumable/drink/cold/rewriter/on_mob_life(mob/living/M) M.Jitter(5) diff --git a/code/modules/reagents/chemistry/reagents/drinks.dm b/code/modules/reagents/chemistry/reagents/drinks.dm index 850df4f2382..6298e79d71d 100644 --- a/code/modules/reagents/chemistry/reagents/drinks.dm +++ b/code/modules/reagents/chemistry/reagents/drinks.dm @@ -6,7 +6,7 @@ drink_icon = "glass_orange" drink_name = "Glass of Orange juice" drink_desc = "Vitamins! Yay!" - taste_message = "orange juice" + taste_description = "orange juice" /datum/reagent/consumable/drink/orangejuice/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -22,7 +22,7 @@ drink_icon = "glass_red" drink_name = "Glass of Tomato juice" drink_desc = "Are you sure this is tomato juice?" - taste_message = "tomato juice" + taste_description = "tomato juice" /datum/reagent/consumable/drink/pineapplejuice name = "Pineapple Juice" @@ -32,7 +32,7 @@ drink_icon = "glass_orange" drink_name = "Glass of pineapple juice" drink_desc = "A bright drink, sweet and sugary." - taste_message = "pineapple juice" + taste_description = "pineapple juice" /datum/reagent/consumable/drink/tomatojuice/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -48,7 +48,7 @@ drink_icon = "glass_green" drink_name = "Glass of Lime juice" drink_desc = "A glass of sweet-sour lime juice." - taste_message = "lime juice" + taste_description = "lime juice" /datum/reagent/consumable/drink/limejuice/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -64,7 +64,7 @@ drink_icon = "carrotjuice" drink_name = "Glass of carrot juice" drink_desc = "It is just like a carrot but without crunching." - taste_message = "carrot juice" + taste_description = "carrot juice" /datum/reagent/consumable/drink/carrotjuice/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -87,7 +87,7 @@ drink_icon = "doctorsdelightglass" drink_name = "Doctor's Delight" drink_desc = "A healthy mixture of juices, guaranteed to keep you healthy until the next toolboxing takes place." - taste_message = "healthy dietary choices" + taste_description = "healthy dietary choices" /datum/reagent/consumable/drink/doctor_delight/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -104,7 +104,7 @@ drink_icon = "triplecitrus" drink_name = "Glass of Triplecitrus Juice" drink_desc = "As colorful and healthy as it is delicious." - taste_message = "citrus juice" + taste_description = "citrus juice" /datum/reagent/consumable/drink/triple_citrus/reaction_mob(mob/living/M, method=TOUCH, volume) if(method == INGEST) @@ -118,7 +118,7 @@ drink_icon = "berryjuice" drink_name = "Glass of berry juice" drink_desc = "Berry juice. Or maybe its jam. Who cares?" - taste_message = "berry juice" + taste_description = "berry juice" /datum/reagent/consumable/drink/poisonberryjuice name = "Poison Berry Juice" @@ -128,7 +128,7 @@ drink_icon = "poisonberryjuice" drink_name = "Glass of poison berry juice" drink_desc = "A glass of deadly juice." - taste_message = "berry juice" + taste_description = "berry juice" /datum/reagent/consumable/drink/poisonberryjuice/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -140,14 +140,14 @@ id = "applejuice" description = "The sweet juice of an apple, fit for all ages." color = "#ECFF56" // rgb: 236, 255, 86 - taste_message = "apple juice" + taste_description = "apple juice" /datum/reagent/consumable/drink/watermelonjuice name = "Watermelon Juice" id = "watermelonjuice" description = "Delicious juice made from watermelon." color = "#863333" // rgb: 134, 51, 51 - taste_message = "watermelon juice" + taste_description = "watermelon juice" /datum/reagent/consumable/drink/lemonjuice name = "Lemon Juice" @@ -157,14 +157,14 @@ drink_icon = "lemonglass" drink_name = "Glass of lemonjuice" drink_desc = "Sour..." - taste_message = "lemon juice" + taste_description = "lemon juice" /datum/reagent/consumable/drink/grapejuice name = "Grape Juice" id = "grapejuice" description = "This juice is known to stain shirts." color = "#993399" // rgb: 153, 51, 153 - taste_message = "grape juice" + taste_description = "grape juice" /datum/reagent/consumable/drink/banana name = "Banana Juice" @@ -174,7 +174,7 @@ drink_icon = "banana" drink_name = "Glass of banana juice" drink_desc = "The raw essence of a banana. HONK" - taste_message = "banana juice" + taste_description = "banana juice" /datum/reagent/consumable/drink/banana/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -190,7 +190,7 @@ drink_icon = "nothing" drink_name = "Nothing" drink_desc = "Absolutely nothing." - taste_message = "nothing... how?" + taste_description = "nothing... how?" /datum/reagent/consumable/drink/nothing/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -208,7 +208,7 @@ drink_icon = "glass_brown" drink_name = "Glass of potato juice" drink_desc = "Who in the hell requests this? Gross!" - taste_message = "puke, you're pretty sure" + taste_description = "puke, you're pretty sure" /datum/reagent/consumable/drink/milk name = "Milk" @@ -218,7 +218,7 @@ drink_icon = "glass_white" drink_name = "Glass of milk" drink_desc = "White and nutritious goodness!" - taste_message = "milk" + taste_description = "milk" /datum/reagent/consumable/drink/milk/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -235,7 +235,7 @@ color = "#DFDFC7" // rgb: 223, 223, 199 drink_name = "Glass of soy milk" drink_desc = "White and nutritious soy goodness!" - taste_message = "fake milk" + taste_description = "fake milk" /datum/reagent/consumable/drink/milk/cream name = "Cream" @@ -244,14 +244,14 @@ color = "#DFD7AF" // rgb: 223, 215, 175 drink_name = "Glass of cream" drink_desc = "Ewwww..." - taste_message = "cream" + taste_description = "cream" /datum/reagent/consumable/drink/milk/chocolate_milk name = "Chocolate milk" id ="chocolate_milk" description = "Chocolate-flavored milk, tastes like being a kid again." color = "#85432C" - taste_message = "chocolate milk" + taste_description = "chocolate milk" /datum/reagent/consumable/drink/hot_coco name = "Hot Chocolate" @@ -263,7 +263,7 @@ drink_icon = "hot_coco" drink_name = "Glass of hot coco" drink_desc = "Delicious and cozy" - taste_message = "chocolate" + taste_description = "chocolate" /datum/reagent/consumable/drink/coffee name = "Coffee" @@ -281,7 +281,7 @@ drink_icon = "glass_brown" drink_name = "Glass of coffee" drink_desc = "Don't drop it, or you'll send scalding liquid and glass shards everywhere." - taste_message = "coffee" + taste_description = "coffee" /datum/reagent/consumable/drink/coffee/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -308,7 +308,7 @@ drink_icon = "icedcoffeeglass" drink_name = "Iced Coffee" drink_desc = "A drink to perk you up and refresh you!" - taste_message = "refreshingly cold coffee" + taste_description = "refreshingly cold coffee" /datum/reagent/consumable/drink/coffee/soy_latte name = "Soy Latte" @@ -320,7 +320,7 @@ drink_icon = "soy_latte" drink_name = "Soy Latte" drink_desc = "A nice and refrshing beverage while you are reading." - taste_message = "fake milky coffee" + taste_description = "fake milky coffee" /datum/reagent/consumable/drink/coffee/soy_latte/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -339,7 +339,7 @@ drink_icon = "cafe_latte" drink_name = "Cafe Latte" drink_desc = "A nice, strong and refreshing beverage while you are reading." - taste_message = "milky coffee" + taste_description = "milky coffee" /datum/reagent/consumable/drink/coffee/cafe_latte/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -355,7 +355,7 @@ color = "#673629" drink_name = "Cafe Mocha" drink_desc = "The perfect blend of coffe, milk, and chocolate." - taste_message = "chocolatey coffee" + taste_description = "chocolatey coffee" /datum/reagent/consumable/drink/tea name = "Tea" @@ -370,7 +370,7 @@ drink_icon = "glass_brown" drink_name = "Glass of Tea" drink_desc = "A glass of hot tea. Perhaps a cup with a handle would have been smarter?" - taste_message = "tea" + taste_description = "tea" /datum/reagent/consumable/drink/tea/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -388,7 +388,7 @@ drink_icon = "icetea" drink_name = "Iced Tea" drink_desc = "No relation to a certain rap artist/ actor." - taste_message = "cold tea" + taste_description = "cold tea" /datum/reagent/consumable/drink/bananahonk name = "Banana Honk" @@ -398,7 +398,7 @@ drink_icon = "bananahonkglass" drink_name = "Banana Honk" drink_desc = "A drink from Banana Heaven." - taste_message = "HONK" + taste_description = "HONK" /datum/reagent/consumable/drink/bananahonk/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -415,7 +415,7 @@ drink_icon = "silencerglass" drink_name = "Silencer" drink_desc = "A drink from mime Heaven." - taste_message = "mphhhh" + taste_description = "mphhhh" /datum/reagent/consumable/drink/silencer/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -433,7 +433,7 @@ drink_icon = "chocolatepudding" drink_name = "Chocolate Pudding" drink_desc = "Tasty" - taste_message = "chocolate" + taste_description = "chocolate" /datum/reagent/consumable/drink/vanillapudding name = "Vanilla Pudding" @@ -444,7 +444,7 @@ drink_icon = "vanillapudding" drink_name = "Vanilla Pudding" drink_desc = "Tasty." - taste_message = "vanilla" + taste_description = "vanilla" /datum/reagent/consumable/drink/cherryshake name = "Cherry Shake" @@ -455,7 +455,7 @@ drink_icon = "cherryshake" drink_name = "Cherry Shake" drink_desc = "A cherry flavored milkshake." - taste_message = "cherry milkshake" + taste_description = "cherry milkshake" /datum/reagent/consumable/drink/bluecherryshake name = "Blue Cherry Shake" @@ -466,7 +466,7 @@ drink_icon = "bluecherryshake" drink_name = "Blue Cherry Shake" drink_desc = "An exotic blue milkshake." - taste_message = "blues" + taste_description = "blues" /datum/reagent/consumable/drink/pumpkin_latte name = "Pumpkin Latte" @@ -477,7 +477,7 @@ drink_icon = "pumpkin_latte" drink_name = "Pumpkin Latte" drink_desc = "A mix of coffee and pumpkin juice." - taste_message = "overpriced hipster spices" + taste_description = "overpriced hipster spices" /datum/reagent/consumable/drink/gibbfloats name = "Gibb Floats" @@ -488,25 +488,25 @@ drink_icon= "gibbfloats" drink_name = "Gibbfloat" drink_desc = "Dr. Gibb with ice cream on top." - taste_message = "taste revolution" + taste_description = "taste revolution" /datum/reagent/consumable/drink/pumpkinjuice name = "Pumpkin Juice" id = "pumpkinjuice" description = "Juiced from real pumpkin." color = "#FFA500" - taste_message = "autumn" + taste_description = "autumn" /datum/reagent/consumable/drink/blumpkinjuice name = "Blumpkin Juice" id = "blumpkinjuice" description = "Juiced from real blumpkin." color = "#00BFFF" - taste_message = "caustic puke" + taste_description = "caustic puke" /datum/reagent/consumable/drink/grape_soda name = "Grape soda" id = "grapesoda" description = "Beloved of children and teetotalers." color = "#E6CDFF" - taste_message = "grape soda" + taste_description = "grape soda" diff --git a/code/modules/reagents/chemistry/reagents/drugs.dm b/code/modules/reagents/chemistry/reagents/drugs.dm index 9e96ed5b56b..a2736cec719 100644 --- a/code/modules/reagents/chemistry/reagents/drugs.dm +++ b/code/modules/reagents/chemistry/reagents/drugs.dm @@ -19,7 +19,7 @@ description = "A chemical element." reagent_state = SOLID color = "#808080" // rgb: 128, 128, 128 - taste_message = "metal" + taste_description = "metal" /datum/reagent/lithium/on_mob_life(mob/living/M) if(isturf(M.loc) && !istype(M.loc, /turf/space)) @@ -35,7 +35,7 @@ description = "A highly potent hallucinogenic substance. Far out, maaaan." reagent_state = LIQUID color = "#0000D8" - taste_message = "a magical journey" + taste_description = "a magical journey" /datum/reagent/lsd/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -52,7 +52,7 @@ metabolization_rate = 0.2 addiction_chance = 65 heart_rate_decrease = 1 - taste_message = "a synthetic high" + taste_description = "a synthetic high" /datum/reagent/space_drugs/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -69,7 +69,7 @@ id = "psilocybin" description = "A strong psycotropic derived from certain species of mushroom." color = "#E700E7" // rgb: 231, 0, 231 - taste_message = "visions" + taste_description = "visions" /datum/reagent/psilocybin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -105,7 +105,7 @@ overdose_threshold = 35 addiction_chance = 70 heart_rate_increase = 1 - taste_message = "calm" + taste_description = "calm" /datum/reagent/nicotine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -242,7 +242,7 @@ color = "#0264B4" overdose_threshold = 20 addiction_chance = 50 - taste_message = "very poor life choices" + taste_description = "very poor life choices" /datum/reagent/krokodil/on_mob_life(mob/living/M) @@ -316,7 +316,7 @@ addiction_chance = 60 metabolization_rate = 0.6 heart_rate_increase = 1 - taste_message = "speed" + taste_description = "speed" /datum/reagent/methamphetamine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -376,7 +376,7 @@ overdose_threshold = 20 addiction_chance = 80 metabolization_rate = 0.6 - taste_message = "WAAAAGH" + taste_description = "WAAAAGH" /datum/reagent/bath_salts/on_mob_life(mob/living/M) var/check = rand(0,100) @@ -475,7 +475,7 @@ reagent_state = LIQUID color = "#644600" addiction_chance = 30 - taste_message = "puke... or worse" + taste_description = "puke... or worse" /datum/reagent/jenkem/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -539,7 +539,7 @@ overdose_threshold = 15 process_flags = ORGANIC | SYNTHETIC //Flipping for everyone! addiction_chance = 10 - taste_message = "flips" + taste_description = "flips" /datum/reagent/fliptonium/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -611,7 +611,7 @@ reagent_state = LIQUID color = "#AC88CA" //RGB: 172, 136, 202 metabolization_rate = 0.6 * REAGENTS_METABOLISM - taste_message = "spinning" + taste_description = "spinning" /datum/reagent/rotatium/on_mob_life(mob/living/carbon/M) if(M.hud_used) @@ -645,7 +645,7 @@ overdose_threshold = 20 addiction_chance = 60 metabolization_rate = 0.6 - taste_message = "wiper fluid" + taste_description = "wiper fluid" /datum/reagent/lube/ultra/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -697,7 +697,7 @@ process_flags = SYNTHETIC overdose_threshold = 20 addiction_chance = 50 - taste_message = "silicone" + taste_description = "silicone" /datum/reagent/surge/on_mob_life(mob/living/M) diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index 6f0c53730b4..2479a82decf 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -5,6 +5,8 @@ /datum/reagent/consumable name = "Consumable" id = "consumable" + taste_description = "generic food" + taste_mult = 4 var/nutriment_factor = 1 * REAGENTS_METABOLISM var/diet_flags = DIET_OMNI | DIET_HERB | DIET_CARN @@ -23,7 +25,6 @@ reagent_state = SOLID nutriment_factor = 15 * REAGENTS_METABOLISM color = "#664330" // rgb: 102, 67, 48 - taste_message = null /datum/reagent/consumable/nutriment/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -38,19 +39,41 @@ H.blood_volume += 0.4 return ..() | update_flags +/datum/reagent/consumable/nutriment/on_new(list/supplied_data) + // taste data can sometimes be ("salt" = 3, "chips" = 1) + // and we want it to be in the form ("salt" = 0.75, "chips" = 0.25) + // which is called "normalizing" + if(!supplied_data) + supplied_data = data + // if data isn't an associative list, this has some WEIRD side effects + // TODO probably check for assoc list? + data = counterlist_normalise(supplied_data) + +/datum/reagent/consumable/nutriment/on_merge(list/newdata, newvolume) + if(!islist(newdata) || !newdata.len) + return + var/list/taste_amounts = list() + var/list/other_taste_amounts = newdata.Copy() + if(data) + taste_amounts = data.Copy() + counterlist_scale(taste_amounts, volume) + counterlist_combine(taste_amounts, other_taste_amounts) + counterlist_normalise(taste_amounts) + data = taste_amounts + /datum/reagent/consumable/nutriment/protein // Meat-based protein, digestable by carnivores and omnivores, worthless to herbivores name = "Protein" id = "protein" description = "Various essential proteins and fats commonly found in animal flesh and blood." diet_flags = DIET_CARN | DIET_OMNI - taste_message = "meat" + taste_description = "meat" //TODO: Remove /datum/reagent/consumable/nutriment/plantmatter // Plant-based biomatter, digestable by herbivores and omnivores, worthless to carnivores name = "Plant-matter" id = "plantmatter" description = "Vitamin-rich fibers and natural sugars commonly found in fresh produce." diet_flags = DIET_HERB | DIET_OMNI - taste_message = "vegetables" + taste_description = "vegetables" //TODO: Remove /datum/reagent/consumable/vitamin name = "Vitamin" @@ -58,7 +81,7 @@ description = "All the best vitamins, minerals, and carbohydrates the body needs in pure form." reagent_state = SOLID color = "#664330" // rgb: 102, 67, 48 - taste_message = "nutrition" + taste_description = "nutrition" /datum/reagent/consumable/vitamin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -82,7 +105,8 @@ color = "#FFFFFF" // rgb: 255, 255, 255 nutriment_factor = 5 * REAGENTS_METABOLISM overdose_threshold = 200 // Hyperglycaemic shock - taste_message = "sweetness" + taste_description = "sweetness" + taste_mult = 1.5 /datum/reagent/consumable/sugar/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -117,7 +141,7 @@ reagent_state = LIQUID nutriment_factor = 2 * REAGENTS_METABOLISM color = "#792300" // rgb: 121, 35, 0 - taste_message = "soy" + taste_description = "soy" /datum/reagent/consumable/ketchup name = "Ketchup" @@ -126,7 +150,7 @@ reagent_state = LIQUID nutriment_factor = 5 * REAGENTS_METABOLISM color = "#731008" // rgb: 115, 16, 8 - taste_message = "ketchup" + taste_description = "ketchup" /datum/reagent/consumable/capsaicin name = "Capsaicin Oil" @@ -134,7 +158,8 @@ description = "This is what makes chilis hot." reagent_state = LIQUID color = "#B31008" // rgb: 179, 16, 8 - taste_message = "HOTNESS" + taste_description = "HOTNESS" + taste_mult = 1.5 /datum/reagent/consumable/capsaicin/on_mob_life(mob/living/M) switch(current_cycle) @@ -164,7 +189,7 @@ description = "This shit goes in pepperspray." reagent_state = LIQUID color = "#B31008" // rgb: 179, 16, 8 - taste_message = "PURE FIRE" + taste_description = "PURE FIRE" /datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/M) if(prob(5)) @@ -233,7 +258,7 @@ reagent_state = LIQUID color = "#8BA6E9" // rgb: 139, 166, 233 process_flags = ORGANIC | SYNTHETIC - taste_message = "cold" + taste_description = "cold" /datum/reagent/consumable/frostoil/on_mob_life(mob/living/M) switch(current_cycle) @@ -273,8 +298,8 @@ reagent_state = SOLID color = "#B1B0B0" overdose_threshold = 100 - taste_strength = 2 - taste_message = "salt" + taste_mult = 2 + taste_description = "salt" /datum/reagent/consumable/sodiumchloride/overdose_process(mob/living/M, severity) var/update_flags = STATUS_UPDATE_NONE @@ -287,7 +312,7 @@ id = "blackpepper" description = "A powder ground from peppercorns. *AAAACHOOO*" reagent_state = SOLID - taste_message = "pepper" + taste_description = "pepper" /datum/reagent/consumable/cocoa name = "Cocoa Powder" @@ -296,7 +321,7 @@ reagent_state = SOLID nutriment_factor = 5 * REAGENTS_METABOLISM color = "#302000" // rgb: 48, 32, 0 - taste_message = "bitter cocoa" + taste_description = "bitter cocoa" /datum/reagent/consumable/vanilla name = "Vanilla Powder" @@ -305,7 +330,7 @@ reagent_state = SOLID nutriment_factor = 5 * REAGENTS_METABOLISM color = "#FFFACD" - taste_message = "bitter vanilla" + taste_description = "bitter vanilla" /datum/reagent/consumable/hot_coco name = "Hot Chocolate" @@ -314,7 +339,7 @@ reagent_state = LIQUID nutriment_factor = 2 * REAGENTS_METABOLISM color = "#403010" // rgb: 64, 48, 16 - taste_message = "chocolate" + taste_description = "chocolate" /datum/reagent/consumable/hot_coco/on_mob_life(mob/living/M) if(M.bodytemperature < 310)//310 is the normal bodytemp. 310.055 @@ -326,7 +351,7 @@ id = "sprinkles" description = "Multi-colored little bits of sugar, commonly found on donuts. Loved by cops." color = "#FF00FF" // rgb: 255, 0, 255 - taste_message = "crunchy sweetness" + taste_description = "crunchy sweetness" /datum/reagent/consumable/sprinkles/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -342,7 +367,7 @@ reagent_state = LIQUID nutriment_factor = 20 * REAGENTS_METABOLISM color = "#302000" // rgb: 48, 32, 0 - taste_message = "oil" + taste_description = "oil" /datum/reagent/consumable/cornoil/reaction_turf(turf/simulated/T, volume) if(!istype(T)) @@ -363,7 +388,7 @@ description = "Heated beyond usefulness, this enzyme is now worthless." reagent_state = LIQUID color = "#282314" // rgb: 54, 94, 48 - taste_message = null + taste_description = "sweetness" /datum/reagent/consumable/dry_ramen name = "Dry Ramen" @@ -371,7 +396,7 @@ description = "Space age food, since August 25, 1958. Contains dried noodles, vegetables, and chemicals that boil in contact with water." reagent_state = SOLID color = "#302000" // rgb: 48, 32, 0 - taste_message = "dry ramen coated with what might just be your tears" + taste_description = "dry ramen coated with what might just be your tears" /datum/reagent/consumable/hot_ramen name = "Hot Ramen" @@ -380,7 +405,7 @@ reagent_state = LIQUID nutriment_factor = 5 * REAGENTS_METABOLISM color = "#302000" // rgb: 48, 32, 0 - taste_message = "cheap ramen and memories" + taste_description = "cheap ramen and memories" /datum/reagent/consumable/hot_ramen/on_mob_life(mob/living/M) if(M.bodytemperature < 310)//310 is the normal bodytemp. 310.055 @@ -394,7 +419,7 @@ reagent_state = LIQUID nutriment_factor = 5 * REAGENTS_METABOLISM color = "#302000" // rgb: 48, 32, 0 - taste_message = "SPICY ramen" + taste_description = "SPICY ramen" /datum/reagent/consumable/hell_ramen/on_mob_life(mob/living/M) M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT @@ -406,7 +431,7 @@ description = "This is what you rub all over yourself to pretend to be a ghost." reagent_state = SOLID color = "#FFFFFF" // rgb: 0, 0, 0 - taste_message = "flour" + taste_description = "flour" /datum/reagent/consumable/flour/reaction_turf(turf/T, volume) if(!isspaceturf(T)) @@ -419,7 +444,7 @@ reagent_state = SOLID nutriment_factor = 3 * REAGENTS_METABOLISM color = "#FFFFFF" // rgb: 0, 0, 0 - taste_message = "rice" + taste_description = "rice" /datum/reagent/consumable/cherryjelly name = "Cherry Jelly" @@ -427,7 +452,7 @@ description = "Totally the best. Only to be spread on foods with excellent lateral symmetry." reagent_state = LIQUID color = "#801E28" // rgb: 128, 30, 40 - taste_message = "cherry jelly" + taste_description = "cherry jelly" /datum/reagent/consumable/bluecherryjelly name = "Blue Cherry Jelly" @@ -435,7 +460,7 @@ description = "Blue and tastier kind of cherry jelly." reagent_state = LIQUID color = "#00F0FF" - taste_message = "the blues" + taste_description = "the blues" /datum/reagent/consumable/egg name = "Egg" @@ -443,7 +468,7 @@ description = "A runny and viscous mixture of clear and yellow fluids." reagent_state = LIQUID color = "#F0C814" - taste_message = "eggs" + taste_description = "eggs" /datum/reagent/consumable/egg/on_mob_life(mob/living/M) if(prob(3)) @@ -456,7 +481,7 @@ description = "The powdered starch of maize, derived from the kernel's endosperm. Used as a thickener for gravies and puddings." reagent_state = LIQUID color = "#C8A5DC" - taste_message = "flour" + taste_description = "flour" /datum/reagent/consumable/corn_syrup name = "Corn Syrup" @@ -464,7 +489,7 @@ description = "A sweet syrup derived from corn starch that has had its starches converted into maltose and other sugars." reagent_state = LIQUID color = "#C8A5DC" - taste_message = "cheap sugar substitute" + taste_description = "cheap sugar substitute" /datum/reagent/consumable/corn_syrup/on_mob_life(mob/living/M) M.reagents.add_reagent("sugar", 1.2) @@ -476,7 +501,7 @@ description = "An incredibly sweet syrup, created from corn syrup treated with enzymes to convert its sugars into fructose." reagent_state = LIQUID color = "#C8A5DC" - taste_message = "diabetes" + taste_description = "diabetes" /datum/reagent/consumable/vhfcs/on_mob_life(mob/living/M) M.reagents.add_reagent("sugar", 2.4) @@ -489,7 +514,7 @@ reagent_state = LIQUID color = "#d3a308" nutriment_factor = 15 * REAGENTS_METABOLISM - taste_message = "sweetness" + taste_description = "sweetness" /datum/reagent/consumable/honey/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -504,7 +529,7 @@ id = "onionjuice" description = "A strong tasting substance that can induce partial blindness." color = "#c0c9a0" - taste_message = "pungency" + taste_description = "pungency" /datum/reagent/consumable/onion/reaction_mob(mob/living/M, method = TOUCH, volume) if(method == TOUCH) @@ -528,7 +553,7 @@ drink_icon = "chocolateglass" drink_name = "Glass of chocolate" drink_desc = "Tasty" - taste_message = "chocolate" + taste_description = "chocolate" /datum/reagent/consumable/chocolate/on_mob_life(mob/living/M) M.reagents.add_reagent("sugar", 0.8) @@ -544,7 +569,7 @@ description = "A rather bitter herb once thought to hold magical protective properties." reagent_state = LIQUID color = "#21170E" - taste_message = "tea" + taste_description = "tea" /datum/reagent/consumable/mugwort/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -564,7 +589,7 @@ color = "#AB5D5D" metabolization_rate = 0.2 overdose_threshold = 133 - taste_message = "bacon" + taste_description = "bacon" /datum/reagent/consumable/porktonium/overdose_process(mob/living/M, severity) if(prob(15)) @@ -582,7 +607,7 @@ color = "#B4B400" metabolization_rate = 0.2 nutriment_factor = 2 - taste_message = "broth" + taste_description = "broth" /datum/reagent/consumable/cheese name = "Cheese" @@ -590,7 +615,7 @@ description = "Some cheese. Pour it out to make it solid." reagent_state = SOLID color = "#FFFF00" - taste_message = "cheese" + taste_description = "cheese" /datum/reagent/consumable/cheese/on_mob_life(mob/living/M) if(prob(3)) @@ -608,7 +633,7 @@ reagent_state = LIQUID color = "#B2B139" overdose_threshold = 50 - taste_message = "cheese?" + taste_description = "cheese?" /datum/reagent/consumable/fake_cheese/overdose_process(mob/living/M, severity) var/update_flags = STATUS_UPDATE_NONE @@ -624,7 +649,7 @@ reagent_state = SOLID color = "#50FF00" addiction_chance = 5 - taste_message = "cheeeeeese...?" + taste_description = "cheeeeeese...?" /datum/reagent/consumable/weird_cheese/on_mob_life(mob/living/M) if(prob(5)) @@ -641,7 +666,7 @@ description = "A dish made of mashed beans cooked with lard." reagent_state = LIQUID color = "#684435" - taste_message = "burritos" + taste_description = "burritos" /datum/reagent/consumable/bread name = "Bread" @@ -649,7 +674,7 @@ description = "Bread! Yep, bread." reagent_state = SOLID color = "#9C5013" - taste_message = "bread" + taste_description = "bread" /datum/reagent/consumable/soybeanoil name = "Space-soybean oil" @@ -657,7 +682,7 @@ description = "An oil derived from extra-terrestrial soybeans." reagent_state = LIQUID color = "#B1B0B0" - taste_message = "oil" + taste_description = "oil" /datum/reagent/consumable/soybeanoil/on_mob_life(mob/living/M) if(prob(10)) @@ -674,7 +699,7 @@ color = "#B1B0B0" metabolization_rate = 0.2 overdose_threshold = 75 - taste_message = "oil" + taste_description = "oil" /datum/reagent/consumable/hydrogenated_soybeanoil/on_mob_life(mob/living/M) if(prob(15)) @@ -707,7 +732,7 @@ description = "A paste comprised of highly-processed organic material. Uncomfortably similar to deviled ham spread." reagent_state = LIQUID color = "#EBD7D7" - taste_message = "meat?" + taste_description = "meat?" /datum/reagent/consumable/meatslurry/on_mob_life(mob/living/M) if(prob(4)) @@ -725,7 +750,7 @@ description = "A starchy food paste made from boiled potatoes." reagent_state = SOLID color = "#D6D9C1" - taste_message = "potatoes" + taste_description = "potatoes" /datum/reagent/consumable/gravy name = "Gravy" @@ -733,7 +758,7 @@ description = "A savory sauce made from a simple meat-dripping roux and milk." reagent_state = LIQUID color = "#B4641B" - taste_message = "gravy" + taste_description = "gravy" /datum/reagent/consumable/beff name = "Beff" @@ -741,7 +766,7 @@ description = "An advanced blend of mechanically-recovered meat and textured synthesized protein product notable for its unusual crystalline grain when sliced." reagent_state = SOLID color = "#AC7E67" - taste_message = "meat" + taste_description = "meat" /datum/reagent/consumable/beff/on_mob_life(mob/living/M) if(prob(5)) @@ -759,7 +784,7 @@ description = "An Italian-American variety of salami usually made from beef and pork" reagent_state = SOLID color = "#AC7E67" - taste_message = "pepperoni" + taste_description = "pepperoni" /datum/reagent/consumable/pepperoni/reaction_mob(mob/living/M, method=TOUCH, volume) if(method == TOUCH) @@ -791,7 +816,7 @@ description = "A gross and unidentifiable substance." reagent_state = LIQUID color = "#63DE63" - taste_message = "burned food" + taste_description = "burned food" /datum/reagent/questionmark/reaction_mob(mob/living/M, method=TOUCH, volume) if(method == INGEST) @@ -808,8 +833,8 @@ reagent_state = LIQUID color = "#F5F5F5" metabolization_rate = 0.2 - taste_message = "excellent cuisine" - taste_strength = 4 + taste_description = "excellent cuisine" + taste_mult = 4 /datum/reagent/msg/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -827,7 +852,7 @@ description = "Pure cholesterol. Probably not very good for you." reagent_state = LIQUID color = "#FFFAC8" - taste_message = "heart attack" + taste_description = "heart attack" /datum/reagent/cholesterol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -851,7 +876,7 @@ description = "Scrapings of some unknown fungus found growing on the station walls." reagent_state = LIQUID color = "#C87D28" - taste_message = "mold" + taste_description = "mold" /datum/reagent/fungus/reaction_mob(mob/living/M, method=TOUCH, volume) if(method == INGEST) @@ -872,7 +897,7 @@ reagent_state = LIQUID color = "#8EAE7B" process_flags = ORGANIC | SYNTHETIC //Because apparently ghosts in the shell - taste_message = "spooks" + taste_description = "spooks" /datum/reagent/ectoplasm/on_mob_life(mob/living/M) var/spooky_message = pick("You notice something moving out of the corner of your eye, but nothing is there...", "Your eyes twitch, you feel like something you can't see is here...", "You've got the heebie-jeebies.", "You feel uneasy.", "You shudder as if cold...", "You feel something gliding across your back...") @@ -901,7 +926,7 @@ description = "Looks like someone lost their lunch. And then collected it. Yuck." reagent_state = LIQUID color = "#FFFF00" - taste_message = "puke" + taste_description = "puke" /datum/reagent/vomit/reaction_turf(turf/T, volume) if(volume >= 5 && !isspaceturf(T)) @@ -913,7 +938,7 @@ description = "Whoa, that can't be natural. That's horrible." reagent_state = LIQUID color = "#78FF74" - taste_message = "puke" + taste_description = "puke" /datum/reagent/greenvomit/reaction_turf(turf/T, volume) if(volume >= 5 && !isspaceturf(T)) @@ -926,7 +951,7 @@ id = "entpoly" description = "An ichor, derived from a certain mushroom, makes for a bad time." color = "#1d043d" - taste_message = "mold" + taste_description = "mold" /datum/reagent/consumable/entpoly/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -946,7 +971,7 @@ description = "A stimulating ichor which causes luminescent fungi to grow on the skin. " color = "#b5a213" var/light_activated = 0 - taste_message = "mold" + taste_description = "mold" /datum/reagent/consumable/tinlux/on_mob_life(mob/living/M) if(!light_activated) @@ -963,7 +988,7 @@ description = "A bubbly paste that heals wounds of the skin." color = "#d3a308" nutriment_factor = 3 * REAGENTS_METABOLISM - taste_message = "sweetness" + taste_description = "sweetness" /datum/reagent/consumable/vitfro/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 59d15cf50bd..09ee8cb3948 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -15,7 +15,7 @@ color = "#C805DC" metabolization_rate = 0.3 // Lasts 1.5 minutes for 15 units shock_reduction = 200 - taste_message = "numbness" + taste_description = "numbness" /datum/reagent/medicine/sterilizine name = "Sterilizine" @@ -23,7 +23,7 @@ description = "Sterilizes wounds in preparation for surgery." reagent_state = LIQUID color = "#C8A5DC" // rgb: 200, 165, 220 - taste_message = "antiseptic" + taste_description = "antiseptic" //makes you squeaky clean /datum/reagent/medicine/sterilizine/reaction_mob(mob/living/M, method=TOUCH, volume) @@ -43,7 +43,7 @@ reagent_state = LIQUID color = "#FA46FA" overdose_threshold = 40 - taste_message = "stimulant" + taste_description = "stimulant" /datum/reagent/medicine/synaptizine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -86,7 +86,7 @@ description = "A specialized drug that stimulates the mitochondria of cells to encourage healing of internal organs." reagent_state = LIQUID color = "#C8A5DC" // rgb: 200, 165, 220 - taste_message = "nurturing" + taste_description = "nurturing" /datum/reagent/medicine/mitocholide/on_mob_life(mob/living/M) if(ishuman(M)) @@ -110,7 +110,7 @@ reagent_state = LIQUID color = "#0000C8" // rgb: 200, 165, 220 heart_rate_decrease = 1 - taste_message = "a safe refuge" + taste_description = "a safe refuge" /datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -134,7 +134,7 @@ reagent_state = SOLID color = "#669900" // rgb: 102, 153, 0 overdose_threshold = 30 - taste_message = "reformation" + taste_description = "reformation" /datum/reagent/medicine/rezadone/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -163,7 +163,7 @@ reagent_state = LIQUID color = "#0AB478" metabolization_rate = 0.2 - taste_message = "antibiotics" + taste_description = "antibiotics" /datum/reagent/medicine/silver_sulfadiazine name = "Silver Sulfadiazine" @@ -172,7 +172,7 @@ reagent_state = LIQUID color = "#F0C814" metabolization_rate = 3 - taste_message = "burn cream" + taste_description = "burn cream" /datum/reagent/medicine/silver_sulfadiazine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -198,7 +198,7 @@ reagent_state = LIQUID color = "#C8A5DC" metabolization_rate = 3 - taste_message = "wound cream" + taste_description = "wound cream" /datum/reagent/medicine/styptic_powder/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -226,7 +226,7 @@ color = "#C8A5DC" penetrates_skin = TRUE metabolization_rate = 0.15 - taste_message = "salt" + taste_description = "salt" /datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -246,7 +246,7 @@ description = "A resorbable microfibrillar collagen and protein mixture that can rapidly heal injuries when applied topically." reagent_state = LIQUID color = "#FFEBEB" - taste_message = "blood" + taste_description = "blood" /datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) if(iscarbon(M)) @@ -268,7 +268,7 @@ description = "Activated charcoal helps to absorb toxins." reagent_state = LIQUID color = "#000000" - taste_message = "dust" + taste_description = "dust" /datum/reagent/medicine/charcoal/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -288,7 +288,7 @@ metabolization_rate = 0.2 overdose_threshold = 30 addiction_chance = 5 - taste_message = "health" + taste_description = "health" /datum/reagent/medicine/omnizine/godblood name = "Godblood" @@ -349,7 +349,7 @@ reagent_state = LIQUID color = "#22AB35" metabolization_rate = 0.8 - taste_message = "a painful cleansing" + taste_description = "a painful cleansing" /datum/reagent/medicine/calomel/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -368,7 +368,7 @@ description = "Potassium Iodide is a medicinal drug used to counter the effects of radiation poisoning." reagent_state = LIQUID color = "#B4DCBE" - taste_message = "cleansing" + taste_description = "cleansing" /datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/M) if(prob(80)) @@ -381,7 +381,7 @@ description = "Pentetic Acid is an aggressive chelation agent. May cause tissue damage. Use with caution." reagent_state = LIQUID color = "#C8A5DC" - taste_message = "a purge" + taste_description = "a purge" /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -405,7 +405,7 @@ metabolization_rate = 0.1 shock_reduction = 25 overdose_threshold = 25 - taste_message = "relief" + taste_description = "relief" /datum/reagent/medicine/sal_acid/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -420,7 +420,7 @@ reagent_state = LIQUID color = "#00FFFF" metabolization_rate = 0.2 - taste_message = "safety" + taste_description = "safety" /datum/reagent/medicine/salbutamol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -436,7 +436,7 @@ color = "#C8A5DC" metabolization_rate = 0.2 addiction_chance = 20 - taste_message = "oxygenation" + taste_description = "oxygenation" /datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M) var/update_flags = STATUS_UPDATE_NONE @@ -457,7 +457,7 @@ metabolization_rate = 0.3 overdose_threshold = 35 addiction_chance = 25 - taste_message = "stimulation" + taste_description = "stimulation" /datum/reagent/medicine/ephedrine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -506,7 +506,7 @@ reagent_state = LIQUID color = "#5BCBE1" addiction_chance = 10 - taste_message = "antihistamine" + taste_description = "antihistamine" /datum/reagent/medicine/diphenhydramine/on_mob_life(mob/living/M) M.AdjustJitter(-20) @@ -529,7 +529,7 @@ overdose_threshold = 20 addiction_chance = 50 shock_reduction = 50 - taste_message = "a delightful numbing" + taste_description = "a delightful numbing" /datum/reagent/medicine/morphine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -551,7 +551,7 @@ description = "Oculine is a saline eye medication with mydriatic and antibiotic effects." reagent_state = LIQUID color = "#C8A5DC" - taste_message = "clarity" + taste_description = "clarity" /datum/reagent/medicine/oculine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -583,7 +583,7 @@ color = "#000000" metabolization_rate = 0.2 overdose_threshold = 25 - taste_message = "a moment of respite" + taste_description = "a moment of respite" /datum/reagent/medicine/atropine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -611,7 +611,7 @@ color = "#96B1AE" metabolization_rate = 0.2 overdose_threshold = 20 - taste_message = "borrowed time" + taste_description = "borrowed time" /datum/reagent/medicine/epinephrine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -667,7 +667,8 @@ reagent_state = LIQUID color = "#A0E85E" metabolization_rate = 0.2 - taste_message = "life" + taste_description = "life" + var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it /datum/reagent/medicine/strange_reagent/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -680,13 +681,14 @@ if(volume < 1) // gotta pay to play return ..() - if(isanimal(M)) - if(method == TOUCH) - var/mob/living/simple_animal/SM = M - if(SM.stat == DEAD) - SM.revive() - SM.loot.Cut() //no abusing strange reagent for unlimited farming of resources - SM.visible_message("[M] seems to rise from the dead!") + if(isanimal(M) && method == TOUCH) + var/mob/living/simple_animal/SM = M + if(SM.sentience_type != revive_type) // No reviving Ash Drakes for you + return + if(SM.stat == DEAD) + SM.revive() + SM.loot.Cut() //no abusing strange reagent for farming unlimited resources + SM.visible_message("[SM] seems to rise from the dead!") if(iscarbon(M)) if(method == INGEST || (method == TOUCH && prob(25))) @@ -726,7 +728,7 @@ id = "mannitol" description = "Mannitol is a sugar alcohol that can help alleviate cranial swelling." color = "#D1D1F1" - taste_message = "neurogenisis" + taste_description = "neurogenisis" /datum/reagent/medicine/mannitol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -738,7 +740,7 @@ id = "mutadone" description = "Mutadone is an experimental bromide that can cure genetic abnomalities." color = "#5096C8" - taste_message = "cleanliness" + taste_description = "cleanliness" /datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/human/M) if(M.mind && M.mind.assigned_role == "Cluwne") // HUNKE @@ -767,7 +769,7 @@ id = "antihol" description = "A medicine which quickly eliminates alcohol in the body." color = "#009CA8" - taste_message = "sobriety" + taste_description = "sobriety" /datum/reagent/medicine/antihol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -854,7 +856,7 @@ description = "A hormone generated by the pancreas responsible for metabolizing carbohydrates and fat in the bloodstream." reagent_state = LIQUID color = "#C8A5DC" - taste_message = "tiredness" + taste_description = "tiredness" /datum/reagent/medicine/insulin/on_mob_life(mob/living/M) M.reagents.remove_reagent("sugar", 5) @@ -868,7 +870,7 @@ color = "#D782E6" addiction_chance = 20 overdose_threshold = 50 - taste_message = "warmth and stability" + taste_description = "warmth and stability" /datum/reagent/medicine/teporone/on_mob_life(mob/living/M) if(M.bodytemperature > 310) @@ -883,7 +885,7 @@ description = "Haloperidol is a powerful antipsychotic and sedative. Will help control psychiatric problems, but may cause brain damage." reagent_state = LIQUID color = "#FFDCFF" - taste_message = "stability" + taste_description = "stability" /datum/reagent/medicine/haloperidol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -915,7 +917,7 @@ reagent_state = LIQUID color = "#96DEDE" metabolization_rate = 0.1 - taste_message = "sleepiness" + taste_description = "sleepiness" /datum/reagent/medicine/ether/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -938,7 +940,7 @@ reagent_state = SOLID color = "#555555" can_synth = FALSE - taste_message = "bodily perfection" + taste_description = "bodily perfection" /datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -958,7 +960,7 @@ color = "#DCDCDC" overdose_threshold = 30 metabolization_rate = 0.1 - taste_message = "faint hope" + taste_description = "faint hope" /datum/reagent/medicine/omnizine_diluted/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -988,7 +990,7 @@ reagent_state = LIQUID color = "#CC7A00" process_flags = SYNTHETIC - taste_message = "overclocking" + taste_description = "overclocking" /datum/reagent/medicine/degreaser/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1019,7 +1021,7 @@ reagent_state = LIQUID color = "#D7B395" process_flags = SYNTHETIC - taste_message = "heavy metals" + taste_description = "heavy metals" /datum/reagent/medicine/liquid_solder/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1036,7 +1038,7 @@ reagent_state = LIQUID color = "#C8A5DC" overdose_threshold = 30 - taste_message = "knitting wounds" + taste_description = "knitting wounds" /datum/reagent/medicine/bicaridine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1055,7 +1057,7 @@ reagent_state = LIQUID color = "#C8A5DC" overdose_threshold = 30 - taste_message = "soothed burns" + taste_description = "soothed burns" /datum/reagent/medicine/kelotane/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1074,7 +1076,7 @@ description = "Ichor from an extremely powerful plant. Great for restoring wounds, but it's a little heavy on the brain." color = "#FFAF00" overdose_threshold = 25 - taste_message = "a gift from nature" + taste_description = "a gift from nature" /datum/reagent/medicine/earthsblood/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1100,7 +1102,7 @@ id = "corazone" description = "A medication used to treat pain, fever, and inflammation, along with heart attacks." color = "#F5F5F5" - taste_message = "a brief respite" + taste_description = "a brief respite" // This reagent's effects are handled in heart attack handling code @@ -1111,7 +1113,7 @@ color = "#9b3401" metabolization_rate = 0.5 can_synth = FALSE - taste_message = "wholeness" + taste_description = "wholeness" /datum/reagent/medicine/nanocalcium/on_mob_life(mob/living/carbon/human/M) var/update_flags = STATUS_UPDATE_NONE diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index 886105e6465..d34e6537cb8 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -38,7 +38,7 @@ description = "A colorless, odorless gas." reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 - taste_message = null + taste_mult = 0 /datum/reagent/nitrogen name = "Nitrogen" @@ -46,7 +46,7 @@ description = "A colorless, odorless, tasteless gas." reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 - taste_message = null + taste_mult = 0 /datum/reagent/hydrogen name = "Hydrogen" @@ -54,7 +54,7 @@ description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas." reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 - taste_message = null + taste_mult = 0 /datum/reagent/potassium name = "Potassium" @@ -62,7 +62,7 @@ description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water." reagent_state = SOLID color = "#A0A0A0" // rgb: 160, 160, 160 - taste_message = "bad ideas" + taste_description = "bad ideas" /datum/reagent/sulfur name = "Sulfur" @@ -70,7 +70,7 @@ description = "A chemical element." reagent_state = SOLID color = "#BF8C00" // rgb: 191, 140, 0 - taste_message = "impulsive decisions" + taste_description = "impulsive decisions" /datum/reagent/sodium name = "Sodium" @@ -78,7 +78,7 @@ description = "A chemical element." reagent_state = SOLID color = "#808080" // rgb: 128, 128, 128 - taste_message = "horrible misjudgement" + taste_description = "horrible misjudgement" /datum/reagent/phosphorus name = "Phosphorus" @@ -86,7 +86,7 @@ description = "A chemical element." reagent_state = SOLID color = "#832828" // rgb: 131, 40, 40 - taste_message = "misguided choices" + taste_description = "misguided choices" /datum/reagent/carbon name = "Carbon" @@ -94,7 +94,7 @@ description = "A chemical element." reagent_state = SOLID color = "#1C1300" // rgb: 30, 20, 0 - taste_message = "like a pencil or something" + taste_description = "like a pencil or something" /datum/reagent/carbon/reaction_turf(turf/T, volume) if(!(locate(/obj/effect/decal/cleanable/dirt) in T) && !isspaceturf(T)) // Only add one dirt per turf. Was causing people to crash. @@ -106,7 +106,7 @@ description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known." reagent_state = SOLID color = "#F7C430" // rgb: 247, 196, 48 - taste_message = "bling" + taste_description = "bling" /datum/reagent/silver @@ -115,7 +115,7 @@ description = "A lustrous metallic element regarded as one of the precious metals." reagent_state = SOLID color = "#D0D0D0" // rgb: 208, 208, 208 - taste_message = "sub-par bling" + taste_description = "sub-par bling" /datum/reagent/silver/reaction_mob(mob/living/M, method=TOUCH, volume) if(M.has_bane(BANE_SILVER)) @@ -128,7 +128,7 @@ description = "A silvery white and ductile member of the boron group of chemical elements." reagent_state = SOLID color = "#A8A8A8" // rgb: 168, 168, 168 - taste_message = "metal" + taste_description = "metal" /datum/reagent/silicon @@ -137,7 +137,7 @@ description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon." reagent_state = SOLID color = "#A8A8A8" // rgb: 168, 168, 168 - taste_message = "a CPU" + taste_description = "a CPU" /datum/reagent/copper @@ -145,7 +145,7 @@ id = "copper" description = "A highly ductile metal." color = "#6E3B08" // rgb: 110, 59, 8 - taste_message = "copper" + taste_description = "copper" /datum/reagent/iron @@ -154,7 +154,7 @@ description = "Pure iron is a metal." reagent_state = SOLID color = "#C8A5DC" // rgb: 200, 165, 220 - taste_message = "metal" + taste_description = "metal" /datum/reagent/iron/on_mob_life(mob/living/M) if(ishuman(M)) @@ -176,7 +176,7 @@ description = "A perfluoronated sulfonic acid that forms a foam when mixed with water." reagent_state = LIQUID color = "#9E6B38" // rgb: 158, 107, 56 - taste_message = "extreme discomfort" + taste_description = "extreme discomfort" // metal foaming agent // this is lithium hydride. Add other recipies (e.g. LiH + H2O -> LiOH + H2) eventually @@ -186,7 +186,7 @@ description = "A caustic substance commonly used in fertilizer or household cleaners." reagent_state = GAS color = "#404030" // rgb: 64, 64, 48 - taste_message = "floor cleaner" + taste_description = "floor cleaner" /datum/reagent/diethylamine name = "Diethylamine" @@ -194,7 +194,7 @@ description = "A secondary amine, useful as a plant nutrient and as building block for other compounds." reagent_state = LIQUID color = "#322D00" - taste_message = null + taste_description = "iron" /datum/reagent/oil name = "Oil" @@ -202,7 +202,7 @@ description = "A decent lubricant for machines. High in benzene, naptha and other hydrocarbons." reagent_state = LIQUID color = "#3C3C3C" - taste_message = "motor oil" + taste_description = "motor oil" process_flags = ORGANIC | SYNTHETIC /datum/reagent/oil/reaction_temperature(exposed_temperature, exposed_volume) @@ -227,7 +227,7 @@ description = "A purple gaseous element." reagent_state = GAS color = "#493062" - taste_message = "chemtrail resistance" + taste_description = "chemtrail resistance" /datum/reagent/carpet name = "Carpet" @@ -235,7 +235,7 @@ description = "A covering of thick fabric used on floors. This type looks particularly gross." reagent_state = LIQUID color = "#701345" - taste_message = "a carpet...what?" + taste_description = "a carpet...what?" /datum/reagent/carpet/reaction_turf(turf/simulated/T, volume) if(istype(T, /turf/simulated/floor/plating) || istype(T, /turf/simulated/floor/plasteel)) @@ -249,7 +249,7 @@ description = "A red-brown liquid element." reagent_state = LIQUID color = "#4E3A3A" - taste_message = null + taste_description = "chemicals" /datum/reagent/phenol name = "Phenol" @@ -257,7 +257,7 @@ description = "Also known as carbolic acid, this is a useful building block in organic chemistry." reagent_state = LIQUID color = "#525050" - taste_message = null + taste_description = "acid" /datum/reagent/ash name = "Ash" @@ -265,7 +265,7 @@ description = "Ashes to ashes, dust to dust." reagent_state = LIQUID color = "#191919" - taste_message = "ash" + taste_description = "ash" /datum/reagent/acetone name = "Acetone" @@ -273,7 +273,7 @@ description = "Pure 100% nail polish remover, also works as an industrial solvent." reagent_state = LIQUID color = "#474747" - taste_message = "nail polish remover" + taste_description = "nail polish remover" /datum/reagent/acetone/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -286,7 +286,7 @@ description = "Volatile." reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 - taste_message = "one third of an explosion" + taste_description = "one third of an explosion" /datum/reagent/colorful_reagent name = "Colorful Reagent" @@ -294,7 +294,7 @@ description = "It's pure liquid colors. That's a thing now." reagent_state = LIQUID color = "#FFFFFF" - taste_message = "the rainbow" + taste_description = "the rainbow" /datum/reagent/colorful_reagent/on_mob_life(mob/living/M) if(ishuman(M)) @@ -320,7 +320,7 @@ description = "A rather tubular and gnarly way of coloring totally bodacious hair. Duuuudddeee." reagent_state = LIQUID color = "#960096" - taste_message = "the 2559 Autumn release of the Le Jeune Homme catalogue for professional hairdressers" + taste_description = "the 2559 Autumn release of the Le Jeune Homme catalogue for professional hairdressers" /datum/reagent/hair_dye/reaction_mob(mob/living/M, volume) if(ishuman(M)) @@ -341,7 +341,7 @@ reagent_state = LIQUID color = "#5DDA5D" penetrates_skin = TRUE - taste_message = "someone's beard" + taste_description = "someone's beard" /datum/reagent/hairgrownium/reaction_mob(mob/living/M, volume) if(ishuman(M)) @@ -360,7 +360,7 @@ reagent_state = LIQUID color = "#5DD95D" penetrates_skin = TRUE - taste_message = "multiple beards" + taste_description = "multiple beards" /datum/reagent/super_hairgrownium/reaction_mob(mob/living/M, volume) if(ishuman(M)) @@ -393,7 +393,7 @@ description = "Hugs, in liquid form. Yes, the concept of a hug. As a liquid. This makes sense in the future." reagent_state = LIQUID color = "#FF97B9" - taste_message = "hugs" + taste_description = "hugs" /datum/reagent/love name = "Pure love" @@ -402,7 +402,7 @@ reagent_state = LIQUID color = "#FF83A5" process_flags = ORGANIC | SYNTHETIC // That's the power of love~ - taste_message = "love" + taste_description = "love" /datum/reagent/love/on_mob_life(mob/living/M) if(M.a_intent != INTENT_HELP) @@ -436,7 +436,7 @@ id = "jestosterone" description = "Jestosterone is an odd chemical compound that induces a variety of annoying side-effects in the average person. It also causes mild intoxication, and is toxic to mimes." color = "#ff00ff" //Fuchsia, pity we can't do rainbow here - taste_message = "a funny flavour" + taste_description = "a funny flavour" /datum/reagent/jestosterone/on_new() ..() @@ -504,7 +504,7 @@ id = "royal_bee_jelly" description = "Royal Bee Jelly, if injected into a Queen Space Bee said bee will split into two bees." color = "#00ff80" - taste_message = "sweetness" + taste_description = "sweetness" /datum/reagent/royal_bee_jelly/on_mob_life(mob/living/M) if(prob(2)) @@ -517,7 +517,7 @@ description = "A commercial chemical designed to help older men in the bedroom." //not really it just makes you a giant color = "#ff0000"//strong red. rgb 255, 0, 0 var/current_size = 1 - taste_message = "enhancement" + taste_description = "enhancement" /datum/reagent/growthserum/on_mob_life(mob/living/carbon/H) var/newsize = current_size @@ -549,7 +549,7 @@ description = "Finely ground Coffee beans, used to make coffee." reagent_state = SOLID color = "#5B2E0D" // rgb: 91, 46, 13 - taste_message = "waste" + taste_description = "waste" /datum/reagent/toxin/teapowder name = "Ground Tea Leaves" @@ -557,7 +557,7 @@ description = "Finely shredded Tea leaves, used for making tea." reagent_state = SOLID color = "#7F8400" // rgb: 127, 132, 0" - taste_message = "the future" + taste_description = "the future" //////////////////////////////////Hydroponics stuff/////////////////////////////// @@ -567,7 +567,7 @@ description = "Some kind of nutriment. You can't really tell what it is. You should probably report it, along with how you obtained it." color = "#000000" // RBG: 0, 0, 0 var/tox_prob = 0 - taste_message = "puke" + taste_description = "puke" /datum/reagent/plantnutriment/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -581,7 +581,7 @@ description = "Cheap and extremely common type of plant nutriment." color = "#376400" // RBG: 50, 100, 0 tox_prob = 10 - taste_message = "obscurity and toil" + taste_description = "obscurity and toil" /datum/reagent/plantnutriment/left4zednutriment name = "Left 4 Zed" @@ -589,7 +589,7 @@ description = "Unstable nutriment that makes plants mutate more often than usual." color = "#1A1E4D" // RBG: 26, 30, 77 tox_prob = 25 - taste_message = "evolution" + taste_description = "evolution" /datum/reagent/plantnutriment/robustharvestnutriment name = "Robust Harvest" @@ -597,7 +597,7 @@ description = "Very potent nutriment that prevents plants from mutating." color = "#9D9D00" // RBG: 157, 157, 0 tox_prob = 15 - taste_message = "bountifulness" + taste_description = "bountifulness" ///Alchemical Reagents @@ -643,7 +643,7 @@ color = "#FFC080" // rgb: 255, 196, 128 Bright orange metabolization_rate = 10 * REAGENTS_METABOLISM // very fast, so it can be applied rapidly. But this changes on an overdose overdose_threshold = 11 //Slightly more than one un-nozzled spraybottle. - taste_message = "sour oranges" + taste_description = "sour oranges" /datum/reagent/spraytan/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(ishuman(M)) diff --git a/code/modules/reagents/chemistry/reagents/paint.dm b/code/modules/reagents/chemistry/reagents/paint.dm index ca6da0d0a23..6c0b04339b0 100644 --- a/code/modules/reagents/chemistry/reagents/paint.dm +++ b/code/modules/reagents/chemistry/reagents/paint.dm @@ -4,7 +4,7 @@ description = "Floor paint is used to color floor tiles." reagent_state = LIQUID color = "#808080" - taste_message = "paint" + taste_description = "paint" /datum/reagent/paint/reaction_turf(turf/T, volume) if(!isspaceturf(T)) @@ -55,7 +55,7 @@ description = "Paint remover is used to remove floor paint from floor tiles." reagent_state = LIQUID color = "#808080" - taste_message = "alcohol" + taste_description = "alcohol" /datum/reagent/paint_remover/reaction_turf(turf/T, volume) if(!isspaceturf(T)) diff --git a/code/modules/reagents/chemistry/reagents/paradise_pop.dm b/code/modules/reagents/chemistry/reagents/paradise_pop.dm index 2294088e54a..af59809da27 100644 --- a/code/modules/reagents/chemistry/reagents/paradise_pop.dm +++ b/code/modules/reagents/chemistry/reagents/paradise_pop.dm @@ -15,7 +15,7 @@ description = "Tastes just how you'd think Paradise would if you could bottle it." reagent_state = LIQUID color = "#cc0044" - taste_message = "paradise" + taste_description = "paradise" //Apple-pocalypse: Low chance to cause a goonchem vortex that pulls things within a very small radius (2 tiles?) towards the drinker /datum/reagent/consumable/drink/apple_pocalypse @@ -24,7 +24,7 @@ description = "If doomsday came in fruit form, it'd probably be apples." reagent_state = LIQUID color = "#44FF44" - taste_message = "doomsday" + taste_description = "doomsday" /datum/reagent/consumable/drink/apple_pocalypse/on_mob_life(mob/living/M) if(prob(1)) @@ -40,7 +40,7 @@ description = "Reason for ban: Excessive Flavor." reagent_state = LIQUID color = "#FF44FF" - taste_message = "a permaban" + taste_description = "a permaban" /datum/reagent/consumable/drink/berry_banned/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -69,7 +69,7 @@ description = "Reason for ban: Excessive Flavor." reagent_state = LIQUID color = "#FF44FF" - taste_message = "a permaban" + taste_description = "a permaban" /datum/reagent/consumable/drink/berry_banned2/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -91,7 +91,7 @@ description = "Creamy, smooth flavor, just like the bald heads of the masses. Supposedly aged for 30 years." reagent_state = LIQUID color = "#4d2600" - taste_message = "greytide" + taste_description = "greytide" /datum/reagent/consumable/drink/blackeye_brew/on_mob_life(mob/living/M) if(prob(25)) @@ -114,7 +114,7 @@ description = "Exploding with grape flavor and a favorite among ERT members system-wide." reagent_state = LIQUID color = "#9933ff" - taste_message = "old people" + taste_description = "old people" /datum/reagent/consumable/drink/grape_granade/on_mob_life(mob/living/M) if(prob(1)) @@ -133,7 +133,7 @@ description = "Soft drinks have been detected on collision course with your tastebuds." reagent_state = LIQUID color = "#cc9900" - taste_message = "flying space rocks" + taste_description = "flying space rocks" /datum/reagent/consumable/drink/meteor_malt/on_mob_life(mob/living/M) if(prob(25)) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm index d611c3c8d86..bd4079d69c6 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -84,7 +84,7 @@ drink_icon = "dr_gibb_glass" drink_name = "Glass of welder fuel" drink_desc = "Unless you are an industrial tool, this is probably not safe for consumption." - taste_message = "mistakes" + taste_description = "mistakes" process_flags = ORGANIC | SYNTHETIC var/max_radius = 7 var/min_radius = 0 @@ -140,7 +140,8 @@ description = "The liquid phase of an unusual extraterrestrial compound." reagent_state = LIQUID color = "#7A2B94" - taste_message = "corporate assets going to waste" + taste_description = "corporate assets going to waste" + taste_mult = 1.5 /datum/reagent/plasma/reaction_temperature(exposed_temperature, exposed_volume) if(exposed_temperature >= T0C + 100) @@ -171,7 +172,7 @@ reagent_state = SOLID color = "#673910" // rgb: 103, 57, 16 process_flags = ORGANIC | SYNTHETIC - taste_message = "rust" + taste_description = "rust" /datum/reagent/thermite/reaction_mob(mob/living/M, method= TOUCH, volume) if(method == TOUCH) @@ -206,7 +207,7 @@ description = "Glycerol is a simple polyol compound. Glycerol is sweet-tasting and of low toxicity." reagent_state = LIQUID color = "#808080" // rgb: 128, 128, 128 - taste_message = "sweetness" + taste_description = "sweetness" /datum/reagent/stabilizing_agent name = "Stabilizing Agent" @@ -214,7 +215,7 @@ description = "A chemical that stabilises normally volatile compounds, preventing them from reacting immediately." reagent_state = LIQUID color = "#FFFF00" - taste_message = "long-term stability" + taste_description = "long-term stability" /datum/reagent/clf3 name = "Chlorine Trifluoride" @@ -224,7 +225,7 @@ color = "#FF0000" metabolization_rate = 4 process_flags = ORGANIC | SYNTHETIC - taste_message = null + taste_mult = 0 /datum/reagent/clf3/on_mob_life(mob/living/M) if(M.on_fire) @@ -268,7 +269,7 @@ description = "Sucks everything into the detonation point." reagent_state = LIQUID color = "#800080" - taste_message = "the end of the world" + taste_description = "the end of the world" /datum/reagent/liquid_dark_matter/reaction_turf(turf/T, volume) //Oh gosh, why if(prob(75)) @@ -287,7 +288,7 @@ color = "#000000" metabolization_rate = 0.05 penetrates_skin = TRUE - taste_message = "explosions" + taste_description = "explosions" /datum/reagent/blackpowder/reaction_turf(turf/T, volume) //oh shit if(volume >= 5 && !isspaceturf(T)) @@ -406,7 +407,8 @@ id = "plasma_dust" description = "A fine dust of plasma. This chemical has unusual mutagenic properties for viruses and slimes alike." color = "#500064" // rgb: 80, 0, 100 - taste_message = "corporate assets going to waste" + taste_description = "corporate assets going to waste" + taste_mult = 1.5 /datum/reagent/plasma_dust/reaction_temperature(exposed_temperature, exposed_volume) if(exposed_temperature >= T0C + 100) diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 8048c21a283..7a060a93996 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -4,6 +4,7 @@ description = "A Toxic chemical." reagent_state = LIQUID color = "#CF3600" // rgb: 207, 54, 0 + taste_mult = 1.2 /datum/reagent/toxin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -28,7 +29,7 @@ description = "Useful for dealing with undesirable customers." reagent_state = LIQUID color = "#CF3600" // rgb: 207, 54, 0 - taste_message = "mint" + taste_description = "mint" /datum/reagent/minttoxin/on_mob_life(mob/living/M) if(FAT in M.mutations) @@ -41,7 +42,8 @@ description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL." reagent_state = LIQUID color = "#801E28" // rgb: 128, 30, 40 - taste_message = "slimes" + taste_description = "slimes" + taste_mult = 1.3 /datum/reagent/slimejelly/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -59,7 +61,7 @@ reagent_state = LIQUID color = "#13BC5E" // rgb: 19, 188, 94 can_synth = FALSE - taste_message = "shadows" + taste_description = "shadows" /datum/reagent/slimetoxin/on_mob_life(mob/living/M) if(ishuman(M)) @@ -93,7 +95,8 @@ color = "#484848" // rgb: 72, 72, 72 metabolization_rate = 0.2 penetrates_skin = TRUE - taste_message = "metal" + taste_description = "metal" + taste_mult = 0 // elemental mercury is tasteless /datum/reagent/mercury/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -109,7 +112,7 @@ color = "#808080" // rgb: 128, 128, 128 penetrates_skin = TRUE process_flags = ORGANIC | SYNTHETIC - taste_message = "fire" + taste_description = "fire" /datum/reagent/chlorine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -124,7 +127,7 @@ color = "#6A6054" penetrates_skin = TRUE process_flags = ORGANIC | SYNTHETIC - taste_message = "spicy freshness" + taste_description = "spicy freshness" /datum/reagent/fluorine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -156,6 +159,7 @@ reagent_state = LIQUID color = "#04DF27" metabolization_rate = 0.3 + taste_mult = 0.9 /datum/reagent/mutagen/reaction_mob(mob/living/M, method=TOUCH, volume) if(!..()) @@ -203,6 +207,25 @@ return ..() +datum/reagent/romerol + name = "romerol" + // the REAL zombie powder + id = "romerol" + description = "Romerol is a highly experimental bioterror agent \ + which causes dormant nodules to be etched into the grey matter of \ + the subject. These nodules only become active upon death of the \ + host, upon which, the secondary structures activate and take control \ + of the host body." + color = "#123524" // RGB (18, 53, 36) + metabolization_rate = INFINITY + can_synth = FALSE + taste_description = "CAAAARL" + +/datum/reagent/romerol/reaction_mob(mob/living/carbon/human/H) + // Silently add the zombie infection organ to be activated upon death + new /obj/item/organ/internal/zombie_infection(H) + ..() + /datum/reagent/stable_mutagen/on_tick() var/datum/reagent/blood/B = locate() in holder.reagent_list if(B && islist(B.data) && !data) @@ -215,7 +238,7 @@ description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." reagent_state = SOLID color = "#B8B8C0" // rgb: 184, 184, 192 - taste_message = null + taste_mult = 0 /datum/reagent/uranium/on_mob_life(mob/living/M) M.apply_effect(2, IRRADIATE, negate_armor = 1) @@ -247,7 +270,7 @@ reagent_state = LIQUID color = "#00FF32" process_flags = ORGANIC | SYNTHETIC - taste_message = "ACID" + taste_description = "ACID" /datum/reagent/sacid/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -340,7 +363,7 @@ drink_icon ="beerglass" drink_name = "Beer glass" drink_desc = "A freezing pint of beer" - taste_message = "beer" + taste_description = "beer" /datum/reagent/beer2/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -361,7 +384,7 @@ metabolization_rate = 0.1 penetrates_skin = TRUE can_synth = FALSE - taste_message = null + taste_mult = 0 /datum/reagent/polonium/on_mob_life(mob/living/M) M.apply_effect(8, IRRADIATE, negate_armor = 1) @@ -375,7 +398,7 @@ color = "#E7C4C4" metabolization_rate = 0.2 overdose_threshold = 40 - taste_message = null + taste_mult = 0 /datum/reagent/histamine/reaction_mob(mob/living/M, method=TOUCH, volume) //dumping histamine on someone is VERY mean. if(iscarbon(M)) @@ -533,7 +556,7 @@ color = "#CF3600" metabolization_rate = 0.1 penetrates_skin = TRUE - taste_message = "almonds" + taste_description = "almonds" /datum/reagent/cyanide/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -592,7 +615,7 @@ reagent_state = LIQUID color = "#5050FF" process_flags = ORGANIC | SYNTHETIC - taste_message = "ACID" + taste_description = "ACID" /datum/reagent/facid/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -648,7 +671,7 @@ reagent_state = LIQUID color = "#7F10C0" can_synth = FALSE - taste_message = null + taste_mult = 0 /datum/reagent/initropidril/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -680,7 +703,7 @@ reagent_state = LIQUID color = "#1E4664" metabolization_rate = 0.2 - taste_message = null + taste_mult = 0 /datum/reagent/pancuronium/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -715,7 +738,7 @@ color = "#5F8BE1" metabolization_rate = 0.7 can_synth = FALSE - taste_message = null + taste_mult = 0 /datum/reagent/sodium_thiopental/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -745,7 +768,7 @@ metabolization_rate = 0.8 penetrates_skin = TRUE can_synth = FALSE - taste_message = null + taste_mult = 0 /datum/reagent/ketamine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -797,7 +820,7 @@ description = "A toxin produced by certain mushrooms. Very deadly." reagent_state = LIQUID color = "#D9D9D9" - taste_message = null + taste_mult = 0 /datum/reagent/amanitin/on_mob_delete(mob/living/M) M.adjustToxLoss(current_cycle*rand(2,4)) @@ -810,7 +833,7 @@ reagent_state = SOLID color = "#D1DED1" metabolization_rate = 0.2 - taste_message = "battery acid" + taste_description = "battery acid" /datum/reagent/lipolicide/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -902,7 +925,7 @@ metabolization_rate = 0.1 penetrates_skin = TRUE overdose_threshold = 25 - taste_message = null + taste_mult = 0 /datum/reagent/sarin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -988,10 +1011,10 @@ C.adjustToxLoss(lethality) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(IS_PLANT in H.dna.species.species_traits) //plantmen take a LOT of damage - H.adjustToxLoss(50) + if(IS_PLANT in H.dna.species.species_traits) //plantmen take extra damage + H.adjustToxLoss(3) ..() - else if(istype(M, /mob/living/simple_animal/diona)) //plantmen monkeys (diona) take EVEN MORE damage + else if(istype(M, /mob/living/simple_animal/diona)) //nymphs take EVEN MORE damage var/mob/living/simple_animal/diona/D = M D.adjustHealth(100) ..() @@ -1038,7 +1061,7 @@ reagent_state = LIQUID color = "#60A584" heart_rate_stop = 1 - taste_message = "sweetness" + taste_description = "sweetness" /datum/reagent/capulettium/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1069,7 +1092,7 @@ reagent_state = LIQUID color = "#60A584" heart_rate_stop = 1 - taste_message = "sweetness" + taste_description = "sweetness" /datum/reagent/capulettium_plus/on_mob_life(mob/living/M) M.Silence(2) @@ -1142,7 +1165,7 @@ reagent_state = SOLID color = "#993333" process_flags = ORGANIC | SYNTHETIC - taste_message = "ANTS OH GOD" + taste_description = "ANTS OH GOD" /datum/reagent/ants/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1165,7 +1188,7 @@ metabolization_rate = 0.2 var/shock_timer = 0 process_flags = ORGANIC | SYNTHETIC - taste_message = "electricity" + taste_description = "electricity" /datum/reagent/teslium/on_mob_life(mob/living/M) shock_timer++ @@ -1181,7 +1204,7 @@ description = "An advanced corruptive toxin produced by something terrible." reagent_state = LIQUID color = "#5EFF3B" //RGB: 94, 255, 59 - taste_message = "decay" + taste_description = "decay" /datum/reagent/gluttonytoxin/reaction_mob(mob/living/L, method=TOUCH, reac_volume) L.ForceContractDisease(new /datum/disease/transformation/morph()) diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index fc79d0b336b..64156a7cadd 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -13,22 +13,22 @@ description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen." reagent_state = LIQUID color = "#0064C8" // rgb: 0, 100, 200 + taste_description = "water" var/cooling_temperature = 2 process_flags = ORGANIC | SYNTHETIC drink_icon = "glass_clear" drink_name = "Glass of Water" drink_desc = "The father of all refreshments." - taste_message = null var/water_temperature = 283.15 // As reagents don't have a temperature value, we'll just use 10 celsius. /datum/reagent/water/reaction_mob(mob/living/M, method = TOUCH, volume) M.water_act(volume, water_temperature, src, method) /datum/reagent/water/reaction_turf(turf/simulated/T, volume) - T.water_act(volume, water_temperature, src) + T.water_act(volume, water_temperature, src) /datum/reagent/water/reaction_obj(obj/O, volume) - O.water_act(volume, water_temperature, src) + O.water_act(volume, water_temperature, src) /datum/reagent/lube name = "Space Lube" @@ -36,7 +36,7 @@ description = "Lubricant is a substance introduced between two moving surfaces to reduce the friction and wear between them. giggity." reagent_state = LIQUID color = "#1BB1AB" - taste_message = "cherry" + taste_description = "cherry" /datum/reagent/lube/reaction_turf(turf/simulated/T, volume) if(volume >= 1 && istype(T)) @@ -49,7 +49,7 @@ description = "A compound used to clean things. Now with 50% more sodium hypochlorite!" reagent_state = LIQUID color = "#61C2C2" - taste_message = "floor cleaner" + taste_description = "floor cleaner" /datum/reagent/space_cleaner/reaction_obj(obj/O, volume) if(is_cleanable(O)) @@ -123,7 +123,8 @@ drink_icon = "glass_red" drink_name = "Glass of Tomato juice" drink_desc = "Are you sure this is tomato juice?" - taste_message = "blood" + taste_description = "blood" + taste_mult = 1.3 /datum/reagent/blood/reaction_mob(mob/living/M, method=TOUCH, volume) if(data && data["viruses"]) @@ -205,7 +206,7 @@ name = "Vaccine" id = "vaccine" color = "#C81040" // rgb: 200, 16, 64 - taste_message = "antibodies" + taste_description = "antibodies" /datum/reagent/vaccine/reaction_mob(mob/living/M, method=TOUCH, volume) if(islist(data) && (method == INGEST)) @@ -225,7 +226,7 @@ description = "Smelly water from a fish tank. Gross!" reagent_state = LIQUID color = "#757547" - taste_message = "puke" + taste_description = "puke" /datum/reagent/fishwater/reaction_mob(mob/living/M, method=TOUCH, volume) if(method == INGEST) @@ -245,7 +246,7 @@ description = "Filthy water scoured from a nasty toilet bowl. Absolutely disgusting." reagent_state = LIQUID color = "#757547" - taste_message = "puke" + taste_description = "puke" /datum/reagent/fishwater/toiletwater/reaction_mob(mob/living/M, method=TOUCH, volume) //For shennanigans return @@ -260,7 +261,7 @@ drink_icon = "glass_clear" drink_name = "Glass of Water" drink_desc = "The father of all refreshments." - taste_message = null + taste_description = "water" /datum/reagent/holywater/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -361,7 +362,7 @@ description = "Something that shouldn't exist on this plane of existance." process_flags = ORGANIC | SYNTHETIC //ethereal means everything processes it. metabolization_rate = 1 - taste_message = "sulfur" + taste_description = "sulfur" /datum/reagent/fuel/unholywater/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -390,7 +391,7 @@ process_flags = ORGANIC | SYNTHETIC //Admin-bus has no brakes! KILL THEM ALL. metabolization_rate = 1 can_synth = FALSE - taste_message = "admin abuse" + taste_description = "admin abuse" /datum/reagent/hellwater/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -407,7 +408,7 @@ color = "#FF9966" description = "You don't even want to think about what's in here." reagent_state = LIQUID - taste_message = "meat" + taste_description = "meat" /datum/reagent/liquidgibs/reaction_turf(turf/T, volume) //yes i took it from synthflesh... if(volume >= 5 && !isspaceturf(T)) @@ -420,7 +421,7 @@ description = "Also known as sodium hydroxide." reagent_state = LIQUID color = "#FFFFD6" // very very light yellow - taste_message = "ACID"//don't drink lye, kids + taste_description = "ACID"//don't drink lye, kids /datum/reagent/drying_agent name = "Drying agent" @@ -428,7 +429,7 @@ description = "Can be used to dry things." reagent_state = LIQUID color = "#A70FFF" - taste_message = "dry mouth" + taste_description = "dry mouth" /datum/reagent/drying_agent/reaction_turf(turf/simulated/T, volume) if(istype(T) && T.wet) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 829d8fd2226..f9077aafab5 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -35,6 +35,9 @@ var/datum/disease/F = new spawned_disease(0) var/list/data = list("viruses" = list(F), "blood_color" = "#A10808") reagents.add_reagent("blood", disease_amount, data) + add_initial_reagents() + +obj/item/reagent_containers/proc/add_initial_reagents() if(list_reagents) reagents.add_reagent_list(list_reagents) diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index 5845b0be15c..b9080bf3d12 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -12,6 +12,11 @@ container_type = OPENCONTAINER volume = 30 +/obj/item/reagent_containers/glass/bottle/romerol + name = "romerol bottle" + desc = "A small bottle of Romerol. The REAL zombie powder." + list_reagents = list("romerol" = 30) + /obj/item/reagent_containers/glass/bottle/on_reagent_change() update_icon() diff --git a/code/modules/reagents/reagent_containers/iv_bag.dm b/code/modules/reagents/reagent_containers/iv_bag.dm index 825aa69632b..cfe84d10f2e 100644 --- a/code/modules/reagents/reagent_containers/iv_bag.dm +++ b/code/modules/reagents/reagent_containers/iv_bag.dm @@ -9,7 +9,7 @@ righthand_file = 'icons/goonstation/mob/inhands/items_righthand.dmi' icon_state = "ivbag" volume = 200 - possible_transfer_amounts = list(1,5,10) + possible_transfer_amounts = list(1,5,10,15,20,25,30,50) // Everything above 10 is NOT usable on a person and is instead used for transfering to other containers amount_per_transfer_from_this = 1 container_type = OPENCONTAINER var/label_text @@ -53,6 +53,11 @@ end_processing() return + if(amount_per_transfer_from_this > 10) // Prevents people from switching to illegal transfer values while the IV is already in someone, i.e. anything over 10 + visible_message("The IV bag's needle pops out of [injection_target]'s arm. The transfer amount is too high!") + end_processing() + return + if(get_dist(get_turf(src), get_turf(injection_target)) > 1) to_chat(injection_target, "The [src]'s' needle is ripped out of you!") injection_target.apply_damage(3, BRUTE, pick("r_arm", "l_arm")) @@ -98,6 +103,9 @@ else // Inserting the needle if(!L.can_inject(user, 1)) return + if(amount_per_transfer_from_this > 10) // We only want to be able to transfer 1, 5, or 10 units to people. Higher numbers are for transfering to other containers + to_chat(user, "The IV bag can only be used on someone with a transfer amount of 1, 5 or 10.") + return if(L != user) L.visible_message("[user] is trying to insert [src]'s needle into [L]'s arm!", \ "[user] is trying to insert [src]'s needle into [L]'s arm!") @@ -107,6 +115,22 @@ "[user] inserts [src]'s needle into [L]'s arm!") begin_processing(L) + else if(target.is_refillable() && is_drainable()) // Transferring from IV bag to other containers + if(!reagents.total_volume) + to_chat(user, "[src] is empty.") + return + + if(target.reagents.total_volume >= target.reagents.maximum_volume) + to_chat(user, "[target] is full.") + return + + var/trans = reagents.trans_to(target, amount_per_transfer_from_this) + to_chat(user, "You transfer [trans] units of the solution to [target].") + + else if(istype(target, /obj/item/reagent_containers/glass) && !target.is_open_container()) + to_chat(user, "You cannot fill [target] while it is sealed.") + return + /obj/item/reagent_containers/iv_bag/update_icon() overlays.Cut() diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index cffc2f0ef06..e22e9c86793 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -10,7 +10,7 @@ possible_transfer_amounts = null volume = 100 consume_sound = null - taste = FALSE + can_taste = FALSE antable = FALSE /obj/item/reagent_containers/food/pill/New() diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index f7719c4fd54..6a5d85e0631 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -1036,6 +1036,7 @@ if(O.currTag > 0)// Tag set sortType = O.currTag + name = GLOB.TAGGERLOCATIONS[O.currTag] playsound(src.loc, 'sound/machines/twobeep.ogg', 100, 1) var/tag = uppertext(GLOB.TAGGERLOCATIONS[O.currTag]) to_chat(user, "Changed filter to [tag]") diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index 184ce84c50e..f4ab9561bd5 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -323,7 +323,7 @@ shoes = /obj/item/clothing/shoes/white gloves = /obj/item/clothing/gloves/color/latex/nitrile suit = /obj/item/clothing/suit/space/hardsuit/ert/medical - glasses = /obj/item/clothing/glasses/hud/health/health_advanced + glasses = /obj/item/clothing/glasses/hud/health/sunglasses suit_store = /obj/item/gun/energy/gun cybernetic_implants = list( /obj/item/organ/internal/cyberimp/arm/surgery, diff --git a/code/modules/ruins/lavalandruin_code/clown_planet.dm b/code/modules/ruins/lavalandruin_code/clown_planet.dm new file mode 100644 index 00000000000..6121c40d2af --- /dev/null +++ b/code/modules/ruins/lavalandruin_code/clown_planet.dm @@ -0,0 +1,7 @@ +//lavaland clown planet papers + +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/escape + info = "If you dare not continue down this path of madness, escape can be found through the chute in this room." + +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/hope + info = "Abandon hope, all ye who enter here." \ No newline at end of file diff --git a/code/modules/ruins/lavalandruin_code/seed_vault.dm b/code/modules/ruins/lavalandruin_code/seed_vault.dm index 21cf86b4a07..db16c7b3a71 100644 --- a/code/modules/ruins/lavalandruin_code/seed_vault.dm +++ b/code/modules/ruins/lavalandruin_code/seed_vault.dm @@ -17,7 +17,7 @@ density = TRUE roundstart = FALSE death = FALSE - mob_species = /datum/species/diona + mob_species = /datum/species/diona/pod flavour_text = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \ seed vaults and spread them across the universe to every planet they could chart. You are in one such seed vault. Your goal is to cultivate and spread life wherever it will go while waiting \ for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago." diff --git a/code/modules/security_levels/security levels.dm b/code/modules/security_levels/security levels.dm index 3b1e56e0c2d..effaae3f0ad 100644 --- a/code/modules/security_levels/security levels.dm +++ b/code/modules/security_levels/security levels.dm @@ -122,7 +122,7 @@ FA.overlays += image('icons/obj/monitors.dmi', "overlay_epsilon") if(SEC_LEVEL_DELTA) - security_announcement_up.Announce("The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.","Attention! Delta security level reached!") + security_announcement_up.Announce("The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.","Attention! Delta security level reached!", new_sound = sound('sound/effects/deltaalarm.ogg')) security_level = SEC_LEVEL_DELTA post_status("alert", "deltaalert") diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 0efd49b0e54..953c0e6682c 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -175,7 +175,7 @@ /obj/docking_port/mobile/emergency/proc/is_hijacked() for(var/mob/living/player in GLOB.player_list) if(player.mind) - if(player.stat != DEAD) + if(player.stat != DEAD || !iszombie(player)) if(issilicon(player)) //Borgs are technically dead anyways continue if(isanimal(player)) //Poly does not own the shuttle diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 42e710d0cf6..0a11a4397ad 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -65,3 +65,11 @@ . = ..() if(!S1.lock_shuttle_doors && id_tag == "s_docking_airlock") INVOKE_ASYNC(src, .proc/unlock) + +/obj/structure/ladder/onShuttleMove() + if(resistance_flags & INDESTRUCTIBLE) + // simply don't be moved + return FALSE + disconnect() + LateInitialize() + return ..() \ No newline at end of file diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index bda89160be4..8c96837e9d5 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -349,7 +349,7 @@ if(mode != SHUTTLE_CALL) return - invertTimer() + timer = world.time - timeLeft(1) mode = SHUTTLE_RECALL /obj/docking_port/mobile/proc/enterTransit() @@ -650,8 +650,9 @@ create_ripples(destination) /obj/docking_port/mobile/proc/setTimer(wait) - timer = world.time + wait - last_timer_length = wait + if(timer <= 0) + timer = world.time + timer += wait - timeLeft(1) /obj/docking_port/mobile/proc/modTimer(multiple) var/time_remaining = timer - world.time diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index 78264ca0329..6f1fb8fe293 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -99,11 +99,11 @@ /mob/living/carbon/proc/bleed_internal(amt) // Return 1 if we've coughed blood up, 2 if we're vomited it. if(blood_volume) blood_volume = max(blood_volume - amt, 0) - if (prob(10 * amt)) // +5% chance per internal bleeding site that we'll cough up blood on a given tick. + if(prob(10 * amt)) // +5% chance per internal bleeding site that we'll cough up blood on a given tick. custom_emote(1, "coughs up blood!") add_splatter_floor(loc, 1) return 1 - else if (amt >= 1 && prob(5 * amt)) // +2.5% chance per internal bleeding site that we'll cough up blood on a given tick. Must be bleeding internally in more than one place to have a chance at this. + else if(amt >= 1 && prob(5 * amt)) // +2.5% chance per internal bleeding site that we'll cough up blood on a given tick. Must be bleeding internally in more than one place to have a chance at this. vomit(0, 1) return 2 return 0 @@ -253,7 +253,7 @@ // Only a certain number of drips (or one large splatter) can be on a given turf. var/obj/effect/decal/cleanable/blood/drip/drop = locate() in T if(drop) - if(drop.drips < 3) + if(drop.drips < 5) drop.drips++ drop.overlays |= pick(drop.random_icon_states) drop.transfer_mob_blood_dna(src) @@ -278,7 +278,8 @@ B = locate() in bloods if(!B) B = new(T) - + if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit + B.bloodiness += BLOOD_AMOUNT_PER_DECAL B.transfer_mob_blood_dna(src) //give blood info to the blood decal. if(temp_blood_DNA) B.blood_DNA |= temp_blood_DNA diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index f291f61c96d..ef2f729811c 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -87,67 +87,68 @@ var/global/list/limb_icon_cache = list() else if(s_col) mob_icon.Blend(s_col, ICON_ADD) + if(owner) //Maintains overlays on disembodied parts. + cut_overlays() + dir = EAST icon = mob_icon return mob_icon /obj/item/organ/external/head/get_icon() - ..() - overlays.Cut() if(!owner) return if(dna.species.has_organ["eyes"]) var/icon/eyes_icon = owner.get_eyecon() if(eyes_icon) - mob_icon.Blend(eyes_icon, ICON_OVERLAY) - overlays |= eyes_icon + mob_icon.Blend(eyes_icon, ICON_OVERLAY) //This is required since update_icons.dm relies on this proc to render non-shining eyes. + add_overlay(eyes_icon) if(owner.lip_style && (LIPS in dna.species.species_traits)) - var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") - overlays |= lip_icon - mob_icon.Blend(lip_icon, ICON_OVERLAY) + add_overlay(mutable_appearance('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s")) //Hefty icon not necessary. var/head_marking = owner.m_styles["head"] - if(head_marking && head_marking != "None") + if(head_marking) var/datum/sprite_accessory/head_marking_style = GLOB.marking_styles_list[head_marking] if(head_marking_style && head_marking_style.species_allowed && (dna.species.name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") - var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") + var/icon/h_marking_s = new /icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(owner.m_colours["head"], ICON_ADD) - overlays |= h_marking_s + add_overlay(h_marking_s) - if(ha_style) - var/datum/sprite_accessory/head_accessory_style = GLOB.head_accessory_styles_list[ha_style] - if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) - var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") - if(head_accessory_style.do_colouration) - head_accessory_s.Blend(headacc_colour, ICON_ADD) - overlays |= head_accessory_s + if(!((owner.head && (owner.head.flags & BLOCKHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHAIR)))) //Common restriction for all the below features. + if(ha_style) + var/datum/sprite_accessory/head_accessory_style = GLOB.head_accessory_styles_list[ha_style] + if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) + var/icon/head_accessory_s = new /icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") + if(head_accessory_style.do_colouration) + head_accessory_s.Blend(headacc_colour, ICON_ADD) + add_overlay(head_accessory_s) - if(f_style) - var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) - var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(istype(dna.species, /datum/species/slime)) // I am el worstos - facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. - else if(facial_hair_style.do_colouration) - facial_s.Blend(facial_colour, ICON_ADD) - overlays |= facial_s + if(f_style) + var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] + if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) + var/icon/facial_s = new /icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") + if(istype(dna.species, /datum/species/slime)) // I am el worstos + facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. + else if(facial_hair_style.do_colouration) + facial_s.Blend(facial_colour, ICON_ADD) + add_overlay(facial_s) - if(h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair_style = GLOB.hair_styles_full_list[h_style] - if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) - var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(istype(dna.species, /datum/species/slime)) // I am el worstos - hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. - else if(hair_style.do_colouration) - hair_s.Blend(hair_colour, ICON_ADD) - overlays |= hair_s + if(h_style) + if(!owner.isSynthetic() || (owner.isSynthetic() && ((owner.head && (owner.head.flags & BLOCKHEADHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHEADHAIR))))) + var/datum/sprite_accessory/hair_style = GLOB.hair_styles_full_list[h_style] + if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) + var/icon/hair_s = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") + if(istype(dna.species, /datum/species/slime)) // I am el worstos + hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. + else if(hair_style.do_colouration) + hair_s.Blend(hair_colour, ICON_ADD) + add_overlay(hair_s) - return mob_icon + return mob_icon //Don't need to blend the above into this as it's handled in human/update_icons(). The overlays are for rendering stuff on disembodied heads. /obj/item/organ/external/proc/get_icon_state(skeletal) var/gender diff --git a/code/modules/surgery/organs/subtypes/diona.dm b/code/modules/surgery/organs/subtypes/diona.dm index be05b2917c3..0e76c8fe20b 100644 --- a/code/modules/surgery/organs/subtypes/diona.dm +++ b/code/modules/surgery/organs/subtypes/diona.dm @@ -2,7 +2,6 @@ name = "core trunk" max_damage = 200 min_broken_damage = 50 - cannot_break = 1 amputation_point = "trunk" encased = null gendered_icon = 0 @@ -10,7 +9,6 @@ /obj/item/organ/external/groin/diona name = "fork" min_broken_damage = 50 - cannot_break = 1 amputation_point = "lower trunk" gendered_icon = 0 @@ -18,58 +16,49 @@ name = "left upper tendril" max_damage = 35 min_broken_damage = 20 - cannot_break = 1 amputation_point = "upper left trunk" /obj/item/organ/external/arm/right/diona name = "right upper tendril" max_damage = 35 min_broken_damage = 20 - cannot_break = 1 amputation_point = "upper right trunk" /obj/item/organ/external/leg/diona name = "left lower tendril" max_damage = 35 min_broken_damage = 20 - cannot_break = 1 amputation_point = "lower left fork" /obj/item/organ/external/leg/right/diona name = "right lower tendril" max_damage = 35 min_broken_damage = 20 - cannot_break = 1 amputation_point = "lower right fork" /obj/item/organ/external/foot/diona name = "left foot" max_damage = 20 min_broken_damage = 10 - cannot_break = 1 amputation_point = "branch" /obj/item/organ/external/foot/right/diona name = "right foot" max_damage = 20 min_broken_damage = 10 - cannot_break = 1 amputation_point = "branch" /obj/item/organ/external/hand/diona name = "left grasper" - cannot_break = 1 amputation_point = "branch" /obj/item/organ/external/hand/right/diona name = "right grasper" - cannot_break = 1 amputation_point = "branch" /obj/item/organ/external/head/diona max_damage = 50 min_broken_damage = 25 - cannot_break = 1 encased = null amputation_point = "upper trunk" gendered_icon = 0 @@ -82,6 +71,11 @@ icon = 'icons/obj/objects.dmi' icon_state = "nymph" +/obj/item/organ/internal/lungs/diona + name = "respiratory vacuoles" + icon = 'icons/obj/objects.dmi' + icon_state = "nymph" + /obj/item/organ/internal/brain/diona // Turns into a nymph instantly, no transplanting possible. name = "gas bladder" icon = 'icons/obj/objects.dmi' diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm new file mode 100644 index 00000000000..3ba12518dd2 --- /dev/null +++ b/code/modules/zombie/items.dm @@ -0,0 +1,67 @@ +/obj/item/zombie_hand + name = "zombie claw" + desc = "A zombie's claw is its primary tool, capable of infecting \ + unconscious or dead humans, butchering all other living things to \ + sustain the zombie, forcing open airlock doors and opening \ + child-safe caps on bottles." + flags = NODROP|ABSTRACT|DROPDEL + icon = 'icons/effects/blood.dmi' + icon_state = "bloodhand_left" + var/icon_left = "bloodhand_left" + var/icon_right = "bloodhand_right" + hitsound = 'sound/hallucinations/growl1.ogg' + force = 25 + damtype = "brute" + +/obj/item/zombie_hand/equipped(mob/user, slot) + . = ..() + switch(slot) + // Yes, these intentionally don't match + if(slot_l_hand) + icon_state = icon_right + if(slot_r_hand) + icon_state = icon_left + +/obj/item/zombie_hand/afterattack(atom/target, mob/user, proximity_flag) + . = ..() + if(!proximity_flag) + return + + else if(isliving(target)) + if(ishuman(target)) + check_infection(target, user) + else + check_feast(target, user) + +/obj/item/zombie_hand/proc/check_infection(var/mob/living/carbon/human/target, var/mob/user) + CHECK_DNA_AND_SPECIES(target) + + if(NOZOMBIE in target.dna.species.species_traits) + // cannot infect any NOZOMBIE subspecies (such as high functioning + // zombies) + return + + var/obj/item/organ/internal/zombie_infection/infection + infection = target.get_organ_slot("zombie_infection") + if(!infection) + if (target.InCritical() || (!target.check_death_method() && target.health <= HEALTH_THRESHOLD_DEAD)) + infection = new(target) + +/obj/item/zombie_hand/proc/check_feast(mob/living/target, mob/living/user) + if(target.stat == DEAD) + var/hp_gained = target.maxHealth + target.gib() + user.adjustBruteLoss(-hp_gained) + user.adjustToxLoss(-hp_gained) + user.adjustFireLoss(-hp_gained) + user.adjustCloneLoss(-hp_gained) + user.adjustBrainLoss(-hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!" + +/obj/item/zombie_hand/suicide_act(mob/living/carbon/human/user) + user.visible_message("[user] is ripping [user.p_their()] brains out! It looks like [user.p_theyre()] trying to commit suicide!") + if(ishuman(user)) + var/mob/living/carbon/human/L = user + var/obj/item/organ/external/O = L.get_organ("head") + if(O) + O.droplimb() + return (BRUTELOSS) \ No newline at end of file diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm new file mode 100644 index 00000000000..76bce6ead3d --- /dev/null +++ b/code/modules/zombie/organs.dm @@ -0,0 +1,93 @@ +/obj/item/organ/internal/zombie_infection + name = "festering ooze" + desc = "A black web of pus and viscera." + parent_organ = "head" + slot = "zombie_infection" + icon_state = "blacktumor" + var/converts_living = FALSE + var/causes_damage = TRUE + var/datum/species/old_species = /datum/species/human + var/living_transformation_time = 3 + var/revive_time_min = 450 + var/revive_time_max = 700 + var/timer_id + var/dont_delete = FALSE // to prevent set_species proc in zombify from deleting the infection organ immediately + +/obj/item/organ/internal/zombie_infection/New() + . = ..() + if(ishuman(owner) && !ismachine(owner) && !iszombie(owner.dna.species)) + old_species = owner.dna.species + GLOB.zombie_infection_list += src + +/obj/item/organ/internal/zombie_infection/Destroy() + GLOB.zombie_infection_list -= src + . = ..() + +/obj/item/organ/internal/zombie_infection/insert(mob/living/carbon/human/M, special = 0) + . = ..() + START_PROCESSING(SSobj, src) + +/obj/item/organ/internal/zombie_infection/remove(mob/living/carbon/human/M, special = 0) + STOP_PROCESSING(SSobj, src) + if(iszombie(M) && old_species && !dont_delete) + M.set_species(old_species) + if(timer_id) + deltimer(timer_id) + ..() + +/obj/item/organ/internal/zombie_infection/on_find(mob/living/finder) + to_chat(finder,"Inside the head is a disgusting black \ + web of pus and viscera, bound tightly around the brain like some \ + biological harness.") + +/obj/item/organ/internal/zombie_infection/process() + if(!ishuman(owner)) // We do not support monkey or xeno zombies. Yet. + qdel(src) + return + if(owner.suiciding) + return + if(owner.stat != DEAD && !converts_living) + return + if(causes_damage && !iszombie(owner) && owner.stat != DEAD) + owner.adjustToxLoss(1) + if (prob(10)) + to_chat(owner, "You feel sick...") + if(!owner.get_int_organ(/obj/item/organ/internal/brain)) + return + if(!iszombie(owner) && !timer_id) + to_chat(owner, "You can feel your heart stopping, but something isn't right... \ + life has not abandoned your broken form. You can only feel a deep and immutable hunger that \ + not even death can stop, you will rise again!") + var/revive_time = rand(revive_time_min, revive_time_max) + var/flags = TIMER_STOPPABLE + timer_id = addtimer(CALLBACK(src, .proc/zombify), revive_time, flags) + +/obj/item/organ/internal/zombie_infection/proc/zombify() + timer_id = null + if(owner.stat != DEAD && !converts_living) + return + + if(!iszombie(owner)) + old_species = owner.dna.species + dont_delete = TRUE // make sure the remove code above does not run when the species code replaces all the organs + owner.set_species(/datum/species/zombie/infectious) + for(var/thing in owner.viruses) // cure any new crit viruses + var/datum/disease/D = thing + D.cure(0) + dont_delete = FALSE + //Fully heal the zombie's damage the first time they rise + owner.setToxLoss(0) + owner.setOxyLoss(0) + owner.setBrainLoss(0) + owner.setCloneLoss(0) + owner.SetLoseBreath(0) + owner.heal_overall_damage(INFINITY,INFINITY,TRUE,TRUE,FALSE) + + if(owner.update_revive()) + owner.grab_ghost() + + owner.visible_message("[owner] suddenly convulses, as [owner.p_they()] stagger to [owner.p_their()] feet and gain a ravenous hunger in [owner.p_their()] eyes!", "You HUNGER!") + playsound(owner.loc, 'sound/hallucinations/far_noise.ogg', 50, 1) + owner.do_jitter_animation(living_transformation_time) + owner.Stun(living_transformation_time) + to_chat(owner, "You are now a zombie! Do not seek to be cured, do not help any non-zombies in any way, do not harm your zombie brethren and spread the disease by killing others. You are a creature of hunger and violence.") diff --git a/config/example/lavaRuinBlacklist.txt b/config/example/lavaRuinBlacklist.txt index 934d86514b0..f8fb3fd196a 100644 --- a/config/example/lavaRuinBlacklist.txt +++ b/config/example/lavaRuinBlacklist.txt @@ -5,6 +5,8 @@ ##BIODOMES #_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm +#_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm +#_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm ##RESPAWN #_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm diff --git a/goon/browserassets/css/browserOutput-dark.css b/goon/browserassets/css/browserOutput-dark.css index b19cc07275f..426493dfc88 100644 --- a/goon/browserassets/css/browserOutput-dark.css +++ b/goon/browserassets/css/browserOutput-dark.css @@ -336,6 +336,7 @@ h1.alert, h2.alert {color: #FFF;} .skrell {color: #00CED1;} .solcom {color: #8282FB;} .com_srus {color: #7c4848;} +.zombie {color: #ff0000;} .soghun {color: #228B22;} .changeling {color: #800080;} .vox {color: #AA00AA;} @@ -389,7 +390,6 @@ h1.alert, h2.alert {color: #FFF;} .whisper {font-style:italic;color:#CCCCCC;} /* Recruiting stuff */ .recruit {color: #5c00e6; font-weight: bold; font-style: italic;} -"} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 75%;} diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index 3b77bb1f97e..07ae914de62 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -333,6 +333,7 @@ h1.alert, h2.alert {color: #000000;} .skrell {color: #00CED1;} .solcom {color: #22228B;} .com_srus {color: #7c4848;} +.zombie {color: #ff0000;} .soghun {color: #228B22;} .changeling {color: #800080;} .vox {color: #AA00AA;} @@ -386,7 +387,6 @@ h1.alert, h2.alert {color: #000000;} .whisper {font-style:italic;color:#333333;} /* Recruiting stuff */ .recruit {color: #5c00e6; font-weight: bold; font-style: italic;} -"} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 75%;} diff --git a/html/changelog.html b/html/changelog.html index 023f1918124..270ef03dd3f 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,251 @@ -->
      +

      30 August 2019

      +

      AffectedArc07 updated:

      +
        +
      • Fixes the changelog
      • +
      +

      Arkatos updated:

      +
        +
      • Added new icon for Charge spell
      • +
      • Added new icon for No Clothes spell
      • +
      • Added new icon for Wizard spellbook
      • +
      • Added new animations to 10 single-use spellbooks
      • +
      • Added new sprite for Bottle of Tickles
      • +
      • Added refunding functionality to the Bottle of Ooze akin to the other summoning bottles. Click with the bottle in hand on a wizard spellbook to refund its cost and limit slot.
      • +
      • Fixed an issue where Bottle of Tickles did not properly refund
      • +
      • Fixed an issue with alpha layering on Bottle of Ooze sprite
      • +
      • Very slightly adjusted brightness of the Boo! ghost spell icon
      • +
      • Wizard spellbook was completely reorganized, and new appropriate categories were added, each category is sorted by price, and if price of the two or more spells is the same, they are sorted alphabetically
      • +
      • Polymorph can now turn a mob into Syndicate medical or saboteur modules
      • +
      • Mobs made via polymorph into borgs are now unbounded free borgs
      • +
      • Repulse spell cost decreased from 2 to 1
      • +
      • Lighting bolt spell cost decreased from 2 to 1
      • +
      • Slaughter/Laughter demons and Magical Morphs now always have their second fluff objective considered as complete no matter the circumstances
      • +
      • Laughter Demons very slightly buffed, they are still a bit weaker than Slaughter Demons
      • +
      • Improved descriptions and wording regarding Wizard spellbook and Wizard spells
      • +
      • Traitor AI now uses action buttons for its malfunction abilities
      • +
      +

      AzuleUtama updated:

      +
        +
      • Adds false-bottomed briefcase from VG.
      • +
      +

      Couls updated:

      +
        +
      • Rechargers can now be crafted from science using one capacitor and a recharger board tweak:Smaller machines like microwaves and cell chargers can now be placed on tables(Fax machines included) tweak:can screwdriver open rechargers and then apply a crowbar to deconstruct them
      • +
      • Blood spread now depends on volume of the blood, requires more drips of blood to create a pool
      • +
      • DUAL WIELDING
      • +
      • new chatsubsystem from TG!
      • +
      • Update issue templates to latest version and clean up the current template
      • +
      • mining shuttle warning message and delay before launching
      • +
      • cardboard boxes are no longer sonic speed
      • +
      • shuttle timers now get set properly
      • +
      +

      EmanTheAlmighty updated:

      +
        +
      • Blobbernauts can now be controlled by players through a prompt which appears when they are spawned by blobs.
      • +
      • Blobbernauts and blobs can now communicate with each other.
      • +
      • Blobbernauts now regenerate health overtime when standing on blob structures.
      • +
      • Blobbernauts will slowly lose health if they are not standing on blob structures while not at full health. balance: Blobbernauts have been nerfed, they now have less health, deal less damage and cannot break walls anymore. balance: Blob's "Produce Blobbernaut" ability has been made more expensive to use, now costing 60 resources instead of 20.
      • +
      +

      Emanthealmighty updated:

      +
        +
      • The poll to play as a blobbernaut now lasts 10 seconds from 15.
      • +
      • Blobbernauts no longer chase after people while players are being polled to play as one.
      • +
      +

      Fox McCloud updated:

      +
        +
      • Plasmamen dramatically overhauled.
      • +
      • Plasmamen can be cloned without burning to death in the clonepod
      • +
      • Plasmamen no longer start with spacesuits
      • +
      • Plasmamen start off with jumpsuits that seal to protect against oxygen. This allows for you to customize their appearance more
      • +
      • Plasmamen helmets now allow you to see a Plasmaman's actual face; should be able to see their eye color and mouth color now
      • +
      • Plasmamen take 50% extra brute and burn
      • +
      • Plasmamen are immune to radiation
      • +
      • Plasmamen start out with a small tank that can fit on a belt or in a pocket; it should be enough to last an entire shift
      • +
      • Plasmaman helmets now have built in welding goggles
      • +
      • Plasmaman karma cost lowered from 100 to 45
      • +
      • Reworks Diona
      • +
      • Diona bleed (call it chlorophy; it's green)
      • +
      • Diona Breathe (plants do need to exchange gas after all)
      • +
      • Rad Immunity Removed
      • +
      • Diona regenerate 1 OXY, 1 BURN, 1 BRUTE, and 1 TOX if they are in a bright area; this effect does not kick in if they're in crit
      • +
      • Diona no longer have unbreakable bones (wood can crack ya know!)
      • +
      • Diona are no longer space proof
      • +
      • Diona are more vulnerable to fire and heat damage
      • +
      • Diona weakness to weedkiller dramatically nerfed
      • +
      • Diona now use Newcrit
      • +
      • Diona are no longer slow
      • +
      • Diona can wear spacesuits
      • +
      • Fixes stun absorbing not working
      • +
      • Fixes parallax insane setting not doing anything
      • +
      • Ores can be destroyed by devastating explosions
      • +
      • silver, gold, and diamond pickaxes do a bit more damage and mine faster than before
      • +
      • drills slightly slower, but diamond drills slightly faster
      • +
      • Spade is the same speed as a shovel
      • +
      • Hivelord stabilizer will now make a hivelord core/legion soul stabilize and be preserved, even if it was previously inert
      • +
      • can use a hivelord core in your active hand to apply it to yourself
      • +
      • soulstone in the abandoned locked crates can now be used by anyone
      • +
      • Adds firelemon seeds to the abandoned locked crates as potential loot
      • +
      • Hardsuits have an integrated helmet; you no longer have to attach helmets
      • +
      • Toggling up/down helmets is now done with an action button
      • +
      • can no longer attach magboots to a hardsuit
      • +
      • Hardsuit base melee armor increased from 10 to 30
      • +
      • Security and HoS hardsuit melee armor increased by 5
      • +
      • HoS hardsuit helmet armor matches his hardsuit
      • +
      • CE's hardsuit helmet armor for rads increased by 10 (should be fully rad proof now)
      • +
      • Elite syndicate suits can't be acided
      • +
      • Fixes stuns and weakens related to reagents
      • +
      • Fixes the displayed cost of Plasmamen
      • +
      • Adds jetpack hardsuit upgrades: get yours at mining for 2000 points
      • +
      • Removes mining carbon dioxide jetpack
      • +
      • Can no longer use jetpacks in your suit storage slot
      • +
      • Chief Engineer's hardsuit, Syndicate Hardsuit (normal and elite), and Shielded Syndicate Hardsuit all have built in jetpacks
      • +
      • Fixes random singularity releases from the grid check event
      • +
      • loadout costs for most things cut from 2 to 1
      • +
      • Adds fingerless gloves, eyepatch, prescription glasses, black shoes, brown shoes, white shoes, and ian's shirt to the loadout
      • +
      • moved hipster glasses from donator to general glasses
      • +
      • Adds in sandbags. Use them to deploy destructable barriers; miners start off with a few
      • +
      • Removes access based security barriers
      • +
      • Adds in security barrier grenade. When it goes off, it will deploy up to 3 barriers that will lock into place; should find 4 of these in the armory
      • +
      • can tear up bedsheet and gauze to get cloth--requires a sharp object
      • +
      • Fixes plasmamen atmos techs not getting their proper suit
      • +
      • Adds in a loom, craft one out of 10 wood
      • +
      • Adds in cotton and durathread cotton to botany to grow
      • +
      • Adds in a number of expanded items to create out of cloth, such as improvised gauze, beanies, and softcaps
      • +
      • Adds the ability to use personal crafting to make durathread jumpsuits, bandanas, armor, helmets, beanies and berets. Aside from the bandana, these all have minor armor on them
      • +
      • Adds a number of new items to personally craft, related to clothing: ability to make health, sec, diagnotic, and reagent sunglasses.
      • +
      • Can additionally craft cowboy boots, lizardskin cowboy boots, fannypacks, and a spooky ghost disguise
      • +
      • adds a whole range of beanies, find them in the clothing vendor or make them yourself
      • +
      • Updates the cowboy boots sprites
      • +
      • Unironically fixes about several thousand runtimes
      • +
      • Fixes jackets not keeping you warm
      • +
      • Chefs are now trained in the art of Close Quarters Cooking
      • +
      • Adds the Book of Babel as tendril loot
      • +
      • Adds Jacbo's Ladder as tendril loot
      • +
      • Fixes fungus, blood, and graffiti not showing up on a wall
      • +
      • Fixes the lavaland inquisitor and berserker hardsuits having incorrect armor and slowdown values
      • +
      • Fixes baseball bats throwing anchored things
      • +
      • Fixes blood drunk buff
      • +
      • Fixes using a crusher on a trophy to equip it causing you to drop the crusher
      • +
      • refactors lazarus capsules; no real behavioral change
      • +
      • Fixes being able to revive megafauna with strange reagent
      • +
      +

      Fox McCloud and FullOfSkittles updated:

      +
        +
      • Tweaks the gummy worm, gummy bear, jeallybean, toffee, and bacon sprites
      • +
      • Fixes telebacon not properly acting as...well, a bacon beacon
      • +
      +

      FreeStylaLT updated:

      +
        +
      • Added an Engine Picker, which uses new engine beacons.
      • +
      • Replaced the current two engine generators with one engine beacon.
      • +
      +

      Ionward updated:

      +
        +
      • Drask crewmembers now have properly fitting shoes.
      • +
      • Fixed some minor issues in Drasks uniforms
      • +
      • non-humans now have proper sprites for durathread goods
      • +
      +

      KasparoVy updated:

      +
        +
      • Adds sprites for all Vox & Armalis earwear.
      • +
      • Adds sprites for Armalis default backpack, nitrogen tank (old-style back & new-style belt) & all breath mask variations.
      • +
      • You can now species-fit in-hand icons: Use a single .dmi file and suffix the icon states with _l or _r.
      • +
      • Fixes an issue preventing Vox Armalis from being rendered with the proper in-hand icons for their massive noise cannons.
      • +
      • Fixes an issue preventing the species-fitting of earwear.
      • +
      • Fixes an issue preventing Vox Armalis from wearing the 'Vox' breath mask.
      • +
      • Picking up uniforms no longer renders a default grey jumpsuit on Vox.
      • +
      • Resolves an issue causing shining eyes to be rendered darker than intended.
      • +
      • Resolves an issue preventing appearance features (hair, eyes, etc.) from rendering on disembodied heads.
      • +
      • Resolves an issue preventing Admin-revived decapitated bodies from having appearance features or ears.
      • +
      • Non-shining eyes render the proper colour again.
      • +
      +

      Kurgis updated:

      +
        +
      • Beepsky now bumps around on its wheels when patrolling for crime.
      • +
      +

      Markolie updated:

      +
        +
      • A new outfit manager has been added for admins (under debug). It lets them save and load custom outfits on their computer and use these to equip players.
      • +
      • Upon transforming players into humans or reincarnating them through the player panel, admins will now directly be able to select their equipment.
      • +
      • The select equipment verb now works on observers: it'll create a human with the given equipment under the ghost.
      • +
      • A "Copy Outfit" button has been added to the View Variables dropdown, which lets admins instantly copy an outfit.
      • +
      • Outfits now support accessories and internal boxes.
      • +
      • The separate option to equip ERT members has been removed. It's been integrated into their regular outfits.
      • +
      • Water coming from sinks and certain water effects is now 10C instead of body temperature.
      • +
      +

      Shadow-Quill updated:

      +
        +
      • [Meta] Added buckshot and slugs to armoury.
      • +
      • [Meta] Added surgical tools, robotic first aid kits, and a photocopier to Robotics.
      • +
      • [Meta] R&D doors now has proper access requirements.
      • +
      • [Meta] Added RCS and telepad to cargo.
      • +
      • [Meta] Disposals sheet stacker and conveyor belts now works properly.
      • +
      • [Meta] One-way airlocks added in Medbay/Brig.
      • +
      • [Meta] Disposals sheet stacker disposals chute leads directly to the mailroom.
      • +
      • AIs not being able to restore their own power if in an area with an APC.
      • +
      • Fixed being able to talk in OOC under certain circumstances if it's disabled.
      • +
      • Lockers can no longer move around anchored mobs.
      • +
      +

      SteelSlayer updated:

      +
        +
      • You can no longer spam dismantle a SMES terminal and get 10 cable for every progress bar
      • +
      • The game will properly remove 10 cable from your stack after building a SMES terminal, instead of removing 0
      • +
      • A cable adding sound gets played when you add wires to create a terminal for a SMES
      • +
      • Rapid pipe dispensers can now place disposal sorting pipes
      • +
      • When changing the sort location of a disposal sorting pipe, the name of the pipe now also changes to the desired destination
      • +
      • Added a destination tagger to the atmosheric technician locker
      • +
      • Added atmospherics access to Engi-Vend's and Engineering checkpoint airlocks
      • +
      • Removed some random grey pixels from disposal sorting junction pipe sprites, and certain normal disposal junction pipe sprites
      • +
      • IV bags are able to transfer their contents to other containers by clicking on them with the bag
      • +
      • Adds a handheld defibrillator to the paramedic EVA closet
      • +
      • You can insert magazines into L6 SAWs again
      • +
      • Removed one of the high capacity tanks in hydroponics
      • +
      • Added a disk compartmentalizer to hydroponics
      • +
      • Delaying round start actually delays round start again
      • +
      +

      Terilia updated:

      +
        +
      • added headcrabs
      • +
      • adjusted the path's for headslugs. They are not called headcrab anymore
      • +
      +

      TheSardele updated:

      +
        +
      • Removes the ability of obese people and those with matter eater to swallow others.
      • +
      +

      Ty-Omaha updated:

      +
        +
      • Fixed a bug where hotwiring solar panels would allow for the station to remain powered in the Grid Check power failure event.
      • +
      +

      datlo updated:

      +
        +
      • Added ashstorm immunity to titanium and plastitanium golems.
      • +
      • Added lava immunity to plastitanium golems.
      • +
      • Bananium golems now slowly waddle around.
      • +
      • Uranium golems now properly irradiate nearby mobs that arent rad immune.
      • +
      • Tranquillite golems now properly get their miming powers.
      • +
      • Added the Clown and Winter biodomes as possible lavaland ruins.
      • +
      • Update a changeling error message to be clearer.
      • +
      +

      farie82 updated:

      +
        +
      • Items with NODROP that are dropped now lose the flag if they didn't get created with it
      • +
      • Adds tip text to the examine text of the ambulance trolley about how to attach it
      • +
      • Adds tip text to the nuke when trying to use the NAD before deploying it
      • +
      • Adds tip text to the fire axe cabinet about how to lock/unlock it
      • +
      • Adds tip text to airlocks if they have a note on them about how to remove the note
      • +
      • Can't put the NAD in the nuke now when it has the NODROP flag
      • +
      • Locking a fire axe cabinet is less weird now. No odd 5 seconds sleep
      • +
      • Can't put a nodrop fire axe in fire axe cabinets now. Duping them
      • +
      • Implants like the IPC charging work again. They won't get deleted after first use
      • +
      +

      variableundefined updated:

      +
        +
      • A proc's name got changed. That's it
      • +
      +

      23 August 2019

      AffectedArc07, Keekenox, Floyd/Qustinnus updated:

        diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 647b9735e00..d03050e2258 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -10819,3 +10819,266 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: adjusts the hierophant blast layer to make for it to always be below the effect. this should be the case already due to mouse_opacity, though for some unknown reason, it just doesn't work sometimes, so this should fix it. +2019-08-30: + AffectedArc07: + - bugfix: Fixes the changelog + Arkatos: + - imageadd: Added new icon for Charge spell + - imageadd: Added new icon for No Clothes spell + - imageadd: Added new icon for Wizard spellbook + - imageadd: Added new animations to 10 single-use spellbooks + - imageadd: Added new sprite for Bottle of Tickles + - rscadd: Added refunding functionality to the Bottle of Ooze akin to the other + summoning bottles. Click with the bottle in hand on a wizard spellbook to refund + its cost and limit slot. + - bugfix: Fixed an issue where Bottle of Tickles did not properly refund + - bugfix: Fixed an issue with alpha layering on Bottle of Ooze sprite + - tweak: Very slightly adjusted brightness of the Boo! ghost spell icon + - tweak: Wizard spellbook was completely reorganized, and new appropriate categories + were added, each category is sorted by price, and if price of the two or more + spells is the same, they are sorted alphabetically + - tweak: Polymorph can now turn a mob into Syndicate medical or saboteur modules + - tweak: Mobs made via polymorph into borgs are now unbounded free borgs + - tweak: Repulse spell cost decreased from 2 to 1 + - tweak: Lighting bolt spell cost decreased from 2 to 1 + - tweak: Slaughter/Laughter demons and Magical Morphs now always have their second + fluff objective considered as complete no matter the circumstances + - tweak: Laughter Demons very slightly buffed, they are still a bit weaker than + Slaughter Demons + - spellcheck: Improved descriptions and wording regarding Wizard spellbook and Wizard + spells + - rscadd: Traitor AI now uses action buttons for its malfunction abilities + AzuleUtama: + - rscadd: Adds false-bottomed briefcase from VG. + Couls: + - rscadd: Rechargers can now be crafted from science using one capacitor and a recharger + board tweak:Smaller machines like microwaves and cell chargers can now be placed + on tables(Fax machines included) tweak:can screwdriver open rechargers and then + apply a crowbar to deconstruct them + - tweak: Blood spread now depends on volume of the blood, requires more drips of + blood to create a pool + - rscadd: DUAL WIELDING + - rscadd: new chatsubsystem from TG! + - tweak: Update issue templates to latest version and clean up the current template + - rscadd: mining shuttle warning message and delay before launching + - bugfix: cardboard boxes are no longer sonic speed + - bugfix: shuttle timers now get set properly + EmanTheAlmighty: + - rscadd: Blobbernauts can now be controlled by players through a prompt which appears + when they are spawned by blobs. + - rscadd: Blobbernauts and blobs can now communicate with each other. + - rscadd: Blobbernauts now regenerate health overtime when standing on blob structures. + - rscadd: 'Blobbernauts will slowly lose health if they are not standing on blob + structures while not at full health. balance: Blobbernauts have been nerfed, + they now have less health, deal less damage and cannot break walls anymore. + balance: Blob''s "Produce Blobbernaut" ability has been made more expensive + to use, now costing 60 resources instead of 20.' + Emanthealmighty: + - tweak: The poll to play as a blobbernaut now lasts 10 seconds from 15. + - tweak: Blobbernauts no longer chase after people while players are being polled + to play as one. + Fox McCloud: + - tweak: Plasmamen dramatically overhauled. + - rscadd: Plasmamen can be cloned without burning to death in the clonepod + - rscdel: Plasmamen no longer start with spacesuits + - rscadd: Plasmamen start off with jumpsuits that seal to protect against oxygen. + This allows for you to customize their appearance more + - tweak: Plasmamen helmets now allow you to see a Plasmaman's actual face; should + be able to see their eye color and mouth color now + - tweak: Plasmamen take 50% extra brute and burn + - rscadd: Plasmamen are immune to radiation + - tweak: Plasmamen start out with a small tank that can fit on a belt or in a pocket; + it should be enough to last an entire shift + - rscadd: Plasmaman helmets now have built in welding goggles + - tweak: Plasmaman karma cost lowered from 100 to 45 + - tweak: Reworks Diona + - rscadd: Diona bleed (call it chlorophy; it's green) + - rscadd: Diona Breathe (plants do need to exchange gas after all) + - rscdel: Rad Immunity Removed + - tweak: Diona regenerate 1 OXY, 1 BURN, 1 BRUTE, and 1 TOX if they are in a bright + area; this effect does not kick in if they're in crit + - rscdel: Diona no longer have unbreakable bones (wood can crack ya know!) + - rscdel: Diona are no longer space proof + - tweak: Diona are more vulnerable to fire and heat damage + - tweak: Diona weakness to weedkiller dramatically nerfed + - rscadd: Diona now use Newcrit + - tweak: Diona are no longer slow + - rscadd: Diona can wear spacesuits + - bugfix: Fixes stun absorbing not working + - bugfix: Fixes parallax insane setting not doing anything + - tweak: Ores can be destroyed by devastating explosions + - tweak: silver, gold, and diamond pickaxes do a bit more damage and mine faster + than before + - tweak: drills slightly slower, but diamond drills slightly faster + - tweak: Spade is the same speed as a shovel + - tweak: Hivelord stabilizer will now make a hivelord core/legion soul stabilize + and be preserved, even if it was previously inert + - tweak: can use a hivelord core in your active hand to apply it to yourself + - rscadd: soulstone in the abandoned locked crates can now be used by anyone + - rscadd: Adds firelemon seeds to the abandoned locked crates as potential loot + - tweak: Hardsuits have an integrated helmet; you no longer have to attach helmets + - tweak: Toggling up/down helmets is now done with an action button + - rscdel: can no longer attach magboots to a hardsuit + - tweak: Hardsuit base melee armor increased from 10 to 30 + - tweak: Security and HoS hardsuit melee armor increased by 5 + - tweak: HoS hardsuit helmet armor matches his hardsuit + - tweak: CE's hardsuit helmet armor for rads increased by 10 (should be fully rad + proof now) + - tweak: Elite syndicate suits can't be acided + - bugfix: Fixes stuns and weakens related to reagents + - bugfix: Fixes the displayed cost of Plasmamen + - rscadd: 'Adds jetpack hardsuit upgrades: get yours at mining for 2000 points' + - rscdel: Removes mining carbon dioxide jetpack + - tweak: Can no longer use jetpacks in your suit storage slot + - rscadd: Chief Engineer's hardsuit, Syndicate Hardsuit (normal and elite), and + Shielded Syndicate Hardsuit all have built in jetpacks + - bugfix: Fixes random singularity releases from the grid check event + - tweak: loadout costs for most things cut from 2 to 1 + - rscadd: Adds fingerless gloves, eyepatch, prescription glasses, black shoes, brown + shoes, white shoes, and ian's shirt to the loadout + - tweak: moved hipster glasses from donator to general glasses + - rscadd: Adds in sandbags. Use them to deploy destructable barriers; miners start + off with a few + - rscdel: Removes access based security barriers + - rscadd: Adds in security barrier grenade. When it goes off, it will deploy up + to 3 barriers that will lock into place; should find 4 of these in the armory + - rscadd: can tear up bedsheet and gauze to get cloth--requires a sharp object + - bugfix: Fixes plasmamen atmos techs not getting their proper suit + - rscadd: Adds in a loom, craft one out of 10 wood + - rscadd: Adds in cotton and durathread cotton to botany to grow + - rscadd: Adds in a number of expanded items to create out of cloth, such as improvised + gauze, beanies, and softcaps + - rscadd: Adds the ability to use personal crafting to make durathread jumpsuits, + bandanas, armor, helmets, beanies and berets. Aside from the bandana, these + all have minor armor on them + - rscadd: 'Adds a number of new items to personally craft, related to clothing: + ability to make health, sec, diagnotic, and reagent sunglasses.' + - rscadd: Can additionally craft cowboy boots, lizardskin cowboy boots, fannypacks, + and a spooky ghost disguise + - rscadd: adds a whole range of beanies, find them in the clothing vendor or make + them yourself + - tweak: Updates the cowboy boots sprites + - bugfix: Unironically fixes about several thousand runtimes + - bugfix: Fixes jackets not keeping you warm + - rscadd: Chefs are now trained in the art of Close Quarters Cooking + - rscadd: Adds the Book of Babel as tendril loot + - rscadd: Adds Jacbo's Ladder as tendril loot + - bugfix: Fixes fungus, blood, and graffiti not showing up on a wall + - bugfix: Fixes the lavaland inquisitor and berserker hardsuits having incorrect + armor and slowdown values + - bugfix: Fixes baseball bats throwing anchored things + - bugfix: Fixes blood drunk buff + - bugfix: Fixes using a crusher on a trophy to equip it causing you to drop the + crusher + - tweak: refactors lazarus capsules; no real behavioral change + - bugfix: Fixes being able to revive megafauna with strange reagent + Fox McCloud and FullOfSkittles: + - tweak: Tweaks the gummy worm, gummy bear, jeallybean, toffee, and bacon sprites + - bugfix: Fixes telebacon not properly acting as...well, a bacon beacon + FreeStylaLT: + - rscadd: Added an Engine Picker, which uses new engine beacons. + - tweak: Replaced the current two engine generators with one engine beacon. + Ionward: + - imageadd: Drask crewmembers now have properly fitting shoes. + - imageadd: Fixed some minor issues in Drasks uniforms + - imageadd: non-humans now have proper sprites for durathread goods + KasparoVy: + - imageadd: Adds sprites for all Vox & Armalis earwear. + - imageadd: Adds sprites for Armalis default backpack, nitrogen tank (old-style + back & new-style belt) & all breath mask variations. + - rscadd: 'You can now species-fit in-hand icons: Use a single .dmi file and suffix + the icon states with _l or _r.' + - bugfix: Fixes an issue preventing Vox Armalis from being rendered with the proper + in-hand icons for their massive noise cannons. + - bugfix: Fixes an issue preventing the species-fitting of earwear. + - bugfix: Fixes an issue preventing Vox Armalis from wearing the 'Vox' breath mask. + - bugfix: Picking up uniforms no longer renders a default grey jumpsuit on Vox. + - bugfix: Resolves an issue causing shining eyes to be rendered darker than intended. + - bugfix: Resolves an issue preventing appearance features (hair, eyes, etc.) from + rendering on disembodied heads. + - bugfix: Resolves an issue preventing Admin-revived decapitated bodies from having + appearance features or ears. + - bugfix: Non-shining eyes render the proper colour again. + Kurgis: + - rscadd: Beepsky now bumps around on its wheels when patrolling for crime. + Markolie: + - rscadd: A new outfit manager has been added for admins (under debug). It lets + them save and load custom outfits on their computer and use these to equip players. + - rscadd: Upon transforming players into humans or reincarnating them through the + player panel, admins will now directly be able to select their equipment. + - rscadd: 'The select equipment verb now works on observers: it''ll create a human + with the given equipment under the ghost.' + - rscadd: A "Copy Outfit" button has been added to the View Variables dropdown, + which lets admins instantly copy an outfit. + - rscadd: Outfits now support accessories and internal boxes. + - rscdel: The separate option to equip ERT members has been removed. It's been integrated + into their regular outfits. + - tweak: Water coming from sinks and certain water effects is now 10C instead of + body temperature. + Shadow-Quill: + - rscadd: '[Meta] Added buckshot and slugs to armoury.' + - rscadd: '[Meta] Added surgical tools, robotic first aid kits, and a photocopier + to Robotics.' + - bugfix: '[Meta] R&D doors now has proper access requirements.' + - rscadd: '[Meta] Added RCS and telepad to cargo.' + - bugfix: '[Meta] Disposals sheet stacker and conveyor belts now works properly.' + - rscadd: '[Meta] One-way airlocks added in Medbay/Brig.' + - tweak: '[Meta] Disposals sheet stacker disposals chute leads directly to the mailroom.' + - bugfix: AIs not being able to restore their own power if in an area with an APC. + - bugfix: Fixed being able to talk in OOC under certain circumstances if it's disabled. + - bugfix: Lockers can no longer move around anchored mobs. + SteelSlayer: + - bugfix: You can no longer spam dismantle a SMES terminal and get 10 cable for + every progress bar + - bugfix: The game will properly remove 10 cable from your stack after building + a SMES terminal, instead of removing 0 + - rscadd: A cable adding sound gets played when you add wires to create a terminal + for a SMES + - rscadd: Rapid pipe dispensers can now place disposal sorting pipes + - tweak: When changing the sort location of a disposal sorting pipe, the name of + the pipe now also changes to the desired destination + - rscadd: Added a destination tagger to the atmosheric technician locker + - tweak: Added atmospherics access to Engi-Vend's and Engineering checkpoint airlocks + - tweak: Removed some random grey pixels from disposal sorting junction pipe sprites, + and certain normal disposal junction pipe sprites + - tweak: IV bags are able to transfer their contents to other containers by clicking + on them with the bag + - rscadd: Adds a handheld defibrillator to the paramedic EVA closet + - bugfix: You can insert magazines into L6 SAWs again + - rscdel: Removed one of the high capacity tanks in hydroponics + - rscadd: Added a disk compartmentalizer to hydroponics + - bugfix: Delaying round start actually delays round start again + Terilia: + - rscadd: added headcrabs + - tweak: adjusted the path's for headslugs. They are not called headcrab anymore + TheSardele: + - rscdel: Removes the ability of obese people and those with matter eater to swallow + others. + Ty-Omaha: + - bugfix: Fixed a bug where hotwiring solar panels would allow for the station to + remain powered in the Grid Check power failure event. + datlo: + - rscadd: Added ashstorm immunity to titanium and plastitanium golems. + - rscadd: Added lava immunity to plastitanium golems. + - rscadd: Bananium golems now slowly waddle around. + - bugfix: Uranium golems now properly irradiate nearby mobs that arent rad immune. + - bugfix: Tranquillite golems now properly get their miming powers. + - rscadd: Added the Clown and Winter biodomes as possible lavaland ruins. + - tweak: Update a changeling error message to be clearer. + farie82: + - bugfix: Items with NODROP that are dropped now lose the flag if they didn't get + created with it + - rscadd: Adds tip text to the examine text of the ambulance trolley about how to + attach it + - rscadd: Adds tip text to the nuke when trying to use the NAD before deploying + it + - rscadd: Adds tip text to the fire axe cabinet about how to lock/unlock it + - rscadd: Adds tip text to airlocks if they have a note on them about how to remove + the note + - bugfix: Can't put the NAD in the nuke now when it has the NODROP flag + - bugfix: Locking a fire axe cabinet is less weird now. No odd 5 seconds sleep + - bugfix: Can't put a nodrop fire axe in fire axe cabinets now. Duping them + - bugfix: Implants like the IPC charging work again. They won't get deleted after + first use + variableundefined: + - tweak: A proc's name got changed. That's it diff --git a/html/changelogs/AutoChangeLog-pr-11143.yml b/html/changelogs/AutoChangeLog-pr-11143.yml new file mode 100644 index 00000000000..ede2fe0cc82 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11143.yml @@ -0,0 +1,4 @@ +author: "farie82" +delete-after: True +changes: + - tweak: "Hoodies now work like they do in TG. Less abuse of NO DROP, more better" diff --git a/html/changelogs/AutoChangeLog-pr-11535.yml b/html/changelogs/AutoChangeLog-pr-11535.yml new file mode 100644 index 00000000000..8355c61fc5c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11535.yml @@ -0,0 +1,5 @@ +author: "Couls" +delete-after: True +changes: + - rscadd: "Romerol virus that requires two traitors to team up to purchase" + - rscadd: "zombies that have a slow but steady health regeneration and cannot be killed permanently outside of decapitations and removal of the tumor in the brain" diff --git a/html/changelogs/AutoChangeLog-pr-11712.yml b/html/changelogs/AutoChangeLog-pr-11712.yml deleted file mode 100644 index ed9937e57c6..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11712.yml +++ /dev/null @@ -1,9 +0,0 @@ -author: "Markolie" -delete-after: True -changes: - - rscadd: "A new outfit manager has been added for admins (under debug). It lets them save and load custom outfits on their computer and use these to equip players." - - rscadd: "Upon transforming players into humans or reincarnating them through the player panel, admins will now directly be able to select their equipment." - - rscadd: "The select equipment verb now works on observers: it'll create a human with the given equipment under the ghost." - - rscadd: "A \"Copy Outfit\" button has been added to the View Variables dropdown, which lets admins instantly copy an outfit." - - rscadd: "Outfits now support accessories and internal boxes." - - rscdel: "The separate option to equip ERT members has been removed. It's been integrated into their regular outfits." diff --git a/html/changelogs/AutoChangeLog-pr-11719.yml b/html/changelogs/AutoChangeLog-pr-11719.yml deleted file mode 100644 index 26164747593..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11719.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Terilia" -delete-after: True -changes: - - rscadd: "added headcrabs" - - tweak: "adjusted the path's for headslugs. They are not called headcrab anymore" diff --git a/html/changelogs/AutoChangeLog-pr-11772.yml b/html/changelogs/AutoChangeLog-pr-11772.yml deleted file mode 100644 index a59b8791f03..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11772.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Couls" -delete-after: True -changes: - - rscadd: "Rechargers can now be crafted from science using one capacitor and a recharger board -tweak:Smaller machines like microwaves and cell chargers can now be placed on tables(Fax machines included) -tweak:can screwdriver open rechargers and then apply a crowbar to deconstruct them" diff --git a/html/changelogs/AutoChangeLog-pr-11862.yml b/html/changelogs/AutoChangeLog-pr-11862.yml deleted file mode 100644 index ecd4aa0fa8b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11862.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ty-Omaha" -delete-after: True -changes: - - bugfix: "Fixed a bug where hotwiring solar panels would allow for the station to remain powered in the Grid Check power failure event." diff --git a/html/changelogs/AutoChangeLog-pr-11888.yml b/html/changelogs/AutoChangeLog-pr-11888.yml new file mode 100644 index 00000000000..62c7ea08710 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11888.yml @@ -0,0 +1,4 @@ +author: "kazboo" +delete-after: True +changes: + - rscadd: "added a nice metalic alarm sound for when the nuclear self-destruct is activated on the station." diff --git a/html/changelogs/AutoChangeLog-pr-11921.yml b/html/changelogs/AutoChangeLog-pr-11921.yml deleted file mode 100644 index d55a327c310..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11921.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Couls" -delete-after: True -changes: - - rscadd: "new chatsubsystem from TG!" diff --git a/html/changelogs/AutoChangeLog-pr-11936.yml b/html/changelogs/AutoChangeLog-pr-11936.yml deleted file mode 100644 index bec331efe04..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11936.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "farie82" -delete-after: True -changes: - - bugfix: "Items with NODROP that are dropped now lose the flag if they didn't get created with it" diff --git a/html/changelogs/AutoChangeLog-pr-11940.yml b/html/changelogs/AutoChangeLog-pr-11940.yml deleted file mode 100644 index 412460535f2..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11940.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Couls" -delete-after: True -changes: - - tweak: "Update issue templates to latest version and clean up the current template" diff --git a/html/changelogs/AutoChangeLog-pr-11941.yml b/html/changelogs/AutoChangeLog-pr-11941.yml deleted file mode 100644 index 5654ca5bdcf..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11941.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: "farie82" -delete-after: True -changes: - - rscadd: "Adds tip text to the examine text of the ambulance trolley about how to attach it" - - rscadd: "Adds tip text to the nuke when trying to use the NAD before deploying it" - - rscadd: "Adds tip text to the fire axe cabinet about how to lock/unlock it" - - rscadd: "Adds tip text to airlocks if they have a note on them about how to remove the note" - - bugfix: "Can't put the NAD in the nuke now when it has the NODROP flag" - - bugfix: "Locking a fire axe cabinet is less weird now. No odd 5 seconds sleep" - - bugfix: "Can't put a nodrop fire axe in fire axe cabinets now. Duping them" diff --git a/html/changelogs/AutoChangeLog-pr-11948.yml b/html/changelogs/AutoChangeLog-pr-11948.yml deleted file mode 100644 index a7048eee037..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11948.yml +++ /dev/null @@ -1,9 +0,0 @@ -author: "EmanTheAlmighty" -delete-after: True -changes: - - rscadd: "Blobbernauts can now be controlled by players through a prompt which appears when they are spawned by blobs." - - rscadd: "Blobbernauts and blobs can now communicate with each other." - - rscadd: "Blobbernauts now regenerate health overtime when standing on blob structures." - - rscadd: "Blobbernauts will slowly lose health if they are not standing on blob structures while not at full health. -balance: Blobbernauts have been nerfed, they now have less health, deal less damage and cannot break walls anymore. -balance: Blob's \"Produce Blobbernaut\" ability has been made more expensive to use, now costing 60 resources instead of 20." diff --git a/html/changelogs/AutoChangeLog-pr-11957.yml b/html/changelogs/AutoChangeLog-pr-11957.yml deleted file mode 100644 index 6e23f4bd87f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11957.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "FreeStylaLT" -delete-after: True -changes: - - rscadd: "Added an Engine Picker, which uses new engine beacons." - - tweak: "Replaced the current two engine generators with one engine beacon." diff --git a/html/changelogs/AutoChangeLog-pr-11962.yml b/html/changelogs/AutoChangeLog-pr-11962.yml new file mode 100644 index 00000000000..9da957d2be6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11962.yml @@ -0,0 +1,7 @@ +author: "variableundefined" +delete-after: True +changes: + - rscadd: "Multiple food now have their own tastes" + - rscadd: "Corgi and mice can now taste food" + - rscadd: "Hallucination causes you to taste strange things" + - rscadd: "Nutriments now carry over the tastes of food" diff --git a/html/changelogs/AutoChangeLog-pr-11978.yml b/html/changelogs/AutoChangeLog-pr-11978.yml deleted file mode 100644 index 6a3cce38167..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11978.yml +++ /dev/null @@ -1,9 +0,0 @@ -author: "KasparoVy" -delete-after: True -changes: - - imageadd: "Adds sprites for all Vox & Armalis earwear." - - imageadd: "Adds sprites for Armalis default backpack, nitrogen tank (old-style back & new-style belt) & all breath mask variations." - - rscadd: "You can now species-fit in-hand icons: Use a single .dmi file and suffix the icon states with _l or _r." - - bugfix: "Fixes an issue preventing Vox Armalis from being rendered with the proper in-hand icons for their massive noise cannons." - - bugfix: "Fixes an issue preventing the species-fitting of earwear." - - bugfix: "Fixes an issue preventing Vox Armalis from wearing the 'Vox' breath mask." diff --git a/html/changelogs/AutoChangeLog-pr-11987.yml b/html/changelogs/AutoChangeLog-pr-11987.yml deleted file mode 100644 index e7ed3c0b338..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11987.yml +++ /dev/null @@ -1,13 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - tweak: "Plasmamen dramatically overhauled." - - rscadd: "Plasmamen can be cloned without burning to death in the clonepod" - - rscdel: "Plasmamen no longer start with spacesuits" - - rscadd: "Plasmamen start off with jumpsuits that seal to protect against oxygen. This allows for you to customize their appearance more" - - tweak: "Plasmamen helmets now allow you to see a Plasmaman's actual face; should be able to see their eye color and mouth color now" - - tweak: "Plasmamen take 50% extra brute and burn" - - rscadd: "Plasmamen are immune to radiation" - - tweak: "Plasmamen start out with a small tank that can fit on a belt or in a pocket; it should be enough to last an entire shift" - - rscadd: "Plasmaman helmets now have built in welding goggles" - - tweak: "Plasmaman karma cost lowered from 100 to 45" diff --git a/html/changelogs/AutoChangeLog-pr-12029.yml b/html/changelogs/AutoChangeLog-pr-12029.yml deleted file mode 100644 index 3677a1afea3..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12029.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: "Shadow-Quill" -delete-after: True -changes: - - rscadd: "[Meta] Added buckshot and slugs to armoury." - - rscadd: "[Meta] Added surgical tools, robotic first aid kits, and a photocopier to Robotics." - - bugfix: "[Meta] R&D doors now has proper access requirements." - - rscadd: "[Meta] Added RCS and telepad to cargo." - - bugfix: "[Meta] Disposals sheet stacker and conveyor belts now works properly." - - rscadd: "[Meta] One-way airlocks added in Medbay/Brig." - - tweak: "[Meta] Disposals sheet stacker disposals chute leads directly to the mailroom." diff --git a/html/changelogs/AutoChangeLog-pr-12037.yml b/html/changelogs/AutoChangeLog-pr-12037.yml deleted file mode 100644 index 307b70d781f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12037.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Couls" -delete-after: True -changes: - - rscadd: "mining shuttle warning message and delay before launching" diff --git a/html/changelogs/AutoChangeLog-pr-12038.yml b/html/changelogs/AutoChangeLog-pr-12038.yml deleted file mode 100644 index f241cfc6c23..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12038.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Shadow-Quill" -delete-after: True -changes: - - bugfix: "AIs not being able to restore their own power if in an area with an APC." diff --git a/html/changelogs/AutoChangeLog-pr-12064.yml b/html/changelogs/AutoChangeLog-pr-12064.yml deleted file mode 100644 index 383526fbbb8..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12064.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Fox McCloud and FullOfSkittles" -delete-after: True -changes: - - tweak: "Tweaks the gummy worm, gummy bear, jeallybean, toffee, and bacon sprites" - - bugfix: "Fixes telebacon not properly acting as...well, a bacon beacon" diff --git a/html/changelogs/AutoChangeLog-pr-12065.yml b/html/changelogs/AutoChangeLog-pr-12065.yml deleted file mode 100644 index 865de5c6587..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12065.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - bugfix: "Fixes parallax insane setting not doing anything" diff --git a/html/changelogs/AutoChangeLog-pr-12066.yml b/html/changelogs/AutoChangeLog-pr-12066.yml deleted file mode 100644 index 71c585e6514..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12066.yml +++ /dev/null @@ -1,11 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - tweak: "Ores can be destroyed by devastating explosions" - - tweak: "silver, gold, and diamond pickaxes do a bit more damage and mine faster than before" - - tweak: "drills slightly slower, but diamond drills slightly faster" - - tweak: "Spade is the same speed as a shovel" - - tweak: "Hivelord stabilizer will now make a hivelord core/legion soul stabilize and be preserved, even if it was previously inert" - - tweak: "can use a hivelord core in your active hand to apply it to yourself" - - rscadd: "soulstone in the abandoned locked crates can now be used by anyone" - - rscadd: "Adds firelemon seeds to the abandoned locked crates as potential loot" diff --git a/html/changelogs/AutoChangeLog-pr-12073.yml b/html/changelogs/AutoChangeLog-pr-12073.yml deleted file mode 100644 index a44956c76c2..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12073.yml +++ /dev/null @@ -1,11 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - tweak: "Hardsuits have an integrated helmet; you no longer have to attach helmets" - - tweak: "Toggling up/down helmets is now done with an action button" - - rscdel: "can no longer attach magboots to a hardsuit" - - tweak: "Hardsuit base melee armor increased from 10 to 30" - - tweak: "Security and HoS hardsuit melee armor increased by 5" - - tweak: "HoS hardsuit helmet armor matches his hardsuit" - - tweak: "CE's hardsuit helmet armor for rads increased by 10 (should be fully rad proof now)" - - tweak: "Elite syndicate suits can't be acided" diff --git a/html/changelogs/AutoChangeLog-pr-12079.yml b/html/changelogs/AutoChangeLog-pr-12079.yml deleted file mode 100644 index 06e129f082d..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12079.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - bugfix: "Fixes stuns and weakens related to reagents" diff --git a/html/changelogs/AutoChangeLog-pr-12080.yml b/html/changelogs/AutoChangeLog-pr-12080.yml deleted file mode 100644 index 14c3e841fd6..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12080.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SteelSlayer" -delete-after: True -changes: - - bugfix: "You can insert magazines into L6 SAWs again" diff --git a/html/changelogs/AutoChangeLog-pr-12081.yml b/html/changelogs/AutoChangeLog-pr-12081.yml deleted file mode 100644 index 931893453db..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12081.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "farie82" -delete-after: True -changes: - - bugfix: "Implants like the IPC charging work again. They won't get deleted after first use" diff --git a/html/changelogs/AutoChangeLog-pr-12086.yml b/html/changelogs/AutoChangeLog-pr-12086.yml deleted file mode 100644 index 6158c7794bd..00000000000 --- a/html/changelogs/AutoChangeLog-pr-12086.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - bugfix: "Fixes the displayed cost of Plasmamen" diff --git a/html/changelogs/AutoChangeLog-pr-12118.yml b/html/changelogs/AutoChangeLog-pr-12118.yml new file mode 100644 index 00000000000..48a42b727a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12118.yml @@ -0,0 +1,4 @@ +author: "datlo" +delete-after: True +changes: + - rscadd: "Added the Banana Touch and Mime Malaise spells to the Wizard spellbook." diff --git a/html/changelogs/AutoChangeLog-pr-12138.yml b/html/changelogs/AutoChangeLog-pr-12138.yml new file mode 100644 index 00000000000..12471d789f5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12138.yml @@ -0,0 +1,5 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "refactored gloves of the North Star to be more adminbusy" + - rscadd: "Adds Gloves of Headpats to the pet vendor as a premium item" diff --git a/html/changelogs/AutoChangeLog-pr-12144.yml b/html/changelogs/AutoChangeLog-pr-12144.yml new file mode 100644 index 00000000000..6c29ebd1cd7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12144.yml @@ -0,0 +1,5 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Refactors the very core and soul of SS13 and enhances the code that powers it" + - tweak: "Bible fartgibbing is now a form of suicide" diff --git a/html/changelogs/AutoChangeLog-pr-12156.yml b/html/changelogs/AutoChangeLog-pr-12156.yml new file mode 100644 index 00000000000..d4c8f9b8c8d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12156.yml @@ -0,0 +1,5 @@ +author: "SteelSlayer" +delete-after: True +changes: + - tweak: "The AI and magistrate get bold text when the \"louder command members\" telecomms setting is on" + - tweak: "Command members will get the first letter of their radio message auto capitalized when the \"louder command members\" telecomms setting is on" diff --git a/html/changelogs/AutoChangeLog-pr-12157.yml b/html/changelogs/AutoChangeLog-pr-12157.yml new file mode 100644 index 00000000000..55c88e6286b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12157.yml @@ -0,0 +1,9 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes mice coming back to life" + - bugfix: "Fixes nurse spiders not wrapping things" + - bugfix: "Fixes spiders not spazzing out" + - tweak: "Simple mobs will now attack everything in the vicinity instead of just specific object types" + - tweak: "Gutlunches now eat internal organs" + - tweak: "ranged guardians don't rapid fire anymore, but have a lower cooldown on attacks" diff --git a/html/changelogs/AutoChangeLog-pr-12166.yml b/html/changelogs/AutoChangeLog-pr-12166.yml new file mode 100644 index 00000000000..c84e4248999 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12166.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes some turf underlays not working" diff --git a/html/changelogs/AutoChangeLog-pr-12167.yml b/html/changelogs/AutoChangeLog-pr-12167.yml new file mode 100644 index 00000000000..7966ce54c6d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12167.yml @@ -0,0 +1,4 @@ +author: "Couls" +delete-after: True +changes: + - bugfix: "blood no longer stacks on itself endlessly" diff --git a/html/changelogs/AutoChangeLog-pr-12168.yml b/html/changelogs/AutoChangeLog-pr-12168.yml new file mode 100644 index 00000000000..4724abff9d3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12168.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "adds in a wooden hatechet and rake to the ashwalker base; replaces the regular bucket with a wooden one" diff --git a/html/changelogs/AutoChangeLog-pr-12174.yml b/html/changelogs/AutoChangeLog-pr-12174.yml new file mode 100644 index 00000000000..9e126feee58 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12174.yml @@ -0,0 +1,4 @@ +author: "Shadow-Quill" +delete-after: True +changes: + - bugfix: "Fixed ATM withdrawals doubling." diff --git a/html/changelogs/AutoChangeLog-pr-12177.yml b/html/changelogs/AutoChangeLog-pr-12177.yml new file mode 100644 index 00000000000..3550a499237 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12177.yml @@ -0,0 +1,5 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes some blank tastes" + - bugfix: "Fixes not being able to brew fruit wine" diff --git a/html/changelogs/AutoChangeLog-pr-12179.yml b/html/changelogs/AutoChangeLog-pr-12179.yml new file mode 100644 index 00000000000..e44162285d6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12179.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes poor TG copy pasta code that caused hundreds of runtimes" diff --git a/html/changelogs/AutoChangeLog-pr-12187.yml b/html/changelogs/AutoChangeLog-pr-12187.yml new file mode 100644 index 00000000000..717a48b84d4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12187.yml @@ -0,0 +1,4 @@ +author: "Shadow-Quill" +delete-after: True +changes: + - bugfix: "Fixed Fore Port Solars' APC not charging." diff --git a/html/changelogs/AutoChangeLog-pr-12188.yml b/html/changelogs/AutoChangeLog-pr-12188.yml new file mode 100644 index 00000000000..2e83839e335 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12188.yml @@ -0,0 +1,4 @@ +author: "Shadow-Quill" +delete-after: True +changes: + - spellcheck: "Fixed a typo in admin gloves of rapidness." diff --git a/html/changelogs/AutoChangeLog-pr-12190.yml b/html/changelogs/AutoChangeLog-pr-12190.yml new file mode 100644 index 00000000000..9fab32462e0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12190.yml @@ -0,0 +1,4 @@ +author: "farie82" +delete-after: True +changes: + - tweak: "Admins now don't get spammed by hugs." diff --git a/html/changelogs/AutoChangeLog-pr-12063.yml b/html/changelogs/AutoChangeLog-pr-12191.yml similarity index 52% rename from html/changelogs/AutoChangeLog-pr-12063.yml rename to html/changelogs/AutoChangeLog-pr-12191.yml index 49e805f3dc5..0cf69141b88 100644 --- a/html/changelogs/AutoChangeLog-pr-12063.yml +++ b/html/changelogs/AutoChangeLog-pr-12191.yml @@ -1,4 +1,4 @@ author: "Fox McCloud" delete-after: True changes: - - bugfix: "Fixes stun absorbing not working" + - bugfix: "Reduces round-start lag" diff --git a/html/changelogs/AutoChangeLog-pr-12195.yml b/html/changelogs/AutoChangeLog-pr-12195.yml new file mode 100644 index 00000000000..591fde9ae4e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12195.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes certain PDA cartridges causing insane performance loss" diff --git a/html/changelogs/AutoChangeLog-pr-12198.yml b/html/changelogs/AutoChangeLog-pr-12198.yml new file mode 100644 index 00000000000..7715b025285 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12198.yml @@ -0,0 +1,5 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Personal crafting now has subcategories" + - tweak: "Finishing crafting an item puts it in your hands instead of on the floor" diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi index d3976bfff61..66795e14830 100644 Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ diff --git a/icons/mob/actions/actions_animal.dmi b/icons/mob/actions/actions_animal.dmi new file mode 100644 index 00000000000..e8f2d4ada83 Binary files /dev/null and b/icons/mob/actions/actions_animal.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index eacb4367d74..eb80e41a87f 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index 09b1f1f79ba..6f3e3f0ea2e 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index fcfef35c38b..e6f132a73a5 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 4bc39d8f80b..0fe42126ef0 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human_races/r_def_zombie.dmi b/icons/mob/human_races/r_def_zombie.dmi new file mode 100644 index 00000000000..007eb3f31f3 Binary files /dev/null and b/icons/mob/human_races/r_def_zombie.dmi differ diff --git a/icons/mob/human_races/r_zombie.dmi b/icons/mob/human_races/r_zombie.dmi new file mode 100644 index 00000000000..007eb3f31f3 Binary files /dev/null and b/icons/mob/human_races/r_zombie.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 03f57f19a92..10eef3b0337 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index b11f98e74ed..926e04b28bf 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 8027568e31b..99be80fb681 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 6209ce84949..78778b27d97 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/species/drask/helmet.dmi b/icons/mob/species/drask/helmet.dmi index f6ade8dca0d..72b614bd3f2 100644 Binary files a/icons/mob/species/drask/helmet.dmi and b/icons/mob/species/drask/helmet.dmi differ diff --git a/icons/mob/species/drask/mask.dmi b/icons/mob/species/drask/mask.dmi index 096faf15970..27fa4502ad7 100644 Binary files a/icons/mob/species/drask/mask.dmi and b/icons/mob/species/drask/mask.dmi differ diff --git a/icons/mob/species/drask/shoes.dmi b/icons/mob/species/drask/shoes.dmi new file mode 100644 index 00000000000..e51947fdd35 Binary files /dev/null and b/icons/mob/species/drask/shoes.dmi differ diff --git a/icons/mob/species/drask/uniform.dmi b/icons/mob/species/drask/uniform.dmi index ab315263ed9..bb350b0a3d8 100644 Binary files a/icons/mob/species/drask/uniform.dmi and b/icons/mob/species/drask/uniform.dmi differ diff --git a/icons/mob/species/grey/helmet.dmi b/icons/mob/species/grey/helmet.dmi index b81d6617e17..b8942e8fd7f 100644 Binary files a/icons/mob/species/grey/helmet.dmi and b/icons/mob/species/grey/helmet.dmi differ diff --git a/icons/mob/species/grey/mask.dmi b/icons/mob/species/grey/mask.dmi index 6d13b33c4bf..cbbd722ae69 100644 Binary files a/icons/mob/species/grey/mask.dmi and b/icons/mob/species/grey/mask.dmi differ diff --git a/icons/mob/species/grey/uniform.dmi b/icons/mob/species/grey/uniform.dmi index 068ec0be122..c1e21d5fa11 100644 Binary files a/icons/mob/species/grey/uniform.dmi and b/icons/mob/species/grey/uniform.dmi differ diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi index f73989fe9b0..d579a1c8384 100644 Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ diff --git a/icons/mob/species/unathi/mask.dmi b/icons/mob/species/unathi/mask.dmi index ba9be383855..535bec089f8 100644 Binary files a/icons/mob/species/unathi/mask.dmi and b/icons/mob/species/unathi/mask.dmi differ diff --git a/icons/mob/species/vox/helmet.dmi b/icons/mob/species/vox/helmet.dmi index a7186d611b6..74bd0762ff8 100644 Binary files a/icons/mob/species/vox/helmet.dmi and b/icons/mob/species/vox/helmet.dmi differ diff --git a/icons/mob/species/vox/mask.dmi b/icons/mob/species/vox/mask.dmi index 7023b2c3247..3e3a074c629 100644 Binary files a/icons/mob/species/vox/mask.dmi and b/icons/mob/species/vox/mask.dmi differ diff --git a/icons/mob/species/vox/shoes.dmi b/icons/mob/species/vox/shoes.dmi index 0a65993e240..99eac81e3a9 100644 Binary files a/icons/mob/species/vox/shoes.dmi and b/icons/mob/species/vox/shoes.dmi differ diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi index 0716073b931..a088466564f 100644 Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ diff --git a/icons/mob/species/vox/uniform.dmi b/icons/mob/species/vox/uniform.dmi index f4d3eda8896..6334c7c7555 100644 Binary files a/icons/mob/species/vox/uniform.dmi and b/icons/mob/species/vox/uniform.dmi differ diff --git a/icons/mob/species/vulpkanin/mask.dmi b/icons/mob/species/vulpkanin/mask.dmi index e50c3421fb0..c839ee98e2d 100644 Binary files a/icons/mob/species/vulpkanin/mask.dmi and b/icons/mob/species/vulpkanin/mask.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index abce25ab86f..1427b5aaf10 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 69f9e04895e..1d96c0b9676 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/aibots.dmi b/icons/obj/aibots.dmi index 9299c999342..a45ff1546da 100644 Binary files a/icons/obj/aibots.dmi and b/icons/obj/aibots.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 0f6aa860754..c0501f9bb36 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index a3d66d4d921..76be29d247d 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index b3a04ce73bf..5650a792d01 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index b008f3139cc..30cdfae56ef 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 8371295985f..95e515f9f86 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 78586b72dfc..2a9fca9c57e 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi index f9e4f6bfbfc..9ad33b40e9d 100644 Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ diff --git a/icons/obj/hydroponics/growing.dmi b/icons/obj/hydroponics/growing.dmi index 5b63f0553bd..d66cdc2c0dd 100644 Binary files a/icons/obj/hydroponics/growing.dmi and b/icons/obj/hydroponics/growing.dmi differ diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi index 53033eb8f48..3059eabe629 100644 Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi index a2415a71a8a..353d2811e67 100644 Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 23e49287922..463e135d35f 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index f28e5f83a33..edb8d7cb2c5 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/pipes/disposal.dmi b/icons/obj/pipes/disposal.dmi index f2dd62c9393..18d97345686 100644 Binary files a/icons/obj/pipes/disposal.dmi and b/icons/obj/pipes/disposal.dmi differ diff --git a/icons/obj/smooth_structures/sandbags.dmi b/icons/obj/smooth_structures/sandbags.dmi new file mode 100644 index 00000000000..8ac099555a8 Binary files /dev/null and b/icons/obj/smooth_structures/sandbags.dmi differ diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi index f30ecfe94d1..d1b6b267f8a 100644 Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index 07c8be38ed9..83a80d2f408 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ diff --git a/icons/turf/floors/ice_turfs.dmi b/icons/turf/floors/ice_turfs.dmi new file mode 100644 index 00000000000..2bee5887fe8 Binary files /dev/null and b/icons/turf/floors/ice_turfs.dmi differ diff --git a/nano/templates/personal_crafting.tmpl b/nano/templates/personal_crafting.tmpl index c209a8ad4bf..3158d7c3906 100644 --- a/nano/templates/personal_crafting.tmpl +++ b/nano/templates/personal_crafting.tmpl @@ -4,7 +4,7 @@
        -

        {{:data.category}}

        +

        {{:data.category}}{{if data.subcategory}} : {{:data.subcategory}}{{/if}}

        {{:helper.link(data.prev_cat, 'arrow-left', {'backwardCat': 1})}} @@ -16,6 +16,12 @@ {{/if}} {{:helper.link('Compact', data.display_compact ? 'check-square-o' : 'square-o', {'toggle_compact': 1})}}
        + {{if data.subcategory}} +
        + {{:helper.link(data.prev_subcat, 'arrow-left', {'backwardSubCat': 1})}} + {{:helper.link(data.next_subcat, 'arrow-right', {'forwardSubCat': 1})}} +
        + {{/if}} {{if data.display_compact}}
        diff --git a/paradise.dme b/paradise.dme index efb27499c47..b4090ec2c83 100644 --- a/paradise.dme +++ b/paradise.dme @@ -359,6 +359,7 @@ #include "code\datums\ruins\lavaland.dm" #include "code\datums\ruins\space.dm" #include "code\datums\spells\area_teleport.dm" +#include "code\datums\spells\banana_touch.dm" #include "code\datums\spells\bloodcrawl.dm" #include "code\datums\spells\chaplain.dm" #include "code\datums\spells\charge.dm" @@ -382,6 +383,7 @@ #include "code\datums\spells\lightning.dm" #include "code\datums\spells\magnet.dm" #include "code\datums\spells\mime.dm" +#include "code\datums\spells\mime_malaise.dm" #include "code\datums\spells\mind_transfer.dm" #include "code\datums\spells\night_vision.dm" #include "code\datums\spells\projectile.dm" @@ -1051,6 +1053,7 @@ #include "code\game\objects\structures\ladders.dm" #include "code\game\objects\structures\lamarr_cage.dm" #include "code\game\objects\structures\lattice.dm" +#include "code\game\objects\structures\loom.dm" #include "code\game\objects\structures\mineral_doors.dm" #include "code\game\objects\structures\mirror.dm" #include "code\game\objects\structures\misc.dm" @@ -1323,6 +1326,8 @@ #include "code\modules\client\preference\loadout\loadout_cosmetics.dm" #include "code\modules\client\preference\loadout\loadout_donor.dm" #include "code\modules\client\preference\loadout\loadout_general.dm" +#include "code\modules\client\preference\loadout\loadout_glasses.dm" +#include "code\modules\client\preference\loadout\loadout_gloves.dm" #include "code\modules\client\preference\loadout\loadout_hat.dm" #include "code\modules\client\preference\loadout\loadout_racial.dm" #include "code\modules\client\preference\loadout\loadout_shoes.dm" @@ -1337,6 +1342,7 @@ #include "code\modules\clothing\gloves\color.dm" #include "code\modules\clothing\gloves\miscellaneous.dm" #include "code\modules\clothing\gloves\rings.dm" +#include "code\modules\clothing\head\beanie.dm" #include "code\modules\clothing\head\collectable.dm" #include "code\modules\clothing\head\hardhat.dm" #include "code\modules\clothing\head\helmet.dm" @@ -1414,6 +1420,7 @@ #include "code\modules\crafting\craft.dm" #include "code\modules\crafting\guncrafting.dm" #include "code\modules\crafting\recipes.dm" +#include "code\modules\crafting\tailoring.dm" #include "code\modules\customitems\item_defines.dm" #include "code\modules\customitems\item_spawning.dm" #include "code\modules\detective_work\detective_work.dm" @@ -1584,6 +1591,7 @@ #include "code\modules\hydroponics\grown\citrus.dm" #include "code\modules\hydroponics\grown\cocoa_vanilla.dm" #include "code\modules\hydroponics\grown\corn.dm" +#include "code\modules\hydroponics\grown\cotton.dm" #include "code\modules\hydroponics\grown\eggplant.dm" #include "code\modules\hydroponics\grown\flowers.dm" #include "code\modules\hydroponics\grown\grass_carpet.dm" @@ -1729,6 +1737,7 @@ #include "code\modules\mob\living\say.dm" #include "code\modules\mob\living\stat_states.dm" #include "code\modules\mob\living\status_procs.dm" +#include "code\modules\mob\living\taste.dm" #include "code\modules\mob\living\update_status.dm" #include "code\modules\mob\living\carbon\_defines.dm" #include "code\modules\mob\living\carbon\carbon.dm" @@ -1820,6 +1829,7 @@ #include "code\modules\mob\living\carbon\human\species\vox.dm" #include "code\modules\mob\living\carbon\human\species\vulpkanin.dm" #include "code\modules\mob\living\carbon\human\species\wryn.dm" +#include "code\modules\mob\living\carbon\human\species\zombies.dm" #include "code\modules\mob\living\carbon\slime\death.dm" #include "code\modules\mob\living\carbon\slime\emote.dm" #include "code\modules\mob\living\carbon\slime\examine.dm" @@ -1894,6 +1904,7 @@ #include "code\modules\mob\living\simple_animal\animal_defense.dm" #include "code\modules\mob\living\simple_animal\constructs.dm" #include "code\modules\mob\living\simple_animal\corpse.dm" +#include "code\modules\mob\living\simple_animal\damage_procs.dm" #include "code\modules\mob\living\simple_animal\parrot.dm" #include "code\modules\mob\living\simple_animal\posessed_object.dm" #include "code\modules\mob\living\simple_animal\powers.dm" @@ -1955,6 +1966,7 @@ #include "code\modules\mob\living\simple_animal\hostile\netherworld.dm" #include "code\modules\mob\living\simple_animal\hostile\pirate.dm" #include "code\modules\mob\living\simple_animal\hostile\russian.dm" +#include "code\modules\mob\living\simple_animal\hostile\skeleton.dm" #include "code\modules\mob\living\simple_animal\hostile\spaceworms.dm" #include "code\modules\mob\living\simple_animal\hostile\statue.dm" #include "code\modules\mob\living\simple_animal\hostile\syndicate.dm" @@ -2335,6 +2347,7 @@ #include "code\modules\ruins\ruin_areas.dm" #include "code\modules\ruins\lavalandruin_code\animal_hospital.dm" #include "code\modules\ruins\lavalandruin_code\ash_walker_den.dm" +#include "code\modules\ruins\lavalandruin_code\clown_planet.dm" #include "code\modules\ruins\lavalandruin_code\dead_ratvar.dm" #include "code\modules\ruins\lavalandruin_code\fountain_hall.dm" #include "code\modules\ruins\lavalandruin_code\hermit.dm" @@ -2459,6 +2472,8 @@ #include "code\modules\vr\vr_controller.dm" #include "code\modules\vr\vr_goggles.dm" #include "code\modules\vr\vr_outfits.dm" +#include "code\modules\zombie\items.dm" +#include "code\modules\zombie\organs.dm" #include "goon\code\datums\browserOutput.dm" #include "interface\interface.dm" #include "interface\skin.dmf" diff --git a/sound/effects/deltaalarm.ogg b/sound/effects/deltaalarm.ogg new file mode 100644 index 00000000000..6eed302098e Binary files /dev/null and b/sound/effects/deltaalarm.ogg differ