Skip to content

Commit

Permalink
Merge remote-tracking branch 'cmss13-devs/master' into forest/flags/a…
Browse files Browse the repository at this point in the history
…dminflags
  • Loading branch information
realforest2001 committed Jul 9, 2023
2 parents 2a8ac7c + 99adec9 commit 1350a3a
Show file tree
Hide file tree
Showing 91 changed files with 1,357 additions and 526 deletions.
5 changes: 5 additions & 0 deletions code/__DEFINES/dcs/signals/atom/signals_obj.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

/// From /obj/effect/alien/weeds/Initialize()
#define COMSIG_WEEDNODE_GROWTH_COMPLETE "weednode_growth_complete"
/// From /obj/effect/alien/weeds/Initialize()
#define COMSIG_WEEDNODE_GROWTH "weednode_growth"
/// From /obj/effect/alien/weeds/proc/on_weed_expand()
#define COMSIG_WEEDNODE_CANNOT_EXPAND_FURTHER "weednode_cannot_expand_further"

Expand All @@ -24,3 +26,6 @@
#define COMSIG_TRANSMITTER_UPDATE_ICON "transmitter_update_icon"

#define COMSIG_TENT_COLLAPSING "tent_collapsing"

/// from /obj/proc/afterbuckle()
#define COSMIG_OBJ_AFTER_BUCKLE "signal_obj_after_buckle"
2 changes: 1 addition & 1 deletion code/__DEFINES/tgui.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
/// Creates a message packet for sending via output()
// This is {"type":type,"payload":payload}, but pre-encoded. This is much faster
// than doing it the normal way.
// To ensure this is correct, this is unit tested in tgui_create_message. However, CM does not have unit tests available.
// To ensure this is correct, this is unit tested in tgui_create_message.
#define TGUI_CREATE_MESSAGE(type, payload) ( \
"%7b%22type%22%3a%22[type]%22%2c%22payload%22%3a[url_encode(json_encode(payload))]%7d" \
)
Expand Down
5 changes: 4 additions & 1 deletion code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
#define TRAIT_SUPER_STRONG "t_super_strong"
/// Foreign biology. Basic medHUDs won't show the mob. (Yautja, Zombies)
#define TRAIT_FOREIGN_BIO "t_foreign_bio"
/// Eye color changes on intent. (G1 Synths)
/// Eye color changes on intent. (G1 Synths and WJs)
#define TRAIT_INTENT_EYES "t_intent_eyes"
/// Masked synthetic biology. Basic medHUDs will percieve the mob as human. (Infiltrator Synths)
#define TRAIT_INFILTRATOR_SYNTH "t_infiltrator_synth"
Expand Down Expand Up @@ -157,6 +157,8 @@
#define TRAIT_LEADERSHIP "t_leadership"
/// If the mob can see the reagents contents of stuff
#define TRAIT_REAGENT_SCANNER "reagent_scanner"
/// If the mob cannot eat/be fed
#define TRAIT_CANNOT_EAT "t_cannot_eat"
/// If the mob is being lazed by a sniper spotter
#define TRAIT_SPOTTER_LAZED "t_spotter_lazed"
/// If the mob has ear protection. Protects from external ear damage effects. Includes explosions, firing the RPG, screeching DEAFNESS only, and flashbangs.
Expand Down Expand Up @@ -261,6 +263,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_BIMEX" = TRAIT_BIMEX,
"TRAIT_EMOTE_CD_EXEMPT" = TRAIT_EMOTE_CD_EXEMPT,
"TRAIT_LISPING" = TRAIT_LISPING,
"TRAIT_CANNOT_EAT" = TRAIT_CANNOT_EAT,
),
/mob/living/carbon/xenomorph = list(
"TRAIT_ABILITY_NO_PLASMA_TRANSFER" = TRAIT_ABILITY_NO_PLASMA_TRANSFER,
Expand Down
8 changes: 8 additions & 0 deletions code/__DEFINES/wj_emotes.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#define JOE_EMOTE_CATEGORY_GREETING "Greeting"
#define JOE_EMOTE_CATEGORY_TASK_UPDATE "Task Update"
#define JOE_EMOTE_CATEGORY_RESTRICTED_AREA "Restricted Area"
#define JOE_EMOTE_CATEGORY_FAREWELL "Farewell"
#define JOE_EMOTE_CATEGORY_QUIP "Quip"
#define JOE_EMOTE_CATEGORY_WARNING "Warning"
#define JOE_EMOTE_CATEGORY_QUESTION "Question"
#define JOE_EMOTE_CATEGORY_NOTICE "Notice"
7 changes: 1 addition & 6 deletions code/__HELPERS/game.dm
Original file line number Diff line number Diff line change
Expand Up @@ -290,21 +290,16 @@
* * cache_only - Whether to not actually send a to_chat message and instead only update larva_queue_cached_message
*/
/proc/message_alien_candidates(list/candidates, dequeued, cache_only = FALSE)
var/new_players = 0
for(var/i in (1 + dequeued) to candidates.len)
var/mob/dead/observer/cur_obs = candidates[i]

// Generate the messages
var/cached_message = SPAN_XENONOTICE("You are currently [i-dequeued]\th in the larva queue. There are [new_players] ahead of you that have yet to play this round.")
var/cached_message = SPAN_XENONOTICE("You are currently [i-dequeued]\th in the larva queue.")
cur_obs.larva_queue_cached_message = cached_message
if(!cache_only)
var/chat_message = dequeued ? replacetext(cached_message, "currently", "now") : cached_message
to_chat(candidates[i], chat_message)

// Count how many are prioritized
if(cur_obs.client.player_details.larva_queue_time < 2) // 0 and 1 because facehuggers/t-domers are slightly deprioritized
new_players++

/proc/convert_k2c(temp)
return ((temp - T0C))

Expand Down
2 changes: 1 addition & 1 deletion code/datums/components/footstep.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
return

var/mob/living/LM = parent
if(LM.buckled || LM.throwing || LM.is_ventcrawling)
if(LM.buckled || LM.throwing || LM.is_ventcrawling || LM.stat == DEAD)
return

if(LM.life_steps_total % steps)
Expand Down
297 changes: 297 additions & 0 deletions code/datums/components/weed_food.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
#define WEED_FOOD_DELAY 5 MINUTES
#define WEED_FOOD_STATE_DELAY 1 MINUTES

/atom/movable/vis_obj/weed_food
name = "weeds"
desc = "Weird black weeds in the shape of a body..."
gender = PLURAL
vis_flags = VIS_INHERIT_DIR|VIS_INHERIT_PLANE|VIS_INHERIT_LAYER
icon = 'icons/mob/xenos/weeds.dmi'
var/static/list/icon_states = list("human_1","human_2","human_3","human_4","human_5")
var/static/list/icon_states_flipped = list("human_1_f","human_2_f","human_3_f","human_4_f","human_5_f")
var/icon_state_idx = 0
var/timer_id = null
var/flipped = FALSE

/atom/movable/vis_obj/weed_food/Initialize(mapload, is_flipped, ...)
flipped = is_flipped
timer_id = addtimer(CALLBACK(src, PROC_REF(on_animation_timer)), WEED_FOOD_STATE_DELAY, TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_LOOP|TIMER_DELETE_ME)
on_animation_timer()
return ..()

/// Timer callback for changing the icon_state
/atom/movable/vis_obj/weed_food/proc/on_animation_timer()
icon_state_idx++
if(icon_state_idx > length(icon_states))
deltimer(timer_id)
timer_id = null
return
icon_state = flipped ? icon_states_flipped[icon_state_idx] : icon_states[icon_state_idx]

/**
* A component that can be attached to a mob/living to be merged with weeds after a delay.
* Attempting to attach a new weed_food even if one already exists is equivalent to calling start().
*
* Attach this to any mob/living that is dead (death or initialized dead) and it should handle the rest.
*/
/datum/component/weed_food
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
/// Whether we are waiting on timer to merge
var/active = FALSE
/// Whether we are merged with weeds
var/merged = FALSE
/// The time we were unmerged (just to handle weeds upgrading)
var/unmerged_time
/// Any active timer for a pending merge
var/timer_id = null
/// The living mob that we are bound to
var/mob/living/parent_mob
/// The turf that our parent is on
var/turf/parent_turf
/// The obj that our parent is buckled to and we have registered a signal
var/obj/parent_buckle
/// The weeds that we are merging/merged with
var/obj/effect/alien/weeds/absorbing_weeds
/// The overlay image when merged
var/atom/movable/vis_obj/weed_food/weed_appearance

/datum/component/weed_food/Initialize(...)
parent_mob = parent
//if(!istype(parent_mob))
//return COMPONENT_INCOMPATIBLE
if(!istype(parent_mob, /mob/living/carbon/human))
return COMPONENT_INCOMPATIBLE // TODO: At the moment we only support humans

parent_turf = get_turf(parent_mob)
if(parent_turf != parent_mob.loc)
parent_turf = null // if our location is actually a container, we want to be safe from weeds

start()

/datum/component/weed_food/InheritComponent(datum/component/C, i_am_original)
start()

/datum/component/weed_food/Destroy(force, silent)
. = ..()

unmerge_with_weeds()
QDEL_NULL(weed_appearance)
parent_mob = null
parent_turf = null

/datum/component/weed_food/RegisterWithParent()
RegisterSignal(parent_mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
RegisterSignal(parent_mob, list(COMSIG_LIVING_REJUVENATED, COMSIG_HUMAN_REVIVED), PROC_REF(on_rejuv))
RegisterSignal(parent_mob, COMSIG_HUMAN_SET_UNDEFIBBABLE, PROC_REF(on_update))
if(parent_turf)
RegisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH, PROC_REF(on_update))

/datum/component/weed_food/UnregisterFromParent()
if(parent_mob)
UnregisterSignal(parent_mob, list(
COMSIG_MOVABLE_MOVED,
COMSIG_LIVING_REJUVENATED,
COMSIG_HUMAN_REVIVED,
COMSIG_HUMAN_SET_UNDEFIBBABLE,
))
if(absorbing_weeds)
UnregisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING)
if(parent_turf)
UnregisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH)
if(parent_buckle)
UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE)

