Skip to content

Commit

Permalink
Player huggers now get second dibs if they hug a player (#3706)
Browse files Browse the repository at this point in the history
# About the pull request

This PR makes it so the ckey of a player hugger is recorded in the
embryo so that they can get second dibs if/when that marine pops. The
marine player still has first dibs. If they manage to get a pop this
way, they forfeit any other hugs they currently have (kudos though if
someone is hugging multiple marines to put this measure into effect).

# Explain why it's good for the game

Another incentive for playable huggers!

# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>

Yes I test, you should too:

![image](https://github.com/cmss13-devs/cmss13/assets/76988376/7194169b-82a1-47ad-836d-42682f102b7a)

</details>


# Changelog
:cl: Drathek
add: Player facehugging gets 2nd dibs on the burst (the original marine
gets first dibs still)
/:cl:
  • Loading branch information
Drulikar authored Jun 25, 2023
1 parent b54efad commit 5809f18
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 26 deletions.
1 change: 1 addition & 0 deletions code/_globalvars/lists/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ GLOBAL_LIST_EMPTY_TYPED(alive_human_list, /mob/living/carbon/human) // list of a
GLOBAL_LIST_EMPTY_TYPED(xeno_mob_list, /mob/living/carbon/xenomorph)
GLOBAL_LIST_EMPTY_TYPED(living_xeno_list, /mob/living/carbon/xenomorph)
GLOBAL_LIST_EMPTY_TYPED(xeno_cultists, /mob/living/carbon/human)
GLOBAL_LIST_EMPTY_TYPED(player_embryo_list, /obj/item/alien_embryo)

GLOBAL_LIST_EMPTY_TYPED(hellhound_list, /mob/living/carbon/xenomorph/hellhound)
GLOBAL_LIST_EMPTY_TYPED(zombie_list, /mob/living/carbon/human)
Expand Down
26 changes: 21 additions & 5 deletions code/modules/mob/living/carbon/xenomorph/Embryo.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
var/hivenumber = XENO_HIVE_NORMAL
var/faction = FACTION_XENOMORPH
var/flags_embryo = FALSE // Used in /ciphering/predator property
/// The ckey of any player hugger that made this embryo
var/hugger_ckey

/obj/item/alien_embryo/Initialize(mapload, ...)
. = ..()
Expand All @@ -33,6 +35,7 @@
C.med_hud_set_status()
STOP_PROCESSING(SSobj, src)
affected_mob = null
GLOB.player_embryo_list -= src
. = ..()

/obj/item/alien_embryo/process()
Expand Down Expand Up @@ -145,20 +148,33 @@

var/mob/picked
// If the bursted person themselves has Xeno enabled, they get the honor of first dibs on the new larva.
if((!isyautja(affected_mob) || (isyautja(affected_mob) && prob(20))) && istype(affected_mob.buckled, /obj/structure/bed/nest))
if((!isyautja(affected_mob) || (isyautja(affected_mob) && prob(20))) && istype(affected_mob.buckled, /obj/structure/bed/nest))
if(affected_mob.first_xeno || (affected_mob.client && affected_mob.client.prefs && (affected_mob.client.prefs.be_special & BE_ALIEN_AFTER_DEATH) && !jobban_isbanned(affected_mob, JOB_XENOMORPH)))
picked = affected_mob
else if(affected_mob.mind && affected_mob.mind.ghost_mob && affected_mob.client && affected_mob.client.prefs && (affected_mob.client.prefs.be_special & BE_ALIEN_AFTER_DEATH) && !jobban_isbanned(affected_mob, JOB_XENOMORPH))
picked = affected_mob.mind.ghost_mob


if(!picked)
// Get a candidate from observers
var/list/candidates = get_alien_candidates()

if(candidates && candidates.len)
picked = candidates[1]
message_alien_candidates(candidates, dequeued = 1)
// If they were facehugged by a player thats still in queue, they get second dibs on the new larva.
if(hugger_ckey)
for(var/mob/dead/observer/cur_obs as anything in candidates)
if(cur_obs.ckey == hugger_ckey)
picked = cur_obs
candidates -= cur_obs
message_alien_candidates(candidates, dequeued = 0)
for(var/obj/item/alien_embryo/embryo as anything in GLOB.player_embryo_list)
if(embryo.hugger_ckey == cur_obs.ckey && embryo != src)
// Skipping src just in case an admin wants to quickly check before this thing fully deletes
// If this nulls out any embryo, wow
embryo.hugger_ckey = null
break

if(!picked)
picked = candidates[1]
message_alien_candidates(candidates, dequeued = 1)

// Spawn the larva
var/mob/living/carbon/xenomorph/larva/new_xeno
Expand Down
40 changes: 21 additions & 19 deletions code/modules/mob/living/carbon/xenomorph/Facehuggers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -241,46 +241,46 @@
throw_atom(target, 3, SPEED_FAST)
return TRUE

/obj/item/clothing/mask/facehugger/proc/attach(mob/living/M, silent = FALSE, knockout_mod = 1)
if(attached || !can_hug(M, hivenumber))
/obj/item/clothing/mask/facehugger/proc/attach(mob/living/living_mob, silent = FALSE, knockout_mod = 1, hugger_ckey = null)
if(attached || !can_hug(living_mob, hivenumber))
return FALSE

// This is always going to be valid because of the can_hug check above
var/mob/living/carbon/human/H = M
var/mob/living/carbon/human/human = living_mob
if(!silent)
H.visible_message(SPAN_DANGER("[src] leaps at [H]'s face!"))
human.visible_message(SPAN_DANGER("[src] leaps at [human]'s face!"))

if(isxeno(loc)) //Being carried? Drop it
var/mob/living/carbon/xenomorph/X = loc
X.drop_inv_item_on_ground(src)

if(isturf(H.loc))
forceMove(H.loc)//Just checkin
if(isturf(human.loc))
forceMove(human.loc)//Just checkin

if(!H.handle_hugger_attachment(src))
if(!human.handle_hugger_attachment(src))
return FALSE

attached = TRUE

forceMove(H)
forceMove(human)
icon_state = initial(icon_state)
H.equip_to_slot(src, WEAR_FACE)
H.update_inv_wear_mask()
H.disable_lights()
H.disable_special_items()
if(ishuman_strict(H))
playsound(loc, H.gender == "male" ? 'sound/misc/facehugged_male.ogg' : 'sound/misc/facehugged_female.ogg' , 25, 0)
else if(isyautja(H))
human.equip_to_slot(src, WEAR_FACE)
human.update_inv_wear_mask()
human.disable_lights()
human.disable_special_items()
if(ishuman_strict(human))
playsound(loc, human.gender == "male" ? 'sound/misc/facehugged_male.ogg' : 'sound/misc/facehugged_female.ogg' , 25, 0)
else if(isyautja(human))
playsound(loc, 'sound/voice/pred_facehugged.ogg', 65, FALSE)
if(!sterile)
if(!H.species || !(H.species.flags & IS_SYNTHETIC)) //synthetics aren't paralyzed
H.apply_effect(MIN_IMPREGNATION_TIME * 0.5 * knockout_mod, PARALYZE) //THIS MIGHT NEED TWEAKS
if(!human.species || !(human.species.flags & IS_SYNTHETIC)) //synthetics aren't paralyzed
human.apply_effect(MIN_IMPREGNATION_TIME * 0.5 * knockout_mod, PARALYZE) //THIS MIGHT NEED TWEAKS

addtimer(CALLBACK(src, PROC_REF(impregnate), H), rand(MIN_IMPREGNATION_TIME, MAX_IMPREGNATION_TIME))
addtimer(CALLBACK(src, PROC_REF(impregnate), human, hugger_ckey), rand(MIN_IMPREGNATION_TIME, MAX_IMPREGNATION_TIME))

return TRUE

/obj/item/clothing/mask/facehugger/proc/impregnate(mob/living/carbon/human/target)
/obj/item/clothing/mask/facehugger/proc/impregnate(mob/living/carbon/human/target, hugger_ckey = null)
if(!target || target.wear_mask != src) //Was taken off or something
return
if(SEND_SIGNAL(target, COMSIG_HUMAN_IMPREGNATE, src) & COMPONENT_NO_IMPREGNATE)
Expand All @@ -295,6 +295,8 @@
if(!embryos)
var/obj/item/alien_embryo/embryo = new /obj/item/alien_embryo(target)
embryo.hivenumber = hivenumber
embryo.hugger_ckey = hugger_ckey
GLOB.player_embryo_list += embryo

embryo.flags_embryo = flags_embryo
flags_embryo = NO_FLAGS
Expand Down
4 changes: 2 additions & 2 deletions code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@

/mob/living/carbon/xenomorph/facehugger/proc/handle_hug(mob/living/carbon/human/human)
var/obj/item/clothing/mask/facehugger/hugger = new /obj/item/clothing/mask/facehugger(loc, hivenumber)
var/did_hug = hugger.attach(human, TRUE, 0.5)
var/did_hug = hugger.attach(human, TRUE, 0.5, client?.ckey)
if(client)
client?.player_data?.adjust_stat(PLAYER_STAT_FACEHUGS, STAT_CATEGORY_XENO, 1)
client.player_data?.adjust_stat(PLAYER_STAT_FACEHUGS, STAT_CATEGORY_XENO, 1)
var/area/hug_area = get_area(src)
if(hug_area)
for(var/mob/dead/observer/observer as anything in GLOB.observer_list)
Expand Down

0 comments on commit 5809f18

Please sign in to comment.