MODsuit module update: new stuff and improved old stuff (#67042)

Doubles the range of the MOD Pathfinder AI
Fixes modules rendering below the suit.
Adds the ability for modules to be used when inactive.
Documents/cleans up some code.
Updates some old descriptions and explains some concepts better.
Armor Booster and Ash Accretion can no longer boost your speed over no slowdown at all.
Makes flashlight module start with 4 instead of 3 range, so it's better for people that don't know about configuration.
Doubles t-ray module range, from 2 to 4 (t-ray scanner is 3).
Puts the noslip module lower in progression, lowers its' price to 2.
New sprites for the magnetic harness module by Onule.
Brings back the holster module, it can now be used when the suit is inactive, can be printed with security suit research.
Adds the power kick module for the ERT Commander. It's a powerful kick.
This commit is contained in:
Fikou
2022-05-18 01:19:31 -04:00
committed by GitHub
parent 30838d991c
commit f501b1e49e
26 changed files with 429 additions and 123 deletions
+1 -1
View File
@@ -145,7 +145,7 @@
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
return FALSE
for(var/obj/item/mod/module/module as anything in modules)
if(!module.active)
if(!module.active || module.allowed_inactive)
continue
module.on_deactivation(display_message = FALSE)
activating = TRUE
-1
View File
@@ -9,7 +9,6 @@
heat_protection = HEAD
cold_protection = HEAD
obj_flags = IMMUTABLE_SLOW
var/alternate_layer = NECK_LAYER
/obj/item/clothing/suit/mod
name = "MOD chestplate"
+4 -5
View File
@@ -622,13 +622,12 @@
CRASH("[src] tried to set skin while active!")
skin = new_skin
var/list/used_skin = theme.skins[new_skin]
alternate_worn_layer = used_skin[CONTROL_LAYER]
if(used_skin[CONTROL_LAYER])
alternate_worn_layer = used_skin[CONTROL_LAYER]
var/list/skin_updating = mod_parts + src
for(var/obj/item/part as anything in skin_updating)
if(used_skin[MOD_ICON_OVERRIDE])
part.icon = used_skin[MOD_ICON_OVERRIDE]
if(used_skin[MOD_WORN_ICON_OVERRIDE])
part.worn_icon = used_skin[MOD_WORN_ICON_OVERRIDE]
part.icon = used_skin[MOD_ICON_OVERRIDE] || 'icons/obj/clothing/modsuit/mod_clothing.dmi'
part.worn_icon = used_skin[MOD_WORN_ICON_OVERRIDE] || 'icons/mob/clothing/modsuit/mod_clothing.dmi'
part.icon_state = "[skin]-[initial(part.icon_state)]"
for(var/obj/item/clothing/part as anything in mod_parts)
var/used_category
+4 -4
View File
@@ -242,11 +242,11 @@
/obj/item/mod/control/pre_equipped/responsory/commander
insignia_type = /obj/item/mod/module/insignia/commander
additional_module = /obj/item/mod/module/noslip
additional_module = /obj/item/mod/module/power_kick
/obj/item/mod/control/pre_equipped/responsory/security
insignia_type = /obj/item/mod/module/insignia/security
additional_module = /obj/item/mod/module/gps
additional_module = /obj/item/mod/module/pepper_shoulders
/obj/item/mod/control/pre_equipped/responsory/engineer
insignia_type = /obj/item/mod/module/insignia/engineer
@@ -281,11 +281,11 @@
/obj/item/mod/control/pre_equipped/responsory/inquisitory/commander
insignia_type = /obj/item/mod/module/insignia/commander
additional_module = /obj/item/mod/module/noslip
additional_module = /obj/item/mod/module/power_kick
/obj/item/mod/control/pre_equipped/responsory/inquisitory/security
insignia_type = /obj/item/mod/module/insignia/security
additional_module = /obj/item/mod/module/gps
additional_module = /obj/item/mod/module/pepper_shoulders
/obj/item/mod/control/pre_equipped/responsory/inquisitory/medic
insignia_type = /obj/item/mod/module/insignia/medic
+27 -24
View File
@@ -43,6 +43,8 @@
var/list/pinned_to = list()
/// If we're allowed to use this module while phased out.
var/allowed_in_phaseout = FALSE
/// If we're allowed to use this module while the suit is disabled.
var/allowed_inactive = FALSE
/// Timer for the cooldown
COOLDOWN_DECLARE(cooldown_timer)
@@ -68,33 +70,10 @@
if(HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD))
. += span_notice("Complexity level: [complexity]")
/// Called from MODsuit's install() proc, so when the module is installed.
/obj/item/mod/module/proc/on_install()
return
/// Called from MODsuit's uninstall() proc, so when the module is uninstalled.
/obj/item/mod/module/proc/on_uninstall(deleting = FALSE)
return
/// Called when the MODsuit is activated
/obj/item/mod/module/proc/on_suit_activation()
return
/// Called when the MODsuit is deactivated
/obj/item/mod/module/proc/on_suit_deactivation(deleting = FALSE)
return
/// Called when the MODsuit is equipped
/obj/item/mod/module/proc/on_equip()
return
/// Called when the MODsuit is unequipped
/obj/item/mod/module/proc/on_unequip()
return
/// Called when the module is selected from the TGUI, radial or the action button
/obj/item/mod/module/proc/on_select()
if(!mod.active || mod.activating || module_type == MODULE_PASSIVE)
if(((!mod.active || mod.activating) && !allowed_inactive) || module_type == MODULE_PASSIVE)
if(mod.wearer)
balloon_alert(mod.wearer, "not active!")
return
@@ -212,6 +191,30 @@
/obj/item/mod/module/proc/on_active_process(delta_time)
return
/// Called from MODsuit's install() proc, so when the module is installed.
/obj/item/mod/module/proc/on_install()
return
/// Called from MODsuit's uninstall() proc, so when the module is uninstalled.
/obj/item/mod/module/proc/on_uninstall(deleting = FALSE)
return
/// Called when the MODsuit is activated
/obj/item/mod/module/proc/on_suit_activation()
return
/// Called when the MODsuit is deactivated
/obj/item/mod/module/proc/on_suit_deactivation(deleting = FALSE)
return
/// Called when the MODsuit is equipped
/obj/item/mod/module/proc/on_equip()
return
/// Called when the MODsuit is unequipped
/obj/item/mod/module/proc/on_unequip()
return
/// Drains power from the suit charge
/obj/item/mod/module/proc/drain_power(amount)
if(!check_power(amount))
+4 -4
View File
@@ -243,11 +243,11 @@
var/list/view = getviewsize(kinesis_user.client.view)
icon_x *= view[1]/FULLSCREEN_OVERLAY_RESOLUTION_X
icon_y *= view[2]/FULLSCREEN_OVERLAY_RESOLUTION_Y
var/our_x = round(icon_x / world.icon_size)
var/our_y = round(icon_y / world.icon_size)
var/our_x = round(icon_x / world.icon_size, 1)
var/our_y = round(icon_y / world.icon_size, 1)
var/mob_x = kinesis_user.x
var/mob_y = kinesis_user.y
var/mob_z = kinesis_user.z
given_turf = locate(mob_x+our_x-round(view[1]/2),mob_y+our_y-round(view[2]/2),mob_z)
given_x = round(icon_x - world.icon_size * our_x)
given_y = round(icon_y - world.icon_size * our_y)
given_x = round(icon_x - world.icon_size * our_x, 1)
given_y = round(icon_y - world.icon_size * our_y, 1)
@@ -3,8 +3,8 @@
name = "MOD pathfinder module"
desc = "This module, brought to you by Nakamura Engineering, has two components. \
The first component is a series of thrusters and a computerized location subroutine installed into the \
very control unit of the suit, allowing it flight at highway speeds, \
and to be able to locate the second part of the system; \
very control unit of the suit, allowing it flight at highway speeds using the suit's access locks \
to navigate through the station, and to be able to locate the second part of the system; \
a pathfinding implant installed into the base of the user's spine, \
broadcasting their location to the suit and allowing them to recall it to their person at any time. \
The implant is stored in the module and needs to be injected in a human to function. \
+169 -4
View File
@@ -18,8 +18,10 @@
use_mod_colors = TRUE
/// Whether or not this module removes pressure protection.
var/remove_pressure_protection = TRUE
/// Slowdown added to the suit.
var/added_slowdown = -0.5
/// Speed added to the control unit.
var/speed_added = 0.5
/// Speed that we actually added.
var/actual_speed_added = 0
/// Armor values added to the suit parts.
var/list/armor_values = list(MELEE = 25, BULLET = 30, LASER = 15, ENERGY = 15)
/// List of parts of the suit that are spaceproofed, for giving them back the pressure protection.
@@ -38,7 +40,8 @@
if(!.)
return
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
mod.slowdown += added_slowdown
actual_speed_added = max(0, min(mod.slowdown_active, speed_added))
mod.slowdown -= actual_speed_added
mod.wearer.update_equipment_speed_mods()
var/list/parts = mod.mod_parts + mod
for(var/obj/item/part as anything in parts)
@@ -56,7 +59,7 @@
return
if(!deleting)
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
mod.slowdown -= added_slowdown
mod.slowdown += actual_speed_added
mod.wearer.update_equipment_speed_mods()
var/list/parts = mod.mod_parts + mod
var/list/removed_armor = armor_values.Copy()
@@ -288,3 +291,165 @@
/obj/projectile/bullet/incendiary/backblast/flamethrower
range = 6
///Power kick - Lets the user launch themselves at someone to kick them.
/obj/item/mod/module/power_kick
name = "MOD power kick module"
desc = "This module uses high-power myomer to generate an incredible amount of energy, transferred into the power of a kick."
icon_state = "power_kick"
module_type = MODULE_ACTIVE
removable = FALSE
use_power_cost = DEFAULT_CHARGE_DRAIN*5
incompatible_modules = list(/obj/item/mod/module/power_kick)
cooldown_time = 5 SECONDS
/// Damage on kick.
var/damage = 20
/// The wound bonus of the kick.
var/wounding_power = 35
/// How long we knockdown for on the kick.
var/knockdown_time = 2 SECONDS
/obj/item/mod/module/power_kick/on_select_use(atom/target)
. = ..()
if(!.)
return
mod.wearer.visible_message(span_warning("[mod.wearer] starts charging a kick!"), \
blind_message = span_hear("You hear a charging sound."))
playsound(src, 'sound/items/modsuit/loader_charge.ogg', 75, TRUE)
balloon_alert(mod.wearer, "you start charging...")
animate(mod.wearer, 0.3 SECONDS, pixel_z = 16, flags = ANIMATION_RELATIVE|SINE_EASING|EASE_OUT)
addtimer(CALLBACK(mod.wearer, /atom.proc/SpinAnimation, 3, 2), 0.3 SECONDS)
if(!do_after(mod.wearer, 1 SECONDS, target = mod))
animate(mod.wearer, 0.2 SECONDS, pixel_z = -16, flags = ANIMATION_RELATIVE|SINE_EASING|EASE_IN)
return
animate(mod.wearer)
drain_power(use_power_cost)
playsound(src, 'sound/items/modsuit/loader_launch.ogg', 75, TRUE)
var/angle = get_angle(mod.wearer, target) + 180
mod.wearer.transform = mod.wearer.transform.Turn(angle)
RegisterSignal(mod.wearer, COMSIG_MOVABLE_IMPACT, .proc/on_throw_impact)
mod.wearer.throw_at(target, range = 7, speed = 2, thrower = mod.wearer, spin = FALSE, gentle = TRUE, callback = CALLBACK(src, .proc/on_throw_end, mod.wearer, -angle))
/obj/item/mod/module/power_kick/proc/on_throw_end(mob/user, angle)
if(!user)
return
user.transform = user.transform.Turn(angle)
animate(user, 0.2 SECONDS, pixel_z = -16, flags = ANIMATION_RELATIVE|SINE_EASING|EASE_IN)
/obj/item/mod/module/power_kick/proc/on_throw_impact(mob/living/source, atom/target, datum/thrownthing/thrownthing)
SIGNAL_HANDLER
UnregisterSignal(source, COMSIG_MOVABLE_IMPACT)
if(!mod?.wearer)
return
if(isliving(target))
var/mob/living/living_target = target
living_target.apply_damage(damage, BRUTE, mod.wearer.zone_selected, wound_bonus = wounding_power)
living_target.Knockdown(knockdown_time)
else if(target.uses_integrity)
target.take_damage(damage, BRUTE, MELEE)
else
return
mod.wearer.do_attack_animation(target, ATTACK_EFFECT_SMASH)
///Chameleon - lets the suit disguise as any item that would fit on that slot.
/obj/item/mod/module/chameleon
name = "MOD chameleon module"
desc = "A module using chameleon technology to disguise the suit as another object."
icon_state = "chameleon"
module_type = MODULE_USABLE
complexity = 2
incompatible_modules = list(/obj/item/mod/module/chameleon)
cooldown_time = 0.5 SECONDS
allowed_inactive = TRUE
/// A list of all the items the suit can disguise as.
var/list/possible_disguises = list()
/// The path of the item we're disguised as.
var/obj/item/current_disguise
/obj/item/mod/module/chameleon/on_install()
var/list/all_disguises = sort_list(subtypesof(get_path_by_slot(mod.slot_flags)), /proc/cmp_typepaths_asc)
for(var/clothing_path in all_disguises)
var/obj/item/clothing = clothing_path
if(!initial(clothing.icon_state))
continue
var/chameleon_item_name = "[initial(clothing.name)] ([initial(clothing.icon_state)])"
possible_disguises[chameleon_item_name] = clothing_path
/obj/item/mod/module/chameleon/on_uninstall(deleting = FALSE)
if(current_disguise)
return_look()
possible_disguises = null
/obj/item/mod/module/chameleon/on_use()
if(mod.active || mod.activating)
balloon_alert(mod.wearer, "suit active!")
return
. = ..()
if(!.)
return
if(current_disguise)
return_look()
return
var/picked_name = tgui_input_list(mod.wearer, "Select look to change into", "Chameleon Settings", possible_disguises)
if(!possible_disguises[picked_name] || mod.active || mod.activating)
return
current_disguise = possible_disguises[picked_name]
update_look()
/obj/item/mod/module/chameleon/proc/update_look()
mod.name = initial(current_disguise.name)
mod.desc = initial(current_disguise.desc)
mod.icon_state = initial(current_disguise.icon_state)
mod.icon = initial(current_disguise.icon)
mod.worn_icon = initial(current_disguise.worn_icon)
mod.alternate_worn_layer = initial(current_disguise.alternate_worn_layer)
mod.lefthand_file = initial(current_disguise.lefthand_file)
mod.righthand_file = initial(current_disguise.righthand_file)
mod.worn_icon_state = initial(current_disguise.worn_icon_state)
mod.inhand_icon_state = initial(current_disguise.inhand_icon_state)
mod.wearer.update_clothing(mod.slot_flags)
RegisterSignal(mod, COMSIG_MOD_ACTIVATE, .proc/return_look)
/obj/item/mod/module/chameleon/proc/return_look()
mod.name = "[mod.theme.name] [initial(mod.name)]"
mod.desc = "[initial(mod.desc)] [mod.theme.desc]"
mod.icon_state = "[mod.skin]-[initial(mod.icon_state)]"
var/list/mod_skin = mod.theme.skins[mod.skin]
mod.icon = mod_skin[MOD_ICON_OVERRIDE] || 'icons/obj/clothing/modsuit/mod_clothing.dmi'
mod.worn_icon = mod_skin[MOD_WORN_ICON_OVERRIDE] || 'icons/mob/clothing/modsuit/mod_clothing.dmi'
mod.alternate_worn_layer = mod_skin[CONTROL_LAYER]
mod.lefthand_file = initial(mod.lefthand_file)
mod.righthand_file = initial(mod.righthand_file)
mod.worn_icon_state = null
mod.inhand_icon_state = null
mod.wearer.update_clothing(mod.slot_flags)
current_disguise = null
UnregisterSignal(mod, COMSIG_MOD_ACTIVATE)
///Plate Compression - Compresses the suit to normal size
/obj/item/mod/module/plate_compression
name = "MOD plate compression module"
desc = "A module that keeps the suit in a very tightly fit state, lowering the overall size. \
Due to the pressure on all the parts, typical storage modules do not fit."
icon_state = "plate_compression"
complexity = 2
incompatible_modules = list(/obj/item/mod/module/plate_compression, /obj/item/mod/module/storage)
/// The size we set the suit to.
var/new_size = WEIGHT_CLASS_NORMAL
/// The suit's size before the module is installed.
var/old_size
/obj/item/mod/module/plate_compression/on_install()
old_size = mod.w_class
mod.w_class = new_size
/obj/item/mod/module/plate_compression/on_uninstall(deleting = FALSE)
mod.w_class = old_size
old_size = null
if(!mod.loc)
return
var/datum/component/storage/holding_storage = mod.loc.GetComponent(/datum/component/storage)
if(!holding_storage || holding_storage.max_w_class >= mod.w_class)
return
mod.forceMove(drop_location())
@@ -28,11 +28,11 @@
icon_state = "tray"
module_type = MODULE_TOGGLE
complexity = 1
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
incompatible_modules = list(/obj/item/mod/module/t_ray)
cooldown_time = 0.5 SECONDS
/// T-ray scan range.
var/range = 2
var/range = 4
/obj/item/mod/module/t_ray/on_active_process(delta_time)
t_ray_scan(mod.wearer, 0.8 SECONDS, range)
@@ -121,6 +121,7 @@
hitsound_wall = 'sound/weapons/batonextend.ogg'
suppressed = SUPPRESSED_VERY
hit_threshhold = LATTICE_LAYER
/// Reference to the beam following the projectile.
var/line
/obj/projectile/tether/fire(setAngle)
@@ -217,6 +218,7 @@
device = /obj/item/reagent_containers/spray/mister
incompatible_modules = list(/obj/item/mod/module/mister)
cooldown_time = 0.5 SECONDS
/// Volume of our reagent holder.
var/volume = 500
/obj/item/mod/module/mister/Initialize(mapload)
+5 -7
View File
@@ -7,7 +7,7 @@
the surface of the suit, useful for storing various bits, and or bobs."
icon_state = "storage"
complexity = 3
incompatible_modules = list(/obj/item/mod/module/storage)
incompatible_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/plate_compression)
/// The storage component of the module.
var/datum/component/storage/concrete/storage
/// Max weight class of items in the storage.
@@ -186,7 +186,7 @@
name = "MOD eating apparatus module"
desc = "A favorite by Miners, this modification to the helmet utilizes a nanotechnology barrier infront of the mouth \
to allow eating and drinking while retaining protection and atmosphere. However, it won't free you from masks, \
and it will do nothing to improve the taste of a goliath steak."
lets pepper spray pass through and it will do nothing to improve the taste of a goliath steak."
icon_state = "apparatus"
complexity = 1
incompatible_modules = list(/obj/item/mod/module/mouthhole)
@@ -228,7 +228,7 @@
///Flashlight - Gives the suit a customizable flashlight.
/obj/item/mod/module/flashlight
name = "MOD flashlight module"
desc = "A simple pair of flashlights installed on the left and right sides of the helmet, \
desc = "A simple pair of configurable flashlights installed on the left and right sides of the helmet, \
useful for providing light in a variety of ranges and colors. \
Some survivalists prefer the color green for their illumination, for reasons unknown."
icon_state = "flashlight"
@@ -240,7 +240,7 @@
overlay_state_inactive = "module_light"
light_system = MOVABLE_LIGHT_DIRECTIONAL
light_color = COLOR_WHITE
light_range = 3
light_range = 4
light_power = 1
light_on = FALSE
/// Charge drain per range amount.
@@ -266,10 +266,8 @@
set_light_on(active)
/obj/item/mod/module/flashlight/on_process(delta_time)
. = ..()
if(!.)
return
active_power_cost = base_power * light_range
return ..()
/obj/item/mod/module/flashlight/generate_worn_overlay(mutable_appearance/standing)
. = ..()
@@ -237,6 +237,8 @@
drain_power(use_power_cost)
num_sheets_dispensed++
///Stamper - Extends a stamp that can switch between accept/deny modes.
/obj/item/mod/module/stamp
name = "MOD stamper module"
desc = "A module installed into the wrist of the suit, this functions as a high-power stamp, \
@@ -128,7 +128,9 @@
use_power_cost = DEFAULT_CHARGE_DRAIN
incompatible_modules = list(/obj/item/mod/module/organ_thrower, /obj/item/mod/module/microwave_beam)
cooldown_time = 0.5 SECONDS
/// How many organs the module can hold.
var/max_organs = 5
/// A list of all our organs.
var/organ_list = list()
/obj/item/mod/module/organ_thrower/on_select_use(atom/target)
@@ -165,6 +167,7 @@
nodamage = TRUE
hitsound = 'sound/effects/attackblob.ogg'
hitsound_wall = 'sound/effects/attackblob.ogg'
/// A reference to the organ we "are".
var/obj/item/organ/organ
/obj/projectile/organ/Initialize(mapload, obj/item/stored_organ)
@@ -168,3 +168,54 @@
return
mod.wearer.visible_message(span_warning("[src] reacts to the attack with a smoke of pepper spray!"), span_notice("Your [src] releases a cloud of pepper spray!"))
on_use()
///Holster - Instantly holsters any not huge gun.
/obj/item/mod/module/holster
name = "MOD holster module"
desc = "Based off typical storage compartments, this system allows the suit to holster a \
standard firearm across its surface and allow for extremely quick retrieval. \
While some users prefer the chest, others the forearm for quick deployment, \
some law enforcement prefer the holster to extend from the thigh."
icon_state = "holster"
module_type = MODULE_USABLE
complexity = 2
incompatible_modules = list(/obj/item/mod/module/holster)
cooldown_time = 0.5 SECONDS
allowed_inactive = TRUE
/// Gun we have holstered.
var/obj/item/gun/holstered
/obj/item/mod/module/holster/on_use()
. = ..()
if(!.)
return
if(!holstered)
var/obj/item/gun/holding = mod.wearer.get_active_held_item()
if(!holding)
balloon_alert(mod.wearer, "nothing to holster!")
return
if(!istype(holding) || holding.w_class > WEIGHT_CLASS_BULKY)
balloon_alert(mod.wearer, "it doesn't fit!")
return
if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE))
holstered = holding
balloon_alert(mod.wearer, "weapon holstered")
playsound(src, 'sound/weapons/gun/revolver/empty.ogg', 100, TRUE)
else if(mod.wearer.put_in_active_hand(holstered, forced = FALSE, ignore_animation = TRUE))
balloon_alert(mod.wearer, "weapon drawn")
playsound(src, 'sound/weapons/gun/revolver/empty.ogg', 100, TRUE)
else
balloon_alert(mod.wearer, "holster full!")
/obj/item/mod/module/holster/on_uninstall(deleting = FALSE)
if(holstered)
holstered.forceMove(drop_location())
/obj/item/mod/module/holster/Exited(atom/movable/gone, direction)
. = ..()
if(gone == holstered)
holstered = null
/obj/item/mod/module/holster/Destroy()
QDEL_NULL(holstered)
return ..()
+12 -11
View File
@@ -253,12 +253,12 @@
mod.wearer.transform = mod.wearer.transform.Turn(angle)
mod.wearer.throw_at(get_ranged_target_turf_direct(mod.wearer, target, power), \
range = power, speed = max(round(0.2*power), 1), thrower = mod.wearer, spin = FALSE, \
callback = CALLBACK(src, .proc/on_throw_end, target, -angle))
callback = CALLBACK(src, .proc/on_throw_end, mod.wearer, -angle))
/obj/item/mod/module/hydraulic/proc/on_throw_end(atom/target, angle)
if(!mod?.wearer)
/obj/item/mod/module/hydraulic/proc/on_throw_end(mob/user, angle)
if(!user)
return
mod.wearer.transform = mod.wearer.transform.Turn(angle)
user.transform = user.transform.Turn(angle)
/obj/item/mod/module/disposal_connector
name = "MOD disposal selector module"
@@ -370,6 +370,8 @@
var/list/armor_values = list(MELEE = 4, BULLET = 1, LASER = 2, ENERGY = 2, BOMB = 4)
/// Speed added when you're fully covered in ash.
var/speed_added = 0.5
/// Speed that we actually added.
var/actual_speed_added = 0
/// Turfs that let us accrete ash.
var/static/list/accretion_turfs
/// Turfs that let us keep ash.
@@ -440,7 +442,8 @@
mod.wearer.color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,3) //make them super light
animate(mod.wearer, 1 SECONDS, color = null, flags = ANIMATION_PARALLEL)
playsound(src, 'sound/effects/sparks1.ogg', 100, TRUE)
mod.slowdown -= speed_added
actual_speed_added = max(0, min(mod.slowdown_active, speed_added))
mod.slowdown -= actual_speed_added
mod.wearer.update_equipment_speed_mods()
else if(is_type_in_typecache(mod.wearer.loc, keep_turfs))
return
@@ -448,7 +451,7 @@
if(traveled_tiles <= 0)
return
if(traveled_tiles == max_traveled_tiles)
mod.slowdown += speed_added
mod.slowdown += actual_speed_added
mod.wearer.update_equipment_speed_mods()
traveled_tiles--
var/list/parts = mod.mod_parts + mod
@@ -481,7 +484,7 @@
. = ..()
if(!.)
return
playsound(src, 'sound/items/modsuit/ballin.ogg', 100)
playsound(src, 'sound/items/modsuit/ballin.ogg', 100, TRUE)
mod.wearer.add_filter("mod_ball", 1, alpha_mask_filter(icon = icon('icons/mob/clothing/modsuit/mod_modules.dmi', "ball_mask"), flags = MASK_INVERSE))
mod.wearer.add_filter("mod_blur", 2, angular_blur_filter(size = 15))
mod.wearer.add_filter("mod_outline", 3, outline_filter(color = "#000000AA"))
@@ -503,7 +506,7 @@
if(!.)
return
if(!deleting)
playsound(src, 'sound/items/modsuit/ballout.ogg', 100)
playsound(src, 'sound/items/modsuit/ballin.ogg', 100, TRUE, frequency = -1)
mod.wearer.base_pixel_y = 0
animate(mod.wearer, animate_time, pixel_y = mod.wearer.base_pixel_y)
addtimer(CALLBACK(mod.wearer, /atom.proc/remove_filter, list("mod_ball", "mod_blur", "mod_outline")), animate_time)
@@ -583,8 +586,6 @@
var/damage = 15
/// Damage multiplier on hostile fauna.
var/fauna_boost = 4
/// Damage multiplier on objects
var/object_boost = 2
/// Image overlaid on explosion.
var/static/image/explosion_image
@@ -609,5 +610,5 @@
for(var/mob/living/mob in range(1, src))
mob.apply_damage(12 * (ishostile(mob) ? fauna_boost : 1), BRUTE, spread_damage = TRUE)
for(var/obj/object in range(1, src))
object.take_damage(damage * object_boost, BRUTE, BOMB)
object.take_damage(damage, BRUTE, BOMB)
qdel(src)