/// SIGNAL_HANDLER for COMSIG_MOVABLE_MOVED
/datum/component/weed_food/proc/on_move()
SIGNAL_HANDLER

if(absorbing_weeds)
UnregisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING)
absorbing_weeds = null

if(parent_turf)
UnregisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH)
parent_turf = get_turf(parent_mob)
if(parent_turf != parent_mob.loc)
parent_turf = null // if our location is actually a container, we want to be safe from weeds
else
RegisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH, PROC_REF(on_update))

// We moved, restart or start the proccess
if(stop() || !merged)
start()
return

// If we somehow moved when we were merged, handle that
absorbing_weeds = parent_turf?.weeds
if(absorbing_weeds)
RegisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING, PROC_REF(on_weed_deletion))
return
unmerge_with_weeds()

/// SIGNAL_HANDLER for COMSIG_LIVING_REJUVENATED and COMSIG_HUMAN_REVIVED
/datum/component/weed_food/proc/on_rejuv()
SIGNAL_HANDLER

qdel(src)

/// SIGNAL_HANDLER for COSMIG_OBJ_AFTER_BUCKLE
/datum/component/weed_food/proc/on_after_buckle(obj/source, mob/buckled)
SIGNAL_HANDLER

if(buckled)
return
start() // We unbuckled, so lets try to start again

