Merge remote-tracking branch 'upstream/master'

This commit is contained in:
BongaTheProto
2023-03-06 22:43:10 -05:00
52 changed files with 563 additions and 499 deletions

View File

@@ -41,7 +41,6 @@ require only minor tweaks.
//boolean - weather types that occur on the level //boolean - weather types that occur on the level
#define ZTRAIT_SNOWSTORM "Weather_Snowstorm" #define ZTRAIT_SNOWSTORM "Weather_Snowstorm"
#define ZTRAIT_ASHSTORM "Weather_Ashstorm" #define ZTRAIT_ASHSTORM "Weather_Ashstorm"
#define ZTRAIT_ACIDRAIN "Weather_Acidrain"
#define ZTRAIT_VOIDSTORM "Weather_Voidstorm" #define ZTRAIT_VOIDSTORM "Weather_Voidstorm"
#define ZTRAIT_ICESTORM "Weather_Icestorm" #define ZTRAIT_ICESTORM "Weather_Icestorm"
#define ZTRAIT_LONGRAIN "Weather_Longrain" #define ZTRAIT_LONGRAIN "Weather_Longrain"

View File

@@ -263,6 +263,14 @@
/// Prevents sprinting from being active. /// Prevents sprinting from being active.
#define TRAIT_SPRINT_LOCKED "sprint_locked" #define TRAIT_SPRINT_LOCKED "sprint_locked"
/// Weather immunities, also protect mobs inside them.
#define TRAIT_LAVA_IMMUNE "lava_immune" //Used by lava turfs and The Floor Is Lava.
#define TRAIT_ASHSTORM_IMMUNE "ashstorm_immune"
#define TRAIT_SNOWSTORM_IMMUNE "snowstorm_immune"
#define TRAIT_RADSTORM_IMMUNE "radstorm_immune"
#define TRAIT_VOIDSTORM_IMMUNE "voidstorm_immune"
#define TRAIT_WEATHER_IMMUNE "weather_immune" //Immune to ALL weather effects.
//non-mob traits //non-mob traits
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it #define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
#define VEHICLE_TRAIT "vehicle" // inherited from riding vehicles #define VEHICLE_TRAIT "vehicle" // inherited from riding vehicles
@@ -298,8 +306,8 @@
#define GHOSTROLE_TRAIT "ghostrole" #define GHOSTROLE_TRAIT "ghostrole"
#define APHRO_TRAIT "aphro" #define APHRO_TRAIT "aphro"
#define BLOODSUCKER_TRAIT "bloodsucker" #define BLOODSUCKER_TRAIT "bloodsucker"
#define SHOES_TRAIT "shoes" //inherited from your sweet kicks
#define GLOVE_TRAIT "glove" //inherited by your cool gloves #define GLOVE_TRAIT "glove" //inherited by your cool gloves
#define SHOES_TRAIT "shoes" //inherited from your sweet kicks
#define BOOK_TRAIT "granter (book)" // knowledge is power #define BOOK_TRAIT "granter (book)" // knowledge is power
#define TURF_TRAIT "turf" #define TURF_TRAIT "turf"
#define STATION_TRAIT "station-trait" #define STATION_TRAIT "station-trait"

View File

@@ -126,10 +126,15 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_EMPATH" = TRAIT_EMPATH, "TRAIT_EMPATH" = TRAIT_EMPATH,
"TRAIT_FRIENDLY" = TRAIT_FRIENDLY, "TRAIT_FRIENDLY" = TRAIT_FRIENDLY,
"TRAIT_IWASBATONED" = TRAIT_IWASBATONED, "TRAIT_IWASBATONED" = TRAIT_IWASBATONED,
"TRAIT_SALT_SENSITIVE" = TRAIT_SALT_SENSITIVE,
"TRAIT_LAVA_IMMUNE" = TRAIT_LAVA_IMMUNE,
"TRAIT_ASHSTORM_IMMUNE" = TRAIT_ASHSTORM_IMMUNE,
"TRAIT_SNOWSTORM_IMMUNE" = TRAIT_SNOWSTORM_IMMUNE,
"TRAIT_VOIDSTORM_IMMUNE" = TRAIT_VOIDSTORM_IMMUNE,
"TRAIT_WEATHER_IMMUNE" = TRAIT_WEATHER_IMMUNE,
"TRAIT_SPACEWALK" = TRAIT_SPACEWALK, "TRAIT_SPACEWALK" = TRAIT_SPACEWALK,
"TRAIT_PRIMITIVE" = TRAIT_PRIMITIVE, //unable to use mechs. Given to Ash Walkers "TRAIT_PRIMITIVE" = TRAIT_PRIMITIVE, //unable to use mechs. Given to Ash Walkers
"TRAIT_SALT_SENSITIVE" = TRAIT_SALT_SENSITIVE ),
),
/obj/item/bodypart = list( /obj/item/bodypart = list(
"TRAIT_PARALYSIS" = TRAIT_PARALYSIS "TRAIT_PARALYSIS" = TRAIT_PARALYSIS
), ),

View File

@@ -723,6 +723,9 @@
button.maptext_height = 12 button.maptext_height = 12
/datum/action/cooldown/IsAvailable(silent = FALSE) /datum/action/cooldown/IsAvailable(silent = FALSE)
. = ..()
if(!.)
return
return next_use_time <= world.time return next_use_time <= world.time
/datum/action/cooldown/proc/StartCooldown() /datum/action/cooldown/proc/StartCooldown()

View File

