mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-26 05:27:39 +01:00
Merge branch 'dev' into Pics
Conflicts: code/modules/paperwork/photography.dm
This commit is contained in:
+103
-32
@@ -634,20 +634,60 @@ as a single icon. Useful for when you want to manipulate an icon via the above a
|
||||
The _flatIcons list is a cache for generated icon files.
|
||||
*/
|
||||
|
||||
proc
|
||||
getFlatIcon(atom/A, dir) // 1 = use cache, 2 = override cache, 0 = ignore cache
|
||||
proc // Creates a single icon from a given /atom or /image. Only the first argument is required.
|
||||
getFlatIcon(image/A, defdir=A.dir, deficon=A.icon, defstate=A.icon_state, defblend=A.blend_mode)
|
||||
// We start with a blank canvas, otherwise some icon procs crash silently
|
||||
var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon
|
||||
if(!A)
|
||||
return flat
|
||||
if(A.alpha <= 0)
|
||||
return flat
|
||||
var/noIcon = FALSE
|
||||
|
||||
var/curicon
|
||||
if(A.icon)
|
||||
curicon = A.icon
|
||||
else
|
||||
curicon = deficon
|
||||
|
||||
if(!curicon)
|
||||
noIcon = TRUE // Do not render this object.
|
||||
|
||||
var/curstate
|
||||
if(A.icon_state)
|
||||
curstate = A.icon_state
|
||||
else
|
||||
curstate = defstate
|
||||
|
||||
if(!noIcon && !(curstate in icon_states(curicon)))
|
||||
if("" in icon_states(curicon))
|
||||
curstate = ""
|
||||
else
|
||||
noIcon = TRUE // Do not render this object.
|
||||
|
||||
var/curdir
|
||||
if(A.dir != 2)
|
||||
curdir = A.dir
|
||||
else
|
||||
curdir = defdir
|
||||
|
||||
var/curblend
|
||||
if(A.blend_mode == BLEND_DEFAULT)
|
||||
curblend = defblend
|
||||
else
|
||||
curblend = A.blend_mode
|
||||
|
||||
// Layers will be a sorted list of icons/overlays, based on the order in which they are displayed
|
||||
var/list/layers = list()
|
||||
|
||||
// Add the atom's icon itself
|
||||
if(A.icon)
|
||||
// Make a copy without pixel_x/y settings
|
||||
var/image/copy = image(icon=A.icon,icon_state=A.icon_state,layer=A.layer,dir=A.dir)
|
||||
var/image/copy
|
||||
// Add the atom's icon itself, without pixel_x/y offsets.
|
||||
if(!noIcon)
|
||||
copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir)
|
||||
copy.color = A.color
|
||||
copy.alpha = A.alpha
|
||||
copy.blend_mode = curblend
|
||||
layers[copy] = A.layer
|
||||
|
||||
// dir defaults to A's dir
|
||||
if(!dir) dir = A.dir
|
||||
|
||||
// Loop through the underlays, then overlays, sorting them into the layers list
|
||||
var/list/process = A.underlays // Current list being processed
|
||||
var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays
|
||||
@@ -662,7 +702,7 @@ proc
|
||||
if(!current) continue
|
||||
currentLayer = current:layer
|
||||
if(currentLayer<0) // Special case for FLY_LAYER
|
||||
if(currentLayer <= -1000) return 0
|
||||
if(currentLayer <= -1000) return flat
|
||||
if(pSet == 0) // Underlay
|
||||
currentLayer = A.layer+currentLayer/1000
|
||||
else // Overlay
|
||||
@@ -688,8 +728,6 @@ proc
|
||||
else // All done
|
||||
break
|
||||
|
||||
// We start with a blank canvas, otherwise some icon procs crash silently
|
||||
var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon
|
||||
var/icon/add // Icon of overlay being added
|
||||
|
||||
// Current dimensions of flattened icon
|
||||
@@ -699,24 +737,33 @@ proc
|
||||
|
||||
for(var/I in layers)
|
||||
|
||||
if(I:icon)
|
||||
if(I:icon_state)
|
||||
// Has icon and state set
|
||||
add = icon(I:icon, I:icon_state)
|
||||
else
|
||||
if(A.icon_state in icon_states(I:icon))
|
||||
// Inherits icon_state from atom
|
||||
add = icon(I:icon, A.icon_state)
|
||||
else
|
||||
// Uses default state ("")
|
||||
add = icon(I:icon)
|
||||
else if(I:icon_state)
|
||||
// Inherits icon from atom
|
||||
add = icon(A.icon, I:icon_state)
|
||||
else
|
||||
// Unknown
|
||||
if(I:alpha == 0)
|
||||
continue
|
||||
|
||||
if(I == copy) // 'I' is an /image based on the object being flattened.
|
||||
curblend = BLEND_OVERLAY
|
||||
add = icon(I:icon, I:icon_state, I:dir)
|
||||
// This checks for a silent failure mode of the icon routine. If the requested dir
|
||||
// doesn't exist in this icon state it returns a 32x32 icon with 0 alpha.
|
||||
if (I:dir != SOUTH && add.Width() == 32 && add.Height() == 32)
|
||||
// Check every pixel for blank (computationally expensive, but the process is limited
|
||||
// by the amount of film on the station, only happens when we hit something that's
|
||||
// turned, and bails at the very first pixel it sees.
|
||||
var/blankpixel;
|
||||
for(var/y;y<=32;y++)
|
||||
for(var/x;x<32;x++)
|
||||
blankpixel = isnull(add.GetPixel(x,y))
|
||||
if(!blankpixel)
|
||||
break
|
||||
if(!blankpixel)
|
||||
break
|
||||
// If we ALWAYS returned a null (which happens when GetPixel encounters something with alpha 0)
|
||||
if (blankpixel)
|
||||
// Pull the default direction.
|
||||
add = icon(I:icon, I:icon_state)
|
||||
else // 'I' is an appearance object.
|
||||
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend)
|
||||
|
||||
// Find the new dimensions of the flat icon to fit the added overlay
|
||||
addX1 = min(flatX1, I:pixel_x+1)
|
||||
addX2 = max(flatX2, I:pixel_x+add.Width())
|
||||
@@ -730,9 +777,14 @@ proc
|
||||
flatY1=addY1;flatY2=addY2
|
||||
|
||||
// Blend the overlay into the flattened icon
|
||||
flat.Blend(add,ICON_OVERLAY,I:pixel_x+2-flatX1,I:pixel_y+2-flatY1)
|
||||
flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1)
|
||||
|
||||
return flat
|
||||
if(A.color)
|
||||
flat.Blend(A.color, ICON_MULTIPLY)
|
||||
if(A.alpha < 255)
|
||||
flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY)
|
||||
|
||||
return icon(flat, "", SOUTH)
|
||||
|
||||
getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
|
||||
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.
|
||||
@@ -783,4 +835,23 @@ proc/adjust_brightness(var/color, var/value)
|
||||
RGB[1] = Clamp(RGB[1]+value,0,255)
|
||||
RGB[2] = Clamp(RGB[2]+value,0,255)
|
||||
RGB[3] = Clamp(RGB[3]+value,0,255)
|
||||
return rgb(RGB[1],RGB[2],RGB[3])
|
||||
return rgb(RGB[1],RGB[2],RGB[3])
|
||||
|
||||
proc/sort_atoms_by_layer(var/list/atoms)
|
||||
// Comb sort icons based on levels
|
||||
var/list/result = atoms.Copy()
|
||||
var/gap = result.len
|
||||
var/swapped = 1
|
||||
while (gap > 1 || swapped)
|
||||
swapped = 0
|
||||
if(gap > 1)
|
||||
gap = round(gap / 1.3) // 1.3 is the emperic comb sort coefficient
|
||||
if(gap < 1)
|
||||
gap = 1
|
||||
for(var/i = 1; gap + i <= result.len; i++)
|
||||
var/atom/l = result[i] //Fucking hate
|
||||
var/atom/r = result[gap+i] //how lists work here
|
||||
if(l.layer > r.layer) //no "result[i].layer" for me
|
||||
result.Swap(i, gap + i)
|
||||
swapped = 1
|
||||
return result
|
||||
|
||||
@@ -298,6 +298,13 @@ proc/tg_list2text(list/list, glue=",")
|
||||
/proc/angle2text(var/degree)
|
||||
return dir2text(angle2dir(degree))
|
||||
|
||||
//Converts a blend_mode constant to one acceptable to icon.Blend()
|
||||
/proc/blendMode2iconMode(blend_mode)
|
||||
switch(blend_mode)
|
||||
if(BLEND_MULTIPLY) return ICON_MULTIPLY
|
||||
if(BLEND_ADD) return ICON_ADD
|
||||
if(BLEND_SUBTRACT) return ICON_SUBTRACT
|
||||
else return ICON_OVERLAY
|
||||
|
||||
//Converts a rights bitfield into a string
|
||||
/proc/rights2text(rights,seperator="")
|
||||
|
||||
+11
-1
@@ -298,7 +298,17 @@
|
||||
|
||||
// Simple helper to face what you clicked on, in case it should be needed in more than one place
|
||||
/mob/proc/face_atom(var/atom/A)
|
||||
if( stat || (buckled && !buckled.movable) || !A || !x || !y || !A.x || !A.y ) return
|
||||
|
||||
// Snowflake for space vines.
|
||||
var/is_buckled = 0
|
||||
if(buckled)
|
||||
if(istype(buckled))
|
||||
if(!buckled.movable)
|
||||
is_buckled = 1
|
||||
else
|
||||
is_buckled = 0
|
||||
|
||||
if( stat || is_buckled || !A || !x || !y || !A.x || !A.y ) return
|
||||
var/dx = A.x - x
|
||||
var/dy = A.y - y
|
||||
if(!dx && !dy) return
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
L.fields["b_dna"] = H.dna.unique_enzymes
|
||||
L.fields["enzymes"] = H.dna.SE // Used in respawning
|
||||
L.fields["identity"] = H.dna.UI // "
|
||||
L.fields["image"] = getFlatIcon(H,0) //This is god-awful
|
||||
L.fields["image"] = getFlatIcon(H) //This is god-awful
|
||||
locked += L
|
||||
return
|
||||
|
||||
|
||||
@@ -266,7 +266,10 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/weapon/minihoe,
|
||||
/obj/item/device/analyzer/plant_analyzer,
|
||||
/obj/item/clothing/gloves/botanic_leather,
|
||||
/obj/item/clothing/suit/apron) // Updated with new things
|
||||
/obj/item/clothing/suit/apron,
|
||||
/obj/item/weapon/minihoe,
|
||||
/obj/item/weapon/storage/box/botanydisk
|
||||
) // Updated with new things
|
||||
cost = 15
|
||||
containertype = /obj/structure/closet/crate/hydroponics
|
||||
containername = "Hydroponics crate"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/active = 1 //No sales pitches if off!
|
||||
var/delay_product_spawn // If set, uses sleep() in product spawn proc (mostly for seeds to retrieve correct names).
|
||||
var/vend_ready = 1 //Are we ready to vend?? Is it time??
|
||||
var/vend_delay = 10 //How long does it take to vend?
|
||||
var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now.
|
||||
@@ -111,7 +112,7 @@
|
||||
|
||||
var/atom/temp = new typepath(null)
|
||||
var/datum/data/vending_product/R = new /datum/data/vending_product()
|
||||
R.product_name = temp.name
|
||||
|
||||
R.product_path = typepath
|
||||
R.amount = amount
|
||||
R.price = price
|
||||
@@ -123,6 +124,13 @@
|
||||
coin_records += R
|
||||
else
|
||||
product_records += R
|
||||
|
||||
if(delay_product_spawn)
|
||||
sleep(1)
|
||||
R.product_name = temp.name
|
||||
else
|
||||
R.product_name = temp.name
|
||||
|
||||
// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]"
|
||||
return
|
||||
|
||||
@@ -814,6 +822,8 @@
|
||||
product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!"
|
||||
product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!"
|
||||
icon_state = "seeds"
|
||||
delay_product_spawn = 1
|
||||
|
||||
products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3,
|
||||
/obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3,
|
||||
/obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3,
|
||||
|
||||
@@ -25,6 +25,14 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/mech_sensor/proc/is_blocked(O as obj)
|
||||
if(istype(O, /obj/mecha/medical/odysseus))
|
||||
var/obj/mecha/medical/odysseus/M = O
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/ME in M.equipment)
|
||||
if(istype(ME, /obj/item/mecha_parts/mecha_equipment/tool/sleeper))
|
||||
var/obj/item/mecha_parts/mecha_equipment/tool/sleeper/S = ME
|
||||
if(S.occupant != null)
|
||||
return 0
|
||||
|
||||
return istype(O, /obj/mecha) || istype(O, /obj/vehicle)
|
||||
|
||||
/obj/machinery/mech_sensor/proc/give_feedback(O as obj)
|
||||
|
||||
@@ -54,7 +54,10 @@ var/list/mechtoys = list(
|
||||
if (istype(A, /obj/structure/stool/bed) && B.buckled_mob)//if it's a bed/chair and someone is buckled, it will not pass
|
||||
return 0
|
||||
|
||||
else if(istype(A, /mob/living)) // You Shall Not Pass!
|
||||
if(istype(A, /obj/vehicle)) //no vehicles
|
||||
return 0
|
||||
|
||||
if(istype(A, /mob/living)) // You Shall Not Pass!
|
||||
var/mob/living/M = A
|
||||
if(!M.lying && !istype(M, /mob/living/carbon/monkey) && !istype(M, /mob/living/carbon/slime) && !istype(M, /mob/living/simple_animal/mouse) && !istype(M, /mob/living/silicon/robot/drone)) //If your not laying down, or a small creature, no pass.
|
||||
return 0
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
//Analyzer, pestkillers, weedkillers, nutrients, hatchets.
|
||||
//Analyzer, pestkillers, weedkillers, nutrients, hatchets, cutters.
|
||||
|
||||
/obj/item/weapon/wirecutters/clippers
|
||||
name = "plant clippers"
|
||||
desc = "A tool used to take samples from plants."
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer
|
||||
name = "plant analyzer"
|
||||
@@ -67,7 +71,9 @@
|
||||
if(grown_seed.harvest_repeat)
|
||||
dat += "This plant can be harvested repeatedly.<br>"
|
||||
|
||||
if(grown_seed.immutable)
|
||||
if(grown_seed.immutable == -1)
|
||||
dat += "This plant is highly mutable.<br>"
|
||||
else if(grown_seed.immutable > 0)
|
||||
dat += "This plant does not possess genetics that are alterable.<br>"
|
||||
|
||||
if(grown_seed.products && grown_seed.products.len)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
var/lastcycle = 0 // Cycle timing/tracking var.
|
||||
var/cycledelay = 150 // Delay per cycle.
|
||||
var/closed_system // If set, the tray will attempt to take atmos from a pipe.
|
||||
var/force_update
|
||||
|
||||
// Seed details/line data.
|
||||
var/datum/seed/seed = null // The currently planted seed
|
||||
@@ -117,6 +118,10 @@
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/bullet_act(var/obj/item/projectile/Proj)
|
||||
|
||||
//Don't act on seeds like dionaea that shouldn't change.
|
||||
if(seed && seed.immutable > 0)
|
||||
return
|
||||
|
||||
//Override for somatoray projectiles.
|
||||
if(istype(Proj ,/obj/item/projectile/energy/floramut) && prob(20))
|
||||
mutate(1)
|
||||
@@ -138,8 +143,11 @@
|
||||
/obj/machinery/portable_atmospherics/hydroponics/process()
|
||||
|
||||
// Update values every cycle rather than every process() tick.
|
||||
if(world.time < (lastcycle + cycledelay))
|
||||
if(force_update)
|
||||
force_update = 0
|
||||
else if(world.time < (lastcycle + cycledelay))
|
||||
return
|
||||
|
||||
lastcycle = world.time
|
||||
|
||||
// Weeds like water and nutrients, there's a chance the weed population will increase.
|
||||
@@ -159,7 +167,12 @@
|
||||
return
|
||||
|
||||
// Advance plant age.
|
||||
age += 1 * HYDRO_SPEED_MULTIPLIER
|
||||
if(prob(25)) age += 1 * HYDRO_SPEED_MULTIPLIER
|
||||
|
||||
//Highly mutable plants have a chance of mutating every tick.
|
||||
if(seed.immutable == -1)
|
||||
var/mut_prob = rand(1,100)
|
||||
if(mut_prob <= 5) mutate(mut_prob == 1 ? 2 : 1)
|
||||
|
||||
// Maintain tray nutrient and water levels.
|
||||
if(seed.nutrient_consumption > 0 && nutrilevel > 0 && prob(25))
|
||||
@@ -188,10 +201,23 @@
|
||||
// If atmos input is not there, grab from turf.
|
||||
if(!environment)
|
||||
if(istype(T))
|
||||
environment = T.return_air()
|
||||
if(!environment) //We're in a crate or nullspace, bail out.
|
||||
environment = T.air
|
||||
if(!environment)
|
||||
return
|
||||
|
||||
// Handle gas consumption.
|
||||
if(seed.consume_gasses && seed.consume_gasses.len)
|
||||
var/missing_gas = 0
|
||||
for(var/gas in seed.consume_gasses)
|
||||
if(environment && environment.gas && environment.gas[gas] && \
|
||||
environment.gas[gas] >= seed.consume_gasses[gas])
|
||||
environment.adjust_gas(gas,-seed.consume_gasses[gas],1)
|
||||
else
|
||||
missing_gas++
|
||||
|
||||
if(missing_gas > 0)
|
||||
health -= missing_gas * HYDRO_SPEED_MULTIPLIER
|
||||
|
||||
// Process it.
|
||||
var/pressure = environment.return_pressure()
|
||||
if(pressure < seed.lowkpa_tolerance || pressure > seed.highkpa_tolerance)
|
||||
@@ -200,6 +226,13 @@
|
||||
if(abs(environment.temperature - seed.ideal_heat) > seed.heat_tolerance)
|
||||
health -= healthmod
|
||||
|
||||
// Handle gas production.
|
||||
if(seed.exude_gasses && seed.exude_gasses.len)
|
||||
var/datum/gas_mixture/exuded = new
|
||||
for(var/gas in seed.exude_gasses)
|
||||
exuded.adjust_gas(gas,seed.exude_gasses[gas*seed.potency],1) //This will need adjustment since it produces moles.
|
||||
loc.assume_air(exuded)
|
||||
|
||||
// Handle light requirements.
|
||||
var/area/A = T.loc
|
||||
if(A)
|
||||
@@ -249,13 +282,14 @@
|
||||
pestlevel = 0
|
||||
|
||||
// If enough time (in cycles, not ticks) has passed since the plant was harvested, we're ready to harvest again.
|
||||
else if(age > seed.production && (age - lastproduce) > seed.production && (!harvest && !dead))
|
||||
else if(seed.products && seed.products.len && age > seed.production && \
|
||||
(age - lastproduce) > seed.production && (!harvest && !dead))
|
||||
|
||||
harvest = 1
|
||||
lastproduce = age
|
||||
|
||||
if(prob(5)) // On each tick, there's a 5 percent chance the pest population will increase
|
||||
pestlevel += 1 * HYDRO_SPEED_MULTIPLIER
|
||||
|
||||
check_level_sanity()
|
||||
update_icon()
|
||||
return
|
||||
@@ -385,7 +419,7 @@
|
||||
return
|
||||
|
||||
// Check if we should even bother working on the current seed datum.
|
||||
if(seed.mutants.len && severity > 1 && prob(10+mutation_mod))
|
||||
if(seed.mutants. && seed.mutants.len && severity > 1 && prob(10+mutation_mod))
|
||||
mutate_species()
|
||||
return
|
||||
|
||||
@@ -437,7 +471,22 @@
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
|
||||
if (istype(O, /obj/item/weapon/reagent_containers/glass))
|
||||
if(istype(O, /obj/item/weapon/wirecutters) || istype(O, /obj/item/weapon/scalpel))
|
||||
|
||||
if(!seed)
|
||||
user << "There is nothing to take a sample from in \the [src]."
|
||||
return
|
||||
|
||||
seed.harvest(user,yield_mod,1)
|
||||
health -= (rand(1,5)*10)
|
||||
check_level_sanity()
|
||||
|
||||
force_update = 1
|
||||
process()
|
||||
|
||||
return
|
||||
|
||||
else if (istype(O, /obj/item/weapon/reagent_containers/glass))
|
||||
var/b_amount = O.reagents.get_reagent_amount("water")
|
||||
if(b_amount > 0 && waterlevel < 100)
|
||||
if(b_amount + waterlevel > 100)
|
||||
@@ -573,7 +622,7 @@
|
||||
reagent_value = mutagenic_reagents[R.id]+mutation_mod
|
||||
if(reagent_total >= reagent_value)
|
||||
if(prob(min(reagent_total*reagent_value,100)))
|
||||
mutate(reagent_value > 10 ? 2 : 1)
|
||||
mutate(reagent_total > 10 ? 2 : 1)
|
||||
|
||||
S.reagents.clear_reagents()
|
||||
|
||||
@@ -613,7 +662,8 @@
|
||||
seed = S.seed //Grab the seed datum.
|
||||
dead = 0
|
||||
age = 1
|
||||
health = seed.endurance
|
||||
//Snowflakey, maybe move this to the seed datum
|
||||
health = (istype(S, /obj/item/seeds/cutting) ? round(seed.endurance/rand(2,5)) : seed.endurance)
|
||||
lastcycle = world.time
|
||||
|
||||
del(O)
|
||||
@@ -622,7 +672,7 @@
|
||||
update_icon()
|
||||
|
||||
else
|
||||
user << "\red The [src] already has seeds in it!"
|
||||
user << "\red \The [src] already has seeds in it!"
|
||||
|
||||
else if (istype(O, /obj/item/weapon/reagent_containers/spray/plantbgone))
|
||||
if(seed)
|
||||
@@ -733,7 +783,30 @@
|
||||
usr << "[src] is \red filled with weeds!"
|
||||
if(pestlevel >= 5)
|
||||
usr << "[src] is \red filled with tiny worms!"
|
||||
usr << text ("")
|
||||
if(!istype(src,/obj/machinery/portable_atmospherics/hydroponics/soil))
|
||||
|
||||
var/turf/T = loc
|
||||
var/datum/gas_mixture/environment
|
||||
|
||||
if(closed_system && (connected_port || holding))
|
||||
environment = air_contents
|
||||
|
||||
if(!environment)
|
||||
if(istype(T))
|
||||
environment = T.return_air()
|
||||
|
||||
if(!environment) //We're in a crate or nullspace, bail out.
|
||||
return
|
||||
|
||||
var/area/A = T.loc
|
||||
var/light_available
|
||||
if(A)
|
||||
if(A.lighting_use_dynamic)
|
||||
light_available = max(0,min(10,T.lighting_lumcount)-5)
|
||||
else
|
||||
light_available = 5
|
||||
|
||||
usr << "The tray's sensor suite is reporting a light level of [light_available] lumens and a temperature of [environment.temperature]K."
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/verb/close_lid()
|
||||
set name = "Toggle Tray Lid"
|
||||
|
||||
@@ -58,9 +58,9 @@ proc/populate_seed_list()
|
||||
|
||||
//Tolerances.
|
||||
var/requires_nutrients = 1 // The plant can starve.
|
||||
var/nutrient_consumption = 0.1 // Plant eats this much per tick.
|
||||
var/nutrient_consumption = 0.25 // Plant eats this much per tick.
|
||||
var/requires_water = 1 // The plant can become dehydrated.
|
||||
var/water_consumption = 1 // Plant drinks this much per tick.
|
||||
var/water_consumption = 3 // Plant drinks this much per tick.
|
||||
var/ideal_heat = 293 // Preferred temperature in Kelvin.
|
||||
var/heat_tolerance = 20 // Departure from ideal that is survivable.
|
||||
var/ideal_light = 8 // Preferred light level in luminosity.
|
||||
@@ -83,7 +83,7 @@ proc/populate_seed_list()
|
||||
var/spread = 0 // 0 limits plant to tray, 1 = creepers, 2 = vines.
|
||||
var/carnivorous = 0 // 0 = none, 1 = eat pests in tray, 2 = eat living things (when a vine).
|
||||
var/parasite = 0 // 0 = no, 1 = gain health from weed level.
|
||||
var/immutable // If set, plant will never mutate.
|
||||
var/immutable = 0 // If set, plant will never mutate. If -1, plant has a chance of mutating during process().
|
||||
var/alter_temp // If set, the plant will periodically alter local temp by this amount.
|
||||
|
||||
// Cosmetics.
|
||||
@@ -99,14 +99,15 @@ proc/populate_seed_list()
|
||||
|
||||
//Returns a key corresponding to an entry in the global seed list.
|
||||
/datum/seed/proc/get_mutant_variant()
|
||||
if(!mutants || !mutants.len || immutable) return 0
|
||||
if(!mutants || !mutants.len || immutable > 0) return 0
|
||||
return pick(mutants)
|
||||
|
||||
//Mutates the plant overall (randomly).
|
||||
/datum/seed/proc/mutate(var/degree,var/turf/source_turf)
|
||||
if(!degree || immutable) return
|
||||
|
||||
source_turf.visible_message("[display_name] quivers uneasily!")
|
||||
if(!degree || immutable > 0) return
|
||||
|
||||
source_turf.visible_message("\blue \The [display_name] quivers!")
|
||||
|
||||
//This looks like shit, but it's a lot easier to read/change this way.
|
||||
var/total_mutations = rand(1,1+degree)
|
||||
@@ -115,7 +116,7 @@ proc/populate_seed_list()
|
||||
if(0) //Plant cancer!
|
||||
lifespan = max(0,lifespan-rand(1,5))
|
||||
endurance = max(0,endurance-rand(10,20))
|
||||
source_turf.visible_message("[display_name] withers rapidly!")
|
||||
source_turf.visible_message("\red \The [display_name] withers rapidly!")
|
||||
if(1)
|
||||
nutrient_consumption = max(0, min(5, nutrient_consumption + rand(-(degree*0.1),(degree*0.1))))
|
||||
water_consumption = max(0, min(50, water_consumption + rand(-degree,degree)))
|
||||
@@ -134,7 +135,7 @@ proc/populate_seed_list()
|
||||
if(prob(degree*5))
|
||||
carnivorous = max(0, min(2, carnivorous + rand(-degree,degree)))
|
||||
if(carnivorous)
|
||||
source_turf.visible_message("[display_name] shudders hungrily.")
|
||||
source_turf.visible_message("\blue \The [display_name] shudders hungrily.")
|
||||
if(6)
|
||||
weed_tolerance = max(0, min(10, weed_tolerance + (rand(-2,2) * degree)))
|
||||
if(prob(degree*5)) parasite = !parasite
|
||||
@@ -148,7 +149,7 @@ proc/populate_seed_list()
|
||||
potency = max(0, min(200, potency + (rand(-20,20) * degree)))
|
||||
if(prob(degree*5))
|
||||
spread = max(0, min(2, spread + rand(-1,1)))
|
||||
source_turf.visible_message("[display_name] spasms visibly, shifting in the tray.")
|
||||
source_turf.visible_message("\blue \The [display_name] spasms visibly, shifting in the tray.")
|
||||
if(9)
|
||||
maturation = max(0, min(30, maturation + (rand(-1,1) * degree)))
|
||||
if(prob(degree*5))
|
||||
@@ -157,28 +158,28 @@ proc/populate_seed_list()
|
||||
if(prob(degree*2))
|
||||
biolum = !biolum
|
||||
if(biolum)
|
||||
source_turf.visible_message("[display_name] begins to glow!")
|
||||
source_turf.visible_message("\blue \The [display_name] begins to glow!")
|
||||
if(prob(degree*2))
|
||||
biolum_colour = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]"
|
||||
source_turf.visible_message("[display_name]'s glow <font=[biolum_colour]>changes colour</font>!")
|
||||
source_turf.visible_message("\blue \The [display_name]'s glow <font=[biolum_colour]>changes colour</font>!")
|
||||
else
|
||||
source_turf.visible_message("[display_name]'s glow dims...")
|
||||
source_turf.visible_message("\blue \The [display_name]'s glow dims...")
|
||||
if(11)
|
||||
if(prob(degree*2))
|
||||
flowers = !flowers
|
||||
if(flowers)
|
||||
source_turf.visible_message("[display_name] sprouts a bevy of flowers!")
|
||||
source_turf.visible_message("\blue \The [display_name] sprouts a bevy of flowers!")
|
||||
if(prob(degree*2))
|
||||
flower_colour = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]"
|
||||
source_turf.visible_message("[display_name]'s flowers <font=[flower_colour]>changes colour</font>!")
|
||||
source_turf.visible_message("\blue \The [display_name]'s flowers <font=[flower_colour]>changes colour</font>!")
|
||||
else
|
||||
source_turf.visible_message("[display_name]'s flowers wither and fall off.")
|
||||
source_turf.visible_message("\blue \The [display_name]'s flowers wither and fall off.")
|
||||
return
|
||||
|
||||
//Mutates a specific trait/set of traits.
|
||||
/datum/seed/proc/apply_gene(var/datum/plantgene/gene)
|
||||
|
||||
if(!gene || !gene.values || immutable) return
|
||||
if(!gene || !gene.values || immutable > 0) return
|
||||
|
||||
switch(gene.genetype)
|
||||
|
||||
@@ -208,11 +209,12 @@ proc/populate_seed_list()
|
||||
else
|
||||
chems[rid] = gene.values[2][rid]
|
||||
|
||||
//TODO.
|
||||
//if(!exude_gasses) exude_gasses = list()
|
||||
//exude_gasses |= gene.values[3]
|
||||
//for(var/gas in exude_gasses)
|
||||
// exude_gasses[gas] = max(1,round(exude_gasses[gas]/2))
|
||||
var/list/new_gasses = gene.values[3]
|
||||
if(istype(new_gasses))
|
||||
if(!exude_gasses) exude_gasses = list()
|
||||
exude_gasses |= new_gasses
|
||||
for(var/gas in exude_gasses)
|
||||
exude_gasses[gas] = max(1,round(exude_gasses[gas]*0.8))
|
||||
|
||||
alter_temp = gene.values[4]
|
||||
potency = gene.values[5]
|
||||
@@ -343,11 +345,10 @@ proc/populate_seed_list()
|
||||
return (P ? P : 0)
|
||||
|
||||
//Place the plant products at the feet of the user.
|
||||
/datum/seed/proc/harvest(var/mob/user,var/yield_mod)
|
||||
/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample)
|
||||
if(!user)
|
||||
return
|
||||
|
||||
//TODO: check for failing to harvest.
|
||||
var/got_product
|
||||
if(!isnull(products) && products.len && yield > 0)
|
||||
got_product = 1
|
||||
@@ -355,7 +356,7 @@ proc/populate_seed_list()
|
||||
if(!got_product)
|
||||
user << "\red You fail to harvest anything useful."
|
||||
else
|
||||
user << "You harvest from the [display_name]."
|
||||
user << "You [harvest_sample ? "take a sample" : "harvest"] from the [display_name]."
|
||||
|
||||
//This may be a new line. Update the global if it is.
|
||||
if(name == "new line" || !(name in seed_types))
|
||||
@@ -363,12 +364,18 @@ proc/populate_seed_list()
|
||||
name = "[uid]"
|
||||
seed_types[name] = src
|
||||
|
||||
if(harvest_sample)
|
||||
var/obj/item/seeds/seeds = new(get_turf(user))
|
||||
seeds.seed_type = name
|
||||
seeds.update_seed()
|
||||
return
|
||||
|
||||
var/total_yield
|
||||
if(isnull(yield_mod) || yield_mod < 1)
|
||||
yield_mod = 0
|
||||
total_yield = yield
|
||||
else
|
||||
total_yield = max(1,rand(1,((yield_mod+yield))))
|
||||
total_yield = max(1,rand(yield_mod,yield_mod+yield))
|
||||
|
||||
currently_querying = list()
|
||||
for(var/i = 0;i<total_yield;i++)
|
||||
@@ -382,7 +389,6 @@ proc/populate_seed_list()
|
||||
handle_living_product(product)
|
||||
|
||||
// Make sure the product is inheriting the correct seed type reference.
|
||||
// TODO: can this be collapsed into one type check since they share vars?
|
||||
else if(istype(product,/obj/item/weapon/reagent_containers/food/snacks/grown))
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/grown/current_product = product
|
||||
current_product.plantname = name
|
||||
@@ -396,7 +402,7 @@ proc/populate_seed_list()
|
||||
// be put into the global datum list until the product is harvested, though.
|
||||
/datum/seed/proc/diverge(var/modified)
|
||||
|
||||
if(immutable) return
|
||||
if(immutable > 0) return
|
||||
|
||||
//Set up some basic information.
|
||||
var/datum/seed/new_seed = new
|
||||
@@ -1163,6 +1169,7 @@ proc/populate_seed_list()
|
||||
yield = -1
|
||||
potency = -1
|
||||
growth_stages = 4
|
||||
immutable = -1
|
||||
|
||||
/datum/seed/whitebeets
|
||||
name = "whitebeet"
|
||||
@@ -1400,4 +1407,4 @@ proc/populate_seed_list()
|
||||
maturation = 1
|
||||
production = 1
|
||||
yield = 1
|
||||
potency = 1
|
||||
potency = 1
|
||||
|
||||
@@ -3,9 +3,16 @@
|
||||
desc = "A small disk used for carrying data on plant genetics."
|
||||
icon = 'icons/obj/hydroponics.dmi'
|
||||
icon_state = "disk"
|
||||
w_class = 1.0
|
||||
|
||||
var/list/genes = list()
|
||||
var/genesource = "unknown"
|
||||
|
||||
/obj/item/weapon/disk/botany/New()
|
||||
..()
|
||||
pixel_x = rand(-5,5)
|
||||
pixel_y = rand(-5,5)
|
||||
|
||||
/obj/item/weapon/disk/botany/attack_self(var/mob/user as mob)
|
||||
if(genes.len)
|
||||
var/choice = alert(user, "Are you sure you want to wipe the disk?", "Xenobotany Data", "No", "Yes")
|
||||
@@ -24,6 +31,7 @@
|
||||
..()
|
||||
for(var/i = 0;i<7;i++)
|
||||
new /obj/item/weapon/disk/botany(src)
|
||||
|
||||
/obj/machinery/botany
|
||||
icon = 'icons/obj/hydroponics.dmi'
|
||||
icon_state = "hydrotray3"
|
||||
@@ -77,16 +85,18 @@
|
||||
/obj/machinery/botany/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/seeds))
|
||||
if(seed)
|
||||
if(seed.seed.immutable)
|
||||
user << "That seed is not compatible with our genetics technology."
|
||||
else
|
||||
user << "There is already a seed loaded."
|
||||
user << "There is already a seed loaded."
|
||||
|
||||
var/obj/item/seeds/S =W
|
||||
if(S.seed && S.seed.immutable > 0)
|
||||
user << "That seed is not compatible with our genetics technology."
|
||||
else
|
||||
user.drop_item(W)
|
||||
W.loc = src
|
||||
seed = W
|
||||
user << "You load [W] into [src]."
|
||||
return
|
||||
|
||||
if(istype(W,/obj/item/weapon/screwdriver))
|
||||
open = !open
|
||||
user << "\blue You [open ? "open" : "close"] the maintenance panel."
|
||||
@@ -181,7 +191,7 @@
|
||||
|
||||
if(seed.seed.name == "new line" || isnull(seed_types[seed.seed.name]))
|
||||
seed.seed.uid = seed_types.len + 1
|
||||
seed.seed.name = "[uid]"
|
||||
seed.seed.name = "[seed.seed.uid]"
|
||||
seed_types[seed.seed.name] = seed.seed
|
||||
|
||||
seed.update_seed()
|
||||
@@ -215,6 +225,8 @@
|
||||
|
||||
if(seed && seed.seed)
|
||||
genetics = seed.seed
|
||||
degradation = 0
|
||||
|
||||
del(seed)
|
||||
seed = null
|
||||
|
||||
@@ -233,7 +245,7 @@
|
||||
if(!genetics.roundstart)
|
||||
loaded_disk.genesource += " (variety #[genetics.uid])"
|
||||
|
||||
loaded_disk.name += " ([gene_tag_masks[href_list["get_gene"]]])"
|
||||
loaded_disk.name += " ([gene_tag_masks[href_list["get_gene"]]], #[genetics.uid])"
|
||||
loaded_disk.desc += " The label reads \'gene [gene_tag_masks[href_list["get_gene"]]], sampled from [genetics.display_name]\'."
|
||||
eject_disk = 1
|
||||
|
||||
|
||||
@@ -32,6 +32,14 @@
|
||||
if(seed && !seed.roundstart)
|
||||
usr << "It's tagged as variety #[seed.uid]."
|
||||
|
||||
/obj/item/seeds/cutting
|
||||
name = "cuttings"
|
||||
desc = "Some plant cuttings."
|
||||
|
||||
/obj/item/seeds/cutting/update_appearance()
|
||||
..()
|
||||
src.name = "packet of [seed.seed_name] cuttings"
|
||||
|
||||
/obj/item/seeds/replicapod
|
||||
seed_type = "diona"
|
||||
|
||||
|
||||
@@ -295,8 +295,8 @@
|
||||
var/limited_growth = 0
|
||||
|
||||
/obj/effect/plant_controller/creeper
|
||||
collapse_limit = 50
|
||||
slowdown_limit = 5
|
||||
collapse_limit = 6
|
||||
slowdown_limit = 3
|
||||
limited_growth = 1
|
||||
|
||||
/obj/effect/plant_controller/New()
|
||||
|
||||
@@ -251,7 +251,7 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
icon_key = "[icon_key]0"
|
||||
else if(part.status & ORGAN_ROBOT)
|
||||
icon_key = "[icon_key]2"
|
||||
else if(part.status & ORGAN_DEAD) //Do we even have necrosis in our current code? ~Z
|
||||
else if(part.status & ORGAN_DEAD)
|
||||
icon_key = "[icon_key]3"
|
||||
else
|
||||
icon_key = "[icon_key]1"
|
||||
@@ -274,6 +274,10 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
//No icon stored, so we need to start with a basic one.
|
||||
var/datum/organ/external/chest = get_organ("chest")
|
||||
base_icon = chest.get_icon(g)
|
||||
|
||||
if(chest.status & ORGAN_DEAD)
|
||||
base_icon.ColorTone(necrosis_color_mod)
|
||||
base_icon.SetIntensity(0.7)
|
||||
|
||||
for(var/datum/organ/external/part in organs)
|
||||
|
||||
|
||||
@@ -53,10 +53,10 @@
|
||||
/obj/item/weapon/photo/proc/show(mob/user as mob)
|
||||
user << browse_rsc(img, "tmp_photo.png")
|
||||
user << browse("<html><head><title>[name]</title></head>" \
|
||||
+ "<body style='overflow:hidden'>" \
|
||||
+ "<div> <img src='tmp_photo.png' width = '180'" \
|
||||
+ "[scribble ? "<div> Written on the back:<br><i>[scribble]</i>" : ]"\
|
||||
+ "</body></html>", "window=book;size=200x[scribble ? 400 : 200]")
|
||||
+ "<body style='overflow:hidden;margin:0;text-align:center'>" \
|
||||
+ "<img src='tmp_photo.png' width='192' style='-ms-interpolation-mode:nearest-neighbor' />" \
|
||||
+ "[scribble ? "<br>Written on the back:<br><i>[scribble]</i>" : ""]"\
|
||||
+ "</body></html>", "window=book;size=192x[scribble ? 400 : 192]")
|
||||
onclose(user, "[name]")
|
||||
return
|
||||
|
||||
@@ -152,41 +152,51 @@
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/camera/proc/get_icon(turf/the_turf as turf)
|
||||
/obj/item/device/camera/proc/get_icon(list/turfs, turf/center)
|
||||
|
||||
//Bigger icon base to capture those icons that were shifted to the next tile
|
||||
//i.e. pretty much all wall-mounted machinery
|
||||
var/icon/res = icon('icons/effects/96x96.dmi', "")
|
||||
|
||||
var/icon/turficon = build_composite_icon(the_turf)
|
||||
res.Blend(turficon, ICON_OVERLAY, 33, 33)
|
||||
// Initialize the photograph to black.
|
||||
res.Blend("#000", ICON_OVERLAY)
|
||||
|
||||
var/atoms[] = list()
|
||||
for(var/atom/A in the_turf)
|
||||
if(A.invisibility) continue
|
||||
atoms.Add(A)
|
||||
for(var/turf/the_turf in turfs)
|
||||
// Add outselves to the list of stuff to draw
|
||||
atoms.Add(the_turf);
|
||||
// As well as anything that isn't invisible.
|
||||
for(var/atom/A in the_turf)
|
||||
if(A.invisibility) continue
|
||||
atoms.Add(A)
|
||||
|
||||
//Sorting icons based on levels
|
||||
var/gap = atoms.len
|
||||
var/swapped = 1
|
||||
while (gap > 1 || swapped)
|
||||
swapped = 0
|
||||
if(gap > 1)
|
||||
gap = round(gap / 1.247330950103979)
|
||||
if(gap < 1)
|
||||
gap = 1
|
||||
for(var/i = 1; gap + i <= atoms.len; i++)
|
||||
var/atom/l = atoms[i] //Fucking hate
|
||||
var/atom/r = atoms[gap+i] //how lists work here
|
||||
if(l.layer > r.layer) //no "atoms[i].layer" for me
|
||||
atoms.Swap(i, gap + i)
|
||||
swapped = 1
|
||||
// Sort the atoms into their layers
|
||||
var/list/sorted = sort_atoms_by_layer(atoms)
|
||||
|
||||
for(var/i; i <= atoms.len; i++)
|
||||
var/atom/A = atoms[i]
|
||||
for(var/i; i <= sorted.len; i++)
|
||||
var/atom/A = sorted[i]
|
||||
if(A)
|
||||
var/icon/img = getFlatIcon(A, A.dir)//build_composite_icon(A)
|
||||
var/icon/img = getFlatIcon(A)//build_composite_icon(A)
|
||||
|
||||
// If what we got back is actually a picture, draw it.
|
||||
if(istype(img, /icon))
|
||||
res.Blend(new/icon(img, "", A.dir), ICON_OVERLAY, 33 + A.pixel_x, 33 + A.pixel_y)
|
||||
// Check if we're looking at a mob that's lying down
|
||||
if(istype(A, /mob/living) && A:lying)
|
||||
// If they are, apply that effect to their picture.
|
||||
img.BecomeLying()
|
||||
// Calculate where we are relative to the center of the photo
|
||||
var/xoff = (A.x - center.x) * 32
|
||||
var/yoff = (A.y - center.y) * 32
|
||||
if (istype(A,/atom/movable))
|
||||
xoff+=A:step_x
|
||||
yoff+=A:step_y
|
||||
res.Blend(img, blendMode2iconMode(A.blend_mode), 33 + A.pixel_x + xoff, 33 + A.pixel_y + yoff)
|
||||
|
||||
// Lastly, render any contained effects on top.
|
||||
for(var/turf/the_turf in turfs)
|
||||
// Calculate where we are relative to the center of the photo
|
||||
var/xoff = (the_turf.x - center.x) * 32
|
||||
var/yoff = (the_turf.y - center.y) * 32
|
||||
res.Blend(getFlatIcon(the_turf.loc), blendMode2iconMode(the_turf.blend_mode),33 + xoff,33 + yoff)
|
||||
return res
|
||||
|
||||
|
||||
@@ -240,27 +250,27 @@
|
||||
var/y_c = target.y + 1
|
||||
var/z_c = target.z
|
||||
|
||||
var/icon/temp = icon('icons/effects/96x96.dmi',"")
|
||||
var/icon/black = icon('icons/turf/space.dmi', "black")
|
||||
|
||||
var/list/turfs = list()
|
||||
var/mobs = ""
|
||||
for(var/i = 1; i <= 3; i++)
|
||||
for(var/j = 1; j <= 3; j++)
|
||||
var/turf/T = locate(x_c, y_c, z_c)
|
||||
if(can_capture_turf(T, user))
|
||||
temp.Blend(get_icon(T), ICON_OVERLAY, 32 * (j-1-1), 32 - 32 * (i-1))
|
||||
mobs += get_mobs(T, user)
|
||||
else
|
||||
temp.Blend(black, ICON_OVERLAY, 32 * (j-1), 64 - 32 * (i-1))
|
||||
turfs.Add(T)
|
||||
mobs += get_mobs(T)
|
||||
x_c++
|
||||
y_c--
|
||||
x_c = x_c - 3
|
||||
|
||||
var/datum/picture/P = createpicture(user, temp, mobs, flag)
|
||||
var/datum/picture/P = createpicture(target, user, turfs, mobs, flag)
|
||||
printpicture(user, P)
|
||||
|
||||
/obj/item/device/camera/proc/createpicture(mob/user, icon/temp, mobs, flag)
|
||||
var/icon/small_img = icon(temp)
|
||||
var/icon/tiny_img = icon(temp)
|
||||
/obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag)
|
||||
var/icon/photoimage = get_icon(turfs, target)
|
||||
|
||||
var/icon/small_img = icon(photoimage)
|
||||
var/icon/tiny_img = icon(photoimage)
|
||||
var/icon/ic = icon('icons/obj/items.dmi',"photo")
|
||||
var/icon/pc = icon('icons/obj/bureaucracy.dmi', "photo")
|
||||
small_img.Scale(8, 8)
|
||||
@@ -272,7 +282,7 @@
|
||||
P.fields["author"] = user
|
||||
P.fields["icon"] = ic
|
||||
P.fields["tiny"] = pc
|
||||
P.fields["img"] = temp
|
||||
P.fields["img"] = photoimage
|
||||
P.fields["desc"] = mobs
|
||||
P.fields["pixel_x"] = rand(-10, 10)
|
||||
P.fields["pixel_y"] = rand(-10, 10)
|
||||
|
||||
@@ -91,42 +91,51 @@ obj/item/weapon/gun/energy/staff
|
||||
var/charge_tick = 0
|
||||
var/mode = 0 //0 = mutate, 1 = yield boost
|
||||
|
||||
New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
/obj/item/weapon/gun/energy/floragun/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/Del()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
Del()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
/obj/item/weapon/gun/energy/floragun/process()
|
||||
charge_tick++
|
||||
if(charge_tick < 4) return 0
|
||||
charge_tick = 0
|
||||
if(!power_supply) return 0
|
||||
power_supply.give(100)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/attack_self(mob/living/user as mob)
|
||||
switch(mode)
|
||||
if(0)
|
||||
mode = 1
|
||||
charge_cost = 100
|
||||
user << "\red The [src.name] is now set to increase yield."
|
||||
projectile_type = "/obj/item/projectile/energy/florayield"
|
||||
modifystate = "florayield"
|
||||
if(1)
|
||||
mode = 0
|
||||
charge_cost = 100
|
||||
user << "\red The [src.name] is now set to induce mutations."
|
||||
projectile_type = "/obj/item/projectile/energy/floramut"
|
||||
modifystate = "floramut"
|
||||
update_icon()
|
||||
return
|
||||
|
||||
process()
|
||||
charge_tick++
|
||||
if(charge_tick < 4) return 0
|
||||
charge_tick = 0
|
||||
if(!power_supply) return 0
|
||||
power_supply.give(100)
|
||||
update_icon()
|
||||
return 1
|
||||
/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, flag)
|
||||
|
||||
attack_self(mob/living/user as mob)
|
||||
switch(mode)
|
||||
if(0)
|
||||
mode = 1
|
||||
charge_cost = 100
|
||||
user << "\red The [src.name] is now set to increase yield."
|
||||
projectile_type = "/obj/item/projectile/energy/florayield"
|
||||
modifystate = "florayield"
|
||||
if(1)
|
||||
mode = 0
|
||||
charge_cost = 100
|
||||
user << "\red The [src.name] is now set to induce mutations."
|
||||
projectile_type = "/obj/item/projectile/energy/floramut"
|
||||
modifystate = "floramut"
|
||||
update_icon()
|
||||
if(flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics))
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/tray = target
|
||||
if(load_into_chamber())
|
||||
user.visible_message("\red <b> \The [user] fires \the [src] into \the [tray]!</b>")
|
||||
Fire(target,user)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun
|
||||
name = "meteor gun"
|
||||
desc = "For the love of god, make sure you're aiming this the right way!"
|
||||
@@ -224,7 +233,7 @@ obj/item/weapon/gun/energy/staff/focus
|
||||
|
||||
|
||||
/*
|
||||
This is called from
|
||||
This is called from
|
||||
modules/mob/mob_movement.dm if you move you will be zoomed out
|
||||
modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
..()
|
||||
cell = new /obj/item/weapon/cell/high
|
||||
verbs -= /atom/movable/verb/pull
|
||||
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
|
||||
key = new()
|
||||
var/image/I = new(icon = 'icons/obj/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs
|
||||
overlays += I
|
||||
@@ -70,8 +71,8 @@
|
||||
if(istype(W, /obj/item/weapon/key/cargo_train))
|
||||
if(!key)
|
||||
user.drop_item()
|
||||
W.forceMove(src)
|
||||
key = W
|
||||
W.loc = src
|
||||
verbs += /obj/vehicle/train/cargo/engine/verb/remove_key
|
||||
return
|
||||
..()
|
||||
@@ -97,7 +98,7 @@
|
||||
var/obj/machinery/door/D = Obstacle
|
||||
var/mob/living/carbon/human/H = load
|
||||
if(istype(D) && istype(H))
|
||||
D.Bumped(H) //a little hacky, but hey, it works, and repects access rights
|
||||
D.Bumped(H) //a little hacky, but hey, it works, and respects access rights
|
||||
|
||||
..()
|
||||
|
||||
@@ -194,6 +195,8 @@
|
||||
turn_on()
|
||||
if (on)
|
||||
usr << "You start [src]'s engine."
|
||||
verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine
|
||||
verbs -= /obj/vehicle/train/cargo/engine/verb/start_engine
|
||||
else
|
||||
if(cell.charge < power_use)
|
||||
usr << "[src] is out of power."
|
||||
@@ -215,6 +218,8 @@
|
||||
turn_off()
|
||||
if (!on)
|
||||
usr << "You stop [src]'s engine."
|
||||
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
|
||||
verbs += /obj/vehicle/train/cargo/engine/verb/start_engine
|
||||
|
||||
/obj/vehicle/train/cargo/engine/verb/remove_key()
|
||||
set name = "Remove key"
|
||||
@@ -243,7 +248,7 @@
|
||||
/obj/vehicle/train/cargo/trolley/load(var/atom/movable/C)
|
||||
if(ismob(C) && !passenger_allowed)
|
||||
return 0
|
||||
if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !ismob(C))
|
||||
if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human))
|
||||
return 0
|
||||
|
||||
..()
|
||||
@@ -255,7 +260,7 @@
|
||||
return 1
|
||||
|
||||
/obj/vehicle/train/cargo/engine/load(var/atom/movable/C)
|
||||
if(!ismob(C))
|
||||
if(!istype(C, /mob/living/carbon/human))
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -68,8 +68,7 @@
|
||||
|
||||
if(user != load)
|
||||
if(user in src) //for handling players stuck in src - this shouldn't happen - but just in case it does
|
||||
user.loc = T
|
||||
contents -= user
|
||||
user.forceMove(T)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -93,8 +92,7 @@
|
||||
return 0
|
||||
|
||||
if(user != load && (user in src))
|
||||
user.loc = loc //for handling players stuck in src
|
||||
contents -= user
|
||||
user.forceMove(loc) //for handling players stuck in src
|
||||
else if(load)
|
||||
unload(user) //unload if loaded
|
||||
else if(!load && !user.buckled)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
anchored = init_anc
|
||||
|
||||
if(load)
|
||||
load.loc = loc
|
||||
load.forceMove(loc)// = loc
|
||||
load.dir = dir
|
||||
|
||||
return 1
|
||||
@@ -196,7 +196,7 @@
|
||||
new /obj/item/weapon/cable_coil/cut(Tsec)
|
||||
|
||||
if(cell)
|
||||
cell.loc = Tsec
|
||||
cell.forceMove(Tsec)
|
||||
cell.update_icon()
|
||||
cell = null
|
||||
|
||||
@@ -234,8 +234,8 @@
|
||||
return
|
||||
|
||||
H.drop_from_inventory(C)
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
C.loc = null //this wont be GC'd since it's referrenced above
|
||||
powercheck()
|
||||
usr << "<span class='notice'>You install [C] in [src].</span>"
|
||||
|
||||
@@ -244,7 +244,8 @@
|
||||
return
|
||||
|
||||
usr << "<span class='notice'>You remove [cell] from [src].</span>"
|
||||
cell.loc = get_turf(H)
|
||||
cell.forceMove(get_turf(H))
|
||||
H.put_in_hands(cell)
|
||||
cell = null
|
||||
powercheck()
|
||||
|
||||
@@ -271,7 +272,7 @@
|
||||
if(istype(crate))
|
||||
crate.close()
|
||||
|
||||
C.loc = loc
|
||||
C.forceMove(loc)
|
||||
C.dir = dir
|
||||
C.anchored = 1
|
||||
|
||||
@@ -310,7 +311,7 @@
|
||||
var/list/options = new()
|
||||
for(var/test_dir in alldirs)
|
||||
var/new_dir = get_step_to(src, get_step(src, test_dir))
|
||||
if(new_dir)
|
||||
if(new_dir && load.Adjacent(new_dir))
|
||||
options += new_dir
|
||||
if(options.len)
|
||||
dest = pick(options)
|
||||
@@ -320,8 +321,7 @@
|
||||
if(!isturf(dest)) //if there still is nowhere to unload, cancel out since the vehicle is probably in nullspace
|
||||
return 0
|
||||
|
||||
|
||||
load.loc = dest
|
||||
load.forceMove(dest)
|
||||
load.dir = get_dir(loc, dest)
|
||||
load.anchored = initial(load.anchored)
|
||||
load.pixel_x = initial(load.pixel_x)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 160 KiB |
+2
-2
@@ -6619,7 +6619,7 @@
|
||||
"cxo" = (/turf/simulated/floor/beach/sand{tag = "icon-desert1"; icon_state = "desert1"},/area/holodeck/source_beach)
|
||||
"cxp" = (/turf/simulated/floor/beach/sand{tag = "icon-desert4"; icon_state = "desert4"},/area/holodeck/source_beach)
|
||||
"cxq" = (/turf/simulated/floor/beach/sand{tag = "icon-desert0"; icon_state = "desert0"},/area/holodeck/source_beach)
|
||||
"cxr" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = -24},/turf/simulated/floor/holofloor{dir = 9; icon_state = "red"},/area/holodeck/source_thunderdomecourt)
|
||||
"cxr" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = 0},/turf/simulated/floor/holofloor{dir = 9; icon_state = "red"},/area/holodeck/source_thunderdomecourt)
|
||||
"cxs" = (/obj/structure/table/holotable,/obj/item/clothing/head/helmet/thunderdome,/obj/item/clothing/suit/armor/tdome/red,/obj/item/clothing/under/color/red,/obj/item/weapon/holo/esword/red,/turf/simulated/floor/holofloor{dir = 1; icon_state = "red"},/area/holodeck/source_thunderdomecourt)
|
||||
"cxt" = (/obj/structure/table/holotable,/turf/simulated/floor/holofloor{dir = 5; icon_state = "red"},/area/holodeck/source_thunderdomecourt)
|
||||
"cxu" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove,/turf/simulated/floor/holofloor{dir = 9; icon_state = "red"},/area/holodeck/source_boxingcourt)
|
||||
@@ -6710,7 +6710,7 @@
|
||||
"czb" = (/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_basketball)
|
||||
"czc" = (/obj/structure/table/holotable,/turf/simulated/floor/holofloor{dir = 10; icon_state = "green"},/area/holodeck/source_thunderdomecourt)
|
||||
"czd" = (/obj/structure/table/holotable,/obj/item/clothing/head/helmet/thunderdome,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/under/color/green,/obj/item/weapon/holo/esword/green,/turf/simulated/floor/holofloor{dir = 2; icon_state = "green"},/area/holodeck/source_thunderdomecourt)
|
||||
"cze" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = -24},/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_thunderdomecourt)
|
||||
"cze" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = 0},/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_thunderdomecourt)
|
||||
"czf" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove{icon_state = "boxinggreen"; item_state = "boxinggreen"},/turf/simulated/floor/holofloor{dir = 10; icon_state = "green"},/area/holodeck/source_boxingcourt)
|
||||
"czg" = (/turf/simulated/floor/holofloor{dir = 2; icon_state = "green"},/area/holodeck/source_boxingcourt)
|
||||
"czh" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove{icon_state = "boxinggreen"; item_state = "boxinggreen"},/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_boxingcourt)
|
||||
|
||||
Reference in New Issue
Block a user