diff --git a/code/modules/cm_aliens/structures/egg.dm b/code/modules/cm_aliens/structures/egg.dm index c23f4f3e2b20..ce0be7c0c8a1 100644 --- a/code/modules/cm_aliens/structures/egg.dm +++ b/code/modules/cm_aliens/structures/egg.dm @@ -296,3 +296,63 @@ linked_egg.HasProximity(C) if(linked_eggmorph) linked_eggmorph.HasProximity(C) + +/* +SPECIAL EGG USED BY EGG CARRIER +*/ + +#define CARRIER_EGG_UNSUSTAINED_LIFE 1 MINUTES +#define CARRIER_EGG_MAXIMUM_LIFE 5 MINUTES + +/obj/effect/alien/egg/carrier_egg + name = "fragile egg" + desc = "It looks like a weird, fragile egg." + ///Owner of the fragile egg, must be a mob/living/carbon/xenomorph/carrier + var/mob/living/carbon/xenomorph/carrier/owner = null + ///Time that the carrier was last within refresh range of the egg (14 tiles) + var/last_refreshed = null + /// Timer holder for the maximum lifetime of the egg as defined CARRIER_EGG_MAXIMUM_LIFE + var/life_timer = null + +/obj/effect/alien/egg/carrier_egg/Initialize(mapload, hivenumber, planter = null) + . = ..() + last_refreshed = world.time + if(!planter) + //If we have no owner when created... this really shouldn't happen but start decaying the egg immediately. + start_unstoppable_decay() + else + //Die after maximum lifetime + life_timer = addtimer(CALLBACK(src, PROC_REF(start_unstoppable_decay)), CARRIER_EGG_MAXIMUM_LIFE, TIMER_STOPPABLE) + set_owner(planter) + +/obj/effect/alien/egg/carrier_egg/Destroy() + if(life_timer) + deltimer(life_timer) + //Remove reference to src in owner's behavior_delegate and set owner to null + if(owner) + var/mob/living/carbon/xenomorph/carrier/my_owner = owner + var/datum/behavior_delegate/carrier_eggsac/behavior = my_owner.behavior_delegate + behavior.eggs_sustained -= src + my_owner = null + return ..() + +/// Set the owner of the egg to the planter. +/obj/effect/alien/egg/carrier_egg/proc/set_owner(mob/living/carbon/xenomorph/carrier/planter) + var/datum/behavior_delegate/carrier_eggsac/my_delegate = planter.behavior_delegate + my_delegate.eggs_sustained += src + owner = planter + +///Check the last refreshed time and burst the egg if we're over the lifetime of the egg +/obj/effect/alien/egg/carrier_egg/proc/check_decay() + if(last_refreshed + CARRIER_EGG_UNSUSTAINED_LIFE < world.time) + start_unstoppable_decay() + +///Burst the egg without hugger release after a 10 second timer & remove the life timer. +/obj/effect/alien/egg/carrier_egg/proc/start_unstoppable_decay() + addtimer(CALLBACK(src, PROC_REF(Burst), TRUE), 10 SECONDS) + if(life_timer) + deltimer(life_timer) + +/obj/effect/alien/egg/carrier_egg/Burst(kill, instant_trigger, mob/living/carbon/xenomorph/X, is_hugger_player_controlled) + . = ..() + owner = null diff --git a/code/modules/mob/living/carbon/xenomorph/egg_item.dm b/code/modules/mob/living/carbon/xenomorph/egg_item.dm index 77c5548d9f9f..05d456d0025d 100644 --- a/code/modules/mob/living/carbon/xenomorph/egg_item.dm +++ b/code/modules/mob/living/carbon/xenomorph/egg_item.dm @@ -98,7 +98,7 @@ to_chat(user, SPAN_XENOWARNING("[src] must be planted on [lowertext(hive.prefix)]weeds.")) return - if(!hive_weeds) + if(!hive_weeds && user.mutation_type != CARRIER_EGGSAC) to_chat(user, SPAN_XENOWARNING("[src] can only be planted on [lowertext(hive.prefix)]hive weeds.")) return @@ -117,9 +117,16 @@ return for(var/obj/effect/alien/weeds/weed in T) - if(weed.weed_strength >= WEED_LEVEL_HIVE) + if(weed.weed_strength >= WEED_LEVEL_HIVE || user.mutation_type == CARRIER_EGGSAC) user.use_plasma(30) - var/obj/effect/alien/egg/newegg = new /obj/effect/alien/egg(T, hivenumber) + var/obj/effect/alien/egg/newegg + if(weed.weed_strength >= WEED_LEVEL_HIVE) + newegg = new /obj/effect/alien/egg(T, hivenumber) + else if(weed.weed_strength == WEED_LEVEL_STANDARD) + newegg = new /obj/effect/alien/egg/carrier_egg(T,hivenumber, user) + else + to_chat(user, SPAN_XENOWARNING("[src] can't be planted on these weeds.")) + return newegg.flags_embryo = flags_embryo diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/carrier/eggsac.dm b/code/modules/mob/living/carbon/xenomorph/mutators/strains/carrier/eggsac.dm index 524571fc0dfd..3d032da2fe36 100644 --- a/code/modules/mob/living/carbon/xenomorph/mutators/strains/carrier/eggsac.dm +++ b/code/modules/mob/living/carbon/xenomorph/mutators/strains/carrier/eggsac.dm @@ -1,6 +1,6 @@ /datum/xeno_mutator/eggsac name = "STRAIN: Carrier - Eggsac" - description = "In exchange for your ability to store huggers and place traps, you gain larger plasma stores, strong pheromones, and the ability to lay eggs by using your plasma stores. In addition, you can now carry twelve eggs at once and can place eggs one pace further than normal" + description = "In exchange for your ability to store huggers and place traps, you gain larger plasma stores, strong pheromones, and the ability to lay eggs by using your plasma stores. In addition, you can now carry twelve eggs at once and can place eggs one pace further than normal. \n\nYou can also place a small number of fragile eggs on normal weeds. These eggs have a lifetime of five minutes while you remain within 14 tiles. Or one minute if you leave this range." flavor_description = "An egg is always an adventure; the next one may be different." cost = MUTATOR_COST_EXPENSIVE individual_only = TRUE @@ -15,6 +15,7 @@ /datum/action/xeno_action/active_toggle/generate_egg, /datum/action/xeno_action/activable/retrieve_egg, // readding it so it gets at the end of the ability list ) + behavior_delegate_type = /datum/behavior_delegate/carrier_eggsac keystone = TRUE /datum/xeno_mutator/eggsac/apply_mutator(datum/mutator_set/individual_mutators/mutator_set) @@ -40,8 +41,57 @@ carrier.update_eggsac_overlays() carrier.eggs_max = 12 carrier.egg_planting_range = 2 + apply_behavior_holder(carrier) return TRUE +#define EGGSAC_OFF_WEED_EGGCAP 4 +#define EGGSAC_EGG_SUSTAIN_DISTANCE 14 + +/datum/behavior_delegate/carrier_eggsac + name = "Eggsac Carrier Behavior Delegate" + ///List of /obj/effect/alien/egg/carrier_egg sustained by the carrier on normal weeds + var/list/eggs_sustained = list() + ///Total number of eggs which can be sustained defined as EGGSAC_OFF_WEED_EGGCAP + var/egg_sustain_cap = EGGSAC_OFF_WEED_EGGCAP + ///Distance from the egg that the carrier can go before it stops sustaining it + var/sustain_distance = EGGSAC_EGG_SUSTAIN_DISTANCE + +/datum/behavior_delegate/carrier_eggsac/append_to_stat() + . = list() + . += "Eggs sustained: [length(eggs_sustained)] / [egg_sustain_cap]" + +/datum/behavior_delegate/carrier_eggsac/on_life() + if(length(eggs_sustained) > egg_sustain_cap) + var/obj/effect/alien/egg/carrier_egg/my_egg = eggs_sustained[1] + remove_egg_owner(my_egg) + my_egg.start_unstoppable_decay() + to_chat(bound_xeno, SPAN_XENOWARNING("You can only sustain [egg_sustain_cap] eggs off hive weeds! Your oldest placed egg is decaying rapidly.")) + + for(var/obj/effect/alien/egg/carrier_egg/my_egg as anything in eggs_sustained) + //Get the distance from us to our sustained egg + if(get_dist(bound_xeno, my_egg) <= sustain_distance) + my_egg.last_refreshed = world.time + else + my_egg.check_decay() + +///Remove owner of egg +/datum/behavior_delegate/carrier_eggsac/proc/remove_egg_owner(obj/effect/alien/egg/carrier_egg/egg) + if(!egg.owner || egg.owner != bound_xeno) + return + eggs_sustained -= egg + egg.owner = null + +/datum/behavior_delegate/carrier_eggsac/handle_death(mob/M) + for(var/obj/effect/alien/egg/carrier_egg/my_egg as anything in eggs_sustained) + remove_egg_owner(my_egg) + my_egg.start_unstoppable_decay() + +///Remove all references to src in eggs_sustained +/datum/behavior_delegate/carrier_eggsac/Destroy() + for(var/obj/effect/alien/egg/carrier_egg/my_egg as anything in eggs_sustained) + my_egg.owner = null + return ..() + /datum/action/xeno_action/active_toggle/generate_egg name = "Generate Eggs (50)" action_icon_state = "lay_egg" @@ -77,3 +127,6 @@ xeno.eggs_cur++ to_chat(xeno, SPAN_XENONOTICE("You generate a egg. Now sheltering: [xeno.eggs_cur] / [xeno.eggs_max].")) xeno.update_icons() + +#undef EGGSAC_OFF_WEED_EGGCAP +#undef EGGSAC_EGG_SUSTAIN_DISTANCE