@@ -64,8 +64,8 @@
var/overlay_plane = BLACKNESS_PLANE var/overlay_plane = BLACKNESS_PLANE
/// If the weather has no purpose but aesthetics. /// If the weather has no purpose but aesthetics.
var/aesthetic = FALSE var/aesthetic = FALSE
/// Used by mobs to prevent them from being affected by the weather /// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather.
var/immunity_type = "storm" var/immunity_type
/// The stage of the weather, from 1-4 /// The stage of the weather, from 1-4
var/stage = END_STAGE var/stage = END_STAGE
@@ -133,15 +133,18 @@
/datum/weather/proc/start() /datum/weather/proc/start()
if(stage >= MAIN_STAGE) if(stage >= MAIN_STAGE)
return return
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type))
stage = MAIN_STAGE stage = MAIN_STAGE
update_areas() update_areas()
for(var/M in GLOB.player_list) for(var/z_level in impacted_z_levels)
var/turf/mob_turf = get_turf(M) for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level])
if(mob_turf && (mob_turf.z in impacted_z_levels)) var/turf/mob_turf = get_turf(player)
if(!mob_turf)
continue
if(weather_message) if(weather_message)
to_chat(M, weather_message) to_chat(player, weather_message)
if(weather_sound) if(weather_sound)
SEND_SOUND(M, sound(weather_sound)) SEND_SOUND(player, sound(weather_sound))
if(!perpetual) if(!perpetual)
addtimer(CALLBACK(src, .proc/wind_down), weather_duration) addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
@@ -192,14 +195,27 @@
* Returns TRUE if the living mob can be affected by the weather * Returns TRUE if the living mob can be affected by the weather
* *
*/ */
/datum/weather/proc/can_weather_act(mob/living/L) /datum/weather/proc/can_weather_act(mob/living/mob_to_check)
var/turf/mob_turf = get_turf(L) var/turf/mob_turf = get_turf(mob_to_check)
if(mob_turf && !(mob_turf.z in impacted_z_levels))
if(!mob_turf)
return return
if(immunity_type in L.weather_immunities)
if(!(mob_turf.z in impacted_z_levels))
return return
if(!(get_area(L) in impacted_areas))
if((immunity_type && HAS_TRAIT(mob_to_check, immunity_type)) || HAS_TRAIT(mob_to_check, TRAIT_WEATHER_IMMUNE))
return return
var/atom/loc_to_check = mob_to_check.loc
while(loc_to_check != mob_turf)
if((immunity_type && HAS_TRAIT(loc_to_check, immunity_type)) || HAS_TRAIT(loc_to_check, TRAIT_WEATHER_IMMUNE))
return
loc_to_check = loc_to_check.loc
if(!(get_area(mob_to_check) in impacted_areas))
return
return TRUE return TRUE
/** /**

View File

@@ -1,32 +0,0 @@
//Acid rain is part of the natural weather cycle in the humid forests of Planetstation, and cause acid damage to anyone unprotected.
/datum/weather/acid_rain
name = "acid rain"
desc = "The planet's thunderstorms are by nature acidic, and will incinerate anyone standing beneath them without protection."
telegraph_duration = 400
telegraph_message = "<span class='boldwarning'>Thunder rumbles far above. You hear droplets drumming against the canopy. Seek shelter.</span>"
telegraph_sound = 'sound/ambience/acidrain_start.ogg'
weather_message = "<span class='userdanger'><i>Acidic rain pours down around you! Get inside!</i></span>"
weather_overlay = "acid_rain"
weather_duration_lower = 600
weather_duration_upper = 1500
weather_sound = 'sound/ambience/acidrain_mid.ogg'
end_duration = 100
end_message = "<span class='boldannounce'>The downpour gradually slows to a light shower. It should be safe outside now.</span>"
end_sound = 'sound/ambience/acidrain_end.ogg'
area_type = /area
protect_indoors = TRUE
target_trait = ZTRAIT_ACIDRAIN
immunity_type = "acid" // temp
barometer_predictable = TRUE
/datum/weather/acid_rain/weather_act(mob/living/L)
var/resist = L.getarmor(null, ACID)
if(prob(max(0,100-resist)))
L.acid_act(20,20)

View File

@@ -1,6 +1,5 @@
//A reference to this list is passed into area sound managers, and it's modified in a manner that preserves that reference in ash_storm.dm //A reference to this list is passed into area sound managers, and it's modified in a manner that preserves that reference in ash_storm.dm
GLOBAL_LIST_EMPTY(ash_storm_sounds) GLOBAL_LIST_EMPTY(ash_storm_sounds)
//Ash storms happen frequently on lavaland. They heavily obscure vision, and cause high fire damage to anyone caught outside.
/datum/weather/ash_storm /datum/weather/ash_storm
name = "ash storm" name = "ash storm"
desc = "An intense atmospheric storm lifts ash off of the planet's surface and billows it down across the area, dealing intense fire damage to the unprotected." desc = "An intense atmospheric storm lifts ash off of the planet's surface and billows it down across the area, dealing intense fire damage to the unprotected."
@@ -22,7 +21,7 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds)
protect_indoors = TRUE protect_indoors = TRUE
target_trait = ZTRAIT_ASHSTORM target_trait = ZTRAIT_ASHSTORM
immunity_type = "ash" immunity_type = TRAIT_ASHSTORM_IMMUNE
probability = 90 probability = 90
@@ -72,10 +71,6 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds)
var/thermal_protection = H.easy_thermal_protection() var/thermal_protection = H.easy_thermal_protection()
if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT) if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT)
return TRUE return TRUE
if(isliving(L))// if we're a non immune mob inside an immune mob we have to reconsider if that mob is immune to protect ourselves
var/mob/living/the_mob = L
if("ash" in the_mob.weather_immunities)
return TRUE
// if(istype(L, /obj/structure/closet)) // if(istype(L, /obj/structure/closet))
// var/obj/structure/closet/the_locker = L // var/obj/structure/closet/the_locker = L
// if(the_locker.weather_protection) // if(the_locker.weather_protection)
@@ -93,7 +88,6 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds)
return return
L.adjustFireLoss(4) L.adjustFireLoss(4)
//Emberfalls are the result of an ash storm passing by close to the playable area of lavaland. They have a 10% chance to trigger in place of an ash storm. //Emberfalls are the result of an ash storm passing by close to the playable area of lavaland. They have a 10% chance to trigger in place of an ash storm.
/datum/weather/ash_storm/emberfall /datum/weather/ash_storm/emberfall
name = "emberfall" name = "emberfall"

View File

@@ -19,19 +19,23 @@
target_trait = ZTRAIT_STATION target_trait = ZTRAIT_STATION
overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only
immunity_type = "lava" immunity_type = TRAIT_LAVA_IMMUNE
/datum/weather/floor_is_lava/weather_act(mob/living/L) /datum/weather/floor_is_lava/can_weather_act(mob/living/mob_to_check)
if(issilicon(L)) if(!mob_to_check.client) //Only sentient people are going along with it!
return return FALSE
if(istype(L.buckled, /obj/structure/bed)) . = ..()
return if(!. || issilicon(mob_to_check) || istype(mob_to_check.buckled, /obj/structure/bed))
for(var/obj/structure/O in L.loc) return FALSE
if(O.density) var/turf/mob_turf = get_turf(mob_to_check)
return if(mob_turf.density) //Walls are not floors.
if(L.loc.density) return FALSE
return for(var/obj/structure/structure_to_check in mob_turf)
if(!L.client) //Only sentient people are going along with it! if(structure_to_check.density)
return return FALSE
L.adjustFireLoss(3) if(mob_to_check.movement_type & FLYING)
return FALSE
/datum/weather/floor_is_lava/weather_act(mob/living/victim)
victim.adjustFireLoss(3)

View File

@@ -21,7 +21,7 @@
protected_areas = list(/area/edina/protected) protected_areas = list(/area/edina/protected)
target_trait = ZTRAIT_ICESTORM target_trait = ZTRAIT_ICESTORM
immunity_type = "rad" immunity_type = TRAIT_SNOWSTORM_IMMUNE
/datum/weather/ice_storm/weather_act(mob/living/L) /datum/weather/ice_storm/weather_act(mob/living/L)
//L.adjust_bodytemperature(-rand(10,20)) //L.adjust_bodytemperature(-rand(10,20))

View File

@@ -21,7 +21,7 @@
/area/ai_monitored/turret_protected/ai, /area/commons/storage/emergency/starboard, /area/commons/storage/emergency/port, /area/shuttle, /area/ruin/lavaland, /area/commons/dorms) /area/ai_monitored/turret_protected/ai, /area/commons/storage/emergency/starboard, /area/commons/storage/emergency/port, /area/shuttle, /area/ruin/lavaland, /area/commons/dorms)
target_trait = ZTRAIT_STATION target_trait = ZTRAIT_STATION
immunity_type = "rad" immunity_type = TRAIT_RADSTORM_IMMUNE
var/radiation_intensity = 100 var/radiation_intensity = 100

View File

@@ -19,7 +19,7 @@
protect_indoors = TRUE protect_indoors = TRUE
target_trait = ZTRAIT_SNOWSTORM target_trait = ZTRAIT_SNOWSTORM
immunity_type = "snow" immunity_type = TRAIT_SNOWSTORM_IMMUNE
barometer_predictable = TRUE barometer_predictable = TRUE

View File

@@ -17,15 +17,18 @@
protect_indoors = FALSE protect_indoors = FALSE
target_trait = ZTRAIT_VOIDSTORM target_trait = ZTRAIT_VOIDSTORM
immunity_type = "void" immunity_type = TRAIT_VOIDSTORM_IMMUNE
barometer_predictable = FALSE barometer_predictable = FALSE
perpetual = TRUE perpetual = TRUE
/datum/weather/void_storm/weather_act(mob/living/L) /datum/weather/void_storm/can_weather_act(mob/living/mob_to_check)
if(IS_HERETIC(L) || IS_HERETIC_MONSTER(L)) . = ..()
return if(IS_HERETIC(mob_to_check) || IS_HERETIC_MONSTER(mob_to_check))
L.adjustOxyLoss(rand(1,3)) return FALSE
L.adjustFireLoss(rand(1,3))
L.adjust_blurriness(rand(0,1)) /datum/weather/void_storm/weather_act(mob/living/victim)
L.adjust_bodytemperature(-rand(5,15)) victim.adjustOxyLoss(rand(1,3))
victim.adjustFireLoss(rand(1,3))
victim.adjust_blurriness(rand(0,1))
victim.adjust_bodytemperature(-rand(5,15))

View File

@@ -325,12 +325,12 @@ as performing this in action() will cause the upgrade to end up in the borg inst
/obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R, user = usr) /obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R, user = usr)
. = ..() . = ..()
if(.) if(.)
R.weather_immunities += "lava" ADD_TRAIT(src, TRAIT_LAVA_IMMUNE, type)
/obj/item/borg/upgrade/lavaproof/deactivate(mob/living/silicon/robot/R, user = usr) /obj/item/borg/upgrade/lavaproof/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..() . = ..()
if (.) if (.)
R.weather_immunities -= "lava" REMOVE_TRAIT(src, TRAIT_LAVA_IMMUNE, type)
/obj/item/borg/upgrade/selfrepair /obj/item/borg/upgrade/selfrepair
name = "self-repair module" name = "self-repair module"

View File

@@ -17,6 +17,16 @@
barefootstep = FOOTSTEP_LAVA barefootstep = FOOTSTEP_LAVA
clawfootstep = FOOTSTEP_LAVA clawfootstep = FOOTSTEP_LAVA
heavyfootstep = FOOTSTEP_LAVA heavyfootstep = FOOTSTEP_LAVA
/// How much fire damage we deal to living mobs stepping on us
var/lava_damage = 20
/// How many firestacks we add to living mobs stepping on us
var/lava_firestacks = 20
/// How much temperature we expose objects with
var/temperature_damage = 10000
/// mobs with this trait won't burn.
var/immunity_trait = TRAIT_LAVA_IMMUNE
/// objects with these flags won't burn.
var/immunity_resistance_flags = LAVA_PROOF
/turf/open/lava/ex_act(severity, target, origin) /turf/open/lava/ex_act(severity, target, origin)
contents_explosion(severity, target, origin) contents_explosion(severity, target, origin)
@@ -107,62 +117,98 @@
LAZYREMOVE(found_safeties, S) LAZYREMOVE(found_safeties, S)
return LAZYLEN(found_safeties) return LAZYLEN(found_safeties)
///Generic return value of the can_burn_stuff() proc. Does nothing.
#define LAVA_BE_IGNORING 0
/// Another. Won't burn the target but will make the turf start processing.
#define LAVA_BE_PROCESSING 1
/// Burns the target and makes the turf process (depending on the return value of do_burn()).
#define LAVA_BE_BURNING 2
/turf/open/lava/proc/burn_stuff(AM) ///Proc that sets on fire something or everything on the turf that's not immune to lava. Returns TRUE to make the turf start processing.
. = 0 /turf/open/lava/proc/burn_stuff(atom/movable/to_burn, delta_time = 1)
if(is_safe()) if(is_safe())
return FALSE return FALSE
var/thing_to_check = src var/thing_to_check = src
if (AM) if (to_burn)
thing_to_check = list(AM) thing_to_check = list(to_burn)
for(var/thing in thing_to_check) for(var/atom/movable/burn_target as anything in thing_to_check)
if(isobj(thing)) switch(can_burn_stuff(burn_target))
var/obj/O = thing if(LAVA_BE_IGNORING)
if((O.resistance_flags & (LAVA_PROOF|INDESTRUCTIBLE)) || O.throwing)
continue continue
. = 1 if(LAVA_BE_BURNING)
if((O.resistance_flags & (ON_FIRE))) if(!do_burn(burn_target, delta_time))
continue
if(!(O.resistance_flags & FLAMMABLE))
O.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava
if(O.resistance_flags & FIRE_PROOF)
O.resistance_flags &= ~FIRE_PROOF
if(O.armor.fire > 50) //obj with 100% fire armor still get slowly burned away.
O.armor = O.armor.setRating(fire = 50)
O.fire_act(10000, 1000)
else if (isliving(thing))
. = 1
var/mob/living/L = thing
if(L.movement_type & FLYING)
continue //YOU'RE FLYING OVER IT
if("lava" in L.weather_immunities)
continue
var/buckle_check = L.buckling
if(!buckle_check)
buckle_check = L.buckled
if(isobj(buckle_check))
var/obj/O = buckle_check
if(O.resistance_flags & LAVA_PROOF)
continue continue
else if(isliving(buckle_check)) . = TRUE
var/mob/living/live = buckle_check
if("lava" in live.weather_immunities)
continue
if(iscarbon(L))
var/mob/living/carbon/C = L
var/obj/item/clothing/S = C.get_item_by_slot(ITEM_SLOT_OCLOTHING)
var/obj/item/clothing/H = C.get_item_by_slot(ITEM_SLOT_HEAD)
if(S && H && S.clothing_flags & LAVAPROTECT && H.clothing_flags & LAVAPROTECT) /turf/open/lava/proc/can_burn_stuff(atom/movable/burn_target)
return if(burn_target.movement_type & (FLYING|FLOATING)) //you're flying over it.
return isliving(burn_target) ? LAVA_BE_PROCESSING : LAVA_BE_IGNORING
L.adjustFireLoss(20) if(isobj(burn_target))
if(L) //mobs turning into object corpses could get deleted here. if(burn_target.throwing) // to avoid gulag prisoners easily escaping, throwing only works for objects.
L.adjust_fire_stacks(20) return LAVA_BE_IGNORING
L.IgniteMob() var/obj/burn_obj = burn_target
if((burn_obj.resistance_flags & immunity_resistance_flags))
return LAVA_BE_PROCESSING
return LAVA_BE_BURNING
if (!isliving(burn_target))
return LAVA_BE_IGNORING
if(HAS_TRAIT(burn_target, immunity_trait))
return LAVA_BE_PROCESSING
var/mob/living/burn_living = burn_target
var/atom/movable/burn_buckled = burn_living.buckled
if(burn_buckled)
if(burn_buckled.movement_type & (FLYING|FLOATING))
return LAVA_BE_PROCESSING
if(isobj(burn_buckled))
var/obj/burn_buckled_obj = burn_buckled
if(burn_buckled_obj.resistance_flags & immunity_resistance_flags)
return LAVA_BE_PROCESSING
else if(HAS_TRAIT(burn_buckled, immunity_trait))
return LAVA_BE_PROCESSING
if(iscarbon(burn_living))
var/mob/living/carbon/burn_carbon = burn_living
var/obj/item/clothing/burn_suit = burn_carbon.get_item_by_slot(ITEM_SLOT_OCLOTHING)
var/obj/item/clothing/burn_helmet = burn_carbon.get_item_by_slot(ITEM_SLOT_HEAD)
if(burn_suit?.clothing_flags & LAVAPROTECT && burn_helmet?.clothing_flags & LAVAPROTECT)
return LAVA_BE_PROCESSING
return LAVA_BE_BURNING
#undef LAVA_BE_IGNORING
#undef LAVA_BE_PROCESSING
#undef LAVA_BE_BURNING
/turf/open/lava/proc/do_burn(atom/movable/burn_target, delta_time = 1)
. = TRUE
if(isobj(burn_target))
var/obj/burn_obj = burn_target
if(burn_obj.resistance_flags & ON_FIRE) // already on fire; skip it.
return
if(!(burn_obj.resistance_flags & FLAMMABLE))
burn_obj.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava
if(burn_obj.resistance_flags & FIRE_PROOF)
burn_obj.resistance_flags &= ~FIRE_PROOF
if(burn_obj.armor.fire > 50) //obj with 100% fire armor still get slowly burned away.
burn_obj.armor = burn_obj.armor.setRating(fire = 50)
burn_obj.fire_act(temperature_damage, 1000 * delta_time)
if(istype(burn_obj, /obj/structure/closet))
var/obj/structure/closet/burn_closet = burn_obj
for(var/burn_content in burn_closet.contents)
burn_stuff(burn_content)
var/mob/living/burn_living = burn_target
burn_living.update_fire()
burn_living.adjustFireLoss(lava_damage * delta_time)
if(!QDELETED(burn_living)) //mobs turning into object corpses could get deleted here.
burn_living.adjust_fire_stacks(lava_firestacks * delta_time)
burn_living.IgniteMob()
/turf/open/lava/smooth /turf/open/lava/smooth
name = "lava" name = "lava"

View File

@@ -164,11 +164,12 @@
icon_state = "liquidplasma" icon_state = "liquidplasma"
initial_gas_mix = "n2=82;plasma=24;TEMP=120" initial_gas_mix = "n2=82;plasma=24;TEMP=120"
baseturfs = /turf/open/lava/plasma baseturfs = /turf/open/lava/plasma
slowdown = 2
light_range = 3 light_range = 3
light_power = 0.75 light_power = 0.75
light_color = LIGHT_COLOR_PURPLE light_color = LIGHT_COLOR_PURPLE
immunity_trait = TRAIT_SNOWSTORM_IMMUNE
immunity_resistance_flags = FREEZE_PROOF
/turf/open/lava/plasma/attackby(obj/item/I, mob/user, params) /turf/open/lava/plasma/attackby(obj/item/I, mob/user, params)
var/obj/item/reagent_containers/glass/C = I var/obj/item/reagent_containers/glass/C = I
@@ -178,78 +179,45 @@
C.reagents.add_reagent(/datum/reagent/toxin/plasma, rand(5, 10)) C.reagents.add_reagent(/datum/reagent/toxin/plasma, rand(5, 10))
user.visible_message("[user] scoops some plasma from the [src] with \the [C].", "<span class='notice'>You scoop out some plasma from the [src] using \the [C].</span>") user.visible_message("[user] scoops some plasma from the [src] with \the [C].", "<span class='notice'>You scoop out some plasma from the [src] using \the [C].</span>")
/turf/open/lava/plasma/burn_stuff(AM) /turf/open/lava/plasma/do_burn(atom/movable/burn_target, delta_time = 1)
. = 0 . = TRUE
if(isobj(burn_target))
return FALSE // Does nothing against objects. Old code.
if(is_safe()) var/mob/living/burn_living = burn_target
return FALSE burn_living.adjustFireLoss(2)
if(QDELETED(burn_living))
return
burn_living.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual
burn_living.adjust_bodytemperature(-rand(50,65)) //its cold, man
if(!ishuman(burn_living) || DT_PROB(65, delta_time))
return
var/mob/living/carbon/human/burn_human = burn_living
var/datum/species/burn_species = burn_human.dna.species
if(istype(burn_species, /datum/species/plasmaman) || istype(burn_species, /datum/species/android) || istype(burn_species, /datum/species/synth)) //ignore plasmamen/robotic species
return
var/thing_to_check = src var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs
if (AM) var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman
thing_to_check = list(AM) for(var/obj/item/bodypart/burn_limb as anything in burn_human.bodyparts)
for(var/thing in thing_to_check) if(burn_limb.status == BODYPART_ORGANIC && burn_limb.species_id != SPECIES_PLASMAMAN) //getting every organic, non-plasmaman limb (augments/androids are immune to this)
if(isobj(thing)) plasma_parts += burn_limb
var/obj/O = thing if(burn_limb.status == BODYPART_ROBOTIC)
if((O.resistance_flags & (FREEZE_PROOF)) || O.throwing) robo_parts += burn_limb
continue
else if (isliving(thing))
. = 1
var/mob/living/L = thing
if(L.movement_type & FLYING)
continue //YOU'RE FLYING OVER IT
if("snow" in L.weather_immunities)
continue
var/buckle_check = L.buckling
if(!buckle_check)
buckle_check = L.buckled
if(isobj(buckle_check))
var/obj/O = buckle_check
if(O.resistance_flags & FREEZE_PROOF)
continue
else if(isliving(buckle_check))
var/mob/living/live = buckle_check
if("snow" in live.weather_immunities)
continue
L.adjustFireLoss(2)
if(L)
L.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual
L.adjust_bodytemperature(-rand(50,65)) //its cold, man
if(ishuman(L))//are they a carbon?
var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs
var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman
var/mob/living/carbon/human/PP = L
var/S = PP.dna.species
if(istype(S, /datum/species/plasmaman) || istype(S, /datum/species/android) || istype(S, /datum/species/synth)) //ignore plasmamen/robotic species
continue
for(var/BP in PP.bodyparts)
var/obj/item/bodypart/NN = BP
if(NN.is_organic_limb() && NN.species_id != "plasmaman") //getting every organic, non-plasmaman limb (augments/androids are immune to this)
plasma_parts += NN
if(NN.is_robotic_limb(FALSE))
robo_parts += NN
if(prob(35)) //checking if the delay is over & if the victim actually has any parts to nom
PP.adjustToxLoss(15)
PP.adjustFireLoss(25)
if(plasma_parts.len)
var/obj/item/bodypart/NB = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs for dismember() to use
PP.emote("scream")
NB.species_id = "plasmaman"//change the species_id of the limb to that of a plasmaman
NB.no_update = TRUE
NB.change_bodypart_status()
PP.visible_message("<span class='warning'>[L] screams in pain as [L.p_their()] [NB] melts down to the bone!</span>", \
"<span class='userdanger'>You scream out in pain as your [NB] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!</span>")
if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman
PP.IgniteMob()
PP.set_species(/datum/species/plasmaman)
PP.visible_message("<span class='warning'>[L] bursts into a brilliant purple flame as [L.p_their()] entire body is that of a skeleton!</span>", \
"<span class='userdanger'>Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!</span>")
burn_human.adjustToxLoss(15)
burn_human.adjustFireLoss(25)
if(plasma_parts.len)
var/obj/item/bodypart/burn_limb = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs
burn_human.emote("scream")
burn_human.update_body_parts()
burn_human.visible_message(span_warning("[burn_human] screams in pain as [burn_human.p_their()] [burn_limb] melts down to the bone!"), \
span_userdanger("You scream out in pain as your [burn_limb] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!"))
if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman
burn_human.IgniteMob()
burn_human.set_species(/datum/species/plasmaman)
burn_human.visible_message(span_warning("[burn_human] bursts into a brilliant purple flame as [burn_human.p_their()] entire body is that of a skeleton!"), \
span_userdanger("Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!"))
/obj/vehicle/ridden/lavaboat/plasma /obj/vehicle/ridden/lavaboat/plasma
name = "plasma boat" name = "plasma boat"

View File

@@ -156,38 +156,48 @@
M.appearance_flags = RESET_COLOR M.appearance_flags = RESET_COLOR
. += M . += M
/****************HEVA Suit and Mask****************/
// CITADEL ADDITIONS BELOW /obj/item/clothing/suit/hooded/explorer/heva
name = "HEVA suit"
/****************SEVA Suit and Mask****************/ desc = "The Hazardous Environments extra-Vehicular Activity suit, developed by WanTon & Sons Perilous Mining and sold to Nanotrasen for missions within inhospitable, mineral-rich zones. \
Its sleek plating deflects most biological - radioactive - and chemical substances and materials. Most notably, this will negate the effects of ash storms and give goliaths better grip against you."
/obj/item/clothing/suit/hooded/explorer/seva icon_state = "heva"
name = "SEVA Suit" item_state = "heva"
desc = "A fire-proof suit for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer."
icon_state = "seva"
item_state = "seva"
w_class = WEIGHT_CLASS_BULKY w_class = WEIGHT_CLASS_BULKY
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
hoodtype = /obj/item/clothing/head/hooded/explorer/seva hoodtype = /obj/item/clothing/head/hooded/explorer/heva
armor = list(MELEE = 15, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 35, BIO = 50, RAD = 25, FIRE = 100, ACID = 25) armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 100, RAD = 80, FIRE = 100, ACID = 80)
resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS
/obj/item/clothing/head/hooded/explorer/seva /obj/item/clothing/head/hooded/explorer/heva
name = "SEVA Hood" name = "HEVA hood"
desc = "A fire-proof hood for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer." desc = "The Hazardous Environments extra-Vehiclar Activity hood, developed by WanTon & Sons Perilous Mining. \
icon_state = "seva" Its sleek plating deflects most biological - radioactive - and chemical substances and materials. An instructive tag dictates that the provided mask is required for full protection."
item_state = "seva" icon_state = "heva"
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT item_state = "heva"
armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 35, BIO = 50, RAD = 25, FIRE = 100, ACID = 25) flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 100, RAD = 20, FIRE = 60, ACID = 20)
resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS
/obj/item/clothing/mask/gas/seva /obj/item/clothing/head/hooded/explorer/heva/equipped(mob/living/carbon/human/user, slot)
name = "SEVA Mask" ..()
desc = "A face-covering plate that can be connected to an air supply. Intended for use with the SEVA Suit." if (slot == ITEM_SLOT_HEAD)
icon_state = "seva" ADD_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit")
item_state = "seva"
resistance_flags = FIRE_PROOF /obj/item/clothing/head/hooded/explorer/heva/dropped(mob/living/carbon/human/user)
..()
if (HAS_TRAIT_FROM(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit"))
REMOVE_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit")
/obj/item/clothing/mask/gas/heva
name = "HEVA mask"
desc = "The Hazardous Environments extra-Vehiclar Activity mask, developed by WanTon & Sons Perilous Mining. \
Its sleek plating deflects most biological - radioactive - and chemical substances and materials. An instructive tag dictates that the provided protective attire is required for full protection."
icon_state = "heva"
item_state = "heva"
flags_inv = HIDEFACIALHAIR|HIDEFACE|HIDEEYES|HIDEEARS|HIDEHAIR
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 60, FIRE = 40, ACID = 50)
/****************Exo-Suit and Mask****************/ /****************Exo-Suit and Mask****************/

View File

@@ -1043,7 +1043,7 @@
user.mind.AddSpell(D) user.mind.AddSpell(D)
if(4) if(4)
to_chat(user, "<span class='danger'>You feel like you could walk straight through lava now.</span>") to_chat(user, "<span class='danger'>You feel like you could walk straight through lava now.</span>")
H.weather_immunities |= "lava" ADD_TRAIT(user, TRAIT_LAVA_IMMUNE, type)
playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1) playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1)
qdel(src) qdel(src)

