Files
Yogstation/code/modules/events/spacevine.dm
phil235 1ea0e47aa4 Visible_message() when being attacked by melee or projectile is replaced by a simple message only to the target instead of all viewers.
The message when firing a gun is removed.
To keep things balanced melee attacks (punches, alien attacks, animal attacks, etc...) now show a visual effect (similar to what we current have with item attacks.
Fixes muzzle flash effect not appearing for mech guns.
Fixes muzzle flash effect not appearing for certain ranged animal.
Fixes the item attack effect not being visible to camera viewers and mech occupants.
Fixes toy guns foam dart not dropping on the ground when shooting a mob on the same tile as us.
Fixes toy smg magazine sprite being invisible sometimes.
Fixes foam dart not facing the correct direction when fired.
Changes the bullet projectile sprite to have a slight tracer effect so as to be more visible.
2016-10-13 19:21:30 +02:00

622 lines
17 KiB
Plaintext

/datum/round_event_control/spacevine
name = "Spacevine"
typepath = /datum/round_event/spacevine
weight = 15
max_occurrences = 3
min_players = 10
/datum/round_event/spacevine/start()
var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
var/obj/structure/spacevine/SV = new()
for(var/area/hallway/A in world)
for(var/turf/F in A)
if(F.Enter(SV))
turfs += F
qdel(SV)
if(turfs.len) //Pick a turf to spawn at if we can
var/turf/T = pick(turfs)
new/obj/effect/spacevine_controller(T) //spawn a controller at turf
/datum/spacevine_mutation
var/name = ""
var/severity = 1
var/hue
var/quality
/datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/structure/spacevine/holder)
holder.mutations |= src
holder.color = hue
/datum/spacevine_mutation/proc/process_mutation(obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/proc/process_temperature(obj/structure/spacevine/holder, temp, volume)
return
/datum/spacevine_mutation/proc/on_birth(obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_grow(obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_death(obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_hit(obj/structure/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
. = expected_damage
/datum/spacevine_mutation/proc/on_cross(obj/structure/spacevine/holder, mob/crosser)
return
/datum/spacevine_mutation/proc/on_chem(obj/structure/spacevine/holder, datum/reagent/R)
return
/datum/spacevine_mutation/proc/on_eat(obj/structure/spacevine/holder, mob/living/eater)
return
/datum/spacevine_mutation/proc/on_spread(obj/structure/spacevine/holder, turf/target)
return
/datum/spacevine_mutation/proc/on_buckle(obj/structure/spacevine/holder, mob/living/buckled)
return
/datum/spacevine_mutation/proc/on_explosion(severity, target, obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/space_covering
name = "space protective"
hue = "#aa77aa"
quality = POSITIVE
/turf/open/floor/vines
color = "#aa77aa"
icon_state = "vinefloor"
broken_states = list()
//All of this shit is useless for vines
/turf/open/floor/vines/attackby()
return
/turf/open/floor/vines/burn_tile()
return
/turf/open/floor/vines/break_tile()
return
/turf/open/floor/vines/make_plating()
return
/turf/open/floor/vines/break_tile_to_plating()
return
/turf/open/floor/vines/ex_act(severity, target)
if(severity < 3 || target == src)
ChangeTurf(src.baseturf)
/turf/open/floor/vines/narsie_act()
if(prob(20))
ChangeTurf(src.baseturf) //nar sie eats this shit
/turf/open/floor/vines/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
if(prob(50))
ChangeTurf(src.baseturf)
/turf/open/floor/vines/ChangeTurf(turf/open/floor/T)
for(var/obj/structure/spacevine/SV in src)
qdel(SV)
. = ..()
UpdateAffectingLights()
/datum/spacevine_mutation/space_covering
var/static/list/coverable_turfs
/datum/spacevine_mutation/space_covering/New()
. = ..()
if(!coverable_turfs)
coverable_turfs = typecacheof(list(
/turf/open/space
))
coverable_turfs -= typecacheof(list(
/turf/open/space/transit
))
/datum/spacevine_mutation/space_covering/on_grow(obj/structure/spacevine/holder)
process_mutation(holder)
/datum/spacevine_mutation/space_covering/process_mutation(obj/structure/spacevine/holder)
var/turf/T = get_turf(holder)
if(is_type_in_typecache(T, coverable_turfs))
var/currtype = T.type
T.ChangeTurf(/turf/open/floor/vines)
T.baseturf = currtype
/datum/spacevine_mutation/space_covering/on_death(obj/structure/spacevine/holder)
var/turf/T = get_turf(holder)
if(istype(T, /turf/open/floor/vines))
T.ChangeTurf(T.baseturf)
/datum/spacevine_mutation/bluespace
name = "bluespace"
hue = "#3333ff"
quality = MINOR_NEGATIVE
/datum/spacevine_mutation/bluespace/on_spread(obj/structure/spacevine/holder, turf/target)
if(holder.energy > 1 && !locate(/obj/structure/spacevine) in target)
holder.master.spawn_spacevine_piece(target, holder)
/datum/spacevine_mutation/light
name = "light"
hue = "#ffff00"
quality = POSITIVE
severity = 4
/datum/spacevine_mutation/light/on_grow(obj/structure/spacevine/holder)
if(holder.energy)
holder.SetLuminosity(severity, 3)
/datum/spacevine_mutation/toxicity
name = "toxic"
hue = "#ff00ff"
severity = 10
quality = NEGATIVE
/datum/spacevine_mutation/toxicity/on_cross(obj/structure/spacevine/holder, mob/living/crosser)
if(issilicon(crosser))
return
if(prob(severity) && istype(crosser) && !isvineimmune(crosser))
crosser << "<span class='alert'>You accidently touch the vine and feel a strange sensation.</span>"
crosser.adjustToxLoss(5)
/datum/spacevine_mutation/toxicity/on_eat(obj/structure/spacevine/holder, mob/living/eater)
if(!isvineimmune(eater))
eater.adjustToxLoss(5)
/datum/spacevine_mutation/explosive //OH SHIT IT CAN CHAINREACT RUN!!!
name = "explosive"
hue = "#ff0000"
quality = NEGATIVE
severity = 2
/datum/spacevine_mutation/explosive/on_explosion(explosion_severity, target, obj/structure/spacevine/holder)
if(explosion_severity < 3)
qdel(src)
else
. = 1
QDEL_IN(src, 5)
/datum/spacevine_mutation/explosive/on_death(obj/structure/spacevine/holder, mob/hitter, obj/item/I)
explosion(holder.loc, 0, 0, severity, 0, 0)
/datum/spacevine_mutation/fire_proof
name = "fire proof"
hue = "#ff8888"
quality = MINOR_NEGATIVE
/datum/spacevine_mutation/fire_proof/process_temperature(obj/structure/spacevine/holder, temp, volume)
return 1
/datum/spacevine_mutation/fire_proof/on_hit(obj/structure/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
if(I && I.damtype == "fire")
. = 0
else
. = expected_damage
/datum/spacevine_mutation/vine_eating
name = "vine eating"
hue = "#ff7700"
quality = MINOR_NEGATIVE
/datum/spacevine_mutation/vine_eating/on_spread(obj/structure/spacevine/holder, turf/target)
var/obj/structure/spacevine/prey = locate() in target
if(prey && !prey.mutations.Find(src)) //Eat all vines that are not of the same origin
qdel(prey)
/datum/spacevine_mutation/aggressive_spread //very OP, but im out of other ideas currently
name = "aggressive spreading"
hue = "#333333"
severity = 3
quality = NEGATIVE
/datum/spacevine_mutation/aggressive_spread/on_spread(obj/structure/spacevine/holder, turf/target)
target.ex_act(severity, src) // vine immunity handled at /mob/ex_act
/datum/spacevine_mutation/aggressive_spread/on_buckle(obj/structure/spacevine/holder, mob/living/buckled)
buckled.ex_act(severity, src)
/datum/spacevine_mutation/transparency
name = "transparent"
hue = ""
quality = POSITIVE
/datum/spacevine_mutation/transparency/on_grow(obj/structure/spacevine/holder)
holder.SetOpacity(0)
holder.alpha = 125
/datum/spacevine_mutation/oxy_eater
name = "oxygen consuming"
hue = "#ffff88"
severity = 3
quality = NEGATIVE
/datum/spacevine_mutation/oxy_eater/process_mutation(obj/structure/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases["o2"])
return
GM.gases["o2"][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/nitro_eater
name = "nitrogen consuming"
hue = "#8888ff"
severity = 3
quality = NEGATIVE
/datum/spacevine_mutation/nitro_eater/process_mutation(obj/structure/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases["n2"])
return
GM.gases["n2"][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/carbondioxide_eater
name = "CO2 consuming"
hue = "#00ffff"
severity = 3
quality = POSITIVE
/datum/spacevine_mutation/carbondioxide_eater/process_mutation(obj/structure/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases["co2"])
return
GM.gases["co2"][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/plasma_eater
name = "toxins consuming"
hue = "#ffbbff"
severity = 3
quality = POSITIVE
/datum/spacevine_mutation/plasma_eater/process_mutation(obj/structure/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases["plasma"])
return
GM.gases["plasma"][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/thorns
name = "thorny"
hue = "#666666"
severity = 10
quality = NEGATIVE
/datum/spacevine_mutation/thorns/on_cross(obj/structure/spacevine/holder, mob/living/crosser)
if(prob(severity) && istype(crosser) && !isvineimmune(holder))
var/mob/living/M = crosser
M.adjustBruteLoss(5)
M << "<span class='alert'>You cut yourself on the thorny vines.</span>"
/datum/spacevine_mutation/thorns/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
if(prob(severity) && istype(hitter) && !isvineimmune(holder))
var/mob/living/M = hitter
M.adjustBruteLoss(5)
M << "<span class='alert'>You cut yourself on the thorny vines.</span>"
. = expected_damage
/datum/spacevine_mutation/woodening
name = "hardened"
hue = "#997700"
quality = NEGATIVE
/datum/spacevine_mutation/woodening/on_grow(obj/structure/spacevine/holder)
if(holder.energy)
holder.density = 1
holder.max_integrity = 100
holder.obj_integrity = holder.max_integrity
/datum/spacevine_mutation/woodening/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
if(I.is_sharp())
. = expected_damage * 0.5
else
. = expected_damage
/datum/spacevine_mutation/flowering
name = "flowering"
hue = "#0A480D"
quality = NEGATIVE
severity = 10
/datum/spacevine_mutation/flowering/on_grow(obj/structure/spacevine/holder)
if(holder.energy == 2 && prob(severity) && !locate(/obj/structure/alien/resin/flower_bud_enemy) in range(5,holder))
new/obj/structure/alien/resin/flower_bud_enemy(get_turf(holder))
/datum/spacevine_mutation/flowering/on_cross(obj/structure/spacevine/holder, mob/living/crosser)
holder.entangle(crosser)
// SPACE VINES (Note that this code is very similar to Biomass code)
/obj/structure/spacevine
name = "space vines"
desc = "An extremely expansionistic species of vine."
icon = 'icons/effects/spacevines.dmi'
icon_state = "Light1"
anchored = 1
density = 0
layer = SPACEVINE_LAYER
mouse_opacity = 2 //Clicking anywhere on the turf is good enough
pass_flags = PASSTABLE | PASSGRILLE
obj_integrity = 50
max_integrity = 50
var/energy = 0
var/obj/effect/spacevine_controller/master = null
var/list/mutations = list()
/obj/structure/spacevine/examine(mob/user)
..()
var/text = "This one is a"
if(mutations.len)
for(var/A in mutations)
var/datum/spacevine_mutation/SM = A
text += " [SM.name]"
else
text += " normal"
text += " vine."
user << text
/obj/structure/spacevine/Destroy()
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_death(src)
if(master)
master.vines -= src
master.growth_queue -= src
if(!master.vines.len)
var/obj/item/seeds/kudzu/KZ = new(loc)
KZ.mutations |= mutations
KZ.potency = min(100, master.mutativness * 10)
KZ.production = (master.spread_cap / initial(master.spread_cap)) * 50
mutations = list()
SetOpacity(0)
if(has_buckled_mobs())
unbuckle_all_mobs(force=1)
return ..()
/obj/structure/spacevine/proc/on_chem_effect(datum/reagent/R)
var/override = 0
for(var/datum/spacevine_mutation/SM in mutations)
override += SM.on_chem(src, R)
if(!override && istype(R, /datum/reagent/toxin/plantbgone))
if(prob(50))
qdel(src)
/obj/structure/spacevine/proc/eat(mob/eater)
var/override = 0
for(var/datum/spacevine_mutation/SM in mutations)
override += SM.on_eat(src, eater)
if(!override)
if(prob(10))
eater.say("Nom")
qdel(src)
/obj/structure/spacevine/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/scythe))
user.changeNext_move(CLICK_CD_MELEE)
for(var/obj/structure/spacevine/B in orange(1,src))
B.take_damage(W.force * 4, BRUTE, "melee", 1)
return
else
return ..()
/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user)
var/damage_dealt = I.force
if(I.is_sharp())
damage_dealt *= 4
if(I.damtype == BURN)
damage_dealt *= 4
for(var/datum/spacevine_mutation/SM in mutations)
damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further
take_damage(damage_dealt, I.damtype, "melee", 1)
/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/weapons/slash.ogg', 50, 1)
else
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
/obj/structure/spacevine/Crossed(mob/crosser)
if(isliving(crosser))
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_cross(src, crosser)
/obj/structure/spacevine/attack_hand(mob/user)
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_hit(src, user)
user_unbuckle_mob(user, user)
/obj/structure/spacevine/attack_paw(mob/living/user)
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_hit(src, user)
user_unbuckle_mob(user,user)
/obj/structure/spacevine/attack_alien(mob/living/user)
eat(user)
/obj/effect/spacevine_controller
invisibility = INVISIBILITY_ABSTRACT
var/list/obj/structure/spacevine/vines = list()
var/list/growth_queue = list()
var/spread_multiplier = 5
var/spread_cap = 30
var/list/mutations_list = list()
var/mutativness = 1
/obj/effect/spacevine_controller/New(loc, list/muts, mttv, spreading)
spawn_spacevine_piece(loc, , muts)
START_PROCESSING(SSobj, src)
init_subtypes(/datum/spacevine_mutation/, mutations_list)
if(mttv != null)
mutativness = mttv / 10
if(spreading != null)
spread_cap *= spreading / 50
spread_multiplier /= spreading / 50
/obj/effect/spacevine_controller/ex_act() //only killing all vines will end this suffering
return
/obj/effect/spacevine_controller/singularity_act()
return
/obj/effect/spacevine_controller/singularity_pull()
return
/obj/effect/spacevine_controller/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/structure/spacevine/parent, list/muts)
var/obj/structure/spacevine/SV = new(location)
growth_queue += SV
vines += SV
SV.master = src
if(muts && muts.len)
for(var/datum/spacevine_mutation/M in muts)
M.add_mutation_to_vinepiece(SV)
return
if(parent)
SV.mutations |= parent.mutations
SV.color = parent.color
if(prob(mutativness))
var/datum/spacevine_mutation/randmut = pick(mutations_list - SV.mutations)
randmut.add_mutation_to_vinepiece(SV)
for(var/datum/spacevine_mutation/SM in SV.mutations)
SM.on_birth(SV)
/obj/effect/spacevine_controller/process()
if(!vines)
qdel(src) //space vines exterminated. Remove the controller
return
if(!growth_queue)
qdel(src) //Sanity check
return
var/length = 0
length = min( spread_cap , max( 1 , vines.len / spread_multiplier ) )
var/i = 0
var/list/obj/structure/spacevine/queue_end = list()
for(var/obj/structure/spacevine/SV in growth_queue)
if(qdeleted(SV))
continue
i++
queue_end += SV
growth_queue -= SV
for(var/datum/spacevine_mutation/SM in SV.mutations)
SM.process_mutation(SV)
if(SV.energy < 2) //If tile isn't fully grown
if(prob(20))
SV.grow()
else //If tile is fully grown
SV.entangle_mob()
//if(prob(25))
SV.spread()
if(i >= length)
break
growth_queue = growth_queue + queue_end
/obj/structure/spacevine/proc/grow()
if(!energy)
src.icon_state = pick("Med1", "Med2", "Med3")
energy = 1
SetOpacity(1)
else
src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
energy = 2
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_grow(src)
/obj/structure/spacevine/proc/entangle_mob()
if(!has_buckled_mobs() && prob(25))
for(var/mob/living/V in src.loc)
entangle(V)
if(has_buckled_mobs())
break //only capture one mob at a time
/obj/structure/spacevine/proc/entangle(mob/living/V)
if(!V || isvineimmune(V))
return
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_buckle(src, V)
if((V.stat != DEAD) && (V.buckled != src)) //not dead or captured
V << "<span class='danger'>The vines [pick("wind", "tangle", "tighten")] around you!</span>"
buckle_mob(V)
/obj/structure/spacevine/proc/spread()
var/direction = pick(cardinal)
var/turf/stepturf = get_step(src,direction)
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_spread(src, stepturf)
stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen
if(!locate(/obj/structure/spacevine, stepturf))
if(stepturf.Enter(src))
if(master)
master.spawn_spacevine_piece(stepturf, src)
/obj/structure/spacevine/ex_act(severity, target)
if(istype(target, type)) //if its agressive spread vine dont do anything
return
var/i
for(var/datum/spacevine_mutation/SM in mutations)
i += SM.on_explosion(severity, target, src)
if(!i && prob(100/severity))
qdel(src)
/obj/structure/spacevine/temperature_expose(null, temp, volume)
var/override = 0
for(var/datum/spacevine_mutation/SM in mutations)
override += SM.process_temperature(src, temp, volume)
if(!override)
qdel(src)
/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target, height=0)
if(isvineimmune(mover))
. = TRUE
else
. = ..()
/proc/isvineimmune(atom/A)
. = FALSE
if(isliving(A))
var/mob/living/M = A
if(("vines" in M.faction) || ("plants" in M.faction))
. = TRUE