/// SIGNAL_HANDLER for COMSIG_HUMAN_SET_UNDEFIBBABLE & COMSIG_WEEDNODE_GROWTH
/datum/component/weed_food/proc/on_update()
SIGNAL_HANDLER

start()

/// SIGNAL_HANDLER for COMSIG_PARENT_QDELETING of weeds
/datum/component/weed_food/proc/on_weed_deletion()
SIGNAL_HANDLER

if(active)
stop()
return
if(merged)
unmerge_with_weeds()
return

/**
* Try to start the process to turn into weeds
* Returns TRUE if started successfully
*/
/datum/component/weed_food/proc/start()
if(active)
return FALSE
if(merged)
return FALSE
if(QDELETED(parent_mob))
return FALSE

if(parent_mob.buckled)
if(parent_mob.buckled == parent_buckle)
return FALSE // Still buckled to the same thing
if(!istype(parent_mob.buckled, /obj/structure/bed/nest))
if(parent_buckle) // Still have a lingering reference somehow?
UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE)
parent_buckle = parent_mob.buckled
RegisterSignal(parent_mob.buckled, COSMIG_OBJ_AFTER_BUCKLE, PROC_REF(on_after_buckle))
return FALSE
if(parent_buckle)
UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE)
parent_buckle = null

if(parent_mob.is_xeno_grabbable())
return FALSE
if(!(parent_mob.status_flags & PERMANENTLY_DEAD))
var/mob/living/carbon/human/parent_human = parent_mob
if(istype(parent_human) && !parent_human.undefibbable)
return FALSE
if(!parent_turf?.weeds)
return FALSE