View File

@@ -236,7 +236,7 @@
/obj/machinery/mineral/equipment_vendor/proc/RedeemSVoucher(obj/item/suit_voucher/voucher, mob/redeemer) /obj/machinery/mineral/equipment_vendor/proc/RedeemSVoucher(obj/item/suit_voucher/voucher, mob/redeemer)
var/items = list( "Exo-suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "exo"), var/items = list( "Exo-suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "exo"),
"SEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "seva")) "HEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "heva"))
var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE)
if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer)
@@ -246,9 +246,9 @@
if("Exo-suit") if("Exo-suit")
new /obj/item/clothing/suit/hooded/explorer/exo(drop_location) new /obj/item/clothing/suit/hooded/explorer/exo(drop_location)
new /obj/item/clothing/mask/gas/exo(drop_location) new /obj/item/clothing/mask/gas/exo(drop_location)
if("SEVA suit") if("HEVA suit")
new /obj/item/clothing/suit/hooded/explorer/seva(drop_location) new /obj/item/clothing/suit/hooded/explorer/heva(drop_location)
new /obj/item/clothing/mask/gas/seva(drop_location) new /obj/item/clothing/mask/gas/heva(drop_location)
playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3)
SSblackbox.record_feedback("tally", "suit_voucher_redeemed", 1, selection) SSblackbox.record_feedback("tally", "suit_voucher_redeemed", 1, selection)
qdel(voucher) qdel(voucher)

