mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-10 23:54:14 +01:00
225 lines
8.2 KiB
Plaintext
225 lines
8.2 KiB
Plaintext
// SPACE VINES (Note that this code is very similar to Biomass code)
|
|
/obj/structure/spacevine
|
|
name = "space vine"
|
|
desc = "An extremely expansionistic species of vine."
|
|
icon = 'icons/mob/spacevines.dmi'
|
|
icon_state = "Light1"
|
|
anchored = TRUE
|
|
density = FALSE
|
|
layer = SPACEVINE_LAYER
|
|
mouse_opacity = MOUSE_OPACITY_OPAQUE //Clicking anywhere on the turf is good enough
|
|
pass_flags = PASSTABLE | PASSGRILLE
|
|
max_integrity = 50
|
|
/// What growth stage is this vine at?
|
|
var/growth_stage = 0
|
|
/// Can this kudzu spread?
|
|
var/can_spread = TRUE
|
|
/// Can this kudzu buckle mobs in?
|
|
var/can_tangle = TRUE
|
|
/// Our associated spacevine_controller, for managing expansion/mutation
|
|
var/datum/spacevine_controller/master
|
|
/// List of mutations for a specific vine
|
|
var/list/mutations = list()
|
|
/// The traits associated with a specific mutation of vines
|
|
var/trait_flags = NONE
|
|
/// Should atmos always process this tile
|
|
var/always_atmos_process = FALSE
|
|
/// The kudzu blocks light on default once it grows
|
|
var/light_state = BLOCK_LIGHT
|
|
|
|
/obj/structure/spacevine/Initialize(mapload)
|
|
. = ..()
|
|
ADD_TRAIT(src, TRAIT_CHASM_DESTROYED, INNATE_TRAIT)
|
|
ADD_TRAIT(src, TRAIT_INVERTED_DEMOLITION, INNATE_TRAIT)
|
|
add_atom_colour("#ffffff", FIXED_COLOUR_PRIORITY)
|
|
var/static/list/loc_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
|
|
)
|
|
AddElement(/datum/element/connect_loc, loc_connections)
|
|
AddElement(/datum/element/atmos_sensitive, mapload)
|
|
AddComponent(/datum/component/storm_hating)
|
|
block_sunlight()
|
|
|
|
/obj/structure/spacevine/examine(mob/user)
|
|
. = ..()
|
|
if(!length(mutations))
|
|
. += "This vine has no mutations."
|
|
return
|
|
var/text = "This vine has the following mutations:\n"
|
|
for(var/datum/spacevine_mutation/mutation as anything in mutations)
|
|
if(mutation.name == "transparent") /// Transparent has no hue
|
|
text += "<font color='#346751'>Transparent</font> "
|
|
else
|
|
text += "<font color='[mutation.hue]'>[mutation.name]</font> "
|
|
. += text
|
|
|
|
/obj/structure/spacevine/Destroy()
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
mutation.on_death(src)
|
|
if(master)
|
|
master.VineDestroyed(src)
|
|
mutations = list()
|
|
set_opacity(PASS_LIGHT)
|
|
if(has_buckled_mobs())
|
|
unbuckle_all_mobs(force=1)
|
|
return ..()
|
|
|
|
/obj/structure/spacevine/proc/on_chem_effect(datum/reagent/chem)
|
|
var/override = FALSE
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
override += mutation.on_chem(src, chem)
|
|
if(!override && prob(75) && istype(chem, /datum/reagent/toxin/plantbgone))
|
|
// SKYRAT EDIT ADD START
|
|
if(plantbgone_resist && prob(50))
|
|
return
|
|
// SKYRAT EDIT ADD END
|
|
qdel(src)
|
|
|
|
/obj/structure/spacevine/proc/eat(mob/eater)
|
|
var/override = FALSE
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
override += mutation.on_eat(src, eater)
|
|
if(!override)
|
|
qdel(src)
|
|
|
|
/obj/structure/spacevine/attacked_by(obj/item/item, mob/living/user, list/modifiers, list/attack_modifiers)
|
|
LAZYSET(attack_modifiers, SILENCE_DEFAULT_MESSAGES, TRUE)
|
|
LAZYSET(attack_modifiers, FORCE_MULTIPLIER, 1)
|
|
if(item.damtype == BURN)
|
|
MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, 4)
|
|
if(item.get_sharpness())
|
|
MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, 4)
|
|
return ..()
|
|
|
|
/obj/structure/spacevine/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
|
switch(damage_type)
|
|
if(BRUTE)
|
|
if(damage_amount)
|
|
playsound(src, 'sound/items/weapons/slash.ogg', 50, TRUE)
|
|
else
|
|
playsound(src, 'sound/items/weapons/tap.ogg', 50, TRUE)
|
|
if(BURN)
|
|
playsound(src.loc, 'sound/items/tools/welder.ogg', 100, TRUE)
|
|
|
|
/obj/structure/spacevine/proc/on_entered(datum/source, atom/movable/movable)
|
|
SIGNAL_HANDLER
|
|
if(!isliving(movable))
|
|
return
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
mutation.on_cross(src, movable)
|
|
|
|
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
|
/obj/structure/spacevine/attack_hand(mob/user, list/modifiers)
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
mutation.on_hit(src, user)
|
|
user_unbuckle_mob(user, user)
|
|
return ..()
|
|
|
|
/obj/structure/spacevine/attack_paw(mob/living/user, list/modifiers)
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
mutation.on_hit(src, user)
|
|
user_unbuckle_mob(user,user)
|
|
|
|
/obj/structure/spacevine/attack_alien(mob/living/user, list/modifiers)
|
|
eat(user)
|
|
|
|
/// Updates the icon as the space vine grows
|
|
/obj/structure/spacevine/proc/grow()
|
|
if(!growth_stage)
|
|
src.icon_state = pick("Med1", "Med2", "Med3")
|
|
growth_stage = 1
|
|
set_opacity(light_state)
|
|
else
|
|
src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
|
|
growth_stage = 2
|
|
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
mutation.on_grow(src)
|
|
|
|
/// Buckles mobs trying to pass through it
|
|
/obj/structure/spacevine/proc/entangle_mob()
|
|
if(has_buckled_mobs() || prob(75))
|
|
return
|
|
|
|
for(var/mob/living/victim in src.loc)
|
|
entangle(victim)
|
|
if(has_buckled_mobs())
|
|
break //only capture one mob at a time
|
|
|
|
/obj/structure/spacevine/proc/entangle(mob/living/victim)
|
|
if(isnull(victim) || isvineimmune(victim))
|
|
return
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
mutation.on_buckle(src, victim)
|
|
if((victim.stat != DEAD) && (victim.buckled != src) && can_tangle) //not dead and not captured and can tangle
|
|
to_chat(victim, span_userdanger("The vines [pick("wind", "tangle", "tighten")] around you!"))
|
|
buckle_mob(victim, force = TRUE)
|
|
|
|
/// Finds a target tile to spread to. If checks pass it will spread to it and also proc on_spread on target.
|
|
/obj/structure/spacevine/proc/spread()
|
|
if(isnull(master)) //If we've lost our controller, something has gone terribly wrong.
|
|
return
|
|
|
|
var/direction = pick(GLOB.cardinals)
|
|
var/turf/stepturf = get_step(src, direction)
|
|
if(!istype(stepturf))
|
|
return
|
|
|
|
if(is_space_or_openspace(stepturf) || !stepturf.Enter(src))
|
|
return
|
|
if(ischasm(stepturf) && !HAS_TRAIT(stepturf, TRAIT_CHASM_STOPPED))
|
|
return
|
|
if(islava(stepturf) && !HAS_TRAIT(stepturf, TRAIT_LAVA_STOPPED))
|
|
return
|
|
var/obj/structure/spacevine/spot_taken = locate() in stepturf
|
|
var/datum/spacevine_mutation/vine_eating/eating = locate() in mutations
|
|
if(!isnull(spot_taken)) //Proceed if there isn't a vine on the target turf, OR we have vine eater AND target vine is from our seed and doesn't.
|
|
if (isnull(eating))
|
|
return
|
|
if (spot_taken.mutations?.Find(eating))
|
|
return
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
mutation.on_spread(src, stepturf)
|
|
stepturf = get_step(src, direction)
|
|
var/obj/structure/spacevine/spawning_vine = master.spawn_spacevine_piece(stepturf, src)
|
|
if(NSCOMPONENT(direction))
|
|
spawning_vine.pixel_y = direction == NORTH ? -32 : 32
|
|
animate(spawning_vine, pixel_y = 0, time = 1 SECONDS)
|
|
else
|
|
spawning_vine.pixel_x = direction == EAST ? -32 : 32
|
|
animate(spawning_vine, pixel_x = 0, time = 1 SECONDS)
|
|
|
|
/// Destroying an explosive vine sets off a chain reaction
|
|
/obj/structure/spacevine/ex_act(severity, target)
|
|
var/index
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
index += mutation.on_explosion(severity, target, src)
|
|
if(!index && prob(34 * severity))
|
|
qdel(src)
|
|
|
|
return TRUE
|
|
|
|
/obj/structure/spacevine/should_atmos_process(datum/gas_mixture/air, exposed_temperature)
|
|
return (always_atmos_process || exposed_temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD || exposed_temperature < VINE_FREEZING_POINT || !can_spread)//if you're room temperature you're safe
|
|
|
|
/obj/structure/spacevine/atmos_expose(datum/gas_mixture/air, exposed_temperature)
|
|
for(var/datum/spacevine_mutation/mutation in mutations)
|
|
mutation.additional_atmos_processes(src, air)
|
|
if(!can_spread && (exposed_temperature >= VINE_FREEZING_POINT || (trait_flags & SPACEVINE_COLD_RESISTANT)))
|
|
can_spread = TRUE // not returning here just in case its now a plasmafire and the kudzu should be deleted
|
|
if(exposed_temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD && !(trait_flags & SPACEVINE_HEAT_RESISTANT))
|
|
qdel(src)
|
|
else if (exposed_temperature < VINE_FREEZING_POINT && !(trait_flags & SPACEVINE_COLD_RESISTANT))
|
|
can_spread = FALSE
|
|
|
|
/obj/structure/spacevine/CanAllowThrough(atom/movable/mover, border_dir)
|
|
. = ..()
|
|
if(isvineimmune(mover))
|
|
return TRUE
|
|
|
|
/obj/structure/spacevine/proc/block_sunlight()
|
|
AddElement(/datum/element/give_turf_traits, string_list(list(TRAIT_TURF_SUN_BLOCKED)))
|
|
|
|
/obj/structure/spacevine/proc/unblock_sunlight()
|
|
RemoveElement(/datum/element/give_turf_traits, string_list(list(TRAIT_TURF_SUN_BLOCKED)))
|