museum away mission (#81208)
## About The Pull Request adds a new gateway map, the Nanotrasen Museum it is filled with """"Mannequins"""" and Common Core lore im not putting the preview here because you really should explore it yourself but if youre that curious i think the Checks tab in mapdiffbot would have it this gateway map contains no combat unless you count falling into chasms because you did not carry a light or going into the boarded room with no loot or any incentive with obvious signs that there is the sole enemy on the map in there the loot is the lore ok thanks also makes mines detonate if theyre detonated by a non-mob im pretty sure this couldnt have been intentional trams stop chasms and also the relevant items <details> <summary>on second thought if you want spoilers check this</summary>  </details> ## Why It's Good For The Game more gateway maps = good ## Changelog 🆑 add: nanotrasen museum gateway map /🆑 --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
@@ -141,5 +141,8 @@
|
||||
/// The next time at which this mob can call for reinforcements
|
||||
#define BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN "BB_basic_mob_reinforcements_cooldown"
|
||||
|
||||
/// the direction we started when executing stare at things
|
||||
#define BB_STARTING_DIRECTION "BB_startdir"
|
||||
|
||||
///Text we display when we befriend someone
|
||||
#define BB_FRIENDLY_MESSAGE "friendly_message"
|
||||
|
||||
@@ -601,6 +601,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_LAVA_STOPPED "lava_stopped"
|
||||
///Chasms will be safe to cross while they've this trait.
|
||||
#define TRAIT_CHASM_STOPPED "chasm_stopped"
|
||||
///Chasms will be safe to cross if there is something with this trait on it
|
||||
#define TRAIT_CHASM_STOPPER "chasm_stopper"
|
||||
///The effects of the immerse element will be halted while this trait is present.
|
||||
#define TRAIT_IMMERSE_STOPPED "immerse_stopped"
|
||||
/// The effects of hyperspace drift are blocked when the tile has this trait
|
||||
|
||||
@@ -65,6 +65,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_VOIDSTORM_IMMUNE" = TRAIT_VOIDSTORM_IMMUNE,
|
||||
"TRAIT_WAS_RENAMED" = TRAIT_WAS_RENAMED,
|
||||
"TRAIT_WEATHER_IMMUNE" = TRAIT_WEATHER_IMMUNE,
|
||||
"TRAIT_CHASM_STOPPER" = TRAIT_CHASM_STOPPER,
|
||||
),
|
||||
/datum/controller/subsystem/economy = list(
|
||||
"TRAIT_MARKET_CRASHING" = TRAIT_MARKET_CRASHING,
|
||||
|
||||
@@ -109,6 +109,9 @@
|
||||
return CHASM_NOT_DROPPING
|
||||
if(dropped_thing.throwing || (dropped_thing.movement_type & MOVETYPES_NOT_TOUCHING_GROUND))
|
||||
return CHASM_REGISTER_SIGNALS
|
||||
for(var/atom/thing_to_check as anything in parent)
|
||||
if(HAS_TRAIT(thing_to_check, TRAIT_CHASM_STOPPER))
|
||||
return CHASM_NOT_DROPPING
|
||||
|
||||
//Flies right over the chasm
|
||||
if(ismob(dropped_thing))
|
||||
|
||||
@@ -23,6 +23,18 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg','sound/ambience/ambiodd.ogg','sound/ambience/ambinice.ogg')
|
||||
|
||||
/area/awaymission/museum
|
||||
name = "Nanotrasen Museum"
|
||||
icon_state = "awaycontent28"
|
||||
sound_environment = SOUND_ENVIRONMENT_CONCERT_HALL
|
||||
|
||||
/area/awaymission/museum/mothroachvoid
|
||||
static_lighting = FALSE
|
||||
base_lighting_alpha = 200
|
||||
base_lighting_color = "#FFF4AA"
|
||||
sound_environment = SOUND_ENVIRONMENT_PLAIN
|
||||
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/ambiodd.ogg','sound/ambience/ambinice.ogg')
|
||||
|
||||
/area/awaymission/errorroom
|
||||
name = "Super Secret Room"
|
||||
static_lighting = FALSE
|
||||
|
||||
@@ -66,3 +66,12 @@
|
||||
/obj/machinery/door/poddoor/shutters/window/preopen
|
||||
icon_state = "open"
|
||||
density = FALSE
|
||||
|
||||
/obj/machinery/door/poddoor/shutters/window/indestructible
|
||||
name = "hardened windowed shutters"
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/machinery/door/poddoor/shutters/window/indestructible/preopen
|
||||
icon_state = "open"
|
||||
density = FALSE
|
||||
opacity = FALSE
|
||||
|
||||
@@ -545,6 +545,19 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32)
|
||||
|
||||
connected_display.receive_signal(status_signal)
|
||||
|
||||
/obj/machinery/status_display/random_message
|
||||
current_mode = SD_MESSAGE
|
||||
/// list to pick the first line from
|
||||
var/list/firstline_to_secondline = list()
|
||||
|
||||
/obj/machinery/status_display/random_message/Initialize(mapload, ndir, building)
|
||||
if(firstline_to_secondline?.len)
|
||||
message1 = pick(firstline_to_secondline)
|
||||
message2 = firstline_to_secondline[message1]
|
||||
return ..() // status displays call update appearance on init so i suppose we should set the messages before calling parent as to not call it twice
|
||||
|
||||
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/random_message, 32)
|
||||
|
||||
#undef MAX_STATIC_WIDTH
|
||||
#undef FONT_STYLE
|
||||
#undef SCROLL_RATE
|
||||
|
||||
@@ -486,6 +486,9 @@
|
||||
ignite()
|
||||
return ..()
|
||||
|
||||
/obj/effect/decal/cleanable/fuel_pool/hivis
|
||||
icon_state = "fuel_pool_hivis"
|
||||
|
||||
/obj/effect/decal/cleanable/rubble
|
||||
name = "rubble"
|
||||
desc = "A pile of rubble."
|
||||
|
||||
@@ -117,8 +117,7 @@
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
if(ismob(triggerer))
|
||||
mineEffect(triggerer)
|
||||
mineEffect(triggerer)
|
||||
triggered = TRUE
|
||||
SEND_SIGNAL(src, COMSIG_MINE_TRIGGERED, triggerer)
|
||||
qdel(src)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/effect/step_trigger/proc/on_entered(datum/source, H as mob|obj)
|
||||
SIGNAL_HANDLER
|
||||
if(!H)
|
||||
if(!H || H == src)
|
||||
return
|
||||
if(isobserver(H) && !affect_ghosts)
|
||||
return
|
||||
@@ -138,6 +138,26 @@
|
||||
if (T)
|
||||
A.forceMove(T)
|
||||
|
||||
/* Teleports atoms directly to an offset, no randomness, looping hallways! */
|
||||
|
||||
/obj/effect/step_trigger/teleporter/offset
|
||||
var/teleport_x_offset = 0
|
||||
var/teleport_y_offset = 0
|
||||
|
||||
/obj/effect/step_trigger/teleporter/offset/on_entered(datum/source, H as mob|obj, atom/old_loc)
|
||||
if(!old_loc?.Adjacent(loc)) // prevents looping, if we were teleported into this then the old loc is usually not adjacent
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/effect/step_trigger/teleporter/offset/Trigger(atom/movable/poor_soul)
|
||||
var/turf/destination = locate(x + teleport_x_offset, y + teleport_y_offset, z)
|
||||
if(!destination)
|
||||
return
|
||||
poor_soul.forceMove(destination)
|
||||
var/mob/living/living_soul = poor_soul
|
||||
if(istype(living_soul) && living_soul.client)
|
||||
living_soul.client.move_delay = 0
|
||||
|
||||
/* Fancy teleporter, creates sparks and smokes when used */
|
||||
|
||||
/obj/effect/step_trigger/teleport_fancy
|
||||
|
||||
@@ -403,3 +403,61 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/puzzle_keycardpad, 32)
|
||||
playsound(src, SFX_SPARKS, 100, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
do_sparks(3, cardinal_only = FALSE, source = src)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/puzzle_blockade/oneway
|
||||
name = "one-way gate"
|
||||
desc = "A wall of solid light, likely defending something important. Virtually indestructible."
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "oneway"
|
||||
base_icon_state = "oneway"
|
||||
light_color = COLOR_BIOLUMINESCENCE_BLUE
|
||||
light_range = 1
|
||||
density = FALSE
|
||||
|
||||
/obj/structure/puzzle_blockade/oneway/update_icon_state()
|
||||
icon_state = "[base_icon_state][density ? "" : "-off"]"
|
||||
return ..()
|
||||
|
||||
/obj/structure/puzzle_blockade/oneway/CanAllowThrough(atom/movable/mover, border_dir)
|
||||
return ..() && (REVERSE_DIR(border_dir) == dir || get_turf(mover) == get_turf(src))
|
||||
|
||||
/obj/structure/puzzle_blockade/oneway/CanAStarPass(border_dir, datum/can_pass_info/pass_info)
|
||||
return REVERSE_DIR(border_dir) == dir
|
||||
|
||||
/obj/structure/puzzle_blockade/oneway/try_signal(datum/source)
|
||||
density = FALSE
|
||||
update_appearance(UPDATE_ICON)
|
||||
|
||||
/obj/effect/puzzle_poddoor_open
|
||||
name = "puzzle-poddoor relay"
|
||||
desc = "activates poddoors if activated with a puzzle signal."
|
||||
icon = 'icons/effects/mapping_helpers.dmi'
|
||||
icon_state = ""
|
||||
anchored = TRUE
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
/// if we receive a puzzle signal with this we do our thing
|
||||
var/queue_id
|
||||
/// door id
|
||||
var/id
|
||||
|
||||
/obj/effect/puzzle_poddoor_open/Initialize(mapload)
|
||||
. = ..()
|
||||
if(isnull(id) || isnull(queue_id))
|
||||
log_mapping("[src] id:[id] has no id or door id and has been deleted")
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
SSqueuelinks.add_to_queue(src, queue_id)
|
||||
|
||||
/obj/effect/puzzle_poddoor_open/MatchedLinks(id, list/partners)
|
||||
for(var/partner in partners)
|
||||
RegisterSignal(partner, COMSIG_PUZZLE_COMPLETED, PROC_REF(try_signal))
|
||||
|
||||
/obj/effect/puzzle_poddoor_open/proc/try_signal(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
var/openclose
|
||||
for(var/obj/machinery/door/poddoor/door as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/door/poddoor))
|
||||
if(door.id != id)
|
||||
continue
|
||||
if(isnull(openclose))
|
||||
openclose = door.density
|
||||
INVOKE_ASYNC(door, openclose ? TYPE_PROC_REF(/obj/machinery/door/poddoor, open) : TYPE_PROC_REF(/obj/machinery/door/poddoor, close))
|
||||
|
||||
@@ -305,3 +305,12 @@
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
deconstructible = TRUE
|
||||
|
||||
/obj/structure/fluff/wallsign
|
||||
name = "direction sign"
|
||||
desc = "Now, where to go?"
|
||||
density = FALSE
|
||||
icon = 'icons/obj/fluff/general.dmi'
|
||||
icon_state = "wallsign"
|
||||
|
||||
MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fluff/wallsign, 32)
|
||||
|
||||
@@ -932,6 +932,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/reinforced/tinted/frosted/spaw
|
||||
icon_state = "clockwork_window-single"
|
||||
glass_type = /obj/item/stack/sheet/bronze
|
||||
|
||||
MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/bronze/spawner, 0)
|
||||
|
||||
/obj/structure/window/bronze/unanchored
|
||||
anchored = FALSE
|
||||
|
||||
|
||||
@@ -116,6 +116,16 @@ INITIALIZE_IMMEDIATE(/turf/closed/indestructible/splashscreen)
|
||||
smoothing_groups = SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS
|
||||
canSmoothWith = SMOOTH_GROUP_WALLS
|
||||
|
||||
/turf/closed/indestructible/reinforced/titanium
|
||||
name = "reinforced titanium imitation wall"
|
||||
desc = "A huge chunk of reinforced metal used to separate rooms. Naturally, to cut down on costs, this is just a really good paint job to resemble titanium. Effectively impervious to conventional methods of destruction."
|
||||
icon = 'icons/turf/walls/shuttle_wall.dmi'
|
||||
icon_state = "shuttle_wall-0"
|
||||
base_icon_state = "shuttle_wall"
|
||||
|
||||
/turf/closed/indestructible/reinforced/titanium/nodiagonal
|
||||
icon_state = "shuttle_wall-15"
|
||||
smoothing_flags = SMOOTH_BITMASK
|
||||
|
||||
/turf/closed/indestructible/riveted
|
||||
icon = 'icons/turf/walls/riveted.dmi'
|
||||
|
||||
@@ -119,3 +119,19 @@
|
||||
|
||||
/turf/open/chasm/true/apply_components(mapload)
|
||||
AddComponent(/datum/component/chasm, null, mapload) //Don't pass anything for below_turf.
|
||||
|
||||
/turf/open/chasm/true/no_smooth
|
||||
smoothing_flags = NONE
|
||||
|
||||
/turf/open/chasm/true/no_smooth/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
return FALSE
|
||||
|
||||
/turf/open/chasm/true/no_smooth/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data)
|
||||
return FALSE
|
||||
|
||||
/turf/open/chasm/true/no_smooth/attackby(obj/item/item, mob/user, params, area/area_restriction)
|
||||
if(istype(item, /obj/item/stack/rods))
|
||||
return
|
||||
else if(istype(item, /obj/item/stack/tile/iron))
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -118,3 +118,19 @@
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "floor"
|
||||
hidden = TRUE
|
||||
|
||||
/// only player mobs (has ckey) may pass, reverse for the opposite
|
||||
/obj/effect/playeronly_barrier
|
||||
name = "player-only barrier"
|
||||
desc = "You shall pass."
|
||||
icon = 'icons/effects/mapping_helpers.dmi'
|
||||
icon_state = "blocker"
|
||||
anchored = TRUE
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
var/reverse = FALSE //Block if has ckey
|
||||
|
||||
/obj/effect/playeronly_barrier/CanAllowThrough(mob/living/mover, border_dir)
|
||||
. = ..()
|
||||
if(!istype(mover))
|
||||
return
|
||||
return isnull(mover.ckey) == reverse
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/obj/machinery/computer/terminal/museum
|
||||
name = "exhibit info terminal"
|
||||
desc = "A relatively low-tech info board. Not as low-tech as an actual sign though. Appears to be quite old."
|
||||
upperinfo = "Nanotrasen Museum Exhibit Info"
|
||||
icon_state = "plaque"
|
||||
icon_screen = "plaque_screen"
|
||||
icon_keyboard = null
|
||||
|
||||
/obj/effect/replica_spawner //description and name are intact, better to make a new fluff object for stuff that is not actually ingame as an object
|
||||
name = "replica creator"
|
||||
desc = "This creates a fluff object that looks exactly like the input, but like obviously a replica. Do not for the love of god use with stuff that has Initialize side effects."
|
||||
icon = 'icons/hud/screen_gen.dmi'
|
||||
icon_state = "x2"
|
||||
invisibility = INVISIBILITY_ABSTRACT //nope, can't see this
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
opacity = FALSE
|
||||
var/replica_path = /obj/structure/fluff
|
||||
var/target_path
|
||||
var/obvious_replica = TRUE
|
||||
|
||||
/obj/effect/replica_spawner/Initialize(mapload)
|
||||
. = ..()
|
||||
if(isnull(target_path))
|
||||
return INITIALIZE_HINT_QDEL //no use to make a replica of null
|
||||
var/atom/appearance_object = new target_path
|
||||
var/atom/new_replica = new replica_path(loc)
|
||||
|
||||
new_replica.icon = appearance_object.icon
|
||||
new_replica.icon_state = appearance_object.icon_state
|
||||
new_replica.copy_overlays(appearance_object.appearance, cut_old = TRUE)
|
||||
new_replica.density = appearance_object.density //for like nondense showers and stuff
|
||||
|
||||
new_replica.name = "[appearance_object.name][obvious_replica ? " replica" : ""]"
|
||||
new_replica.desc = "[appearance_object.desc][obvious_replica ? " ..except this one is a replica.": ""]"
|
||||
qdel(appearance_object)
|
||||
qdel(src)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/structure/fluff/dnamod
|
||||
name = "DNA Modifier"
|
||||
desc = "DNA Manipulator replica. Essentially just a box of cool lights."
|
||||
icon = 'icons/obj/service/hydroponics/equipment.dmi'
|
||||
icon_state = "dnamod"
|
||||
density = TRUE
|
||||
|
||||
/obj/structure/fluff/preserved_borer
|
||||
name = "preserved borer exhibit"
|
||||
desc = "A preserved cortical borer. Probably been there long enough to not last long outside the exhibit."
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "preservedborer"
|
||||
density = TRUE
|
||||
|
||||
/obj/structure/fluff/balloon_nuke
|
||||
name = "nuclear balloon explosive"
|
||||
desc = "You probably shouldn't stick around to see if this is inflated."
|
||||
icon = /obj/machinery/nuclearbomb::icon
|
||||
icon_state = /obj/machinery/nuclearbomb::icon_state
|
||||
density = TRUE
|
||||
max_integrity = 5 //one tap
|
||||
|
||||
/obj/structure/fluff/balloon_nuke/atom_destruction()
|
||||
playsound(loc, 'sound/effects/cartoon_pop.ogg', 75, vary = TRUE)
|
||||
..()
|
||||
|
||||
/obj/structure/fluff/fake_camera
|
||||
name = /obj/machinery/camera::name
|
||||
desc = /obj/machinery/camera::desc
|
||||
icon = /obj/machinery/camera::icon
|
||||
icon_state = /obj/machinery/camera::icon_state
|
||||
|
||||
/obj/structure/fluff/fake_scrubber
|
||||
name = /obj/machinery/atmospherics/components/unary/vent_scrubber::name
|
||||
desc = /obj/machinery/atmospherics/components/unary/vent_scrubber::desc
|
||||
icon = /obj/machinery/atmospherics/components/unary/vent_scrubber::icon
|
||||
layer = /obj/machinery/atmospherics/components/unary/vent_scrubber::layer
|
||||
plane = FLOOR_PLANE
|
||||
icon_state = "scrub_on"
|
||||
|
||||
/obj/structure/fluff/fake_vent
|
||||
name = /obj/machinery/atmospherics/components/unary/vent_pump::name
|
||||
desc = /obj/machinery/atmospherics/components/unary/vent_pump::desc
|
||||
icon = /obj/machinery/atmospherics/components/unary/vent_pump::icon
|
||||
layer = /obj/machinery/atmospherics/components/unary/vent_scrubber::layer
|
||||
plane = FLOOR_PLANE
|
||||
icon_state = "vent_out"
|
||||
|
||||
/turf/open/mirage
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "mirage"
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
/// target turf x and y are offsets from our location instead of a direct coordinate
|
||||
var/offset = TRUE
|
||||
/// tile range that we show, 2 means that the target tile and two tiles ahead of it in our direction will show
|
||||
var/range
|
||||
var/target_turf_x = 0
|
||||
var/target_turf_y = 0
|
||||
/// if not specified, uses our Z
|
||||
var/target_turf_z
|
||||
|
||||
/turf/open/mirage/Initialize(mapload)
|
||||
. = ..()
|
||||
if(isnull(range))
|
||||
range = world.view
|
||||
var/used_z = target_turf_z || z //if target z is not defined, use ours
|
||||
var/turf/target = locate(offset ? target_turf_x + x : target_turf_x, offset ? target_turf_y + y : target_turf_y, used_z)
|
||||
AddElement(/datum/element/mirage_border, target, dir, range)
|
||||
|
||||
/obj/effect/mapping_helpers/ztrait_injector/museum
|
||||
traits_to_add = list(ZTRAIT_NOPARALLAX = TRUE, ZTRAIT_NOXRAY = TRUE, ZTRAIT_NOPHASE = TRUE, ZTRAIT_BASETURF = /turf/open/indestructible/plating, ZTRAIT_SECRET = TRUE)
|
||||
|
||||
/obj/effect/smooths_with_walls
|
||||
name = "effect that smooths with walls"
|
||||
desc = "to supplement /turf/open/mirage."
|
||||
icon = 'icons/hud/screen_gen.dmi'
|
||||
icon_state = "x2"
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
smoothing_flags = SMOOTH_BITMASK
|
||||
smoothing_groups = SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS
|
||||
|
||||
/obj/item/paper/fluff/museum/noend
|
||||
name = "scrambled note"
|
||||
default_raw_text = {"this place,
|
||||
<br>god whose idea was to build a museum in the void in the middle of god knows where there is no reason we should have done this
|
||||
<br>and those mannequins why do they stare back where the fuck did you get these from
|
||||
<br>how would we even get visitors here
|
||||
<br>sometimes i can catch them moving
|
||||
<br>
|
||||
<br>we should have never come here"}
|
||||
@@ -1395,3 +1395,32 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
|
||||
var/turf/our_turf = get_turf(src) // In case a locker ate us or something
|
||||
our_turf.AddElement(/datum/element/bombable_turf)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/// this helper buckles all mobs on the tile to the first buckleable object
|
||||
/obj/effect/mapping_helpers/mob_buckler
|
||||
name = "Buckle Mob"
|
||||
icon_state = "buckle"
|
||||
late = TRUE
|
||||
///whether we force a buckle
|
||||
var/force_buckle = FALSE
|
||||
|
||||
/obj/effect/mapping_helpers/mob_buckler/Initialize(mapload)
|
||||
. = ..()
|
||||
var/atom/movable/buckle_to
|
||||
var/list/mobs = list()
|
||||
for(var/atom/movable/possible_buckle as anything in loc)
|
||||
if(isnull(buckle_to) && possible_buckle.can_buckle)
|
||||
buckle_to = possible_buckle
|
||||
continue
|
||||
|
||||
if(isliving(possible_buckle))
|
||||
mobs += possible_buckle
|
||||
|
||||
if(isnull(buckle_to))
|
||||
log_mapping("[type] at [x] [y] [z] did not find anything to buckle to")
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
for(var/mob/living/mob as anything in mobs)
|
||||
buckle_to.buckle_mob(mob, force = force_buckle)
|
||||
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/mob/living/basic/statue/mannequin
|
||||
name = "mannequin"
|
||||
desc = "Oh, so this is a dress-up game now."
|
||||
icon = 'icons/mob/human/mannequin.dmi'
|
||||
icon_state = "mannequin_wood_male"
|
||||
icon_living = "mannequin_wood_male"
|
||||
icon_dead = "mannequin_wood_male"
|
||||
health = 300
|
||||
maxHealth = 300
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 30
|
||||
sentience_type = SENTIENCE_ARTIFICIAL
|
||||
ai_controller = /datum/ai_controller/basic_controller/stares_at_people
|
||||
/// the path to a fake item we will hold in our right hand
|
||||
var/obj/item/held_item
|
||||
/// the path to a fake hat we will wear
|
||||
var/obj/item/hat
|
||||
|
||||
/mob/living/basic/statue/mannequin/Initialize(mapload)
|
||||
. = ..()
|
||||
update_appearance()
|
||||
|
||||
/mob/living/basic/statue/mannequin/update_overlays()
|
||||
. = ..()
|
||||
if(held_item)
|
||||
. += mutable_appearance(initial(held_item.righthand_file), initial(held_item.inhand_icon_state))
|
||||
if(hat)
|
||||
. += mutable_appearance(initial(hat.worn_icon), initial(hat.worn_icon_state) || initial(hat.icon_state))
|
||||
|
||||
/datum/ai_controller/basic_controller/stares_at_people
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
BB_AGGRO_RANGE = 6,
|
||||
)
|
||||
|
||||
ai_movement = /datum/ai_movement/dumb
|
||||
idle_behavior = null
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/face_target_or_face_initial, // we be creepy and all
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/face_target_or_face_initial
|
||||
|
||||
/datum/ai_planning_subtree/face_target_or_face_initial/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
if(isnull(controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]))
|
||||
return
|
||||
var/mob/living/we = controller.pawn
|
||||
controller.blackboard[BB_STARTING_DIRECTION] = we.dir
|
||||
controller.queue_behavior(/datum/ai_behavior/face_target_or_face_initial, BB_BASIC_MOB_CURRENT_TARGET)
|
||||
|
||||
/datum/ai_behavior/face_target_or_face_initial
|
||||
|
||||
/datum/ai_behavior/face_target_or_face_initial/setup(datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
var/atom/movable/target = controller.blackboard[target_key]
|
||||
return ismovable(target) && isturf(target.loc) && ismob(controller.pawn)
|
||||
|
||||
/datum/ai_behavior/face_target_or_face_initial/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
var/atom/movable/target = controller.blackboard[target_key]
|
||||
var/mob/living/we = controller.pawn
|
||||
if(isnull(target) || get_dist(we, target) > 8)
|
||||
we.dir = controller.blackboard[BB_STARTING_DIRECTION]
|
||||
finish_action(controller, TRUE)
|
||||
else
|
||||
we.face_atom(target)
|
||||
|
||||
/mob/living/basic/statue/mannequin/suspicious
|
||||
name = "mannequin?"
|
||||
desc = "Their eyes follow you."
|
||||
health = 1500 //yeah uhh avoid these
|
||||
maxHealth = 1500
|
||||
ai_controller = /datum/ai_controller/basic_controller/suspicious_mannequin
|
||||
|
||||
/datum/ai_controller/basic_controller/suspicious_mannequin
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
BB_AGGRO_RANGE = 14,
|
||||
BB_EMOTE_KEY = "scream", //spooky
|
||||
)
|
||||
|
||||
ai_movement = /datum/ai_movement/jps //threat
|
||||
idle_behavior = null
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/run_emote,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
)
|
||||
@@ -73,3 +73,10 @@
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/random_speech/mothroach,
|
||||
)
|
||||
|
||||
/mob/living/basic/mothroach/bar
|
||||
name = "mothroach bartender"
|
||||
desc = "A mothroach serving drinks. Look at him go."
|
||||
icon_state = "barroach"
|
||||
icon_living = "barroach"
|
||||
icon_dead = "barroach_dead"
|
||||
|
||||
@@ -672,6 +672,11 @@
|
||||
dispatch_transport(destination_platform = push_destination)
|
||||
return push_destination
|
||||
|
||||
|
||||
/datum/transport_controller/linear/tram/slow //for some reason speed is set to initial() in the code but if i touched it it would probably break so
|
||||
speed_limiter = 3
|
||||
base_speed_limiter = 3
|
||||
|
||||
/**
|
||||
* The physical cabinet on the tram. Acts as the interface between players and the controller datum.
|
||||
*/
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
if(radial_travel)
|
||||
AddElement(/datum/element/contextual_screentip_bare_hands, lmb_text = "Send Transport")
|
||||
|
||||
ADD_TRAIT(src, TRAIT_CHASM_STOPPER, INNATE_TRAIT)
|
||||
set_movement_registrations()
|
||||
|
||||
//since transport_controller datums find all connected platforms when a transport structure first creates it and then
|
||||
@@ -936,3 +937,7 @@
|
||||
var/throw_target = get_edge_target_turf(src, throw_direction)
|
||||
var/datum/callback/land_slam = new(passenger, TYPE_PROC_REF(/mob/living/, tram_slam_land))
|
||||
passenger.throw_at(throw_target, 400, 4, force = MOVE_FORCE_OVERPOWERING, callback = land_slam)
|
||||
|
||||
/obj/structure/transport/linear/tram/slow
|
||||
transport_controller_type = /datum/transport_controller/linear/tram/slow
|
||||
speed_limiter = /datum/transport_controller/linear/tram/slow::speed_limiter
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
#Do NOT tick the maps during compile -- the game uses this list to decide which map to load. Ticking the maps will result in them ALL being loaded at once.
|
||||
#DO tick the associated code file for the away mission you are enabling. Otherwise, the map will be trying to reference objects which do not exist, which will cause runtime errors!
|
||||
|
||||
#_maps/RandomZLevels/blackmarketpackers.dmm
|
||||
#_maps/RandomZLevels/TheBeach.dmm
|
||||
#_maps/RandomZLevels/centcomAway.dmm
|
||||
#_maps/RandomZLevels/moonoutpost19.dmm
|
||||
#_maps/RandomZLevels/undergroundoutpost45.dmm
|
||||
#_maps/RandomZLevels/caves.dmm
|
||||
#_maps/RandomZLevels/snowdin.dmm
|
||||
#_maps/RandomZLevels/research.dmm
|
||||
#_maps/RandomZLevels/SnowCabin.dmm
|
||||
#_maps/RandomZLevels/museum.dmm
|
||||
|
||||
|
Before Width: | Height: | Size: 935 KiB After Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 205 KiB After Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 364 KiB After Width: | Height: | Size: 358 KiB |
@@ -4360,6 +4360,7 @@
|
||||
#include "code\modules\mapfluff\ruins\lavalandruin_code\watcher_grave.dm"
|
||||
#include "code\modules\mapfluff\ruins\objects_and_mobs\ash_walker_den.dm"
|
||||
#include "code\modules\mapfluff\ruins\objects_and_mobs\cursed_slot_machine.dm"
|
||||
#include "code\modules\mapfluff\ruins\objects_and_mobs\museum.dm"
|
||||
#include "code\modules\mapfluff\ruins\objects_and_mobs\necropolis_gate.dm"
|
||||
#include "code\modules\mapfluff\ruins\objects_and_mobs\sin_ruins.dm"
|
||||
#include "code\modules\mapfluff\ruins\spaceruin_code\allamericandiner.dm"
|
||||
@@ -4763,6 +4764,7 @@
|
||||
#include "code\modules\mob\living\basic\space_fauna\spider\spiderlings\spiderling_subtypes.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\spider\young_spider\young_spider.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\spider\young_spider\young_spider_subtypes.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\statue\mannequin.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\statue\statue.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\wumborian_fugu\fugu_gland.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\wumborian_fugu\inflation.dm"
|
||||
|
||||