View File

@@ -48,13 +48,11 @@
else //Maybe uses plasma in the future, although that wouldn't make any sense... else //Maybe uses plasma in the future, although that wouldn't make any sense...
leaping = 1 leaping = 1
weather_immunities += "lava"
update_icons() update_icons()
throw_at(A, MAX_ALIEN_LEAP_DIST, 1, src, FALSE, TRUE, callback = CALLBACK(src, .proc/leap_end)) throw_at(A, MAX_ALIEN_LEAP_DIST, 1, src, FALSE, TRUE, callback = CALLBACK(src, .proc/leap_end))
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end() /mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
leaping = 0 leaping = 0
weather_immunities -= "lava"
update_icons() update_icons()
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) /mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)

View File

@@ -214,11 +214,11 @@
/datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) /datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..() . = ..()
C.weather_immunities |= "ash" ADD_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT)
/datum/species/golem/titanium/on_species_loss(mob/living/carbon/C) /datum/species/golem/titanium/on_species_loss(mob/living/carbon/C)
. = ..() . = ..()
C.weather_immunities -= "ash" REMOVE_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT)
//Immune to ash storms and lava //Immune to ash storms and lava
/datum/species/golem/plastitanium /datum/species/golem/plastitanium
@@ -233,13 +233,13 @@
/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) /datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..() . = ..()
C.weather_immunities |= "lava" ADD_TRAIT(C, TRAIT_LAVA_IMMUNE, SPECIES_TRAIT)
C.weather_immunities |= "ash" ADD_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT)
/datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C) /datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C)
. = ..() . = ..()
C.weather_immunities -= "ash" REMOVE_TRAIT(C, TRAIT_LAVA_IMMUNE, SPECIES_TRAIT)
C.weather_immunities -= "lava" REMOVE_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT)
//Fast and regenerates... but can only speak like an abductor //Fast and regenerates... but can only speak like an abductor
/datum/species/golem/alloy /datum/species/golem/alloy

