Working on vines.

This commit is contained in:
Zuhayr
2015-02-18 23:37:27 +10:30
parent ae1161184c
commit 728cb3cffa
11 changed files with 147 additions and 116 deletions
+7 -6
View File
@@ -47,10 +47,11 @@
for(var/rid in seed.chems)
var/list/reagent_data = seed.chems[rid]
var/rtotal = reagent_data[1]
if(reagent_data.len > 1 && potency > 0)
rtotal += round(potency/reagent_data[2])
reagents.add_reagent(rid,max(1,rtotal))
if(reagent_data && reagent_data.len)
var/rtotal = reagent_data[1]
if(reagent_data.len > 1 && potency > 0)
rtotal += round(potency/reagent_data[2])
reagents.add_reagent(rid,max(1,rtotal))
update_desc()
if(reagents.total_volume > 0)
bitesize = 1+round(reagents.total_volume / 2, 1)
@@ -119,7 +120,7 @@
desc += " mushroom"
else
desc += " fruit"
plant_controller.product_descs[seed.uid] = desc
plant_controller.product_descs["[seed.uid]"] = desc
desc += ". Delicious! Probably."
/obj/item/weapon/reagent_containers/food/snacks/grown/update_icon()
@@ -184,7 +185,7 @@
del(src)
return
else if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || (istype(W, /obj/item/weapon/twohanded/fireaxe) && W:wielded) || istype(W, /obj/item/weapon/melee/energy))
if(seed.get_trait(TRAIT_PRODUCT_ICON) == "mushroom7")
if(seed.chems && !isnull(seed.chems["woodpulp"]))
user.show_message("<span class='notice'>You make planks out of \the [src]!</span>", 1)
for(var/i=0,i<2,i++)
var/obj/item/stack/sheet/wood/NG = new (user.loc)
+1
View File
@@ -362,6 +362,7 @@
if(additional_chems)
var/list/possible_chems = list(
"woodpulp",
"bicaridine",
"hyperzine",
"cryoxadone",
+21 -18
View File
@@ -1,8 +1,8 @@
// Attempts to offload processing for the spreading plants from the MC.
// Processes vines/spreading plants.
#define PLANTS_PER_TICK 5
#define PLANT_TICK_TIME 10
#define PLANTS_PER_TICK 100
#define PLANT_TICK_TIME 50
// Debug for testing seed genes.
/client/proc/show_plant_genes()
@@ -25,9 +25,8 @@ var/global/datum/controller/plants/plant_controller // Set in New().
var/plants_per_tick = PLANTS_PER_TICK
var/plant_tick_time = PLANT_TICK_TIME
var/list/product_descs = list() // Stores generated fruit descs.
var/list/next_plants = list() // All queued plants.
var/list/plant_queue = list() // All queued plants.
var/list/seeds = list() // All seed data stored here.
var/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness.
var/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds.
@@ -107,6 +106,9 @@ var/global/datum/controller/plants/plant_controller // Set in New().
if(seed.consume_gasses)
seed.consume_gasses["phoron"] = null
seed.consume_gasses["carbon_dioxide"] = null
if(seed.chems && !isnull(seed.chems["pacid"]))
seed.chems["pacid"] = null // Eating through the hull will make these plants completely inviable, albeit very dangerous.
seed.chems -= null // Setting to null does not actually remove the entry, which is weird.
seed.set_trait(TRAIT_IDEAL_HEAT,293)
seed.set_trait(TRAIT_HEAT_TOLERANCE,20)
seed.set_trait(TRAIT_IDEAL_LIGHT,8)
@@ -125,19 +127,20 @@ var/global/datum/controller/plants/plant_controller // Set in New().
sleep(plant_tick_time)
else
processed = 0
var/list/plants = next_plants
next_plants = list()
for(var/x=0;x<plants_per_tick;x++)
if(!plants.len)
break
sleep(-1)
var/obj/effect/plant/plant = pick(plants)
plants -= plant
plant.process()
processed++
if(plants.len)
next_plants |= plants
sleep(plant_tick_time - processed)
if(plant_queue.len)
var/target_to_process = min(plant_queue.len,PLANT_TICK_TIME)
for(var/x=0;x<target_to_process;x++)
if(!plant_queue.len)
break
var/obj/effect/plant/plant = pick(plant_queue)
if(!istype(plant))
world << "<span class='danger'>Null or non-plant entry in plant controller queue.</span>"
break
plant_queue -= plant
sleep(1) // Stagger processing out so previous tick can resolve (overlapping plant segments etc)
plant.process()
processed++
sleep(max(1,(plant_tick_time-processed)))
/datum/controller/plants/proc/add_plant(var/obj/effect/plant/plant)
next_plants |= plant
plant_queue |= plant
+1
View File
@@ -443,6 +443,7 @@
name = "towercap"
seed_name = "tower cap"
display_name = "tower caps"
chems = list("woodpulp" = list(10,1))
mutants = null
/datum/seed/mushroom/towercap/New()
+38 -31
View File
@@ -30,8 +30,8 @@
/obj/effect/dead_plant/attackby()
..()
for(var/obj/effect/plant/neighbor in view(1,src))
neighbor.wake_up()
for(var/obj/effect/plant/neighbor in range(1))
neighbor.update_neighbors()
del(src)
/obj/effect/plant
@@ -50,13 +50,12 @@
var/growth_type = 0
var/max_growth = 0
var/list/children = list()
var/list/neighbors = list()
var/obj/effect/plant/parent
var/datum/seed/seed
var/floor = 0
var/spread_chance = 40
var/spread_distance = 3
var/spread_into_adjacent = 60
var/evolve_chance = 2
var/last_tick = 0
var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant
@@ -64,9 +63,14 @@
/obj/effect/plant/single
spread_chance = 0
/obj/effect/plant/New(var/newloc, var/datum/seed/newseed)
/obj/effect/plant/New(var/newloc, var/datum/seed/newseed, var/obj/effect/plant/newparent)
..()
if(!newparent)
parent = src
else
parent = newparent
if(!plant_controller)
sleep(250) // ugly hack, should mean roundstart plants are fine.
if(!plant_controller)
@@ -102,22 +106,27 @@
if(max_growth > 2 && prob(50))
max_growth-- //Ensure some variation in final sprite, makes the carpet of crap look less wonky.
spread_into_adjacent = round(seed.get_trait(TRAIT_POTENCY)/2)
spread_distance = ((growth_type>0) ? round(spread_into_adjacent/2) : round(spread_into_adjacent/15))
spread_chance = round(spread_into_adjacent/2)
spread_chance = seed.get_trait(TRAIT_POTENCY)
spread_distance = ((growth_type>0) ? round(spread_chance*0.6) : round(spread_chance*0.3))
set_dir(calc_dir())
update_icon()
wake_up()
last_tick = world.timeofday
spawn(1)
plant_controller.add_plant(src)
// Some plants eat through plating.
if(!isnull(seed.chems["pacid"]))
var/turf/T = get_turf(src)
T.ex_act(prob(80) ? 3 : 2)
/obj/effect/plant/update_icon()
//TODO: should really be caching this.
refresh_icon()
if(growth_type == 0 && !floor)
src.transform = null
var/matrix/M = matrix()
M.Translate(0,-(rand(12,14))) // should make the plant flush against the wall it's meant to be growing from.
// should make the plant flush against the wall it's meant to be growing from.
M.Translate(0,-(rand(12,14)))
switch(dir)
if(WEST)
M.Turn(90)
@@ -141,7 +150,13 @@
SetLuminosity(0)
/obj/effect/plant/proc/refresh_icon()
var/growth = min(max_growth,max(1,round(health/growth_threshold)))
var/growth = min(max_growth,round(health/growth_threshold))
var/at_fringe = get_dist(src,parent)
if(at_fringe >= (spread_distance-3))
max_growth--
if(at_fringe >= (spread_distance-2))
max_growth--
max_growth = max(1,max_growth)
if(growth_type > 0)
switch(growth_type)
if(1)
@@ -155,24 +170,14 @@
else
icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[growth]"
layer = (growth == max_growth ? 4 : 3)
/obj/effect/plant/Del()
if(children && children.len)
die_off(null,1)
..()
/obj/effect/plant/proc/get_dist_to_parent(var/current_count)
if(!parent)
return current_count
current_count++
return parent.get_dist_to_parent(current_count)
/obj/effect/plant/proc/get_root()
if(parent)
return parent.get_root()
if(growth>2 && growth == max_growth)
layer = 5
opacity = 1
if(!isnull(seed.chems["woodpulp"]))
density = 1
else
return src
layer = 3
density = 0
/obj/effect/plant/proc/calc_dir(turf/location = loc)
set background = 1
@@ -209,6 +214,8 @@
/obj/effect/plant/attackby(var/obj/item/weapon/W, var/mob/user)
plant_controller.add_plant(src)
if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel))
if(!seed)
user << "There is nothing to take a sample from in \the [src]."
@@ -240,7 +247,7 @@
/obj/effect/plant/proc/check_health()
if(health <= 0)
die_off(1)
die_off()
/obj/effect/plant/proc/is_mature()
return (health < (max_health/3))
@@ -1,8 +1,31 @@
#define NEIGHBOR_REFRESH_TIME 100
/obj/effect/plant/proc/update_neighbors()
// Update our list of valid neighboring turfs.
neighbors = list()
for(var/turf/simulated/floor/floor in range(1,src))
if(get_dist(parent, floor) > spread_distance)
continue
if((locate(/obj/effect/plant) in floor.contents) || (locate(/obj/effect/dead_plant) in floor.contents) )
continue
if(floor.density)
if(!isnull(seed.chems["pacid"]))
spawn(rand(5,25)) floor.ex_act(3)
continue
else if(!floor.Enter(src))
continue
neighbors |= floor
// Update all of our friends.
var/turf/T = get_turf(src)
for(var/obj/effect/plant/neighbor in range(1,src))
neighbor.neighbors -= T
/obj/effect/plant/process()
// Something is very wrong, kill ourselves.
if(!seed)
die_off()
return 0
// Handle life.
var/turf/simulated/T = get_turf(src)
@@ -10,26 +33,13 @@
health -= seed.handle_environment(T, T.return_air(),1)
if(health < max_health)
health += rand(3,5)
refresh_icon()
if(health > max_health)
health = max_health
refresh_icon()
if(buckled_mob)
seed.do_sting(buckled_mob,src)
if(seed.get_trait(TRAIT_CARNIVOROUS))
seed.do_thorns(buckled_mob,src)
var/list/possible_locs = list()
var/failed_turfs = 0
for(var/turf/simulated/floor/floor in range(1))
if((locate(/obj/effect/plant) in floor.contents) || (locate(/obj/effect/dead_plant) in floor.contents) || floor.density)
failed_turfs++
if(floor.Enter(src))
possible_locs |= floor
if(health == max_health && failed_turfs > 3 && !plant)
else if(health == max_health && !plant)
plant = new(T,seed)
plant.dir = src.dir
plant.transform = src.transform
plant.age = seed.get_trait(TRAIT_MATURATION)-1
plant.update_icon()
if(growth_type==0) //Vines do not become invisible.
@@ -37,42 +47,44 @@
else
plant.layer = layer + 0.1
if(possible_locs.len && prob(spread_chance))
if(buckled_mob)
seed.do_sting(buckled_mob,src)
if(seed.get_trait(TRAIT_CARNIVOROUS))
seed.do_thorns(buckled_mob,src)
if(world.time >= last_tick+NEIGHBOR_REFRESH_TIME)
last_tick = world.time
update_neighbors()
if(neighbors.len && prob(spread_chance))
for(var/i=1,i<=seed.get_trait(TRAIT_YIELD),i++)
if(!possible_locs.len)
break
if(prob(spread_into_adjacent))
var/turf/target_turf = pick(possible_locs)
possible_locs -= target_turf
var/obj/effect/plant/child = new(target_turf, seed)
child.parent = get_root()
child.parent.children |= child
if(prob(spread_chance))
sleep(rand(3,5))
if(!neighbors.len)
break
var/turf/target_turf = pick(neighbors)
var/obj/effect/plant/child = new(get_turf(src),seed,parent)
spawn(1) // This should do a little bit of animation.
child.loc = target_turf
child.update_icon()
// Update neighboring squares.
for(var/obj/effect/plant/neighbor in range(1,target_turf))
neighbor.neighbors -= target_turf
if(buckled_mob || health != max_health || possible_locs.len)
wake_up() // We still need to process!
/obj/effect/plant/proc/wake_up()
if(plant_controller)
// We shouldn't have spawned if the controller doesn't exist.
check_health()
if(neighbors.len && health == max_health)
plant_controller.add_plant(src)
/obj/effect/plant/proc/die_off(var/no_remains, var/no_del)
// Remove ourselves from our parent.
if(parent && parent.children)
parent.children -= src
// Kill off any of our children (and as an added bonus, other plants in this area)
for(var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant in get_turf(src))
plant.dead = 1
plant.update_icon()
// Cause the plants around us to update.
if(children && children.len)
for(var/obj/effect/plant/child in children)
child.die_off()
for(var/obj/effect/plant/neighbor in view(1,src))
neighbor.wake_up()
/obj/effect/plant/proc/die_off()
// Kill off our plant.
if(plant) plant.die()
// This turf is clear now, let our buddies know.
var/turf/T = get_turf(src)
for(var/obj/effect/plant/neighbor in range(1,src))
neighbor.neighbors |= T
plant_controller.add_plant(neighbor)
spawn(1) if(src) del(src)
if(!no_remains && !(locate(/obj/effect/dead_plant) in get_turf(src)))
var/obj/effect/dead_plant/plant_remains = new(get_turf(src))
plant_remains.icon = src.icon
plant_remains.icon_state = src.icon_state
if(!no_del)
del(src)
#undef NEIGHBOR_REFRESH_TIME
@@ -1,5 +1,5 @@
/obj/effect/plant/HasProximity(var/atom/movable/AM)
wake_up()
if(!is_mature() || seed.get_trait(TRAIT_SPREAD) != 2)
return
@@ -11,11 +11,10 @@
entangle(M)
/obj/effect/plant/attack_hand(mob/user as mob)
wake_up()
// Todo, cause damage.
manual_unbuckle(user)
/obj/effect/plant/proc/trodden_on(var/mob/living/victim)
wake_up()
if(!is_mature())
return
var/mob/living/carbon/human/H = victim
+1 -1
View File
@@ -521,7 +521,7 @@
A.hydrotray_type = src.type
del(src)
else if(O.force && seed)
user.visible_message("<span class='danger'>\The [src] attacks the [seed.display_name] with \the [O]!</span>")
user.visible_message("<span class='danger'>\The [user] attacks the [seed.display_name] with \the [O]!</span>")
if(!dead)
health -= O.force
check_health()
+2 -3
View File
@@ -19,7 +19,7 @@
/obj/machinery/portable_atmospherics/hydroponics/soil/CanPass()
return 1
// This is a hack pending a proper rewrite of the plant controller.
// Holder for vine plants.
// Icons for plants are generated as overlays, so setting it to invisible wouldn't work.
// Hence using a blank icon.
/obj/machinery/portable_atmospherics/hydroponics/soil/invisible
@@ -43,7 +43,7 @@
/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/harvest()
..()
if(!seed)
if(!seed) // Repeat harvests are a thing.
del(src)
/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/die()
@@ -62,5 +62,4 @@
for(var/obj/effect/plant/plant in get_turf(src))
if(plant.invisibility == INVISIBILITY_MAXIMUM)
plant.invisibility = initial(plant.invisibility)
plant.die_off()
..()
+9 -2
View File
@@ -192,6 +192,13 @@ datum
M.resistances += self.data
return
woodpulp
name = "Wood Pulp"
id = "woodpulp"
description = "A mass of wood fibers."
reagent_state = LIQUID
color = "#B97A57"
#define WATER_LATENT_HEAT 19000 // How much heat is removed when applied to a hot turf, in J/unit (19000 makes 120 u of water roughly equivalent to 4L)
water
name = "Water"
@@ -260,13 +267,13 @@ datum
reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)
if (istype(M, /mob/living/carbon/slime))
var/mob/living/carbon/slime/S = M
var/mob/living/carbon/slime/S = M
S.apply_water(volume)
if(method == TOUCH && isliving(M))
M.adjust_fire_stacks(-(volume / 10))
if(M.fire_stacks <= 0)
M.ExtinguishMob()
return
return
water/holywater
name = "Holy Water"