* Shield time
Adds a shield for clockies which empowers bashes via the damage it blocks. Might or might not compile yet. Icons going to be added in the next commit because I'd rather not have to revert all instead of just the icons if I do a fucky
* Icon time
Adds the icons for the clockie shield. Just the implementation + icons as of now, no way to get it. Might still not compile 😳
* Compilation issue resolution
Now it compiles. So it works. Maybe.
* Little change
Only harm-intent bashes amplify the bash / use energy.
* Fixes up shield.dms repeair proc and moves the brass shield repair there
Oh cool time to throw in a fix aswell, neat!
* Some tweaks
Buffs the shields armor and integrity since it was VERY easy to break with energy before, now its medium against those and very strong against ballistics. also a bit easier to accumulate charge because its ''only'' 50% block
* Some more stuff for the shield
Adds a spell to summon the shield (20dc time, 600kw cost, tier-two spell)
aswell as adding some ''fun'' for non-clockie users of the shield.
* typo man bad
* more spellchecking
* even more little tweaks
* clarification on a comment
* sound tweak
only plays a special sound if its an empowered bash
* final tweakies before PR
* Abuse safeguard
Yeeah might be best to not allow clockies to bash eachother for infinite charge.
* another typo fix
I really shouldn't have been coding stuff for this at 5 am...
* Safeguards for a VERY specific edge case
Would have caused some weird behavious for edge cases if not resetting the values, so I'm doing it to be sure.
* 5am code bad
same thing like the previous commit but not unreachable because of return statements.
* Applying requested changes / suggestions proposed by Ghommie
Early return statement done by the harmful / servant check, other returns / simillar done via . = ..()
* Formatting
456 lines
19 KiB
Plaintext
456 lines
19 KiB
Plaintext
/obj/item/shield
|
|
name = "shield"
|
|
icon = 'icons/obj/shields.dmi'
|
|
block_chance = 50
|
|
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
|
|
/// Shield flags
|
|
var/shield_flags = SHIELD_FLAGS_DEFAULT
|
|
/// Last shieldbash world.time
|
|
var/last_shieldbash = 0
|
|
/// Shieldbashing cooldown
|
|
var/shieldbash_cooldown = 5 SECONDS
|
|
/// Shieldbashing stamina cost
|
|
var/shieldbash_stamcost = 7.5
|
|
/// Shieldbashing knockback
|
|
var/shieldbash_knockback = 2
|
|
/// Shield bashing brute damage
|
|
var/shieldbash_brutedamage = 5
|
|
/// Shield bashing stamina damage
|
|
var/shieldbash_stamdmg = 15
|
|
/// Shield bashing stagger duration
|
|
var/shieldbash_stagger_duration = 3.5 SECONDS
|
|
/// Shield bashing push distance
|
|
var/shieldbash_push_distance = 1
|
|
|
|
/obj/item/shield/examine(mob/user)
|
|
. = ..()
|
|
if(shield_flags & SHIELD_CAN_BASH)
|
|
. += "<span class='notice'>Right click on combat mode attack with [src] to shield bash!</span>"
|
|
if(shield_flags & SHIELD_BASH_GROUND_SLAM)
|
|
. += "<span class='notice'>Directly rightclicking on a downed target with [src] will slam them instead of bashing.</span>"
|
|
|
|
/obj/item/shield/proc/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance)
|
|
return TRUE
|
|
|
|
/obj/item/shield/alt_pre_attack(atom/A, mob/living/user, params)
|
|
user_shieldbash(user, A, user.a_intent == INTENT_HARM)
|
|
return TRUE
|
|
|
|
/obj/item/shield/altafterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
|
user_shieldbash(user, target, user.a_intent == INTENT_HARM)
|
|
return TRUE
|
|
|
|
/obj/item/shield/proc/do_shieldbash_effect(mob/living/user, dir, harmful)
|
|
var/px = 0
|
|
var/py = 0
|
|
switch(dir)
|
|
if(NORTH)
|
|
py = 12
|
|
if(SOUTH)
|
|
py = -12
|
|
if(EAST)
|
|
px = 12
|
|
if(WEST)
|
|
px = -12
|
|
var/obj/effect/temp_visual/dir_setting/shield_bash/effect = new(user.loc, dir)
|
|
effect.pixel_x = user.pixel_x - 32 //96x96 effect, -32.
|
|
effect.pixel_y = user.pixel_y - 32
|
|
user.visible_message("<span class='warning'>[user] [harmful? "charges forwards with" : "sweeps"] [src]!</span>")
|
|
animate(user, pixel_x = px, pixel_y = py, time = 3, easing = SINE_EASING | EASE_OUT, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE)
|
|
animate(user, pixel_x = -px, pixel_y = -py, time = 3, flags = ANIMATION_RELATIVE)
|
|
animate(effect, alpha = 0, pixel_x = px * 1.5, pixel_y = py * 1.5, time = 3, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE)
|
|
|
|
/obj/item/shield/proc/bash_target(mob/living/user, mob/living/target, bashdir, harmful)
|
|
if(!(target.status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)) // should probably add stun absorption check at some point I guess..
|
|
// unified stun absorption system when lol
|
|
target.visible_message("<span class='warning'>[user] slams [target] with [src], but [target] doesn't falter!</span>", "<span class='userdanger'>[user] slams you with [src], but it barely fazes you!</span>")
|
|
return FALSE
|
|
var/target_downed = !CHECK_MOBILITY(target, MOBILITY_STAND)
|
|
var/wallhit = FALSE
|
|
var/turf/target_current_turf = get_turf(target)
|
|
if(harmful)
|
|
target.visible_message("<span class='warning'>[target_downed? "[user] slams [src] into [target]" : "[user] bashes [target] with [src]"]!</span>",
|
|
"<span class='warning'>[target_downed? "[user] slams [src] into you" : "[user] bashes you with [src]"]!</span>")
|
|
else
|
|
target.visible_message("<span class='warning'>[user] shoves [target] with [src]!</span>",
|
|
"<span class='warning'>[user] shoves you with [src]!</span>")
|
|
for(var/i in 1 to harmful? shieldbash_knockback : shieldbash_push_distance)
|
|
var/turf/new_turf = get_step(target, bashdir)
|
|
var/mob/living/carbon/human/H = locate() in (new_turf.contents - target)
|
|
if(H && harmful)
|
|
H.visible_message("<span class='warning'>[target] is sent crashing into [H]!</span>",
|
|
"<span class='userdanger'>[target] is sent crashing into you!</span>")
|
|
H.KnockToFloor()
|
|
wallhit = TRUE
|
|
break
|
|
else
|
|
step(target, bashdir)
|
|
if(get_turf(target) == target_current_turf)
|
|
wallhit = TRUE
|
|
break
|
|
else
|
|
target_current_turf = get_turf(target)
|
|
var/disarming = (target_downed && (shield_flags & SHIELD_BASH_GROUND_SLAM_DISARM)) || (shield_flags & SHIELD_BASH_ALWAYS_DISARM) || (wallhit && (shield_flags & SHIELD_BASH_WALL_DISARM))
|
|
var/knockdown = !target_downed && ((shield_flags & SHIELD_BASH_ALWAYS_KNOCKDOWN) || (wallhit && (shield_flags & SHIELD_BASH_WALL_KNOCKDOWN)))
|
|
if(shieldbash_stagger_duration || knockdown)
|
|
target.visible_message("<span class='warning'>[target] is knocked [knockdown? "to the floor" : "off balanace"]!</span>",
|
|
"<span class='userdanger'>You are knocked [knockdown? "to the floor" : "off balanace"]!</span>")
|
|
if(knockdown)
|
|
target.KnockToFloor(disarming)
|
|
else if(disarming)
|
|
target.drop_all_held_items()
|
|
|
|
if(harmful)
|
|
target.apply_damage(shieldbash_stamdmg, STAMINA, BODY_ZONE_CHEST)
|
|
target.apply_damage(shieldbash_brutedamage, BRUTE, BODY_ZONE_CHEST)
|
|
target.Stagger(shieldbash_stagger_duration)
|
|
return TRUE
|
|
|
|
/obj/item/shield/proc/user_shieldbash(mob/living/user, atom/target, harmful)
|
|
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //Combat mode has to be enabled for shield bashing
|
|
return FALSE
|
|
if(!(shield_flags & SHIELD_CAN_BASH))
|
|
to_chat(user, "<span class='warning'>[src] can't be used to shield bash!</span>")
|
|
return FALSE
|
|
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
|
to_chat(user, "<span class='warning'>You can't bash with [src] while on the ground!</span>")
|
|
return FALSE
|
|
if(world.time < last_shieldbash + shieldbash_cooldown)
|
|
to_chat(user, "<span class='warning'>You can't bash with [src] again so soon!</span>")
|
|
return FALSE
|
|
var/mob/living/livingtarget = target //only access after an isliving check!
|
|
if(isliving(target) && !CHECK_MOBILITY(livingtarget, MOBILITY_STAND)) //GROUND SLAAAM
|
|
if(!(shield_flags & SHIELD_BASH_GROUND_SLAM))
|
|
to_chat(user, "<span class='warning'>You can't ground slam with [src]!</span>")
|
|
return FALSE
|
|
bash_target(user, target, NONE, harmful)
|
|
user.do_attack_animation(target, used_item = src)
|
|
playsound(src, harmful? "swing_hit" : 'sound/weapons/thudswoosh.ogg', 75, 1)
|
|
last_shieldbash = world.time
|
|
user.adjustStaminaLossBuffered(shieldbash_stamcost)
|
|
return TRUE
|
|
// Directional sweep!
|
|
last_shieldbash = world.time
|
|
user.adjustStaminaLossBuffered(shieldbash_stamcost)
|
|
// Since we are in combat mode, we can probably safely use the user's dir instead of getting their mouse pointing cardinal dir.
|
|
var/bashdir = user.dir
|
|
do_shieldbash_effect(user, bashdir, harmful)
|
|
var/list/checking = list(get_step(user, user.dir), get_step(user, turn(user.dir, 45)), get_step(user, turn(user.dir, -45)))
|
|
var/list/victims = list()
|
|
for(var/i in checking)
|
|
var/turf/T = i
|
|
for(var/mob/living/L in T.contents)
|
|
victims += L
|
|
if(length(victims))
|
|
for(var/i in victims)
|
|
bash_target(user, i, bashdir, harmful)
|
|
playsound(src, harmful? "swing_hit" : 'sound/weapons/thudswoosh.ogg', 75, 1)
|
|
else
|
|
playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1)
|
|
return length(victims)
|
|
|
|
/obj/effect/temp_visual/dir_setting/shield_bash
|
|
icon = 'icons/effects/96x96_attack_sweep.dmi'
|
|
icon_state = "shield_bash"
|
|
duration = 3
|
|
|
|
/obj/item/shield/riot
|
|
name = "riot shield"
|
|
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
|
|
icon_state = "riot"
|
|
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
|
slot_flags = ITEM_SLOT_BACK
|
|
force = 10
|
|
throwforce = 5
|
|
throw_speed = 2
|
|
throw_range = 3
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
custom_materials = list(/datum/material/glass=7500, /datum/material/iron=1000)
|
|
attack_verb = list("shoved", "bashed")
|
|
var/cooldown = 0 //shield bash cooldown. based on world.time
|
|
var/repair_material = /obj/item/stack/sheet/mineral/titanium
|
|
var/can_shatter = TRUE
|
|
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_TRANSPARENT
|
|
max_integrity = 75
|
|
|
|
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
|
if(ismovable(object))
|
|
var/atom/movable/AM = object
|
|
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
|
return BLOCK_NONE
|
|
if(attack_type & ATTACK_TYPE_THROWN)
|
|
final_block_chance += 30
|
|
if(attack_type & ATTACK_TYPE_TACKLE)
|
|
final_block_chance = 100
|
|
. = ..()
|
|
if(. & BLOCK_SUCCESS)
|
|
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
|
|
|
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
|
|
if(istype(W, /obj/item/melee/baton))
|
|
if(cooldown < world.time - 25)
|
|
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
|
|
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
|
|
cooldown = world.time
|
|
else if(istype(W, repair_material))
|
|
if(obj_integrity >= max_integrity)
|
|
to_chat(user, "<span class='warning'>[src] is already in perfect condition.</span>")
|
|
else
|
|
var/obj/item/stack/S = W
|
|
S.use(1)
|
|
obj_integrity = max_integrity
|
|
to_chat(user, "<span class='notice'>You repair [src] with [S].</span>")
|
|
else
|
|
return ..()
|
|
|
|
/obj/item/shield/riot/examine(mob/user)
|
|
. = ..()
|
|
var/healthpercent = round((obj_integrity/max_integrity) * 100, 1)
|
|
switch(healthpercent)
|
|
if(50 to 99)
|
|
. += "<span class='info'>It looks slightly damaged.</span>"
|
|
if(25 to 50)
|
|
. += "<span class='info'>It appears heavily damaged.</span>"
|
|
if(0 to 25)
|
|
. += "<span class='warning'>It's falling apart!</span>"
|
|
|
|
/obj/item/shield/riot/proc/shatter(mob/living/carbon/human/owner)
|
|
playsound(owner, 'sound/effects/glassbr3.ogg', 100)
|
|
new /obj/item/shard((get_turf(src)))
|
|
|
|
/obj/item/shield/riot/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
|
if(can_shatter && (obj_integrity <= damage))
|
|
var/turf/T = get_turf(owner)
|
|
T.visible_message("<span class='warning'>[attack_text] destroys [src]!</span>")
|
|
shatter(owner)
|
|
qdel(src)
|
|
return FALSE
|
|
take_damage(damage)
|
|
return ..()
|
|
|
|
/obj/item/shield/riot/laser_proof
|
|
name = "laser resistant shield"
|
|
desc = "A far more frail shield made of dark glass meant to block lasers but suffers from being being weak to ballistic projectiles."
|
|
armor = list("melee" = 30, "bullet" = -10, "laser" = 80, "energy" = 80, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
|
icon_state = "riot_laser"
|
|
item_state = "riot_laser"
|
|
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
|
shield_flags = SHIELD_FLAGS_DEFAULT
|
|
max_integrity = 55 //Weak
|
|
|
|
obj/item/shield/riot/bullet_proof
|
|
name = "bullet resistant shield"
|
|
desc = "A far more frail shield made of resistant plastics and kevlar meant to block ballistics."
|
|
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
|
max_integrity = 55 //Weaker
|
|
|
|
/obj/item/shield/riot/roman
|
|
name = "\improper Roman shield"
|
|
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>."
|
|
icon_state = "roman_shield"
|
|
item_state = "roman_shield"
|
|
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
|
repair_material = /obj/item/stack/sheet/mineral/wood
|
|
shield_flags = SHIELD_FLAGS_DEFAULT
|
|
max_integrity = 65
|
|
|
|
/obj/item/shield/riot/roman/fake
|
|
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>. It appears to be a bit flimsy."
|
|
block_chance = 0
|
|
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
|
max_integrity = 30
|
|
|
|
/obj/item/shield/riot/roman/shatter(mob/living/carbon/human/owner)
|
|
playsound(owner, 'sound/effects/grillehit.ogg', 100)
|
|
new /obj/item/stack/sheet/metal(get_turf(src))
|
|
|
|
/obj/item/shield/riot/buckler
|
|
name = "wooden buckler"
|
|
desc = "A medieval wooden buckler."
|
|
icon_state = "buckler"
|
|
item_state = "buckler"
|
|
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
|
custom_materials = null
|
|
resistance_flags = FLAMMABLE
|
|
repair_material = /obj/item/stack/sheet/mineral/wood
|
|
block_chance = 30
|
|
shield_flags = SHIELD_FLAGS_DEFAULT
|
|
max_integrity = 55
|
|
|
|
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
|
|
playsound(owner, 'sound/effects/bang.ogg', 50)
|
|
new /obj/item/stack/sheet/mineral/wood(get_turf(src))
|
|
|
|
/obj/item/shield/riot/tele
|
|
name = "telescopic shield"
|
|
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
|
|
icon_state = "teleriot0"
|
|
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
|
slot_flags = null
|
|
force = 3
|
|
throwforce = 3
|
|
throw_speed = 3
|
|
throw_range = 4
|
|
w_class = WEIGHT_CLASS_NORMAL
|
|
var/active = 0
|
|
|
|
/obj/item/shield/riot/tele/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
|
if(!active)
|
|
return BLOCK_NONE
|
|
return ..()
|
|
|
|
/obj/item/shield/riot/tele/attack_self(mob/living/user)
|
|
active = !active
|
|
icon_state = "teleriot[active]"
|
|
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
|
|
|
|
if(active)
|
|
force = 8
|
|
throwforce = 5
|
|
throw_speed = 2
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
slot_flags = ITEM_SLOT_BACK
|
|
to_chat(user, "<span class='notice'>You extend \the [src].</span>")
|
|
else
|
|
force = 3
|
|
throwforce = 3
|
|
throw_speed = 3
|
|
w_class = WEIGHT_CLASS_NORMAL
|
|
slot_flags = null
|
|
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
|
|
add_fingerprint(user)
|
|
|
|
/obj/item/shield/makeshift
|
|
name = "metal shield"
|
|
desc = "A large shield made of wired and welded sheets of metal. The handle is made of cloth and leather making it unwieldy."
|
|
armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 80)
|
|
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
|
item_state = "metal"
|
|
icon_state = "makeshift_shield"
|
|
custom_materials = list(/datum/material/iron = 18000)
|
|
slot_flags = null
|
|
block_chance = 35
|
|
max_integrity = 100 //Made of metal welded together its strong but not unkillable
|
|
force = 10
|
|
throwforce = 7
|
|
|
|
/obj/item/shield/riot/tower
|
|
name = "tower shield"
|
|
desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking."
|
|
armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user
|
|
item_state = "metal"
|
|
icon_state = "metal"
|
|
block_chance = 75 //1/4 shots will hit*
|
|
force = 16
|
|
slowdown = 2
|
|
throwforce = 15 //Massive pice of metal
|
|
w_class = WEIGHT_CLASS_HUGE
|
|
item_flags = SLOWS_WHILE_IN_HAND
|
|
shield_flags = SHIELD_FLAGS_DEFAULT
|
|
|
|
/obj/item/shield/riot/tower/swat
|
|
name = "swat shield"
|
|
desc = "A massive, heavy shield that can block a lot of attacks, can take a lot of abuse before breaking."
|
|
max_integrity = 175
|
|
block_chance = 50
|
|
|
|
/obj/item/shield/riot/implant
|
|
name = "telescoping shield implant"
|
|
desc = "A compact, arm-mounted telescopic shield. While nigh-indestructible when powered by a host user, it will eventually overload from damage. Recharges while inside its implant."
|
|
item_state = "metal"
|
|
icon_state = "metal"
|
|
block_chance = 50
|
|
slowdown = 1
|
|
shield_flags = SHIELD_FLAGS_DEFAULT
|
|
max_integrity = 60
|
|
obj_integrity = 60
|
|
can_shatter = FALSE
|
|
item_flags = SLOWS_WHILE_IN_HAND
|
|
var/recharge_timerid
|
|
var/recharge_delay = 15 SECONDS
|
|
|
|
/// Entirely overriden take_damage. This shouldn't exist outside of an implant (other than maybe christmas).
|
|
/obj/item/shield/riot/implant/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, armour_penetration = 0)
|
|
obj_integrity -= damage_amount
|
|
if(obj_integrity < 0)
|
|
obj_integrity = 0
|
|
if(obj_integrity == 0)
|
|
if(ismob(loc))
|
|
var/mob/living/L = loc
|
|
playsound(src, 'sound/effects/glassbr3.ogg', 100)
|
|
L.visible_message("<span class='boldwarning'>[src] overloads from the damage sustained!</span>")
|
|
L.dropItemToGround(src) //implant component catch hook will grab it.
|
|
|
|
/obj/item/shield/riot/implant/Moved()
|
|
. = ..()
|
|
if(istype(loc, /obj/item/organ/cyberimp/arm/shield))
|
|
recharge_timerid = addtimer(CALLBACK(src, .proc/recharge), recharge_delay, flags = TIMER_STOPPABLE)
|
|
else //extending
|
|
if(recharge_timerid)
|
|
deltimer(recharge_timerid)
|
|
recharge_timerid = null
|
|
|
|
/obj/item/shield/riot/implant/proc/recharge()
|
|
if(obj_integrity == max_integrity)
|
|
return
|
|
obj_integrity = max_integrity
|
|
if(ismob(loc.loc)) //cyberimplant.user
|
|
to_chat(loc, "<span class='notice'>[src] has recharged its reinforcement matrix and is ready for use!</span>")
|
|
|
|
/obj/item/shield/energy
|
|
name = "energy combat shield"
|
|
desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere."
|
|
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
|
w_class = WEIGHT_CLASS_TINY
|
|
attack_verb = list("shoved", "bashed")
|
|
throw_range = 5
|
|
force = 3
|
|
throwforce = 3
|
|
throw_speed = 3
|
|
var/base_icon_state = "eshield" // [base_icon_state]1 for expanded, [base_icon_state]0 for contracted
|
|
var/on_force = 10
|
|
var/on_throwforce = 8
|
|
var/on_throw_speed = 2
|
|
var/active = 0
|
|
var/clumsy_check = TRUE
|
|
|
|
/obj/item/shield/energy/Initialize()
|
|
. = ..()
|
|
icon_state = "[base_icon_state]0"
|
|
|
|
/obj/item/shield/energy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
|
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
|
|
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
|
|
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
|
|
return ..()
|
|
|
|
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
|
|
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
|
to_chat(user, "<span class='userdanger'>You beat yourself in the head with [src]!</span>")
|
|
user.take_bodypart_damage(5)
|
|
active = !active
|
|
icon_state = "[base_icon_state][active]"
|
|
|
|
if(active)
|
|
force = on_force
|
|
throwforce = on_throwforce
|
|
throw_speed = on_throw_speed
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
playsound(user, 'sound/weapons/saberon.ogg', 35, TRUE)
|
|
to_chat(user, "<span class='notice'>[src] is now active.</span>")
|
|
else
|
|
force = initial(force)
|
|
throwforce = initial(throwforce)
|
|
throw_speed = initial(throw_speed)
|
|
w_class = WEIGHT_CLASS_TINY
|
|
playsound(user, 'sound/weapons/saberoff.ogg', 35, TRUE)
|
|
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
|
|
add_fingerprint(user)
|