View File

@@ -107,8 +107,6 @@
var/hellbound = 0 //People who've signed infernal contracts are unrevivable. var/hellbound = 0 //People who've signed infernal contracts are unrevivable.
var/list/weather_immunities = list()
var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added
var/blood_volume = 0 //how much blood the mob has var/blood_volume = 0 //how much blood the mob has

View File

@@ -6,7 +6,6 @@
pass_flags = PASSTABLE | PASSMOB pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_TINY mob_size = MOB_SIZE_TINY
desc = "A generic pAI mobile hard-light holographics emitter. It seems to be deactivated." desc = "A generic pAI mobile hard-light holographics emitter. It seems to be deactivated."
weather_immunities = list("ash")
health = 500 health = 500
maxHealth = 500 maxHealth = 500
layer = BELOW_MOB_LAYER layer = BELOW_MOB_LAYER

View File

@@ -8,7 +8,6 @@
initial_language_holder = /datum/language_holder/synthetic initial_language_holder = /datum/language_holder/synthetic
see_in_dark = 8 see_in_dark = 8
bubble_icon = "machine" bubble_icon = "machine"
weather_immunities = list("ash")
possible_a_intents = list(INTENT_HELP, INTENT_HARM) possible_a_intents = list(INTENT_HELP, INTENT_HARM)
mob_biotypes = MOB_ROBOTIC mob_biotypes = MOB_ROBOTIC
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
@@ -60,6 +59,7 @@
diag_hud.add_to_hud(src) diag_hud.add_to_hud(src)
diag_hud_set_status() diag_hud_set_status()
diag_hud_set_health() diag_hud_set_health()
ADD_TRAIT(src, TRAIT_ASHSTORM_IMMUNE, ROUNDSTART_TRAIT)
/mob/living/silicon/ComponentInitialize() /mob/living/silicon/ComponentInitialize()
. = ..() . = ..()

View File

@@ -61,7 +61,7 @@
icon_living = "snowbear" icon_living = "snowbear"
icon_dead = "snowbear_dead" icon_dead = "snowbear_dead"
desc = "It's a polar bear, in space, but not actually in space." desc = "It's a polar bear, in space, but not actually in space."
weather_immunities = list("snow") weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
/mob/living/simple_animal/hostile/bear/russian /mob/living/simple_animal/hostile/bear/russian
name = "combat bear" name = "combat bear"

View File

@@ -26,7 +26,7 @@
gold_core_spawnable = HOSTILE_SPAWN gold_core_spawnable = HOSTILE_SPAWN
faction = list(ROLE_WIZARD) faction = list(ROLE_WIZARD)
footstep_type = FOOTSTEP_MOB_SHOE footstep_type = FOOTSTEP_MOB_SHOE
weather_immunities = list("lava","ash") weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
minbodytemp = 0 minbodytemp = 0
maxbodytemp = INFINITY maxbodytemp = INFINITY
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)

View File

@@ -16,7 +16,7 @@ Difficulty: Extremely Hard
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
light_color = "#E4C7C5" light_color = "#E4C7C5"
movement_type = GROUND movement_type = GROUND
weather_immunities = list("snow") weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
speak_emote = list("roars") speak_emote = list("roars")
armour_penetration = 100 armour_penetration = 100
melee_damage_lower = 10 melee_damage_lower = 10

View File

@@ -10,7 +10,7 @@
obj_damage = 400 obj_damage = 400
light_range = 3 light_range = 3
faction = list("mining", "boss") faction = list("mining", "boss")
weather_immunities = list("lava","ash") weather_immunities = list(TRAIT_LAVA_IMMUNE,TRAIT_ASHSTORM_IMMUNE)
movement_type = FLYING movement_type = FLYING
robust_searching = 1 robust_searching = 1
ranged_ignores_vision = TRUE ranged_ignores_vision = TRUE

View File

@@ -52,7 +52,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
crusher_achievement_type = /datum/award/achievement/boss/swarmer_beacon_crusher crusher_achievement_type = /datum/award/achievement/boss/swarmer_beacon_crusher
score_achievement_type = /datum/award/score/swarmer_beacon_score score_achievement_type = /datum/award/score/swarmer_beacon_score
faction = list("mining", "boss", "swarmer") faction = list("mining", "boss", "swarmer")
weather_immunities = list("lava","ash") weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
stop_automated_movement = TRUE stop_automated_movement = TRUE
wander = FALSE wander = FALSE
layer = BELOW_MOB_LAYER layer = BELOW_MOB_LAYER
@@ -101,7 +101,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
/mob/living/simple_animal/hostile/swarmer/ai /mob/living/simple_animal/hostile/swarmer/ai
wander = 1 wander = 1
faction = list("swarmer", "mining") faction = list("swarmer", "mining")
weather_immunities = list("ash") //wouldn't be fun otherwise weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) //wouldn't be fun otherwise
AIStatus = AI_ON AIStatus = AI_ON
/mob/living/simple_animal/hostile/swarmer/ai/Initialize(mapload) /mob/living/simple_animal/hostile/swarmer/ai/Initialize(mapload)

View File

@@ -14,7 +14,7 @@ Difficulty: Hard
attack_verb_continuous = "claws" attack_verb_continuous = "claws"
attack_verb_simple = "claw" attack_verb_simple = "claw"
attack_sound = 'sound/magic/demon_attack1.ogg' attack_sound = 'sound/magic/demon_attack1.ogg'
weather_immunities = list("snow") weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
speak_emote = list("roars") speak_emote = list("roars")
armour_penetration = 40 armour_penetration = 40
melee_damage_lower = 40 melee_damage_lower = 40

View File

@@ -10,7 +10,7 @@
speak_emote = list("warbles", "quavers") speak_emote = list("warbles", "quavers")
emote_hear = list("trills.") emote_hear = list("trills.")
emote_see = list("sniffs.", "burps.") emote_see = list("sniffs.", "burps.")
weather_immunities = list("lava","ash") weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
faction = list("mining", "ashwalker") faction = list("mining", "ashwalker")
density = FALSE density = FALSE
speak_chance = 1 speak_chance = 1

View File

