mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-12 16:37:19 +01:00
Shielding Auras (#8760)
Ports Baystation12/Baystation12#19992 and Baystation12/Baystation12#27266. Added a personal shield device to the traitor tools uplink. Added a radiant shielding aura spell to Battlemage and Cleric. Added an exosuit shield drone to the mechfab. This works, but I'm not entirely happy with the sprites. The personal shield has no on-mob shimmer, it uses a mindbatterer grenade as an icon sprite. The wizard radiant spell uses a pretty big and janky sprite as an on-mob, and the exosuit's shield sprite doesn't follow the dir the mech faces, but that one I can maybe fix on my own. If anyone knows about that last one, lemme know, Bay had code for it that we do not.
This commit is contained in:
@@ -762,6 +762,9 @@
|
||||
#include "code\game\objects\items.dm"
|
||||
#include "code\game\objects\objs.dm"
|
||||
#include "code\game\objects\structures.dm"
|
||||
#include "code\game\objects\auras\auras.dm"
|
||||
#include "code\game\objects\auras\personal_shield.dm"
|
||||
#include "code\game\objects\auras\radiant_aura.dm"
|
||||
#include "code\game\objects\effects\aliens.dm"
|
||||
#include "code\game\objects\effects\bump_teleporter.dm"
|
||||
#include "code\game\objects\effects\effect_system.dm"
|
||||
@@ -840,6 +843,7 @@
|
||||
#include "code\game\objects\items\devices\multitool.dm"
|
||||
#include "code\game\objects\items\devices\oxycandle.dm"
|
||||
#include "code\game\objects\items\devices\paicard.dm"
|
||||
#include "code\game\objects\items\devices\personal_shield.dm"
|
||||
#include "code\game\objects\items\devices\pin_extractor.dm"
|
||||
#include "code\game\objects\items\devices\pipe_painter.dm"
|
||||
#include "code\game\objects\items\devices\powersink.dm"
|
||||
@@ -2642,6 +2646,7 @@
|
||||
#include "code\modules\spell_system\spells\spell_list\self\conjure\golem.dm"
|
||||
#include "code\modules\spell_system\spells\spell_list\self\conjure\grove.dm"
|
||||
#include "code\modules\spell_system\spells\spell_list\self\conjure\plant_sanctuary.dm"
|
||||
#include "code\modules\spell_system\spells\spell_list\self\conjure\radiant_aura.dm"
|
||||
#include "code\modules\spell_system\spells\spell_list\self\conjure\summon_carp.dm"
|
||||
#include "code\modules\spell_system\spells\spell_list\self\conjure\summon_demon_creature.dm"
|
||||
#include "code\modules\spell_system\spells\spell_list\self\conjure\summon_ed_swarm.dm"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define SCREEN_LAYER 22 //Mob HUD/effects layer
|
||||
#define CINEMA_LAYER 23
|
||||
|
||||
#define MECH_UNDER_LAYER 4
|
||||
#define MECH_BASE_LAYER 4.01
|
||||
#define MECH_INTERMEDIATE_LAYER 4.02
|
||||
#define MECH_PILOT_LAYER 4.03
|
||||
@@ -28,4 +29,5 @@
|
||||
#define MECH_COCKPIT_LAYER 4.05
|
||||
#define MECH_ARM_LAYER 4.06
|
||||
#define MECH_DECAL_LAYER 4.07
|
||||
#define MECH_GEAR_LAYER 4.08
|
||||
#define MECH_GEAR_LAYER 4.08
|
||||
#define MECH_ABOVE_LAYER 4.09
|
||||
@@ -344,4 +344,11 @@
|
||||
// Surgery Stuff
|
||||
#define SURGERY_SUCCESS 2 // Proceed with surgery
|
||||
#define SURGERY_FAIL 1 // Autofail surgery
|
||||
#define SURGERY_IGNORE 0 // Ignore surgery completely and just attack
|
||||
#define SURGERY_IGNORE 0 // Ignore surgery completely and just attack
|
||||
|
||||
#define AURA_CANCEL 1
|
||||
#define AURA_FALSE 2
|
||||
#define AURA_TYPE_BULLET "Bullet"
|
||||
#define AURA_TYPE_WEAPON "Weapon"
|
||||
#define AURA_TYPE_THROWN "Thrown"
|
||||
#define AURA_TYPE_LIFE "Life"
|
||||
@@ -91,6 +91,8 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.do_attack_animation(M)
|
||||
if(!user.aura_check(AURA_TYPE_WEAPON, src, user))
|
||||
return FALSE
|
||||
|
||||
var/hit_zone = M.resolve_item_attack(src, user, target_zone)
|
||||
if(hit_zone)
|
||||
|
||||
@@ -68,6 +68,12 @@
|
||||
item_cost = 6
|
||||
path = /obj/item/card/emag
|
||||
|
||||
/datum/uplink_item/item/tools/personal_shield
|
||||
name = "Personal Shield"
|
||||
desc = "A personal shield that, when kept in your hand and activated, will protect its user from five projectile shots."
|
||||
item_cost = 6
|
||||
path = /obj/item/device/personal_shield
|
||||
|
||||
/datum/uplink_item/item/tools/hacking_tool
|
||||
name = "Door Hacking Tool"
|
||||
item_cost = 6
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*Auras are simple: They are simple overriders for attackbys, bullet_act, damage procs, etc. They also tick after their respective mob.
|
||||
They should be used for undeterminate mob effects, like for instance a toggle-able forcefield, or indestructability as long as you don't move.
|
||||
They should also be used for when you want to effect the ENTIRE mob, like having an armor buff or showering candy everytime you walk.
|
||||
*/
|
||||
|
||||
/obj/aura
|
||||
var/mob/living/user
|
||||
|
||||
/obj/aura/Destroy()
|
||||
if(user)
|
||||
user.remove_aura(src)
|
||||
return ..()
|
||||
|
||||
/obj/aura/proc/added_to(var/mob/living/target)
|
||||
user = target
|
||||
user.add_aura(src)
|
||||
|
||||
/obj/aura/proc/removed()
|
||||
user = null
|
||||
|
||||
/obj/aura/proc/life_tick()
|
||||
return FALSE
|
||||
|
||||
/obj/aura/attackby(obj/item/I, mob/user)
|
||||
return FALSE
|
||||
|
||||
/obj/aura/bullet_act(obj/item/projectile/P, def_zone)
|
||||
return FALSE
|
||||
|
||||
/obj/aura/hitby(atom/movable/M, speed)
|
||||
return FALSE
|
||||
@@ -0,0 +1,34 @@
|
||||
/obj/aura/personal_shield
|
||||
name = "personal shield"
|
||||
|
||||
/obj/aura/personal_shield/added_to(mob/living/L)
|
||||
..()
|
||||
playsound(user, 'sound/weapons/flash.ogg', 35, 1)
|
||||
to_chat(user, SPAN_NOTICE("You feel your body prickle as \the [src] comes online."))
|
||||
|
||||
/obj/aura/personal_shield/bullet_act(obj/item/projectile/P, var/def_zone)
|
||||
user.visible_message(SPAN_WARNING("\The [user]'s [src.name] flashes before \the [P] can hit them!"))
|
||||
|
||||
flick("shield_impact", src)
|
||||
playsound(user, 'sound/effects/basscannon.ogg', 35, TRUE)
|
||||
return AURA_FALSE|AURA_CANCEL
|
||||
|
||||
/obj/aura/personal_shield/removed()
|
||||
to_chat(user, SPAN_WARNING("\The [src] goes offline!"))
|
||||
playsound(user, 'sound/mecha/internaldmgalarm.ogg', 25, TRUE)
|
||||
..()
|
||||
|
||||
/obj/aura/personal_shield/device
|
||||
var/obj/item/device/personal_shield/shield
|
||||
|
||||
/obj/aura/personal_shield/device/bullet_act()
|
||||
. = ..()
|
||||
if(shield)
|
||||
shield.take_charge()
|
||||
|
||||
/obj/aura/personal_shield/device/proc/set_shield(var/user_shield)
|
||||
shield = user_shield
|
||||
|
||||
/obj/aura/personal_shield/device/Destroy()
|
||||
shield = null
|
||||
return ..()
|
||||
@@ -0,0 +1,21 @@
|
||||
/obj/aura/radiant_aura
|
||||
name = "radiant aura"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "at_shield1"
|
||||
alpha = 75
|
||||
layer = ABOVE_MOB_LAYER
|
||||
|
||||
/obj/aura/radiant_aura/added_to(mob/living/user)
|
||||
..()
|
||||
to_chat(user, SPAN_NOTICE("A bubble of light appears around you, exuding protection and warmth."))
|
||||
set_light(6, 6, COLOR_AMBER)
|
||||
|
||||
/obj/aura/radiant_aura/Destroy()
|
||||
to_chat(user, SPAN_WARNING("Your protective aura dissipates, leaving you feeling cold and unsafe."))
|
||||
return ..()
|
||||
|
||||
/obj/aura/radiant_aura/bullet_act(obj/item/projectile/P, var/def_zone)
|
||||
if(P.check_armour == LASER)
|
||||
user.visible_message(SPAN_WARNING("\The [P] refracts, bending into \the [user]'s aura."))
|
||||
return AURA_FALSE
|
||||
return FALSE
|
||||
@@ -0,0 +1,64 @@
|
||||
/obj/item/device/personal_shield
|
||||
name = "personal shield"
|
||||
desc = "Truely a life-saver: this device protects its user from being hit by objects moving very, very fast, though only for a few shots."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "batterer"
|
||||
var/next_recharge
|
||||
var/uses = 5
|
||||
var/obj/aura/personal_shield/device/shield
|
||||
|
||||
/obj/item/device/personal_shield/examine(mob/user, distance)
|
||||
..()
|
||||
if(Adjacent(user))
|
||||
to_chat(user, SPAN_NOTICE("\The [src] can absorb [uses] more shot\s."))
|
||||
|
||||
/obj/item/device/personal_shield/Initialize()
|
||||
. = ..()
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/obj/item/device/personal_shield/process()
|
||||
if(next_recharge < world.time)
|
||||
uses = min(5, uses + 1)
|
||||
if(uses == 1)
|
||||
update_icon()
|
||||
next_recharge = world.time + 1 MINUTE
|
||||
|
||||
/obj/item/device/personal_shield/attack_self(mob/living/user)
|
||||
if(uses && !shield)
|
||||
shield = new /obj/aura/personal_shield/device(user)
|
||||
shield.added_to(user)
|
||||
shield.set_shield(src)
|
||||
else
|
||||
dissipate()
|
||||
|
||||
/obj/item/device/personal_shield/Move()
|
||||
dissipate()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/personal_shield/forceMove()
|
||||
dissipate()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/personal_shield/proc/take_charge()
|
||||
uses--
|
||||
if(!uses)
|
||||
to_chat(shield.user, FONT_LARGE(SPAN_WARNING("\The [src] begins to spark as it breaks!")))
|
||||
QDEL_NULL(shield)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/device/personal_shield/update_icon()
|
||||
if(uses)
|
||||
icon_state = "batterer"
|
||||
else
|
||||
icon_state = "battererburnt"
|
||||
|
||||
/obj/item/device/personal_shield/Destroy()
|
||||
dissipate()
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/personal_shield/proc/dissipate()
|
||||
if(shield?.user)
|
||||
to_chat(shield.user, FONT_LARGE(SPAN_WARNING("\The [src] fades around you, dissipating.")))
|
||||
QDEL_NULL(shield)
|
||||
@@ -287,3 +287,157 @@
|
||||
if(istype(C))
|
||||
return C.charge/C.maxcharge
|
||||
return null
|
||||
|
||||
/obj/item/mecha_equipment/shield
|
||||
name = "exosuit shield droid"
|
||||
desc = "The Hephaestus Armature system is a well liked energy deflector system designed to stop any projectile before it has a chance to become a threat."
|
||||
icon_state = "shield_droid"
|
||||
var/obj/aura/mechshield/aura
|
||||
var/max_charge = 150
|
||||
var/charge = 150
|
||||
var/last_recharge = 0
|
||||
var/charging_rate = 7500 * CELLRATE
|
||||
var/cooldown = 3.5 SECONDS // Time until we can recharge again after a blocked impact
|
||||
restricted_hardpoints = list(HARDPOINT_BACK)
|
||||
restricted_software = list(MECH_SOFTWARE_WEAPONS)
|
||||
|
||||
/obj/item/mecha_equipment/shield/installed(mob/living/heavy_vehicle/_owner)
|
||||
. = ..()
|
||||
aura = new /obj/aura/mechshield(_owner)
|
||||
aura.added_to(_owner)
|
||||
aura.set_holder(src)
|
||||
|
||||
/obj/item/mecha_equipment/shield/uninstalled()
|
||||
QDEL_NULL(aura)
|
||||
. = ..()
|
||||
|
||||
/obj/item/mecha_equipment/shield/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
toggle()
|
||||
|
||||
/obj/item/mecha_equipment/shield/proc/stop_damage(var/damage)
|
||||
var/difference = damage - charge
|
||||
charge = Clamp(charge - damage, 0, max_charge)
|
||||
|
||||
last_recharge = world.time
|
||||
|
||||
if(difference > 0)
|
||||
for(var/mob/pilot in owner.pilots)
|
||||
to_chat(pilot, FONT_LARGE(SPAN_WARNING("Warning: Deflector shield failure detected, shutting down.")))
|
||||
toggle()
|
||||
playsound(get_turf(owner),'sound/mecha/internaldmgalarm.ogg', 35, TRUE)
|
||||
return difference
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_equipment/shield/proc/toggle()
|
||||
if(!aura)
|
||||
return
|
||||
aura.toggle()
|
||||
aura.dir = owner.dir
|
||||
if(aura.dir == NORTH)
|
||||
aura.layer = MECH_UNDER_LAYER
|
||||
else
|
||||
aura.layer = ABOVE_MOB_LAYER
|
||||
playsound(owner,'sound/weapons/flash.ogg', 35, TRUE)
|
||||
update_icon()
|
||||
if(aura.active)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
else
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
owner.update_icon()
|
||||
|
||||
/obj/item/mecha_equipment/shield/update_icon()
|
||||
. = ..()
|
||||
if(!aura)
|
||||
return
|
||||
if(aura.active)
|
||||
icon_state = "shield_droid_a"
|
||||
else
|
||||
icon_state = "shield_droid"
|
||||
|
||||
/obj/item/mecha_equipment/shield/process()
|
||||
if(charge >= max_charge)
|
||||
return
|
||||
if((world.time - last_recharge) < cooldown)
|
||||
return
|
||||
var/obj/item/cell/cell = owner.get_cell()
|
||||
|
||||
var/actual_required_power = Clamp(max_charge - charge, 0, charging_rate)
|
||||
charge += cell.use(actual_required_power)
|
||||
|
||||
/obj/item/mecha_equipment/shield/get_hardpoint_status_value()
|
||||
return charge / max_charge
|
||||
|
||||
/obj/item/mecha_equipment/shield/get_hardpoint_maptext()
|
||||
return "[(aura && aura.active) ? "ONLINE" : "OFFLINE"]: [round((charge / max_charge) * 100)]%"
|
||||
|
||||
/obj/aura/mechshield
|
||||
icon = 'icons/mecha/shield.dmi'
|
||||
name = "mechshield"
|
||||
var/obj/item/mecha_equipment/shield/shields
|
||||
var/active = FALSE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
pixel_x = 8
|
||||
pixel_y = 4
|
||||
mouse_opacity = 0
|
||||
|
||||
/obj/aura/mechshield/added_to(mob/living/target)
|
||||
..()
|
||||
target.vis_contents += src
|
||||
dir = target.dir
|
||||
|
||||
/obj/aura/mechshield/proc/set_holder(var/obj/item/mecha_equipment/shield/holder)
|
||||
shields = holder
|
||||
|
||||
/obj/aura/mechshield/Destroy()
|
||||
if(user)
|
||||
user.vis_contents -= src
|
||||
shields = null
|
||||
. = ..()
|
||||
|
||||
/obj/aura/mechshield/proc/toggle()
|
||||
active = !active
|
||||
|
||||
update_icon()
|
||||
|
||||
if(active)
|
||||
flick("shield_raise", src)
|
||||
else
|
||||
flick("shield_drop", src)
|
||||
|
||||
|
||||
/obj/aura/mechshield/update_icon()
|
||||
. = ..()
|
||||
if(active)
|
||||
icon_state = "shield"
|
||||
else
|
||||
icon_state = "shield_null"
|
||||
|
||||
/obj/aura/mechshield/bullet_act(obj/item/projectile/P, var/def_zone)
|
||||
if(!active)
|
||||
return
|
||||
if(shields?.charge)
|
||||
P.damage = shields.stop_damage(P.damage)
|
||||
user.visible_message(SPAN_WARNING("\The [shields.owner]'s shields flash and crackle."))
|
||||
flick("shield_impact", src)
|
||||
playsound(user, 'sound/effects/basscannon.ogg', 35, TRUE)
|
||||
//light up the night.
|
||||
new /obj/effect/effect/smoke/illumination(get_turf(src), 5, 4, 1, "#ffffff")
|
||||
if(P.damage <= 0)
|
||||
return AURA_FALSE|AURA_CANCEL
|
||||
|
||||
spark(get_turf(src), 5, global.alldirs)
|
||||
playsound(get_turf(src), "sparks", 25, TRUE)
|
||||
|
||||
/obj/aura/mechshield/hitby(atom/movable/M, var/speed)
|
||||
. = ..()
|
||||
if(!active)
|
||||
return
|
||||
if(shields.charge && speed <= 5)
|
||||
user.visible_message(SPAN_WARNING("\The [shields.owner]'s shields flash briefly as they deflect \the [M]."))
|
||||
flick("shield_impact", src)
|
||||
playsound(user, 'sound/effects/basscannon.ogg', 10, TRUE)
|
||||
return AURA_FALSE|AURA_CANCEL
|
||||
//Too fast!
|
||||
@@ -307,6 +307,14 @@
|
||||
playsound(src.loc,legs.mech_turn_sound,40,1)
|
||||
next_move = world.time + legs.turn_delay
|
||||
set_dir(direction)
|
||||
if(istype(hardpoints[HARDPOINT_BACK], /obj/item/mecha_equipment/shield))
|
||||
var/obj/item/mecha_equipment/shield/S = hardpoints[HARDPOINT_BACK]
|
||||
if(S.aura)
|
||||
S.aura.dir = direction
|
||||
if(S.aura.dir == NORTH)
|
||||
S.aura.layer = MECH_UNDER_LAYER
|
||||
else
|
||||
S.aura.layer = ABOVE_MOB_LAYER
|
||||
update_icon()
|
||||
|
||||
/mob/living/heavy_vehicle/Move()
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/mob/living/exosuit
|
||||
movement_handlers = list(
|
||||
/datum/movement_handler/mob/space/exosuit,
|
||||
/datum/movement_handler/mob/exosuit
|
||||
)
|
||||
|
||||
/mob/living/exosuit/Move()
|
||||
. = ..()
|
||||
if(. && !istype(loc, /turf/space) && legs.mech_step_sound)
|
||||
playsound(src.loc, mech_step_sound, 40, 1)
|
||||
|
||||
//Override this and space move once a way to travel vertically is in
|
||||
///mob/living/exosuit/can_ztravel()
|
||||
// if(Allow_Spacemove()) //Handle here
|
||||
// return 1
|
||||
|
||||
// for(var/turf/simulated/T in trange(1,src))
|
||||
// if(T.density)
|
||||
// return 1
|
||||
|
||||
|
||||
/mob/living/exosuit/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = src.loc)
|
||||
//mechs are always anchored, so falling should always ignore it
|
||||
if(..(TRUE, location_override))
|
||||
return !(can_overcome_gravity())
|
||||
|
||||
|
||||
/datum/movement_handler/mob/exosuit
|
||||
expected_host_type = /mob/living/exosuit
|
||||
var/next_move
|
||||
|
||||
/datum/movement_handler/mob/exosuit/MayMove(var/mob/mover, var/is_external)
|
||||
var/mob/living/exosuit/exosuit = host
|
||||
if(world.time < next_move)
|
||||
return MOVEMENT_STOP
|
||||
if((!(mover in exosuit.pilots) && mover != exosuit) || exosuit.incapacitated() || mover.incapacitated())
|
||||
return MOVEMENT_STOP
|
||||
if(!exosuit.legs)
|
||||
to_chat(mover, "<span class='warning'>\The [exosuit] has no means of propulsion!</span>")
|
||||
next_move = world.time + 3 // Just to stop them from getting spammed with messages.
|
||||
return MOVEMENT_STOP
|
||||
if(!exosuit.legs.motivator || !exosuit.legs.motivator.is_functional())
|
||||
to_chat(mover, "<span class='warning'>Your motivators are damaged! You can't move!</span>")
|
||||
next_move = world.time + 15
|
||||
return MOVEMENT_STOP
|
||||
if(exosuit.maintenance_protocols)
|
||||
to_chat(mover, "<span class='warning'>Maintenance protocols are in effect.</span>")
|
||||
next_move = world.time + 3 // Just to stop them from getting spammed with messages.
|
||||
return MOVEMENT_STOP
|
||||
if(exosuit.lockdown)
|
||||
to_chat(mover, span("warning", "You cannot move while the exosuit's lockdown mode is active."))
|
||||
next_move = world.time + 3 // Just to stop them from getting spammed with messages.
|
||||
return MOVEMENT_STOP
|
||||
var/obj/item/cell/C = exosuit.get_cell()
|
||||
if(!C || !C.check_charge(exosuit.legs.power_use * CELLRATE))
|
||||
to_chat(mover, "<span class='warning'>The power indicator flashes briefly.</span>")
|
||||
next_move = world.time + 3 //On fast exosuits this got annoying fast
|
||||
return MOVEMENT_STOP
|
||||
|
||||
next_move = world.time + (exosuit.legs ? exosuit.legs.move_delay : 3)
|
||||
return MOVEMENT_PROCEED
|
||||
|
||||
/datum/movement_handler/mob/exosuit/DoMove(var/direction, var/mob/mover, var/is_external)
|
||||
var/mob/living/exosuit/exosuit = host
|
||||
var/moving_dir = direction
|
||||
|
||||
var/failed = FALSE
|
||||
if(exosuit.emp_damage >= EMP_MOVE_DISRUPT && prob(30))
|
||||
failed = TRUE
|
||||
if(failed)
|
||||
moving_dir = pick(cardinal - exosuit.dir)
|
||||
|
||||
exosuit.get_cell().use(exosuit.legs.power_use * CELLRATE)
|
||||
if(exosuit.dir != moving_dir)
|
||||
playsound(exosuit.loc, exosuit.mech_turn_sound, 40,1)
|
||||
exosuit.set_dir(moving_dir)
|
||||
next_move = world.time + exosuit.legs.turn_delay
|
||||
else
|
||||
var/turf/target_loc = get_step(exosuit, direction)
|
||||
if(target_loc && exosuit.legs && exosuit.legs.can_move_on(exosuit.loc, target_loc) && exosuit.MayEnterTurf(target_loc))
|
||||
exosuit.Move(target_loc)
|
||||
return MOVEMENT_HANDLED
|
||||
|
||||
|
||||
/datum/movement_handler/mob/space/exosuit
|
||||
expected_host_type = /mob/living/exosuit
|
||||
|
||||
// Space movement
|
||||
/datum/movement_handler/mob/space/exosuit/DoMove(var/direction, var/mob/mover)
|
||||
|
||||
if(!mob.check_solid_ground())
|
||||
mob.anchored = FALSE
|
||||
var/allowmove = mob.Allow_Spacemove(0)
|
||||
if(!allowmove)
|
||||
return MOVEMENT_HANDLED
|
||||
else if(allowmove == -1 && mob.handle_spaceslipping()) //Check to see if we slipped
|
||||
return MOVEMENT_HANDLED
|
||||
else
|
||||
mob.inertia_dir = 0 //If not then we can reset inertia and move
|
||||
else mob.anchored = TRUE
|
||||
|
||||
/datum/movement_handler/mob/space/exosuit/MayMove(var/mob/mover, var/is_external)
|
||||
if((mover != host) && is_external)
|
||||
return MOVEMENT_PROCEED
|
||||
|
||||
if(!mob.check_solid_ground())
|
||||
if(!mob.Allow_Spacemove(0))
|
||||
return MOVEMENT_STOP
|
||||
return MOVEMENT_PROCEED
|
||||
|
||||
/mob/living/exosuit/lost_in_space()
|
||||
for(var/atom/movable/AM in contents)
|
||||
if(!AM.lost_in_space())
|
||||
return FALSE
|
||||
return !pilots.len
|
||||
|
||||
/mob/living/exosuit/fall_damage()
|
||||
return 100 //Exosuits are big and heavy
|
||||
|
||||
/mob/living/exosuit/handle_fall_effect(var/turf/landing)
|
||||
// Return here if for any reason you shouldnt take damage
|
||||
..()
|
||||
var/damage = 30 //Enough to cause a malfunction if unlucky
|
||||
apply_damage(rand(0, damage), BRUTE, BP_R_LEG) //Any leg is good, will damage both
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
h_l_hand = /obj/item/mecha_equipment/mounted_system/taser/laser
|
||||
h_r_hand = /obj/item/mecha_equipment/mounted_system/taser/ion
|
||||
h_back = /obj/item/mecha_equipment/shield
|
||||
|
||||
/obj/item/mech_component/manipulators/heavy
|
||||
name = "heavy arms"
|
||||
|
||||
@@ -149,6 +149,11 @@ There are several things that need to be remembered:
|
||||
if(species.has_floating_eyes)
|
||||
ovr += species.get_eyes(src)
|
||||
|
||||
for(var/aura in auras)
|
||||
var/obj/aura/A = aura
|
||||
var/icon/aura_overlay = icon(A.icon, icon_state = A.icon_state)
|
||||
ovr += aura_overlay
|
||||
|
||||
add_overlay(ovr)
|
||||
|
||||
if (lying_prev != lying || size_multiplier != 1)
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
//Random events (vomiting etc)
|
||||
handle_random_events()
|
||||
|
||||
aura_check(AURA_TYPE_LIFE)
|
||||
|
||||
. = 1
|
||||
|
||||
//Handle temperature/pressure differences between body and environment
|
||||
|
||||
@@ -906,3 +906,25 @@ default behaviour is:
|
||||
Paralyse(rand(8,16))
|
||||
make_jittery(rand(150,200))
|
||||
adjustHalLoss(rand(50,60))
|
||||
|
||||
/mob/living/update_icons()
|
||||
for(var/aura in auras)
|
||||
var/obj/aura/A = aura
|
||||
var/icon/aura_overlay = icon(A.icon, icon_state = A.icon_state)
|
||||
add_overlay(aura_overlay)
|
||||
|
||||
/mob/living/proc/add_aura(var/obj/aura/aura)
|
||||
LAZYDISTINCTADD(auras, aura)
|
||||
update_icons()
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/remove_aura(var/obj/aura/aura)
|
||||
LAZYREMOVE(auras, aura)
|
||||
update_icons()
|
||||
return TRUE
|
||||
|
||||
/mob/living/Destroy()
|
||||
if(auras)
|
||||
for(var/a in auras)
|
||||
remove_aura(a)
|
||||
return ..()
|
||||
@@ -100,6 +100,28 @@
|
||||
P.on_hit(src, absorb, def_zone)
|
||||
return absorb
|
||||
|
||||
/mob/living/proc/aura_check(var/type)
|
||||
if(!auras)
|
||||
return TRUE
|
||||
. = TRUE
|
||||
var/list/newargs = args - args[1]
|
||||
for(var/a in auras)
|
||||
var/obj/aura/aura = a
|
||||
var/result = 0
|
||||
switch(type)
|
||||
if(AURA_TYPE_WEAPON)
|
||||
result = aura.attackby(arglist(newargs))
|
||||
if(AURA_TYPE_BULLET)
|
||||
result = aura.bullet_act(arglist(newargs))
|
||||
if(AURA_TYPE_THROWN)
|
||||
result = aura.hitby(arglist(newargs))
|
||||
if(AURA_TYPE_LIFE)
|
||||
result = aura.life_tick()
|
||||
if(result & AURA_FALSE)
|
||||
. = FALSE
|
||||
if(result & AURA_CANCEL)
|
||||
break
|
||||
|
||||
//For visuals, blood splatters and so on.
|
||||
/mob/living/proc/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage)
|
||||
var/list/impact_sounds = LAZYACCESS(P.impact_sounds, get_bullet_impact_effect_type(def_zone))
|
||||
@@ -170,6 +192,8 @@
|
||||
|
||||
//this proc handles being hit by a thrown atom
|
||||
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve
|
||||
if(!aura_check(AURA_TYPE_THROWN, AM, speed))
|
||||
return
|
||||
if(istype(AM,/obj/))
|
||||
var/obj/O = AM
|
||||
var/dtype = O.damtype
|
||||
|
||||
@@ -69,4 +69,5 @@
|
||||
var/burn_mod = 1
|
||||
var/brute_mod = 1
|
||||
|
||||
var/limb_breaking = FALSE // used to limit people from queuing up limb-breaks
|
||||
var/limb_breaking = FALSE // used to limit people from queuing up limb-breaks
|
||||
var/list/obj/aura/auras //Basically a catch-all aura/force-field thing.
|
||||
@@ -174,6 +174,8 @@
|
||||
var/result = PROJECTILE_FORCE_MISS
|
||||
if(hit_zone)
|
||||
def_zone = hit_zone //set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part
|
||||
if(!target_mob.aura_check(AURA_TYPE_BULLET, src, def_zone))
|
||||
return TRUE
|
||||
result = target_mob.bullet_act(src, def_zone)
|
||||
|
||||
if(result == PROJECTILE_FORCE_MISS && (can_miss == 0)) //if you're shooting at point blank you can't miss.
|
||||
|
||||
@@ -267,4 +267,11 @@
|
||||
/datum/design/item/mechfab/exosuit/passenger_compartment
|
||||
name = "Mounted Passenger Compartment"
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 10000)
|
||||
build_path = /obj/item/mecha_equipment/sleeper/passenger_compartment
|
||||
build_path = /obj/item/mecha_equipment/sleeper/passenger_compartment
|
||||
|
||||
/datum/design/item/mechfab/exosuit/mechshields
|
||||
name = "Energy Shield Drone"
|
||||
time = 90
|
||||
materials = list(MATERIAL_STEEL = 20000, MATERIAL_SILVER = 12000, MATERIAL_GOLD = 12000)
|
||||
req_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 4, TECH_POWER = 4, TECH_COMBAT = 2)
|
||||
build_path = /obj/item/mecha_equipment/shield
|
||||
@@ -22,6 +22,7 @@
|
||||
/spell/aoe_turf/conjure/mirage = 1,
|
||||
/spell/targeted/shapeshift/corrupt_form = 1,
|
||||
/spell/targeted/flesh_to_stone = 1,
|
||||
/spell/radiant_aura = 1,
|
||||
/spell/noclothes = 1,
|
||||
/obj/structure/closet/wizard/armor = 1,
|
||||
/obj/item/gun/energy/staff/focus = 1,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
/spell/aoe_turf/knock = 1,
|
||||
/spell/targeted/equip_item/holy_relic = 1,
|
||||
/spell/aoe_turf/conjure/grove/sanctuary = 1,
|
||||
/spell/radiant_aura = 1,
|
||||
/spell/targeted/projectile/dumbfire/fireball = 2,
|
||||
/spell/aoe_turf/conjure/forcewall = 1,
|
||||
/spell/targeted/subjugation = 1,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/spell/radiant_aura
|
||||
name = "Radiant Aura"
|
||||
desc = "Form a protective layer of light around you, making you immune to laser fire."
|
||||
school = "transmutation"
|
||||
feedback = "ra"
|
||||
invocation_type = SpI_EMOTE
|
||||
invocation = "conjures a sphere of fire around themselves."
|
||||
school = "conjuration"
|
||||
spell_flags = NEEDSCLOTHES
|
||||
charge_max = 300
|
||||
cooldown_min = 200
|
||||
level_max = list(Sp_TOTAL = 2, Sp_SPEED = 2, Sp_POWER = 0)
|
||||
cast_sound = 'sound/effects/snap.ogg'
|
||||
duration = 250
|
||||
hud_state = "gen_immolate"
|
||||
|
||||
/spell/radiant_aura/choose_targets()
|
||||
return list(holder)
|
||||
|
||||
/spell/radiant_aura/cast(var/list/targets, mob/user)
|
||||
var/obj/aura/radiant_aura/A = new /obj/aura/radiant_aura(user)
|
||||
A.added_to(user)
|
||||
QDEL_IN(A, duration)
|
||||
|
||||
/spell/radiant_aura/starlight
|
||||
spell_flags = 0
|
||||
charge_max = 400
|
||||
@@ -0,0 +1,8 @@
|
||||
author: Geeves
|
||||
|
||||
delete-after: True
|
||||
|
||||
changes:
|
||||
- rscadd: "Added a personal shield device to the traitor tools uplink."
|
||||
- rscadd: "Added a radiant shielding aura spell to Battlemage and Cleric."
|
||||
- rscadd: "Added an exosuit shield drone to the mechfab."
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 18 KiB |
Reference in New Issue
Block a user