Skip to content

Commit

Permalink
[PORT] Shuttle events! (#2473)
Browse files Browse the repository at this point in the history
* Shuttle events (#76008)

https://github.com/tgstation/tgstation/assets/7501474/a2d83ce8-eba1-42d9-a1f8-9d73f7c40b21

Adds shuttle events! Stuff can now start to happen outside the shuttle,
either benign or spicy (but usually just fun to watch)!

The shuttle escape sequence is an important part of the game, uniting
about every player surviving player. Recently, #71906 has made the
escape sequence more forgiving as well as more interesting by
conditionally doubling the playing field. The area outside the shuttle
is still mostly empty though, except for the few people being spaced,
daredevils and the occasional epic space fight.

This PR adds adds some space events to spice up the outside of the
shuttle! This both gives people something too look at, making the escape
sequence feel less static and more lively, as well as give people a
reason to go outside and get the full experience of ~being decapitated
by a meteor~ swimming with the fishes!

<details>
  <summary>Shuttle Events</summary>

**Friendly carp swarm**
Spawns a group of carp that flies past the shuttle, completely friendly
unless provoked.

**Friendly meteors**
Spawns a lot of strong meteors, but they all miss the shuttle.
Completely safe as long as you don't go EVA

**Maintenance debris**
Picks random stuff from the maintenance spawn pool and throws it at the
shuttle. Completely benign, unless you get hit in the head by a toolbox.
Could get you some cool stuff though!

**Dust storm**
Spawns a bunch of dust meteors. Has a rare chance to hit the shuttle,
doing minimal damage but can damage windows and might need inflight
maintenance

**Alien queen**
One in every 250 escapes. Spawns a player controlled alien queen and a
ripley mech. RIP AND TEAR!! Really not that dangerous when you realize
the entire crew is on the shuttle and the queen is fat as fuck, but can
still be fun to throw people around a bit before being torn to shreds.

**ANGRY CARP**
Once in every 500 escapes. Spawns 12 normal carp and 3 big carps, who
may just decide to go through the shuttle or try and bust through the
window if you look at them wrong. Somewhat dangerous, you could stay
away from the windows and try to hide, or more likely shoot at them and
weld the windows

**Fake TTV**
Lol

**Italian Storm**
Once in every 2000 rounds. Throws pasta, pizza and meatballs at the
shuttle. Definitely not me going off the rails with a testing event

**Player controlled carp trio**
Once in every 100 escapes. Spawns three player controlled carp to harass
the shuttle. May rarely be a magicarp, megacarp or chaos carp. I can't
honestly see them do anything other than be annoying for 3 seconds and
die

There are some other admin only ones: a group of passive carps going
directly through the shuttle and just being little shits, and a magic
carp swarm
</details>

Events are selected seperately, there isn't a crazy weighting system,
each just has a chance to run, and multiple could run at once. They also
don't immediately trigger, so people can get settled a bit, and to make
sure just waiting out the more dangerous ones is still a valid strategy.

:cl:
add: Adds shuttle events! If shuttle escapes weren't exciting before
(doubtful), they definitely are now! I'm joking it's mostly an
atmosphere thing.
admin: Adds an admin panel to interact with shuttle events, under the
Events tab: Change Shuttle Events
fix: Objects spawned in hyperspace will properly catch hyperspace drift
/:cl:

There's a few things I'd like to do later (another PR) (honestly anyone
can do them because I suck at follow-ups), because this is too big as
is:
- Hijack triggered shuttle events
- More events (got a lot of cool suggestions, but I'm putting most of
them on hold)
- Maybe stration announcements if some more dangerous ones get added
- Structures appearing next to the escape shuttle???

---------

Co-authored-by: MrMelbert <[email protected]>

* Fix anti-breach shields being dragged away (#76859)

* [no gbp] Fixes runtimes in shuttle event and shuttle cling (#77343)

Fixes no-candidate runtime from pick() on an empty list
Fixes spawning null movables if run out of mobs to spawn
Fixes shuttle cling qdeling on Initialize due to lattices not counting
as hyperspace

:cl:
runtime: Fixes runtimes in shuttle event and shuttle cling code
/:cl:

---------

Co-authored-by: Jacquerel <[email protected]>

* Fixes triple carp shuttle event failing (#76860)

* Add admin blackhole(s) shuttle event (#77188)

## About The Pull Request
This adds a new **Black Hole** admin shuttle event while the escape
shuttle is in transit. The regular version spawns a small 1x1
singularity that falls through the ship. There is also a special
adminbus Kobayashi Maru version that spawns multiple black holes
rapidly.

## Why It's Good For The Game

![dreamseeker_MxqHmKXXQ8](https://github.com/tgstation/tgstation/assets/5195984/e169669a-fb71-48c5-8314-df82852eef3b)

Tell me this doesn't look fun?

## Changelog
:cl:
add: Add admin blackhole shuttle event with a normal version and
suicidal version.
fix: Fix several shuttle event runtimes
/:cl:

---------

Co-authored-by: Time-Green <[email protected]>

* Shuttle event "Turbulence" (#80358)

## About The Pull Request

Adds a new shuttle event: turbulence.
The escape shuttle is experiencing subspace turbulence, effectively
causing the takeoff/landing buckle check to repeat a couple of times
during the duration of the flight.
Players will get a two second warning when the screen starts shaking,
after which if they are not buckled (or... outside of the shuttle I
guess) they will fall over for a few seconds.

The presence of turbulence in the shuttle's path will be announced
shortly after takeoff, so strap yourself in.

## Why It's Good For The Game

I think it adds a bit of flavour and influences what is going on in the
shuttle (falling over at the wrong moment can turn a scrum over bridge
access on its head) without being quite as disruptive as "there's 13
carp in here now".

## Changelog

:cl:
add: Adds a new shuttle event, where space shuttles can experience minor
turbulance. Keep your belt on while the appropriate cabin light is lit.
/:cl:

Co-authored-by: John Willard <[email protected]>

* fix duplicate definition

---------

Co-authored-by: Time-Green <[email protected]>
Co-authored-by: MrMelbert <[email protected]>
Co-authored-by: Time-Green <[email protected]>
Co-authored-by: Jacquerel <[email protected]>
Co-authored-by: Tim <[email protected]>
Co-authored-by: John Willard <[email protected]>
  • Loading branch information
7 people authored Jul 5, 2024
1 parent caeca3c commit aa5c846
Show file tree
Hide file tree
Showing 27 changed files with 671 additions and 58 deletions.
10 changes: 10 additions & 0 deletions code/__DEFINES/shuttles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,13 @@
#define SHUTTLE_UNLOCK_BUBBLEGUM "bubblegum"
#define SHUTTLE_UNLOCK_MEDISIM "holodeck"
#define SHUTTLE_UNLOCK_NARNAR "narnar"

//Shuttle Events

///Self destruct if this is returned in process
#define SHUTTLE_EVENT_CLEAR 2

///spawned stuff should float by the window and not hit the shuttle
#define SHUTTLE_EVENT_MISS_SHUTTLE 1 << 0
///spawned stuff should hit the shuttle
#define SHUTTLE_EVENT_HIT_SHUTTLE 1 << 1
2 changes: 2 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,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"
/// The effects of hyperspace drift are blocked when the tile has this trait
#define TRAIT_HYPERSPACE_STOPPED "hyperspace_stopped"
///Turf slowdown will be ignored when this trait is added to a turf.
#define TRAIT_TURF_IGNORE_SLOWDOWN "turf_ignore_slowdown"
///Mobs won't slip on a wet turf while it has this trait
Expand Down
4 changes: 2 additions & 2 deletions code/controllers/subsystem/shuttle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ SUBSYSTEM_DEF(shuttle)
if(!thing)
mobile_docking_ports.Remove(thing)
continue
var/obj/docking_port/mobile/P = thing
P.check()
var/obj/docking_port/mobile/port = thing
port.check()
for(var/thing in transit_docking_ports)
var/obj/docking_port/stationary/transit/T = thing
if(!T.owner)
Expand Down
27 changes: 24 additions & 3 deletions code/datums/components/shuttle_cling.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,25 @@
ADD_TRAIT(parent, TRAIT_HYPERSPACED, src)

RegisterSignals(parent, list(COMSIG_MOVABLE_MOVED, COMSIG_MOVABLE_UNBUCKLE, COMSIG_ATOM_NO_LONGER_PULLED), PROC_REF(update_state))
RegisterSignal(parent, SIGNAL_REMOVETRAIT(TRAIT_FREE_HYPERSPACE_MOVEMENT), PROC_REF(initialize_loop))
RegisterSignal(parent, SIGNAL_ADDTRAIT(TRAIT_FREE_HYPERSPACE_MOVEMENT), PROC_REF(clear_loop))

//Items have this cool thing where they're first put on the floor if you grab them from storage, and then into your hand, which isn't caught by movement signals that well
if(isitem(parent))
RegisterSignal(parent, COMSIG_ITEM_PICKUP, PROC_REF(do_remove))

hyperloop = SSmove_manager.move(moving = parent, direction = direction, delay = not_clinging_move_delay, subsystem = SShyperspace_drift, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_NO_DIR_UPDATE|MOVEMENT_LOOP_DRAGGING)
if(!HAS_TRAIT(parent, TRAIT_FREE_HYPERSPACE_MOVEMENT))
initialize_loop()

update_state(parent) //otherwise we'll get moved 1 tile before we can correct ourselves, which isnt super bad but just looks jank

/datum/component/shuttle_cling/proc/initialize_loop()
hyperloop = SSmove_manager.move(moving = parent, direction = direction, delay = not_clinging_move_delay, subsystem = SShyperspace_drift, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_NO_DIR_UPDATE|MOVEMENT_LOOP_OUTSIDE_CONTROL)
update_state()

/datum/component/shuttle_cling/proc/clear_loop()
QDEL_NULL(hyperloop)

///Check if we're in hyperspace and our state in hyperspace
/datum/component/shuttle_cling/proc/update_state()
SIGNAL_HANDLER
Expand All @@ -55,6 +65,9 @@
qdel(src)
return

if(!hyperloop)
return

var/should_loop = FALSE

switch(is_holding_on(parent))
Expand All @@ -72,6 +85,10 @@
if(ALL_GOOD)
should_loop = FALSE

// the hyperloop can get reset to null from the above procs
if(!hyperloop)
return

//Do pause/unpause/nothing for the hyperloop
if(should_loop && hyperloop.paused)
hyperloop.resume_loop()
Expand All @@ -80,12 +97,16 @@

///Check if we're "holding on" to the shuttle
/datum/component/shuttle_cling/proc/is_holding_on(atom/movable/movee)
if(movee.pulledby || !isturf(movee.loc))
if(movee.pulledby || !isturf(movee.loc) || HAS_TRAIT(movee, TRAIT_FREE_HYPERSPACE_MOVEMENT))
return ALL_GOOD

if(!isliving(movee))
if(HAS_TRAIT(movee, TRAIT_FORCED_GRAVITY)) // nothing can block the singularity
return SUPER_NOT_HOLDING_ON

if(is_tile_solid(get_step(movee, direction))) //something is blocking us so do the cool drift
return CLINGING

return SUPER_NOT_HOLDING_ON

var/mob/living/living = movee
Expand All @@ -108,7 +129,7 @@

///Are we on a hyperspace tile? There's some special bullshit with lattices so we just wrap this check
/datum/component/shuttle_cling/proc/is_on_hyperspace(atom/movable/clinger)
if(istype(clinger.loc, hyperspace_type) && !(locate(/obj/structure/lattice) in clinger.loc))
if(istype(clinger.loc, hyperspace_type) && !HAS_TRAIT(clinger.loc, TRAIT_HYPERSPACE_STOPPED))
return TRUE
return FALSE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
icon_file = 'icons/mob/simple/carp.dmi'
json_config = 'code/datums/greyscale/json_configs/carp.json'

/datum/greyscale_config/carp_friend
name = "Friend Carp"
icon_file = 'icons/mob/simple/carp.dmi'
json_config = 'code/datums/greyscale/json_configs/carp_friend.json'

/datum/greyscale_config/carp_magic
name = "Magicarp"
icon_file = 'icons/mob/simple/carp.dmi'
Expand Down
23 changes: 23 additions & 0 deletions code/datums/greyscale/json_configs/carp_friend.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"base_friend": [
{
"type": "icon_state",
"icon_state": "base_friend",
"blend_mode": "overlay",
"color_ids": [ 1 ]
},
{
"type": "icon_state",
"icon_state": "base_friend_mouth",
"blend_mode": "overlay"
}
],
"base_friend_dead": [
{
"type": "icon_state",
"icon_state": "base_friend_dead",
"blend_mode": "overlay",
"color_ids": [ 1 ]
}
]
}
8 changes: 8 additions & 0 deletions code/game/objects/items/devices/transfer_valve.dm
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,11 @@
*/
/obj/item/transfer_valve/proc/ready()
return tank_one && tank_two

/obj/item/transfer_valve/fake/Initialize(mapload)
. = ..()

tank_one = new /obj/item/tank/internals/plasma (src)
tank_two = new /obj/item/tank/internals/oxygen (src)

update_appearance()
7 changes: 3 additions & 4 deletions code/game/objects/structures/lattice.dm
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@
canSmoothWith = SMOOTH_GROUP_LATTICE + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_OPEN_FLOOR
var/number_of_mats = 1
var/build_material = /obj/item/stack/rods
var/list/give_turf_traits = list(TRAIT_CHASM_STOPPED)
var/list/give_turf_traits = list(TRAIT_CHASM_STOPPED, TRAIT_HYPERSPACE_STOPPED)

/obj/structure/lattice/Initialize(mapload)
. = ..()
if(length(give_turf_traits))
give_turf_traits = string_list(give_turf_traits)
AddElement(/datum/element/give_turf_traits, give_turf_traits)


/datum/armor/structure_lattice
melee = 50
fire = 80
Expand Down Expand Up @@ -100,7 +99,7 @@
smoothing_groups = SMOOTH_GROUP_CATWALK + SMOOTH_GROUP_LATTICE + SMOOTH_GROUP_OPEN_FLOOR
canSmoothWith = SMOOTH_GROUP_CATWALK
obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN | BLOCK_Z_IN_UP
give_turf_traits = list(TRAIT_TURF_IGNORE_SLOWDOWN, TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED)
give_turf_traits = list(TRAIT_TURF_IGNORE_SLOWDOWN, TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED, TRAIT_HYPERSPACE_STOPPED)

/obj/structure/lattice/catwalk/Initialize(mapload)
. = ..()
Expand Down Expand Up @@ -155,7 +154,7 @@
canSmoothWith = SMOOTH_GROUP_LATTICE
obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN | BLOCK_Z_IN_UP
resistance_flags = FIRE_PROOF | LAVA_PROOF
give_turf_traits = list(TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED)
give_turf_traits = list(TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED, TRAIT_HYPERSPACE_STOPPED)

/obj/structure/lattice/lava/deconstruction_hints(mob/user)
return span_notice("The rods look like they could be <b>cut</b>, but the <i>heat treatment will shatter off</i>. There's space for a <i>tile</i>.")
Expand Down
23 changes: 18 additions & 5 deletions code/game/turfs/open/space/transit.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
. = ..()
update_appearance()
RegisterSignal(src, COMSIG_TURF_RESERVATION_RELEASED, PROC_REF(launch_contents))
RegisterSignal(src, COMSIG_ATOM_ENTERED, PROC_REF(initialize_drifting))
RegisterSignal(src, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, PROC_REF(initialize_drifting_but_from_initialize))

/turf/open/space/transit/Destroy()
//Signals are NOT removed from turfs upon replacement, and we get replaced ALOT, so unregister our signal
UnregisterSignal(src, COMSIG_TURF_RESERVATION_RELEASED)
UnregisterSignal(src, list(COMSIG_TURF_RESERVATION_RELEASED, COMSIG_ATOM_ENTERED, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON))

return ..()

/turf/open/space/transit/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
Expand All @@ -30,11 +33,17 @@
icon_state = "speedspace_ns_[get_transit_state(src)]"
return ..()

/turf/open/space/transit/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
. = ..()
/turf/open/space/transit/proc/initialize_drifting(atom/entered, atom/movable/enterer)
SIGNAL_HANDLER

if(!HAS_TRAIT(arrived, TRAIT_HYPERSPACED) && !HAS_TRAIT(arrived, TRAIT_FREE_HYPERSPACE_MOVEMENT))
arrived.AddComponent(/datum/component/shuttle_cling, turn(dir, 180), old_loc)
if(enterer && !HAS_TRAIT(enterer, TRAIT_HYPERSPACED) && !HAS_TRAIT(src, TRAIT_HYPERSPACE_STOPPED))
enterer.AddComponent(/datum/component/shuttle_cling, turn(dir, 180))

/turf/open/space/transit/proc/initialize_drifting_but_from_initialize(atom/movable/location, atom/movable/enterer, mapload)
SIGNAL_HANDLER

if(!mapload && !enterer.anchored)
INVOKE_ASYNC(src, PROC_REF(initialize_drifting), src, enterer)

/turf/open/space/transit/Exited(atom/movable/gone, direction)
. = ..()
Expand All @@ -52,6 +61,10 @@

///Dump a movable in a random valid spacetile
/proc/dump_in_space(atom/movable/dumpee)
if(HAS_TRAIT(dumpee, TRAIT_DEL_ON_SPACE_DUMP))
qdel(dumpee)
return

var/max = world.maxx-TRANSITIONEDGE
var/min = 1+TRANSITIONEDGE

Expand Down
1 change: 1 addition & 0 deletions code/modules/admin/admin_verbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
/datum/admins/proc/open_artifactpanel,
/datum/verbs/menu/Admin/verb/playerpanel, /* It isn't /datum/admin but it fits no less */
/datum/admins/proc/kick_player_by_ckey, //MONKESTATION ADDITION - kick a player by their ckey
/datum/admins/proc/change_shuttle_events, //allows us to change the shuttle events
// Client procs
/client/proc/admin_call_shuttle, /*allows us to call the emergency shuttle*/
/client/proc/admin_cancel_shuttle, /*allows us to cancel the emergency shuttle, sending it back to centcom*/
Expand Down
42 changes: 42 additions & 0 deletions code/modules/admin/verbs/change_shuttle_events.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
///Manipulate the events that are gonna run/are running on the escape shuttle
/datum/admins/proc/change_shuttle_events()
set category = "Admin.Events"
set name = "Change Shuttle Events"
set desc = "Allows you to change the events on a shuttle."

if (!istype(src, /datum/admins))
src = usr.client.holder
if (!istype(src, /datum/admins))
to_chat(usr, "Error: you are not an admin!", confidential = TRUE)
return

//At least for now, just letting admins modify the emergency shuttle is fine
var/obj/docking_port/mobile/port = SSshuttle.emergency

if(!port)
to_chat(usr, span_admin("Uh oh, couldn't find the escape shuttle!"))

var/list/options = list("Clear"="Clear")

//Grab the active events so we know which ones we can Add or Remove
var/list/active = list()
for(var/datum/shuttle_event/event in port.event_list)
active[event.type] = event

for(var/datum/shuttle_event/event as anything in subtypesof(/datum/shuttle_event))
options[((event in active) ? "(Remove)" : "(Add)") + initial(event.name)] = event

//Throw up an ugly menu with the shuttle events and the options to add or remove them, or clear them all
var/result = input(usr, "Choose an event to add/remove", "Shuttle Events") as null|anything in sort_list(options)

if(result == "Clear")
port.event_list.Cut()
log_admin("[key_name_admin(usr)] has cleared the shuttle events on: [port]")
else if(options[result])
var/typepath = options[result]
if(typepath in active)
port.event_list.Remove(active[options[result]])
log_admin("[key_name_admin(usr)] has removed '[active[result]]' from [port].")
else
port.event_list.Add(new typepath (port))
log_admin("[key_name_admin(usr)] has added '[typepath]' to [port].")
6 changes: 6 additions & 0 deletions code/modules/awaymissions/cordon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
/turf/cordon/Adjacent(atom/neighbor, atom/target, atom/movable/mover)
return FALSE

/turf/cordon/Bumped(atom/movable/bumped_atom)
. = ..()

if(HAS_TRAIT(bumped_atom, TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT)) //we could feasibly reach the border, so just dont
dump_in_space(bumped_atom)

/// Area used in conjuction with the cordon turf to create a fully functioning world border.
/area/misc/cordon
name = "CORDON"
Expand Down
7 changes: 6 additions & 1 deletion code/modules/mapping/space_management/space_reservation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
/datum/turf_reservation/transit/make_repel(turf/pre_cordon_turf)
..()

RegisterSignal(pre_cordon_turf, COMSIG_ATOM_ENTERED, PROC_REF(space_dump))
RegisterSignal(pre_cordon_turf, COMSIG_ATOM_ENTERED, PROC_REF(space_dump_soft))

/datum/turf_reservation/transit/stop_repel(turf/pre_cordon_turf)
..()
Expand All @@ -127,6 +127,11 @@

dump_in_space(enterer)

/datum/turf_reservation/transit/proc/space_dump_soft(atom/source, atom/movable/enterer)
SIGNAL_HANDLER

if(!HAS_TRAIT(enterer, TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT))
space_dump(source, enterer)

/// Internal proc which handles reserving the area for the reservation.
/datum/turf_reservation/proc/_reserve_area(width, height, zlevel)
Expand Down
35 changes: 34 additions & 1 deletion code/modules/mob/living/basic/space_fauna/carp/carp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@
)

/mob/living/basic/carp/Initialize(mapload, mob/tamer)
ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT) //Need to set before init cause if we init in hyperspace we get dragged before the trait can be added
. = ..()
apply_colour()
add_traits(list(TRAIT_HEALS_FROM_CARP_RIFTS, TRAIT_SPACEWALK, TRAIT_FREE_HYPERSPACE_MOVEMENT), INNATE_TRAIT)
add_traits(list(TRAIT_HEALS_FROM_CARP_RIFTS, TRAIT_SPACEWALK), INNATE_TRAIT)

if (cell_line)
AddElement(/datum/element/swabable, cell_line, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
Expand Down Expand Up @@ -165,6 +166,16 @@

ai_controller.set_blackboard_key(BB_CARP_MIGRATION_PATH, actual_points)

/mob/living/basic/carp/death(gibbed)
. = ..()

REMOVE_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT)

/mob/living/basic/carp/revive(full_heal_flags, excess_healing, force_grab_ghost)
. = ..()

ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT)

/**
* Holographic carp from the holodeck
*/
Expand Down Expand Up @@ -259,3 +270,25 @@
new_overlays += disk_overlay

#undef RARE_CAYENNE_CHANCE

///Wild carp that just vibe ya know
/mob/living/basic/carp/passive
name = "passive carp"
desc = "A timid, sucker-bearing creature that resembles a fish. "

icon_state = "base_friend"
icon_living = "base_friend"
icon_dead = "base_friend_dead"
greyscale_config = /datum/greyscale_config/carp_friend

attack_verb_continuous = "suckers"
attack_verb_simple = "suck"

melee_damage_lower = 4
melee_damage_upper = 4
ai_controller = /datum/ai_controller/basic_controller/carp/passive

/mob/living/basic/carp/passive/Initialize(mapload)
. = ..()
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/pet_bonus, "bloops happily!")
5 changes: 5 additions & 0 deletions code/modules/power/singularity/singularity.dm
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
/// What the game tells ghosts when you make one
var/ghost_notification_message = "IT'S LOOSE"

pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINE | PASSSTRUCTURE | PASSDOORS
flags_1 = SUPERMATTER_IGNORES_1
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF | SHUTTLE_CRUSH_PROOF
obj_flags = CAN_BE_HIT | DANGEROUS_POSSESSION
Expand Down Expand Up @@ -470,3 +471,7 @@
/obj/singularity/deadchat_controlled/Initialize(mapload, starting_energy)
. = ..()
deadchat_plays(mode = DEMOCRACY_MODE)

/// Special singularity that spawns for shuttle events only
/obj/singularity/shuttle_event
anchored = FALSE
Loading

0 comments on commit aa5c846

Please sign in to comment.