@@ -272,7 +272,7 @@
aggro_vision_range = 9 aggro_vision_range = 9
speed = 3 speed = 3
faction = list("mining") faction = list("mining")
weather_immunities = list("lava","ash") weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
obj_damage = 30 obj_damage = 30
environment_smash = ENVIRONMENT_SMASH_STRUCTURES environment_smash = ENVIRONMENT_SMASH_STRUCTURES
see_in_dark = 8 see_in_dark = 8
@@ -321,7 +321,7 @@
gloves = /obj/item/clothing/gloves/color/black gloves = /obj/item/clothing/gloves/color/black
mask = /obj/item/clothing/mask/gas/explorer mask = /obj/item/clothing/mask/gas/explorer
if(prob(20)) if(prob(20))
suit = pickweight(list(/obj/item/clothing/suit/hooded/explorer/standard = 6, /obj/item/clothing/suit/hooded/cloak/goliath = 2, /obj/item/clothing/suit/hooded/explorer/exo = 6, /obj/item/clothing/suit/hooded/explorer/seva = 6)) suit = pickweight(list(/obj/item/clothing/suit/hooded/explorer/standard = 6, /obj/item/clothing/suit/hooded/cloak/goliath = 2, /obj/item/clothing/suit/hooded/explorer/exo = 6, /obj/item/clothing/suit/hooded/explorer/heva = 6))
if(prob(30)) if(prob(30))
r_pocket = pickweight(list(/obj/item/stack/marker_beacon = 20, /obj/item/stack/spacecash/c1000 = 7, /obj/item/reagent_containers/hypospray/medipen/survival = 2, /obj/item/borg/upgrade/modkit/damage = 1 )) r_pocket = pickweight(list(/obj/item/stack/marker_beacon = 20, /obj/item/stack/spacecash/c1000 = 7, /obj/item/reagent_containers/hypospray/medipen/survival = 2, /obj/item/borg/upgrade/modkit/damage = 1 ))
if(prob(10)) if(prob(10))

View File

@@ -3,7 +3,7 @@
vision_range = 2 vision_range = 2
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
faction = list("mining") faction = list("mining")
weather_immunities = list("lava","ash") weather_immunities = list(TRAIT_LAVA_IMMUNE,TRAIT_ASHSTORM_IMMUNE)
obj_damage = 30 obj_damage = 30
environment_smash = ENVIRONMENT_SMASH_WALLS environment_smash = ENVIRONMENT_SMASH_WALLS
minbodytemp = 0 minbodytemp = 0

View File

@@ -46,7 +46,7 @@
icon_dead = "eskimo_dead" icon_dead = "eskimo_dead"
maxHealth = 55 maxHealth = 55
health = 55 health = 55
weather_immunities = list("snow") weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
gold_core_spawnable = NO_SPAWN gold_core_spawnable = NO_SPAWN
melee_damage_lower = 17 melee_damage_lower = 17
melee_damage_upper = 20 melee_damage_upper = 20
@@ -65,7 +65,7 @@
icon_dead = "templar_dead" icon_dead = "templar_dead"
maxHealth = 150 maxHealth = 150
health = 150 health = 150
weather_immunities = list("snow") weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
speed = 2 speed = 2
gold_core_spawnable = NO_SPAWN gold_core_spawnable = NO_SPAWN
speak_chance = 1 speak_chance = 1
@@ -86,7 +86,7 @@
speed = 5 speed = 5
maxHealth = 75 maxHealth = 75
health = 75 health = 75
weather_immunities = list("snow") weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
color = rgb(114,228,250) color = rgb(114,228,250)
loot = list(/obj/effect/decal/remains/human{color = rgb(114,228,250)}) loot = list(/obj/effect/decal/remains/human{color = rgb(114,228,250)})

View File

@@ -56,6 +56,9 @@
var/minbodytemp = 250 var/minbodytemp = 250
var/maxbodytemp = 350 var/maxbodytemp = 350
/// List of weather immunity traits that are then added on Initialize(), see traits.dm.
var/list/weather_immunities
///Healable by medical stacks? Defaults to yes. ///Healable by medical stacks? Defaults to yes.
var/healable = 1 var/healable = 1
@@ -165,6 +168,8 @@
AddComponent(/datum/component/personal_crafting) AddComponent(/datum/component/personal_crafting)
if(footstep_type) if(footstep_type)
AddComponent(/datum/component/footstep, footstep_type) AddComponent(/datum/component/footstep, footstep_type)
for(var/trait in weather_immunities)
ADD_TRAIT(src, trait, ROUNDSTART_TRAIT)
/mob/living/simple_animal/Destroy() /mob/living/simple_animal/Destroy()
GLOB.simple_animals[AIStatus] -= src GLOB.simple_animals[AIStatus] -= src

View File

@@ -85,7 +85,8 @@
/datum/uplink_item/suits/wallwalkers /datum/uplink_item/suits/wallwalkers
name = "Wall Walking Boots" name = "Wall Walking Boots"
desc = "Through bluespace magic stolen from an organisation that hoards technology, these boots simply allow you to slip through the atoms that make up anything, but only while walking, for safety reasons. As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through." desc = "Through bluespace magic stolen from an organisation that hoards technology, these boots simply allow you to slip through the atoms that make up anything,but only while walking, \
for safety reasons.As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through."
item = /obj/item/clothing/shoes/wallwalkers item = /obj/item/clothing/shoes/wallwalkers
cost = 6 cost = 6
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)

View File

@@ -15,6 +15,7 @@
- rscadd: Added mime messages for all SPLURT audio emotes - rscadd: Added mime messages for all SPLURT audio emotes
- tweak: All SPLURT audio emotes now use length-based cooldowns - tweak: All SPLURT audio emotes now use length-based cooldowns
- refactor: Refactored SPLURT audio emote code - refactor: Refactored SPLURT audio emote code
- bugfix: Fixed Cargo protolathe access (MAILSORTING instead of CARGO)
2023-03-05: 2023-03-05:
thux-tk: thux-tk:
- rscadd: new arousal meter to humanoid mob's interface - rscadd: new arousal meter to humanoid mob's interface

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 KiB

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 KiB

After

Width:  |  Height:  |  Size: 508 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 KiB

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 185 KiB

View File

@@ -666,43 +666,58 @@
name = "lava walking medal" name = "lava walking medal"
desc = "A golden medal. Capable of making any jumpsuit completely lava proof for a brief window of time." desc = "A golden medal. Capable of making any jumpsuit completely lava proof for a brief window of time."
icon_state = "gold" icon_state = "gold"
actions_types = list(/datum/action/item_action/lavawalk) var/datum/action/cooldown/lavawalk/lavawalk
var/cool_down = 0 var/effectduration = 10 SECONDS
var/cooldown_time = 1200 //two full minutes var/timer
var/effectduration = 100 //10 seconds of lava walking
var/storedimmunities = list()
/obj/item/clothing/accessory/lavawalk/on_uniform_equip(obj/item/clothing/under/U, user) /obj/item/clothing/accessory/lavawalk/ComponentInitialize()
. = ..() . = ..()
var/mob/living/L = U.loc lavawalk = new(src)
if(L && istype(L)) RegisterSignal(lavawalk, COMSIG_ACTION_TRIGGER, .proc/activate)
for(var/datum/action/A in actions_types)
A.Grant(L)
/obj/item/clothing/accessory/lavawalk/on_uniform_dropped(obj/item/clothing/under/U, user) /obj/item/clothing/accessory/lavawalk/Destroy()
. = ..() . = ..()
var/mob/living/L = U.loc var/mob/living/user = get_atom_on_turf(src, /mob/living)
if(L && istype(L)) if(user && timer)
for(var/datum/action/A in actions_types) reset_user(user)
A.Remove(L) UnregisterSignal(lavawalk, COMSIG_ACTION_TRIGGER)
QDEL_NULL(lavawalk)
/datum/action/item_action/lavawalk /obj/item/clothing/accessory/lavawalk/on_uniform_equip(obj/item/clothing/under/U, mob/living/user)
. = ..()
if(istype(user))
lavawalk.Grant(user)
/obj/item/clothing/accessory/lavawalk/on_uniform_dropped(obj/item/clothing/under/U, mob/living/user)
. = ..()
if(istype(user))
if(timer)
reset_user(user)
lavawalk.Remove(user)
/datum/action/cooldown/lavawalk
name = "Lava Walk" name = "Lava Walk"
desc = "Become immune to lava for a brief period of time." desc = "Become immune to lava for a brief period of time."
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
cooldown_time = 2 MINUTES //two full minutes
use_target_appearance = TRUE
/obj/item/clothing/accessory/lavawalk/ui_action_click(mob/user, actiontype) /obj/item/clothing/accessory/lavawalk/proc/activate(datum/action/cooldown/lavawalk/action, obj/item/clothing/accessory/lavawalk/item)
if(istype(actiontype, /datum/action/item_action/lavawalk)) var/mob/living/L = usr
if(world.time >= cool_down) if(istype(L))
var/mob/living/L = user to_chat(L, span_notice("\The [src] begins glowing!"))
if(istype(L)) L.balloon_alert(L, "activated")
storedimmunities = L.weather_immunities.Copy() ADD_TRAIT(L, TRAIT_ASHSTORM_IMMUNE, src)
L.weather_immunities |= list("ash", "lava") ADD_TRAIT(L, TRAIT_LAVA_IMMUNE, src)
cool_down = world.time + cooldown_time timer = addtimer(CALLBACK(src, .proc/reset_user, L), effectduration)
addtimer(CALLBACK(src, .proc/reset_user, L), effectduration) action.StartCooldown()
/obj/item/clothing/accessory/lavawalk/proc/reset_user(mob/living/user) /obj/item/clothing/accessory/lavawalk/proc/reset_user(mob/living/user)
user.weather_immunities = storedimmunities REMOVE_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, src)
storedimmunities = list() REMOVE_TRAIT(user, TRAIT_LAVA_IMMUNE, src)
to_chat(user, span_boldwarning("\The [src]'s glow dims."))
user.balloon_alert(user, "wore off")
QDEL_NULL(timer)
//Nerfing those on the chest because too OP yada yada //Nerfing those on the chest because too OP yada yada
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/damaged /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/damaged