if(unmerged_time == world.time)
return merge_with_weeds() // Weeds upgraded, re-merge now re-using the apperance
QDEL_NULL(weed_appearance)
absorbing_weeds = parent_turf.weeds
RegisterSignal(parent_turf.weeds, COMSIG_PARENT_QDELETING, PROC_REF(on_weed_deletion))

active = TRUE
timer_id = addtimer(CALLBACK(src, PROC_REF(merge_with_weeds)), WEED_FOOD_DELAY, TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_DELETE_ME|TIMER_OVERRIDE)

return TRUE

/**
* Try to stop the process turning into weeds
* Returns TRUE if stopped successfully (was active when called)
*/
/datum/component/weed_food/proc/stop()
if(!active)
return FALSE

active = FALSE
deltimer(timer_id)
timer_id = null

return TRUE

/**
* Finish becomming one with the weeds
* Returns TRUE if merged successfully
*/
/datum/component/weed_food/proc/merge_with_weeds()
if(merged)
return FALSE
if(QDELETED(parent_mob))
return FALSE

if(absorbing_weeds) // Remove the signal that would call stop
UnregisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING)

if(parent_mob.buckled)
if(parent_mob.buckled == parent_buckle)
return FALSE // Still buckled to the same thing somehow?
if(!istype(parent_mob.buckled, /obj/structure/bed/nest))
if(parent_buckle) // Still have a lingering reference somehow?
UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE)
parent_buckle = parent_mob.buckled
RegisterSignal(parent_mob.buckled, COSMIG_OBJ_AFTER_BUCKLE, PROC_REF(on_after_buckle))
return FALSE
if(parent_buckle)
UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE)
parent_buckle = null

absorbing_weeds = parent_turf?.weeds
if(!absorbing_weeds)
return FALSE
RegisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING, PROC_REF(on_weed_deletion))
// Technically we could have just left the signal alone, but both because of the posibility of other conditions preventing a merge or weeds somehow changing and on_move didn't catch it, this is less fragile

active = FALSE
merged = TRUE

parent_mob.density = FALSE
parent_mob.anchored = TRUE
parent_mob.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
parent_mob.plane = FLOOR_PLANE
parent_mob.remove_from_all_mob_huds()

if(!weed_appearance) // Make a new sprite if we aren't re-merging
var/is_flipped = parent_mob.transform.b == -1 // Technically we should check if d is 1 too, but corpses can only be rotated 90 or 270 (1/-1 or -1/1)
if(parent_mob.dir & WEST)
is_flipped = !is_flipped // The direction reversed the effect of the flip!
weed_appearance = new(null, is_flipped)
weed_appearance.color = absorbing_weeds.color
// TODO: For non-humans change the icon_state or something here
parent_mob.vis_contents += weed_appearance

return TRUE

/**
* Undo the weedening
* Returns TRUE if unmerged successfully (always)
*/
/datum/component/weed_food/proc/unmerge_with_weeds()
merged = FALSE
unmerged_time = world.time

if(absorbing_weeds)
UnregisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING)
absorbing_weeds = null

parent_mob.anchored = FALSE
parent_mob.mouse_opacity = MOUSE_OPACITY_ICON
parent_mob.plane = GAME_PLANE
parent_mob.vis_contents -= weed_appearance

if(!QDELETED(parent_mob))
parent_mob.add_to_all_mob_huds()

return TRUE

#undef WEED_FOOD_DELAY
#undef WEED_FOOD_STATE_DELAY
Loading

0 comments on commit 1350a3a

Please sign in to comment.