Merge remote-tracking branch 'upstream/master'
@@ -41,7 +41,6 @@ require only minor tweaks.
|
||||
//boolean - weather types that occur on the level
|
||||
#define ZTRAIT_SNOWSTORM "Weather_Snowstorm"
|
||||
#define ZTRAIT_ASHSTORM "Weather_Ashstorm"
|
||||
#define ZTRAIT_ACIDRAIN "Weather_Acidrain"
|
||||
#define ZTRAIT_VOIDSTORM "Weather_Voidstorm"
|
||||
#define ZTRAIT_ICESTORM "Weather_Icestorm"
|
||||
#define ZTRAIT_LONGRAIN "Weather_Longrain"
|
||||
|
||||
@@ -263,6 +263,14 @@
|
||||
/// Prevents sprinting from being active.
|
||||
#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
|
||||
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
|
||||
#define VEHICLE_TRAIT "vehicle" // inherited from riding vehicles
|
||||
@@ -298,8 +306,8 @@
|
||||
#define GHOSTROLE_TRAIT "ghostrole"
|
||||
#define APHRO_TRAIT "aphro"
|
||||
#define BLOODSUCKER_TRAIT "bloodsucker"
|
||||
#define SHOES_TRAIT "shoes" //inherited from your sweet kicks
|
||||
#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 TURF_TRAIT "turf"
|
||||
#define STATION_TRAIT "station-trait"
|
||||
|
||||
@@ -126,10 +126,15 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_EMPATH" = TRAIT_EMPATH,
|
||||
"TRAIT_FRIENDLY" = TRAIT_FRIENDLY,
|
||||
"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_PRIMITIVE" = TRAIT_PRIMITIVE, //unable to use mechs. Given to Ash Walkers
|
||||
"TRAIT_SALT_SENSITIVE" = TRAIT_SALT_SENSITIVE
|
||||
),
|
||||
),
|
||||
/obj/item/bodypart = list(
|
||||
"TRAIT_PARALYSIS" = TRAIT_PARALYSIS
|
||||
),
|
||||
|
||||
@@ -723,6 +723,9 @@
|
||||
button.maptext_height = 12
|
||||
|
||||
/datum/action/cooldown/IsAvailable(silent = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
return next_use_time <= world.time
|
||||
|
||||
/datum/action/cooldown/proc/StartCooldown()
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
var/overlay_plane = BLACKNESS_PLANE
|
||||
/// If the weather has no purpose but aesthetics.
|
||||
var/aesthetic = FALSE
|
||||
/// Used by mobs to prevent them from being affected by the weather
|
||||
var/immunity_type = "storm"
|
||||
/// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather.
|
||||
var/immunity_type
|
||||
|
||||
/// The stage of the weather, from 1-4
|
||||
var/stage = END_STAGE
|
||||
@@ -133,15 +133,18 @@
|
||||
/datum/weather/proc/start()
|
||||
if(stage >= MAIN_STAGE)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type))
|
||||
stage = MAIN_STAGE
|
||||
update_areas()
|
||||
for(var/M in GLOB.player_list)
|
||||
var/turf/mob_turf = get_turf(M)
|
||||
if(mob_turf && (mob_turf.z in impacted_z_levels))
|
||||
for(var/z_level in impacted_z_levels)
|
||||
for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level])
|
||||
var/turf/mob_turf = get_turf(player)
|
||||
if(!mob_turf)
|
||||
continue
|
||||
if(weather_message)
|
||||
to_chat(M, weather_message)
|
||||
to_chat(player, weather_message)
|
||||
if(weather_sound)
|
||||
SEND_SOUND(M, sound(weather_sound))
|
||||
SEND_SOUND(player, sound(weather_sound))
|
||||
if(!perpetual)
|
||||
addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
|
||||
|
||||
@@ -192,14 +195,27 @@
|
||||
* Returns TRUE if the living mob can be affected by the weather
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/can_weather_act(mob/living/L)
|
||||
var/turf/mob_turf = get_turf(L)
|
||||
if(mob_turf && !(mob_turf.z in impacted_z_levels))
|
||||
/datum/weather/proc/can_weather_act(mob/living/mob_to_check)
|
||||
var/turf/mob_turf = get_turf(mob_to_check)
|
||||
|
||||
if(!mob_turf)
|
||||
return
|
||||
if(immunity_type in L.weather_immunities)
|
||||
|
||||
if(!(mob_turf.z in impacted_z_levels))
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
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
|
||||
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."
|
||||
@@ -22,7 +21,7 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds)
|
||||
protect_indoors = TRUE
|
||||
target_trait = ZTRAIT_ASHSTORM
|
||||
|
||||
immunity_type = "ash"
|
||||
immunity_type = TRAIT_ASHSTORM_IMMUNE
|
||||
|
||||
probability = 90
|
||||
|
||||
@@ -72,10 +71,6 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds)
|
||||
var/thermal_protection = H.easy_thermal_protection()
|
||||
if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT)
|
||||
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))
|
||||
// var/obj/structure/closet/the_locker = L
|
||||
// if(the_locker.weather_protection)
|
||||
@@ -93,7 +88,6 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds)
|
||||
return
|
||||
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.
|
||||
/datum/weather/ash_storm/emberfall
|
||||
name = "emberfall"
|
||||
|
||||
@@ -19,19 +19,23 @@
|
||||
target_trait = ZTRAIT_STATION
|
||||
|
||||
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)
|
||||
if(issilicon(L))
|
||||
return
|
||||
if(istype(L.buckled, /obj/structure/bed))
|
||||
return
|
||||
for(var/obj/structure/O in L.loc)
|
||||
if(O.density)
|
||||
return
|
||||
if(L.loc.density)
|
||||
return
|
||||
if(!L.client) //Only sentient people are going along with it!
|
||||
return
|
||||
L.adjustFireLoss(3)
|
||||
/datum/weather/floor_is_lava/can_weather_act(mob/living/mob_to_check)
|
||||
if(!mob_to_check.client) //Only sentient people are going along with it!
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(!. || issilicon(mob_to_check) || istype(mob_to_check.buckled, /obj/structure/bed))
|
||||
return FALSE
|
||||
var/turf/mob_turf = get_turf(mob_to_check)
|
||||
if(mob_turf.density) //Walls are not floors.
|
||||
return FALSE
|
||||
for(var/obj/structure/structure_to_check in mob_turf)
|
||||
if(structure_to_check.density)
|
||||
return FALSE
|
||||
if(mob_to_check.movement_type & FLYING)
|
||||
return FALSE
|
||||
|
||||
/datum/weather/floor_is_lava/weather_act(mob/living/victim)
|
||||
victim.adjustFireLoss(3)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
protected_areas = list(/area/edina/protected)
|
||||
target_trait = ZTRAIT_ICESTORM
|
||||
|
||||
immunity_type = "rad"
|
||||
immunity_type = TRAIT_SNOWSTORM_IMMUNE
|
||||
|
||||
/datum/weather/ice_storm/weather_act(mob/living/L)
|
||||
//L.adjust_bodytemperature(-rand(10,20))
|
||||
|
||||
@@ -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)
|
||||
target_trait = ZTRAIT_STATION
|
||||
|
||||
immunity_type = "rad"
|
||||
immunity_type = TRAIT_RADSTORM_IMMUNE
|
||||
|
||||
var/radiation_intensity = 100
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
protect_indoors = TRUE
|
||||
target_trait = ZTRAIT_SNOWSTORM
|
||||
|
||||
immunity_type = "snow"
|
||||
immunity_type = TRAIT_SNOWSTORM_IMMUNE
|
||||
|
||||
barometer_predictable = TRUE
|
||||
|
||||
|
||||
@@ -17,15 +17,18 @@
|
||||
protect_indoors = FALSE
|
||||
target_trait = ZTRAIT_VOIDSTORM
|
||||
|
||||
immunity_type = "void"
|
||||
immunity_type = TRAIT_VOIDSTORM_IMMUNE
|
||||
|
||||
barometer_predictable = FALSE
|
||||
perpetual = TRUE
|
||||
|
||||
/datum/weather/void_storm/weather_act(mob/living/L)
|
||||
if(IS_HERETIC(L) || IS_HERETIC_MONSTER(L))
|
||||
return
|
||||
L.adjustOxyLoss(rand(1,3))
|
||||
L.adjustFireLoss(rand(1,3))
|
||||
L.adjust_blurriness(rand(0,1))
|
||||
L.adjust_bodytemperature(-rand(5,15))
|
||||
/datum/weather/void_storm/can_weather_act(mob/living/mob_to_check)
|
||||
. = ..()
|
||||
if(IS_HERETIC(mob_to_check) || IS_HERETIC_MONSTER(mob_to_check))
|
||||
return FALSE
|
||||
|
||||
/datum/weather/void_storm/weather_act(mob/living/victim)
|
||||
victim.adjustOxyLoss(rand(1,3))
|
||||
victim.adjustFireLoss(rand(1,3))
|
||||
victim.adjust_blurriness(rand(0,1))
|
||||
victim.adjust_bodytemperature(-rand(5,15))
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
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)
|
||||
. = ..()
|
||||
if (.)
|
||||
R.weather_immunities -= "lava"
|
||||
REMOVE_TRAIT(src, TRAIT_LAVA_IMMUNE, type)
|
||||
|
||||
/obj/item/borg/upgrade/selfrepair
|
||||
name = "self-repair module"
|
||||
|
||||
@@ -17,6 +17,16 @@
|
||||
barefootstep = FOOTSTEP_LAVA
|
||||
clawfootstep = 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)
|
||||
contents_explosion(severity, target, origin)
|
||||
@@ -107,62 +117,98 @@
|
||||
LAZYREMOVE(found_safeties, S)
|
||||
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)
|
||||
. = 0
|
||||
///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.
|
||||
/turf/open/lava/proc/burn_stuff(atom/movable/to_burn, delta_time = 1)
|
||||
|
||||
if(is_safe())
|
||||
return FALSE
|
||||
|
||||
var/thing_to_check = src
|
||||
if (AM)
|
||||
thing_to_check = list(AM)
|
||||
for(var/thing in thing_to_check)
|
||||
if(isobj(thing))
|
||||
var/obj/O = thing
|
||||
if((O.resistance_flags & (LAVA_PROOF|INDESTRUCTIBLE)) || O.throwing)
|
||||
if (to_burn)
|
||||
thing_to_check = list(to_burn)
|
||||
for(var/atom/movable/burn_target as anything in thing_to_check)
|
||||
switch(can_burn_stuff(burn_target))
|
||||
if(LAVA_BE_IGNORING)
|
||||
continue
|
||||
. = 1
|
||||
if((O.resistance_flags & (ON_FIRE)))
|
||||
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)
|
||||
if(LAVA_BE_BURNING)
|
||||
if(!do_burn(burn_target, delta_time))
|
||||
continue
|
||||
else if(isliving(buckle_check))
|
||||
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)
|
||||
. = TRUE
|
||||
|
||||
if(S && H && S.clothing_flags & LAVAPROTECT && H.clothing_flags & LAVAPROTECT)
|
||||
return
|
||||
/turf/open/lava/proc/can_burn_stuff(atom/movable/burn_target)
|
||||
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(L) //mobs turning into object corpses could get deleted here.
|
||||
L.adjust_fire_stacks(20)
|
||||
L.IgniteMob()
|
||||
if(isobj(burn_target))
|
||||
if(burn_target.throwing) // to avoid gulag prisoners easily escaping, throwing only works for objects.
|
||||
return LAVA_BE_IGNORING
|
||||
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
|
||||
name = "lava"
|
||||
|
||||
@@ -164,11 +164,12 @@
|
||||
icon_state = "liquidplasma"
|
||||
initial_gas_mix = "n2=82;plasma=24;TEMP=120"
|
||||
baseturfs = /turf/open/lava/plasma
|
||||
slowdown = 2
|
||||
|
||||
light_range = 3
|
||||
light_power = 0.75
|
||||
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)
|
||||
var/obj/item/reagent_containers/glass/C = I
|
||||
@@ -178,78 +179,45 @@
|
||||
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>")
|
||||
|
||||
/turf/open/lava/plasma/burn_stuff(AM)
|
||||
. = 0
|
||||
/turf/open/lava/plasma/do_burn(atom/movable/burn_target, delta_time = 1)
|
||||
. = TRUE
|
||||
if(isobj(burn_target))
|
||||
return FALSE // Does nothing against objects. Old code.
|
||||
|
||||
if(is_safe())
|
||||
return FALSE
|
||||
var/mob/living/burn_living = burn_target
|
||||
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
|
||||
if (AM)
|
||||
thing_to_check = list(AM)
|
||||
for(var/thing in thing_to_check)
|
||||
if(isobj(thing))
|
||||
var/obj/O = thing
|
||||
if((O.resistance_flags & (FREEZE_PROOF)) || O.throwing)
|
||||
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>")
|
||||
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
|
||||
for(var/obj/item/bodypart/burn_limb as anything in burn_human.bodyparts)
|
||||
if(burn_limb.status == BODYPART_ORGANIC && burn_limb.species_id != SPECIES_PLASMAMAN) //getting every organic, non-plasmaman limb (augments/androids are immune to this)
|
||||
plasma_parts += burn_limb
|
||||
if(burn_limb.status == BODYPART_ROBOTIC)
|
||||
robo_parts += burn_limb
|
||||
|
||||
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
|
||||
name = "plasma boat"
|
||||
|
||||
@@ -156,38 +156,48 @@
|
||||
M.appearance_flags = RESET_COLOR
|
||||
. += M
|
||||
|
||||
/****************HEVA Suit and Mask****************/
|
||||
|
||||
// CITADEL ADDITIONS BELOW
|
||||
|
||||
/****************SEVA Suit and Mask****************/
|
||||
|
||||
/obj/item/clothing/suit/hooded/explorer/seva
|
||||
name = "SEVA Suit"
|
||||
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"
|
||||
/obj/item/clothing/suit/hooded/explorer/heva
|
||||
name = "HEVA suit"
|
||||
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."
|
||||
icon_state = "heva"
|
||||
item_state = "heva"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
hoodtype = /obj/item/clothing/head/hooded/explorer/seva
|
||||
armor = list(MELEE = 15, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 35, BIO = 50, RAD = 25, FIRE = 100, ACID = 25)
|
||||
hoodtype = /obj/item/clothing/head/hooded/explorer/heva
|
||||
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
|
||||
|
||||
/obj/item/clothing/head/hooded/explorer/seva
|
||||
name = "SEVA 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."
|
||||
icon_state = "seva"
|
||||
item_state = "seva"
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 35, BIO = 50, RAD = 25, FIRE = 100, ACID = 25)
|
||||
/obj/item/clothing/head/hooded/explorer/heva
|
||||
name = "HEVA hood"
|
||||
desc = "The Hazardous Environments extra-Vehiclar Activity hood, 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 mask is required for full protection."
|
||||
icon_state = "heva"
|
||||
item_state = "heva"
|
||||
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
|
||||
|
||||
/obj/item/clothing/mask/gas/seva
|
||||
name = "SEVA Mask"
|
||||
desc = "A face-covering plate that can be connected to an air supply. Intended for use with the SEVA Suit."
|
||||
icon_state = "seva"
|
||||
item_state = "seva"
|
||||
resistance_flags = FIRE_PROOF
|
||||
/obj/item/clothing/head/hooded/explorer/heva/equipped(mob/living/carbon/human/user, slot)
|
||||
..()
|
||||
if (slot == ITEM_SLOT_HEAD)
|
||||
ADD_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit")
|
||||
|
||||
/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****************/
|
||||
|
||||
|
||||
@@ -1043,7 +1043,7 @@
|
||||
user.mind.AddSpell(D)
|
||||
if(4)
|
||||
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)
|
||||
qdel(src)
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
|
||||
/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"),
|
||||
"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)
|
||||
if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer)
|
||||
@@ -246,9 +246,9 @@
|
||||
if("Exo-suit")
|
||||
new /obj/item/clothing/suit/hooded/explorer/exo(drop_location)
|
||||
new /obj/item/clothing/mask/gas/exo(drop_location)
|
||||
if("SEVA suit")
|
||||
new /obj/item/clothing/suit/hooded/explorer/seva(drop_location)
|
||||
new /obj/item/clothing/mask/gas/seva(drop_location)
|
||||
if("HEVA suit")
|
||||
new /obj/item/clothing/suit/hooded/explorer/heva(drop_location)
|
||||
new /obj/item/clothing/mask/gas/heva(drop_location)
|
||||
playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3)
|
||||
SSblackbox.record_feedback("tally", "suit_voucher_redeemed", 1, selection)
|
||||
qdel(voucher)
|
||||
|
||||
@@ -48,13 +48,11 @@
|
||||
|
||||
else //Maybe uses plasma in the future, although that wouldn't make any sense...
|
||||
leaping = 1
|
||||
weather_immunities += "lava"
|
||||
update_icons()
|
||||
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()
|
||||
leaping = 0
|
||||
weather_immunities -= "lava"
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
|
||||
@@ -214,11 +214,11 @@
|
||||
|
||||
/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)
|
||||
. = ..()
|
||||
C.weather_immunities -= "ash"
|
||||
REMOVE_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT)
|
||||
|
||||
//Immune to ash storms and lava
|
||||
/datum/species/golem/plastitanium
|
||||
@@ -233,13 +233,13 @@
|
||||
|
||||
/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
C.weather_immunities |= "lava"
|
||||
C.weather_immunities |= "ash"
|
||||
ADD_TRAIT(C, TRAIT_LAVA_IMMUNE, SPECIES_TRAIT)
|
||||
ADD_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT)
|
||||
|
||||
/datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
C.weather_immunities -= "ash"
|
||||
C.weather_immunities -= "lava"
|
||||
REMOVE_TRAIT(C, TRAIT_LAVA_IMMUNE, SPECIES_TRAIT)
|
||||
REMOVE_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT)
|
||||
|
||||
//Fast and regenerates... but can only speak like an abductor
|
||||
/datum/species/golem/alloy
|
||||
|
||||
@@ -107,8 +107,6 @@
|
||||
|
||||
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/blood_volume = 0 //how much blood the mob has
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
mob_size = MOB_SIZE_TINY
|
||||
desc = "A generic pAI mobile hard-light holographics emitter. It seems to be deactivated."
|
||||
weather_immunities = list("ash")
|
||||
health = 500
|
||||
maxHealth = 500
|
||||
layer = BELOW_MOB_LAYER
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
initial_language_holder = /datum/language_holder/synthetic
|
||||
see_in_dark = 8
|
||||
bubble_icon = "machine"
|
||||
weather_immunities = list("ash")
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
|
||||
mob_biotypes = MOB_ROBOTIC
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
@@ -60,6 +59,7 @@
|
||||
diag_hud.add_to_hud(src)
|
||||
diag_hud_set_status()
|
||||
diag_hud_set_health()
|
||||
ADD_TRAIT(src, TRAIT_ASHSTORM_IMMUNE, ROUNDSTART_TRAIT)
|
||||
|
||||
/mob/living/silicon/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
icon_living = "snowbear"
|
||||
icon_dead = "snowbear_dead"
|
||||
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
|
||||
name = "combat bear"
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
faction = list(ROLE_WIZARD)
|
||||
footstep_type = FOOTSTEP_MOB_SHOE
|
||||
weather_immunities = list("lava","ash")
|
||||
weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
|
||||
minbodytemp = 0
|
||||
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)
|
||||
|
||||
@@ -16,7 +16,7 @@ Difficulty: Extremely Hard
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
light_color = "#E4C7C5"
|
||||
movement_type = GROUND
|
||||
weather_immunities = list("snow")
|
||||
weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
|
||||
speak_emote = list("roars")
|
||||
armour_penetration = 100
|
||||
melee_damage_lower = 10
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
obj_damage = 400
|
||||
light_range = 3
|
||||
faction = list("mining", "boss")
|
||||
weather_immunities = list("lava","ash")
|
||||
weather_immunities = list(TRAIT_LAVA_IMMUNE,TRAIT_ASHSTORM_IMMUNE)
|
||||
movement_type = FLYING
|
||||
robust_searching = 1
|
||||
ranged_ignores_vision = TRUE
|
||||
|
||||
@@ -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
|
||||
score_achievement_type = /datum/award/score/swarmer_beacon_score
|
||||
faction = list("mining", "boss", "swarmer")
|
||||
weather_immunities = list("lava","ash")
|
||||
weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
|
||||
stop_automated_movement = TRUE
|
||||
wander = FALSE
|
||||
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
|
||||
wander = 1
|
||||
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
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/ai/Initialize(mapload)
|
||||
|
||||
@@ -14,7 +14,7 @@ Difficulty: Hard
|
||||
attack_verb_continuous = "claws"
|
||||
attack_verb_simple = "claw"
|
||||
attack_sound = 'sound/magic/demon_attack1.ogg'
|
||||
weather_immunities = list("snow")
|
||||
weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
|
||||
speak_emote = list("roars")
|
||||
armour_penetration = 40
|
||||
melee_damage_lower = 40
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
speak_emote = list("warbles", "quavers")
|
||||
emote_hear = list("trills.")
|
||||
emote_see = list("sniffs.", "burps.")
|
||||
weather_immunities = list("lava","ash")
|
||||
weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
|
||||
faction = list("mining", "ashwalker")
|
||||
density = FALSE
|
||||
speak_chance = 1
|
||||
|
||||
@@ -272,7 +272,7 @@
|
||||
aggro_vision_range = 9
|
||||
speed = 3
|
||||
faction = list("mining")
|
||||
weather_immunities = list("lava","ash")
|
||||
weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
|
||||
obj_damage = 30
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
|
||||
see_in_dark = 8
|
||||
@@ -321,7 +321,7 @@
|
||||
gloves = /obj/item/clothing/gloves/color/black
|
||||
mask = /obj/item/clothing/mask/gas/explorer
|
||||
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))
|
||||
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))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
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)
|
||||
faction = list("mining")
|
||||
weather_immunities = list("lava","ash")
|
||||
weather_immunities = list(TRAIT_LAVA_IMMUNE,TRAIT_ASHSTORM_IMMUNE)
|
||||
obj_damage = 30
|
||||
environment_smash = ENVIRONMENT_SMASH_WALLS
|
||||
minbodytemp = 0
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
icon_dead = "eskimo_dead"
|
||||
maxHealth = 55
|
||||
health = 55
|
||||
weather_immunities = list("snow")
|
||||
weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
melee_damage_lower = 17
|
||||
melee_damage_upper = 20
|
||||
@@ -65,7 +65,7 @@
|
||||
icon_dead = "templar_dead"
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
weather_immunities = list("snow")
|
||||
weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
|
||||
speed = 2
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
speak_chance = 1
|
||||
@@ -86,7 +86,7 @@
|
||||
speed = 5
|
||||
maxHealth = 75
|
||||
health = 75
|
||||
weather_immunities = list("snow")
|
||||
weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
|
||||
color = rgb(114,228,250)
|
||||
loot = list(/obj/effect/decal/remains/human{color = rgb(114,228,250)})
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
var/minbodytemp = 250
|
||||
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.
|
||||
var/healable = 1
|
||||
|
||||
@@ -165,6 +168,8 @@
|
||||
AddComponent(/datum/component/personal_crafting)
|
||||
if(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()
|
||||
GLOB.simple_animals[AIStatus] -= src
|
||||
|
||||
@@ -85,7 +85,8 @@
|
||||
|
||||
/datum/uplink_item/suits/wallwalkers
|
||||
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
|
||||
cost = 6
|
||||
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
- rscadd: Added mime messages for all SPLURT audio emotes
|
||||
- tweak: All SPLURT audio emotes now use length-based cooldowns
|
||||
- refactor: Refactored SPLURT audio emote code
|
||||
- bugfix: Fixed Cargo protolathe access (MAILSORTING instead of CARGO)
|
||||
2023-03-05:
|
||||
thux-tk:
|
||||
- rscadd: new arousal meter to humanoid mob's interface
|
||||
|
||||
|
Before Width: | Height: | Size: 237 KiB After Width: | Height: | Size: 239 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 513 KiB After Width: | Height: | Size: 508 KiB |
|
Before Width: | Height: | Size: 297 KiB After Width: | Height: | Size: 296 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 185 KiB |
@@ -666,43 +666,58 @@
|
||||
name = "lava walking medal"
|
||||
desc = "A golden medal. Capable of making any jumpsuit completely lava proof for a brief window of time."
|
||||
icon_state = "gold"
|
||||
actions_types = list(/datum/action/item_action/lavawalk)
|
||||
var/cool_down = 0
|
||||
var/cooldown_time = 1200 //two full minutes
|
||||
var/effectduration = 100 //10 seconds of lava walking
|
||||
var/storedimmunities = list()
|
||||
var/datum/action/cooldown/lavawalk/lavawalk
|
||||
var/effectduration = 10 SECONDS
|
||||
var/timer
|
||||
|
||||
/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
|
||||
if(L && istype(L))
|
||||
for(var/datum/action/A in actions_types)
|
||||
A.Grant(L)
|
||||
lavawalk = new(src)
|
||||
RegisterSignal(lavawalk, COMSIG_ACTION_TRIGGER, .proc/activate)
|
||||
|
||||
/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
|
||||
if(L && istype(L))
|
||||
for(var/datum/action/A in actions_types)
|
||||
A.Remove(L)
|
||||
var/mob/living/user = get_atom_on_turf(src, /mob/living)
|
||||
if(user && timer)
|
||||
reset_user(user)
|
||||
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"
|
||||
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)
|
||||
if(istype(actiontype, /datum/action/item_action/lavawalk))
|
||||
if(world.time >= cool_down)
|
||||
var/mob/living/L = user
|
||||
if(istype(L))
|
||||
storedimmunities = L.weather_immunities.Copy()
|
||||
L.weather_immunities |= list("ash", "lava")
|
||||
cool_down = world.time + cooldown_time
|
||||
addtimer(CALLBACK(src, .proc/reset_user, L), effectduration)
|
||||
/obj/item/clothing/accessory/lavawalk/proc/activate(datum/action/cooldown/lavawalk/action, obj/item/clothing/accessory/lavawalk/item)
|
||||
var/mob/living/L = usr
|
||||
if(istype(L))
|
||||
to_chat(L, span_notice("\The [src] begins glowing!"))
|
||||
L.balloon_alert(L, "activated")
|
||||
ADD_TRAIT(L, TRAIT_ASHSTORM_IMMUNE, src)
|
||||
ADD_TRAIT(L, TRAIT_LAVA_IMMUNE, src)
|
||||
timer = addtimer(CALLBACK(src, .proc/reset_user, L), effectduration)
|
||||
action.StartCooldown()
|
||||
|
||||
/obj/item/clothing/accessory/lavawalk/proc/reset_user(mob/living/user)
|
||||
user.weather_immunities = storedimmunities
|
||||
storedimmunities = list()
|
||||
REMOVE_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, src)
|
||||
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
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/damaged
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
req_access = list(ACCESS_MEDICAL)
|
||||
|
||||
/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
|
||||
req_access = list(ACCESS_RESEARCH)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
req_access = list(ACCESS_MEDICAL)
|
||||
|
||||
/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
|
||||
req_access = list(ACCESS_RESEARCH)
|
||||
|
||||
@@ -856,7 +856,6 @@
|
||||
#include "code\datums\traits\negative.dm"
|
||||
#include "code\datums\traits\neutral.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\floor_is_lava.dm"
|
||||
#include "code\datums\weather\weather_types\ice_storm.dm"
|
||||
|
||||
@@ -2,23 +2,18 @@ import { map, sortBy } from 'common/collections';
|
||||
import { flow } from 'common/fp';
|
||||
import { pureComponentHooks } from 'common/react';
|
||||
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 { AreaCharge, powerRank } from './PowerMonitor';
|
||||
|
||||
export const ApcControl = (props, context) => {
|
||||
const { data } = useBackend(context);
|
||||
return (
|
||||
<Window
|
||||
title="APC Controller"
|
||||
width={550}
|
||||
height={500}>
|
||||
{data.authenticated === 1 && (
|
||||
<ApcLoggedIn />
|
||||
)}
|
||||
{data.authenticated === 0 && (
|
||||
<ApcLoggedOut />
|
||||
)}
|
||||
<Window title="APC Controller" width={550} height={500}>
|
||||
<Window.Content>
|
||||
{data.authenticated === 1 && <ApcLoggedIn />}
|
||||
{data.authenticated === 0 && <ApcLoggedOut />}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -28,25 +23,24 @@ const ApcLoggedOut = (props, context) => {
|
||||
const { emagged } = data;
|
||||
const text = emagged === 1 ? 'Open' : 'Log In';
|
||||
return (
|
||||
<Window.Content>
|
||||
<Section>
|
||||
<Button
|
||||
fluid
|
||||
icon="sign-in-alt"
|
||||
color={emagged === 1 ? '' : 'good'}
|
||||
content={text}
|
||||
onClick={() => act('log-in')} />
|
||||
</Window.Content>
|
||||
fluid
|
||||
onClick={() => act('log-in')}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const ApcLoggedIn = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { restoring } = data;
|
||||
const [
|
||||
tabIndex,
|
||||
setTabIndex,
|
||||
] = useLocalState(context, 'tab-index', 1);
|
||||
const [tabIndex, setTabIndex] = useLocalState(context, 'tab-index', 1);
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
selected={tabIndex === 1}
|
||||
@@ -72,59 +66,62 @@ const ApcLoggedIn = (props, context) => {
|
||||
</Dimmer>
|
||||
)}
|
||||
{tabIndex === 1 && (
|
||||
<>
|
||||
<ControlPanel />
|
||||
<Box fillPositionedParent top="53px">
|
||||
<Window.Content overflow="auto">
|
||||
<Stack vertical>
|
||||
<Stack.Item>
|
||||
<Section>
|
||||
<ControlPanel />
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Section scrollable>
|
||||
<ApcControlScene />
|
||||
</Window.Content>
|
||||
</Box>
|
||||
</>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
{tabIndex === 2 && (
|
||||
<Box fillPositionedParent top="20px">
|
||||
<Window.Content overflow="auto">
|
||||
<Section scrollable>
|
||||
<Box height={34}>
|
||||
<LogPanel />
|
||||
</Window.Content>
|
||||
</Box>
|
||||
</Box>
|
||||
</Section>
|
||||
)}
|
||||
</>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const ControlPanel = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
emagged,
|
||||
logging,
|
||||
} = data;
|
||||
const [
|
||||
sortByField,
|
||||
setSortByField,
|
||||
] = useLocalState(context, 'sortByField', null);
|
||||
const { emagged, logging } = data;
|
||||
const [sortByField, setSortByField] = useLocalState(
|
||||
context,
|
||||
'sortByField',
|
||||
'name'
|
||||
);
|
||||
return (
|
||||
<Flex>
|
||||
<Flex.Item>
|
||||
<Stack justify="space-between">
|
||||
<Stack.Item>
|
||||
<Box inline mr={2} color="label">
|
||||
Sort by:
|
||||
</Box>
|
||||
<Button.Checkbox
|
||||
checked={sortByField === 'name'}
|
||||
content="Name"
|
||||
onClick={() => setSortByField(sortByField !== 'name' && 'name')} />
|
||||
onClick={() => setSortByField(sortByField !== 'name' && 'name')}
|
||||
/>
|
||||
<Button.Checkbox
|
||||
checked={sortByField === 'charge'}
|
||||
content="Charge"
|
||||
onClick={() => setSortByField(
|
||||
sortByField !== 'charge' && 'charge'
|
||||
)} />
|
||||
onClick={() => setSortByField(sortByField !== 'charge' && 'charge')}
|
||||
/>
|
||||
<Button.Checkbox
|
||||
checked={sortByField === 'draw'}
|
||||
content="Draw"
|
||||
onClick={() => setSortByField(sortByField !== 'draw' && 'draw')} />
|
||||
</Flex.Item>
|
||||
<Flex.Item grow={1} />
|
||||
<Flex.Item>
|
||||
onClick={() => setSortByField(sortByField !== 'draw' && 'draw')}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow={1} />
|
||||
<Stack.Item>
|
||||
{emagged === 1 && (
|
||||
<>
|
||||
<Button
|
||||
@@ -139,21 +136,20 @@ const ControlPanel = (props, context) => {
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
icon="sign-out-alt"
|
||||
color="bad"
|
||||
content="Log Out"
|
||||
onClick={() => act('log-out')}
|
||||
/>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
const ApcControlScene = (props, context) => {
|
||||
const { data, act } = useBackend(context);
|
||||
|
||||
const [
|
||||
sortByField,
|
||||
] = useLocalState(context, 'sortByField', null);
|
||||
const [sortByField] = useLocalState(context, 'sortByField', 'name');
|
||||
|
||||
const apcs = flow([
|
||||
map((apc, i) => ({
|
||||
@@ -161,94 +157,87 @@ const ApcControlScene = (props, context) => {
|
||||
// Generate a unique id
|
||||
id: apc.name + i,
|
||||
})),
|
||||
sortByField === 'name' && sortBy(apc => apc.name),
|
||||
sortByField === 'charge' && sortBy(apc => -apc.charge),
|
||||
sortByField === 'draw' && sortBy(
|
||||
apc => -powerRank(apc.load),
|
||||
apc => -parseFloat(apc.load)),
|
||||
sortByField === 'name' && sortBy((apc) => apc.name),
|
||||
sortByField === 'charge' && sortBy((apc) => -apc.charge),
|
||||
sortByField === 'draw'
|
||||
&& sortBy(
|
||||
(apc) => -powerRank(apc.load),
|
||||
(apc) => -parseFloat(apc.load)
|
||||
),
|
||||
])(data.apcs);
|
||||
return (
|
||||
<Table>
|
||||
<Table.Row header>
|
||||
<Table.Cell>
|
||||
On/Off
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Area
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing>
|
||||
Charge
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing textAlign="right">
|
||||
Draw
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing title="Equipment">
|
||||
Eqp
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing title="Lighting">
|
||||
Lgt
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing title="Environment">
|
||||
Env
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
{apcs.map((apc, i) => (
|
||||
<tr
|
||||
key={apc.id}
|
||||
className="Table__row candystripe">
|
||||
<td>
|
||||
<Button
|
||||
icon={apc.operating ? 'power-off' : 'times'}
|
||||
color={apc.operating ? 'good' : 'bad'}
|
||||
onClick={() => act('breaker', {
|
||||
ref: apc.ref,
|
||||
})}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<Button
|
||||
onClick={() => act('access-apc', {
|
||||
ref: apc.ref,
|
||||
})}>
|
||||
{apc.name}
|
||||
</Button>
|
||||
</td>
|
||||
<td className="Table__cell text-right text-nowrap">
|
||||
<AreaCharge
|
||||
charging={apc.charging}
|
||||
charge={apc.charge}
|
||||
/>
|
||||
</td>
|
||||
<td className="Table__cell text-right text-nowrap">
|
||||
{apc.load}
|
||||
</td>
|
||||
<td className="Table__cell text-center text-nowrap">
|
||||
<AreaStatusColorButton
|
||||
target="equipment"
|
||||
status={apc.eqp}
|
||||
apc={apc}
|
||||
act={act}
|
||||
/>
|
||||
</td>
|
||||
<td className="Table__cell text-center text-nowrap">
|
||||
<AreaStatusColorButton
|
||||
target="lighting"
|
||||
status={apc.lgt}
|
||||
apc={apc}
|
||||
act={act}
|
||||
/>
|
||||
</td>
|
||||
<td className="Table__cell text-center text-nowrap">
|
||||
<AreaStatusColorButton
|
||||
target="environ"
|
||||
status={apc.env}
|
||||
apc={apc}
|
||||
act={act}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</Table>
|
||||
<Box height={30}>
|
||||
<Table>
|
||||
<Table.Row header>
|
||||
<Table.Cell>On/Off</Table.Cell>
|
||||
<Table.Cell>Area</Table.Cell>
|
||||
<Table.Cell collapsing>Charge</Table.Cell>
|
||||
<Table.Cell collapsing textAlign="right">
|
||||
Draw
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing title="Equipment">
|
||||
Eqp
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing title="Lighting">
|
||||
Lgt
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing title="Environment">
|
||||
Env
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
{apcs.map((apc, i) => (
|
||||
<tr key={apc.id} className="Table__row candystripe">
|
||||
<td>
|
||||
<Button
|
||||
icon={apc.operating ? 'power-off' : 'times'}
|
||||
color={apc.operating ? 'good' : 'bad'}
|
||||
onClick={() =>
|
||||
act('breaker', {
|
||||
ref: apc.ref,
|
||||
})}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('access-apc', {
|
||||
ref: apc.ref,
|
||||
})}>
|
||||
{apc.name}
|
||||
</Button>
|
||||
</td>
|
||||
<td className="Table__cell text-right text-nowrap">
|
||||
<AreaCharge charging={apc.charging} charge={apc.charge} />
|
||||
</td>
|
||||
<td className="Table__cell text-right text-nowrap">{apc.load}</td>
|
||||
<td className="Table__cell text-center text-nowrap">
|
||||
<AreaStatusColorButton
|
||||
target="equipment"
|
||||
status={apc.eqp}
|
||||
apc={apc}
|
||||
act={act}
|
||||
/>
|
||||
</td>
|
||||
<td className="Table__cell text-center text-nowrap">
|
||||
<AreaStatusColorButton
|
||||
target="lighting"
|
||||
status={apc.lgt}
|
||||
apc={apc}
|
||||
act={act}
|
||||
/>
|
||||
</td>
|
||||
<td className="Table__cell text-center text-nowrap">
|
||||
<AreaStatusColorButton
|
||||
target="environ"
|
||||
status={apc.env}
|
||||
apc={apc}
|
||||
act={act}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</Table>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -261,16 +250,12 @@ const LogPanel = (props, context) => {
|
||||
// Generate a unique id
|
||||
id: line.entry + i,
|
||||
})),
|
||||
logs => logs.reverse(),
|
||||
(logs) => logs.reverse(),
|
||||
])(data.logs);
|
||||
return (
|
||||
<Box m={-0.5}>
|
||||
{logs.map(line => (
|
||||
<Box
|
||||
p={0.5}
|
||||
key={line.id}
|
||||
className="candystripe"
|
||||
bold>
|
||||
{logs.map((line) => (
|
||||
<Box p={0.5} key={line.id} className="candystripe" bold>
|
||||
{line.entry}
|
||||
</Box>
|
||||
))}
|
||||
@@ -278,7 +263,7 @@ const LogPanel = (props, context) => {
|
||||
);
|
||||
};
|
||||
|
||||
const AreaStatusColorButton = props => {
|
||||
const AreaStatusColorButton = (props) => {
|
||||
const { target, status, apc, act } = props;
|
||||
const power = Boolean(status & 2);
|
||||
const mode = Boolean(status & 1);
|
||||
@@ -286,20 +271,20 @@ const AreaStatusColorButton = props => {
|
||||
<Button
|
||||
icon={mode ? 'sync' : 'power-off'}
|
||||
color={power ? 'good' : 'bad'}
|
||||
onClick={() => act('toggle-minor', {
|
||||
type: target,
|
||||
value: statusChange(status),
|
||||
ref: apc.ref,
|
||||
})}
|
||||
onClick={() =>
|
||||
act('toggle-minor', {
|
||||
type: target,
|
||||
value: statusChange(status),
|
||||
ref: apc.ref,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const statusChange = status => {
|
||||
const statusChange = (status) => {
|
||||
// mode flip power flip both flip
|
||||
// 0, 2, 3
|
||||
return status === 0 ? 2 : status === 2 ? 3 : 0;
|
||||
};
|
||||
|
||||
AreaStatusColorButton.defaultHooks = pureComponentHooks;
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
97
tgui/packages/tgui/interfaces/CellularEmporium.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
};
|
||||