View File

@@ -8,7 +8,7 @@
req_access = list(ACCESS_MEDICAL) req_access = list(ACCESS_MEDICAL)
/obj/machinery/rnd/production/protolathe/department/cargo /obj/machinery/rnd/production/protolathe/department/cargo
req_access = list(ACCESS_CARGO) req_one_access = list(ACCESS_CARGO, ACCESS_MINING)
/obj/machinery/rnd/production/protolathe/department/science /obj/machinery/rnd/production/protolathe/department/science
req_access = list(ACCESS_RESEARCH) req_access = list(ACCESS_RESEARCH)

View File

@@ -8,7 +8,7 @@
req_access = list(ACCESS_MEDICAL) req_access = list(ACCESS_MEDICAL)
/obj/machinery/rnd/production/techfab/department/cargo /obj/machinery/rnd/production/techfab/department/cargo
req_access = list(ACCESS_CARGO) req_one_access = list(ACCESS_CARGO, ACCESS_MINING)
/obj/machinery/rnd/production/techfab/department/science /obj/machinery/rnd/production/techfab/department/science
req_access = list(ACCESS_RESEARCH) req_access = list(ACCESS_RESEARCH)

View File

@@ -856,7 +856,6 @@
#include "code\datums\traits\negative.dm" #include "code\datums\traits\negative.dm"
#include "code\datums\traits\neutral.dm" #include "code\datums\traits\neutral.dm"
#include "code\datums\weather\weather.dm" #include "code\datums\weather\weather.dm"
#include "code\datums\weather\weather_types\acid_rain.dm"
#include "code\datums\weather\weather_types\ash_storm.dm" #include "code\datums\weather\weather_types\ash_storm.dm"
#include "code\datums\weather\weather_types\floor_is_lava.dm" #include "code\datums\weather\weather_types\floor_is_lava.dm"
#include "code\datums\weather\weather_types\ice_storm.dm" #include "code\datums\weather\weather_types\ice_storm.dm"

View File

@@ -2,23 +2,18 @@ import { map, sortBy } from 'common/collections';
import { flow } from 'common/fp'; import { flow } from 'common/fp';
import { pureComponentHooks } from 'common/react'; import { pureComponentHooks } from 'common/react';
import { useBackend, useLocalState } from '../backend'; import { useBackend, useLocalState } from '../backend';
import { Box, Button, Dimmer, Flex, Icon, Table, Tabs } from '../components'; import { Box, Button, Dimmer, Icon, Table, Tabs, Stack, Section } from '../components';
import { Window } from '../layouts'; import { Window } from '../layouts';
import { AreaCharge, powerRank } from './PowerMonitor'; import { AreaCharge, powerRank } from './PowerMonitor';
export const ApcControl = (props, context) => { export const ApcControl = (props, context) => {
const { data } = useBackend(context); const { data } = useBackend(context);
return ( return (
<Window <Window title="APC Controller" width={550} height={500}>
title="APC Controller" <Window.Content>
width={550} {data.authenticated === 1 && <ApcLoggedIn />}
height={500}> {data.authenticated === 0 && <ApcLoggedOut />}
{data.authenticated === 1 && ( </Window.Content>
<ApcLoggedIn />
)}
{data.authenticated === 0 && (
<ApcLoggedOut />
)}
</Window> </Window>
); );
}; };
@@ -28,25 +23,24 @@ const ApcLoggedOut = (props, context) => {
const { emagged } = data; const { emagged } = data;
const text = emagged === 1 ? 'Open' : 'Log In'; const text = emagged === 1 ? 'Open' : 'Log In';
return ( return (
<Window.Content> <Section>
<Button <Button
fluid icon="sign-in-alt"
color={emagged === 1 ? '' : 'good'} color={emagged === 1 ? '' : 'good'}
content={text} content={text}
onClick={() => act('log-in')} /> fluid
</Window.Content> onClick={() => act('log-in')}
/>
</Section>
); );
}; };
const ApcLoggedIn = (props, context) => { const ApcLoggedIn = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend(context);
const { restoring } = data; const { restoring } = data;
const [ const [tabIndex, setTabIndex] = useLocalState(context, 'tab-index', 1);
tabIndex,
setTabIndex,
] = useLocalState(context, 'tab-index', 1);
return ( return (
<> <Box>
<Tabs> <Tabs>
<Tabs.Tab <Tabs.Tab
selected={tabIndex === 1} selected={tabIndex === 1}
@@ -72,59 +66,62 @@ const ApcLoggedIn = (props, context) => {
</Dimmer> </Dimmer>
)} )}
{tabIndex === 1 && ( {tabIndex === 1 && (
<> <Stack vertical>
<ControlPanel /> <Stack.Item>
<Box fillPositionedParent top="53px"> <Section>
<Window.Content overflow="auto"> <ControlPanel />
</Section>
</Stack.Item>
<Stack.Item>
<Section scrollable>
<ApcControlScene /> <ApcControlScene />
</Window.Content> </Section>
</Box> </Stack.Item>
</> </Stack>
)} )}
{tabIndex === 2 && ( {tabIndex === 2 && (
<Box fillPositionedParent top="20px"> <Section scrollable>
<Window.Content overflow="auto"> <Box height={34}>
<LogPanel /> <LogPanel />
</Window.Content> </Box>
</Box> </Section>
)} )}
</> </Box>
); );
}; };
const ControlPanel = (props, context) => { const ControlPanel = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend(context);
const { const { emagged, logging } = data;
emagged, const [sortByField, setSortByField] = useLocalState(
logging, context,
} = data; 'sortByField',
const [ 'name'
sortByField, );
setSortByField,
] = useLocalState(context, 'sortByField', null);
return ( return (
<Flex> <Stack justify="space-between">
<Flex.Item> <Stack.Item>
<Box inline mr={2} color="label"> <Box inline mr={2} color="label">
Sort by: Sort by:
</Box> </Box>
<Button.Checkbox <Button.Checkbox
checked={sortByField === 'name'} checked={sortByField === 'name'}
content="Name" content="Name"
onClick={() => setSortByField(sortByField !== 'name' && 'name')} /> onClick={() => setSortByField(sortByField !== 'name' && 'name')}
/>
<Button.Checkbox <Button.Checkbox
checked={sortByField === 'charge'} checked={sortByField === 'charge'}
content="Charge" content="Charge"
onClick={() => setSortByField( onClick={() => setSortByField(sortByField !== 'charge' && 'charge')}
sortByField !== 'charge' && 'charge' />
)} />
<Button.Checkbox <Button.Checkbox
checked={sortByField === 'draw'} checked={sortByField === 'draw'}
content="Draw" content="Draw"
onClick={() => setSortByField(sortByField !== 'draw' && 'draw')} /> onClick={() => setSortByField(sortByField !== 'draw' && 'draw')}
</Flex.Item> />
<Flex.Item grow={1} /> </Stack.Item>
<Flex.Item> <Stack.Item grow={1} />
<Stack.Item>
{emagged === 1 && ( {emagged === 1 && (
<> <>
<Button <Button
@@ -139,21 +136,20 @@ const ControlPanel = (props, context) => {
</> </>
)} )}
<Button <Button
icon="sign-out-alt"
color="bad" color="bad"
content="Log Out" content="Log Out"
onClick={() => act('log-out')} onClick={() => act('log-out')}
/> />
</Flex.Item> </Stack.Item>
</Flex> </Stack>
); );
}; };
const ApcControlScene = (props, context) => { const ApcControlScene = (props, context) => {
const { data, act } = useBackend(context); const { data, act } = useBackend(context);
const [ const [sortByField] = useLocalState(context, 'sortByField', 'name');
sortByField,
] = useLocalState(context, 'sortByField', null);
const apcs = flow([ const apcs = flow([
map((apc, i) => ({ map((apc, i) => ({
@@ -161,94 +157,87 @@ const ApcControlScene = (props, context) => {
// Generate a unique id // Generate a unique id
id: apc.name + i, id: apc.name + i,
})), })),
sortByField === 'name' && sortBy(apc => apc.name), sortByField === 'name' && sortBy((apc) => apc.name),
sortByField === 'charge' && sortBy(apc => -apc.charge), sortByField === 'charge' && sortBy((apc) => -apc.charge),
sortByField === 'draw' && sortBy( sortByField === 'draw'
apc => -powerRank(apc.load), && sortBy(
apc => -parseFloat(apc.load)), (apc) => -powerRank(apc.load),
(apc) => -parseFloat(apc.load)
),
])(data.apcs); ])(data.apcs);
return ( return (
<Table> <Box height={30}>
<Table.Row header> <Table>
<Table.Cell> <Table.Row header>
On/Off <Table.Cell>On/Off</Table.Cell>
</Table.Cell> <Table.Cell>Area</Table.Cell>
<Table.Cell> <Table.Cell collapsing>Charge</Table.Cell>
Area <Table.Cell collapsing textAlign="right">
</Table.Cell> Draw
<Table.Cell collapsing> </Table.Cell>
Charge <Table.Cell collapsing title="Equipment">
</Table.Cell> Eqp
<Table.Cell collapsing textAlign="right"> </Table.Cell>
Draw <Table.Cell collapsing title="Lighting">
</Table.Cell> Lgt
<Table.Cell collapsing title="Equipment"> </Table.Cell>
Eqp <Table.Cell collapsing title="Environment">
</Table.Cell> Env
<Table.Cell collapsing title="Lighting"> </Table.Cell>
Lgt </Table.Row>
</Table.Cell> {apcs.map((apc, i) => (
<Table.Cell collapsing title="Environment"> <tr key={apc.id} className="Table__row candystripe">
Env <td>
</Table.Cell> <Button
</Table.Row> icon={apc.operating ? 'power-off' : 'times'}
{apcs.map((apc, i) => ( color={apc.operating ? 'good' : 'bad'}
<tr onClick={() =>
key={apc.id} act('breaker', {
className="Table__row candystripe"> ref: apc.ref,
<td> })}
<Button />
icon={apc.operating ? 'power-off' : 'times'} </td>
color={apc.operating ? 'good' : 'bad'} <td>
onClick={() => act('breaker', { <Button
ref: apc.ref, onClick={() =>
})} act('access-apc', {
/> ref: apc.ref,
</td> })}>
<td> {apc.name}
<Button </Button>
onClick={() => act('access-apc', { </td>
ref: apc.ref, <td className="Table__cell text-right text-nowrap">
})}> <AreaCharge charging={apc.charging} charge={apc.charge} />
{apc.name} </td>
</Button> <td className="Table__cell text-right text-nowrap">{apc.load}</td>
</td> <td className="Table__cell text-center text-nowrap">
<td className="Table__cell text-right text-nowrap"> <AreaStatusColorButton
<AreaCharge target="equipment"
charging={apc.charging} status={apc.eqp}
charge={apc.charge} apc={apc}
/> act={act}
</td> />
<td className="Table__cell text-right text-nowrap"> </td>
{apc.load} <td className="Table__cell text-center text-nowrap">
</td> <AreaStatusColorButton
<td className="Table__cell text-center text-nowrap"> target="lighting"
<AreaStatusColorButton status={apc.lgt}
target="equipment" apc={apc}
status={apc.eqp} act={act}
apc={apc} />
act={act} </td>
/> <td className="Table__cell text-center text-nowrap">
</td> <AreaStatusColorButton
<td className="Table__cell text-center text-nowrap"> target="environ"
<AreaStatusColorButton status={apc.env}
target="lighting" apc={apc}
status={apc.lgt} act={act}
apc={apc} />
act={act} </td>
/> </tr>
</td> ))}
<td className="Table__cell text-center text-nowrap"> </Table>
<AreaStatusColorButton </Box>
target="environ"
status={apc.env}
apc={apc}
act={act}
/>
</td>
</tr>
))}
</Table>
); );
}; };
@@ -261,16 +250,12 @@ const LogPanel = (props, context) => {
// Generate a unique id // Generate a unique id
id: line.entry + i, id: line.entry + i,
})), })),
logs => logs.reverse(), (logs) => logs.reverse(),
])(data.logs); ])(data.logs);
return ( return (
<Box m={-0.5}> <Box m={-0.5}>
{logs.map(line => ( {logs.map((line) => (
<Box <Box p={0.5} key={line.id} className="candystripe" bold>
p={0.5}
key={line.id}
className="candystripe"
bold>
{line.entry} {line.entry}
</Box> </Box>
))} ))}
@@ -278,7 +263,7 @@ const LogPanel = (props, context) => {
); );
}; };
const AreaStatusColorButton = props => { const AreaStatusColorButton = (props) => {
const { target, status, apc, act } = props; const { target, status, apc, act } = props;
const power = Boolean(status & 2); const power = Boolean(status & 2);
const mode = Boolean(status & 1); const mode = Boolean(status & 1);
@@ -286,20 +271,20 @@ const AreaStatusColorButton = props => {
<Button <Button
icon={mode ? 'sync' : 'power-off'} icon={mode ? 'sync' : 'power-off'}
color={power ? 'good' : 'bad'} color={power ? 'good' : 'bad'}
onClick={() => act('toggle-minor', { onClick={() =>
type: target, act('toggle-minor', {
value: statusChange(status), type: target,
ref: apc.ref, value: statusChange(status),
})} ref: apc.ref,
})}
/> />
); );
}; };
const statusChange = status => { const statusChange = (status) => {
// mode flip power flip both flip // mode flip power flip both flip
// 0, 2, 3 // 0, 2, 3
return status === 0 ? 2 : status === 2 ? 3 : 0; return status === 0 ? 2 : status === 2 ? 3 : 0;
}; };
AreaStatusColorButton.defaultHooks = pureComponentHooks; AreaStatusColorButton.defaultHooks = pureComponentHooks;

View File

@@ -1,58 +0,0 @@
import { useBackend } from '../backend';
import { Box, Button, LabeledList, Section } from '../components';
import { Window } from '../layouts';
export const CellularEmporium = (props, context) => {
const { act, data } = useBackend(context);
const { abilities } = data;
return (
<Window
width={900}
height={480}>
<Window.Content overflow="auto">
<Section>
<LabeledList>
<LabeledList.Item
label="Genetic Points"
buttons={(
<Button
icon="undo"
content="Readapt"
disabled={!data.can_readapt}
onClick={() => act('readapt')} />
)}>
{data.genetic_points_remaining}
</LabeledList.Item>
</LabeledList>
</Section>
<Section>
<LabeledList>
{abilities.map(ability => (
<LabeledList.Item
key={ability.name}
className="candystripe"
label={ability.name}
buttons={(
<>
{ability.dna_cost}
{' '}
<Button
content={ability.owned ? 'Evolved' : 'Evolve'}
selected={ability.owned}
onClick={() => act('evolve', {
name: ability.name,
})} />
</>
)}>
{ability.desc}
<Box color="good">
{ability.helptext}
</Box>
</LabeledList.Item>
))}
</LabeledList>
</Section>
</Window.Content>
</Window>
);
};

View File

@@ -0,0 +1,97 @@
import { useBackend } from '../backend';
import { Button, Section, Icon, Stack, LabeledList, Box, NoticeBox } from '../components';
import { Window } from '../layouts';
type CellularEmporiumContext = {
abilities: Ability[];
can_readapt: boolean;
genetic_points_remaining: number;
};
type Ability = {
name: string;
desc: string;
path: string;
dna_cost: number;
helptext: string;
owned: boolean;
can_purchase: boolean;
};
export const CellularEmporium = (props, context) => {
const { act, data } = useBackend<CellularEmporiumContext>(context);
const { can_readapt, genetic_points_remaining } = data;
return (
<Window width={900} height={480}>
<Window.Content>
<Section
fill
scrollable
title={'Genetic Points'}
buttons={
<Stack>
<Stack.Item fontSize="16px">
{genetic_points_remaining && genetic_points_remaining}{' '}
<Icon name="dna" color="#DD66DD" />
</Stack.Item>
<Stack.Item>
<Button
icon="undo"
content="Readapt"
disabled={!can_readapt}
onClick={() => act('readapt')}
/>
</Stack.Item>
</Stack>
}>
<AbilityList />
</Section>
</Window.Content>
</Window>
);
};
const AbilityList = (props, context) => {
const { act, data } = useBackend<CellularEmporiumContext>(context);
const { abilities, genetic_points_remaining } = data;
if (!abilities) {
return <NoticeBox>None</NoticeBox>;
} else {
return (
<LabeledList>
{abilities.map((ability) => (
<LabeledList.Item
key={ability.name}
className="candystripe"
label={ability.name}
buttons={
<Stack>
<Stack.Item>{ability.dna_cost}</Stack.Item>
<Stack.Item>
<Icon name="dna" color={ability.owned ? '#DD66DD' : 'gray'} />
</Stack.Item>
<Stack.Item>
<Button
content={'Evolve'}
disabled={
ability.owned
|| ability.dna_cost > genetic_points_remaining
|| !ability.can_purchase
}
onClick={() =>
act('evolve', {
path: ability.path,
})}
/>
</Stack.Item>
</Stack>
}>
{ability.desc}
<Box color="good">{ability.helptext}</Box>
</LabeledList.Item>
))}
</LabeledList>
);
}
};