Adds personal shield generators. [READY FOR MERGE]

This commit is contained in:
Casey
2022-09-22 20:52:28 -04:00
committed by CHOMPStation2
parent a7ed7ff168
commit 524cd2e671
15 changed files with 1095 additions and 5 deletions

View File

@@ -10,7 +10,11 @@
active_power_usage = 40000 //40 kW
var/efficiency = 40000 //will provide the modified power rate when upgraded
var/obj/item/charging = null
<<<<<<< HEAD
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/suit_cooling_unit/emergency, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/device/defib_kit, /obj/item/ammo_casing/microbattery, /obj/item/device/paicard, /obj/item/ammo_magazine/cell_mag, /obj/item/weapon/gun/projectile/cell_loaded) // CHOMPedit: medigun stuff
=======
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/suit_cooling_unit/emergency, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/device/defib_kit, /obj/item/ammo_casing/microbattery, /obj/item/device/paicard, /obj/item/device/personal_shield_generator) //VOREStation Add - NSFW Batteries
>>>>>>> 95138e4672... Merge pull request #13696 from Cameron653/TEST
var/icon_state_charged = "recharger2"
var/icon_state_charging = "recharger1"
var/icon_state_idle = "recharger0" //also when unpowered

View File

@@ -0,0 +1,601 @@
// TO ANYBODY LOOKING AT THIS FILE:
// Everything is mostly commented on to give as much detailed information as possible.
// Some things may be difficult to understand, but every variable in here has a comment explaining what it is/does.
// The base unit, the 'personal_shield_generator' is a backpack, comes with a gun, and has normal numbers for everything.
// The belt units do NOT come with a gun and have a cell that is half the capacity of backpack units.
// These can be VERY, VERY, VERY strong if too many are handed out, the cell is too strong, or the modifier is too strong.
// Additionally, if you are mapping any of these in, ensure you map in the /loaded versions or else they won't have a battery.
// I have also made it so you can modify everything about them, including the modifier they give and the cell, which can be changed via mapping.
// In essence, these can be viewed as an extra layer of armor that has upsides and downsides with more extensive features.
// Shield generators apply PRE armor. Ultimately this shouldn't matter too much, but it makes more sense this way.
// There are a good amount of variants in here, ranging from mining to security to misc ones.
// If you want to make a variant, you need to only change modifier_type and make the modifier desired.
/obj/item/device/personal_shield_generator
name = "personal shield generator"
desc = "A personal shield generator."
icon = 'icons/obj/items_vr.dmi'
icon_state = "shield_pack"
item_state = "defibunit" //Placeholder
slot_flags = SLOT_BACK
force = 5
throwforce = 6
preserve_item = 1
w_class = ITEMSIZE_HUGE //It's a giant shield generator!!!
unacidable = TRUE
origin_tech = list(TECH_MATERIAL = 6, TECH_COMBAT = 8, TECH_POWER = 6, TECH_DATA = 4) //These are limited AND high tech. Breaking one of them down is massive.
action_button_name = "Toggle Shield"
var/obj/item/weapon/gun/energy/gun/generator/active_weapon
var/obj/item/weapon/cell/device/bcell = null
var/generator_hit_cost = 100 // Power used when a special effect (such as a bullet being blocked) is performed! Could also be expanded to other things.
var/generator_active_cost = 10 // Power used when turned on.
var/damage_cost = 25 // 40 damage absorbed per 1000 charge.
var/modifier_type = /datum/modifier/shield_projection // What type of modifier will it add? Used for variant modifiers!
var/has_weapon = 1 // Backpack units generally have weapons.
var/shield_active = 0 // If the shield gen is active.
var/effect_color = "#99FFFF" // Allows for changing shield colors. Default cyan.
/obj/item/device/personal_shield_generator/get_cell()
return bcell
/obj/item/device/personal_shield_generator/New()
..()
if(ispath(bcell))
bcell = new bcell(src)
if(has_weapon)
if(ispath(active_weapon))
active_weapon = new active_weapon(src, src)
active_weapon.power_supply = bcell
else
active_weapon = new(src, src)
active_weapon.power_supply = bcell
else
verbs -= /obj/item/device/personal_shield_generator/verb/weapon_toggle
STOP_PROCESSING(SSobj, src) //We do this so it doesn't start processing until it's first used.
update_icon()
/obj/item/device/personal_shield_generator/Destroy()
. = ..()
QDEL_NULL(active_weapon)
QDEL_NULL(bcell)
/obj/item/device/personal_shield_generator/loaded //starts with a cell
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
/obj/item/device/personal_shield_generator/update_icon()
if(shield_active)
icon_state = "shieldpack_basic_on"
else
icon_state = "shieldpack_basic"
/obj/item/device/personal_shield_generator/examine(mob/user)
. = ..()
if(Adjacent(user))
if(bcell)
. += "The internal cell is [round(bcell.percent() )]% charged."
else
. += "The device has no cell installed."
return
if(damage_cost) //Prevention of dividing by 0 errors.
. += "It reads that it can take [bcell.charge/damage_cost] more damage before the shield goes down."
if(bcell.self_recharge && bcell.charge_amount)
. += "This model is self charging and will take [bcell.maxcharge/bcell.charge_amount] seconds to fully charge from empty."
if(bcell.rigged)
. += "A red flashing 'WARNING' is visible on the display, noting that the cell is unstable and requires replacement."
/* //This would be cool, but we need sprites.
cut_overlays()
if(has_weapon && active_weapon && active_weapon.loc == src) //in case gun gets destroyed somehow.
add_overlay("[initial(icon_state)]-paddles")
if(bcell)
if(bcell.check_charge(generator_hit_cost)) //Can we take a blow?
add_overlay("[initial(icon_state)]-powered")
else if(has_weapon && active_weapon)
if(bcell.check_charge(active_weapon.charge_cost)) //We got enough to go pew pew?
add_overlay("[initial(icon_state)]-powered")
var/ratio = CEILING(bcell.percent()/25, 1) * 25
add_overlay("[initial(icon_state)]-charge[ratio]")
else
add_overlay("[initial(icon_state)]-nocell")
*/
/obj/item/device/personal_shield_generator/emp_act(severity)
if(bcell && shield_active)
switch(severity)
if(1) //Point blank EMP shots have a good chance of burning the cell charge.
if(prob(50))
bcell.emp_act(severity)
if(prob(5)) //1 in 20% chance to fry the battery completly, which has a 1/10 chance of making the battery explode on next use.
bcell.corrupt() //Not too bad if you slotted a battery in. Disasterous if it has a self-charging battery.
if(bcell.rigged) //Did the above just rig the cell? Turn it off. Don't immediately have it go boom. Instead have the cell blow soon-ish.
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
shield_active = 0
if(bcell.charge_delay) //It WILL blow up soon. Downside of self-charging cells.
to_chat(src.loc, "<span class='critical'>Your shield generator sparks and suddenly goes down! A warning message pops up on screen: \
'WARNING, INTERNAL CELL MELTDOWN IMMINENT. TIME TILL EXPLOSION: [bcell.charge_delay/10] SECONDS. DISCARD UNIT IMMEDIATELY!'</span>")
else //It won't blow up unless you turn it back on again. Upside of using non-charging cells.
to_chat(src.loc, "<span class='critical'>Your shield generator sparks and suddenly goes down! A warning message pops up on screen: \
'WARNING, INTERNAL CELL CRITICALLY DAMAGED. REPLACE CELL IMMEDIATELY.'</span>")
STOP_PROCESSING(SSobj, src)
update_icon()
else
if(prob(25))
bcell.emp_act(severity)
..()
/obj/item/device/personal_shield_generator/ui_action_click()
toggle_shield()
/obj/item/device/personal_shield_generator/attack_hand(mob/user)
if(loc == user)
toggle_shield()
else
..()
/obj/item/device/personal_shield_generator/AltClick(mob/living/user)
weapon_toggle()
/obj/item/device/personal_shield_generator/MouseDrop()
if(ismob(src.loc))
if(!CanMouseDrop(src))
return
var/mob/M = src.loc
if(!M.unEquip(src))
return
src.add_fingerprint(usr)
M.put_in_any_hand_if_possible(src)
/obj/item/device/personal_shield_generator/attackby(obj/item/weapon/W, mob/user, params)
if(W == active_weapon)
reattach_gun(user)
else if(istype(W, /obj/item/weapon/cell))
if(bcell)
to_chat(user, "<span class='notice'>\The [src] already has a cell.</span>")
else if(!istype(W, /obj/item/weapon/cell/device/weapon)) //Weapon cells only!
to_chat(user, "<span class='notice'>This cell will not fit in the device.</span>")
else
if(!user.unEquip(W))
return
W.forceMove(src)
bcell = W
if(active_weapon)
active_weapon.power_supply = bcell
to_chat(user, "<span class='notice'>You install a cell in \the [src].</span>")
update_icon()
else if(W.is_screwdriver())
if(bcell)
if(istype(bcell, /obj/item/weapon/cell/device/shield_generator)) //No stealing self charging batteries!
var/choice = tgui_alert(user, "A popup appears on the device 'REMOVING THE INTERNAL CELL WILL DESTROY THE BATTERY. DO YOU WISH TO CONTINUE?'...Well, do you?", "Selection List", list("Cancel", "Remove"))
if(choice == "Remove") //Warned you...
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
bcell.forceMove(get_turf(src.loc))
qdel(bcell)
bcell = null //Sanity.
if(active_weapon)
reattach_gun() //Put the gun back if it's out. No shooting if we don't have a cell!
active_weapon.power_supply = null //No power cell anymore!
to_chat(user, "<span class='notice'>You remove the cell from \the [src], destroying the battery.</span>")
update_icon()
return
else
return
else
bcell.update_icon()
bcell.forceMove(get_turf(src.loc))
bcell = null
if(active_weapon)
reattach_gun() //Put the gun back if it's out. No shooting if we don't have a cell!
active_weapon.power_supply = null //No power cell anymore!
to_chat(user, "<span class='notice'>You remove the cell from \the [src].</span>")
update_icon()
else if(istype(W,/obj/item/device/multitool))
var/new_color = input(usr, "Choose a color to set the shield to!", "", effect_color) as color|null
if(new_color)
effect_color = new_color
else
return ..()
// TODO: EMAG ACT
// Perhaps make it so emagging the generator gives two options: One to rig the cell (stealthily) and one to disable the safeties (supercharge it)
// Disabling the safeties would make it a stronger variant but boost the 'damage_cost' perhaps. Dunno.
// We're an RP server so emags don't come into play except for random trash finds. Meaning it'd be RNG if you could 'supercharge' your shield genrator.
// This would kind of be like people being able to emag the NIFSoft for bloodletters & all the buffs that come with an emagged NIFSoft.
// Making it so emagging the weapon it comes with would also be a good idea. Different modes, perhaps?
/*
/obj/item/device/personal_shield_generator/emag_act(var/remaining_charges, var/mob/user)
if(active_weapon)
. = active_weapon.emag_act(user)
update_icon()
return
*/
//Gun stuff
/obj/item/device/personal_shield_generator/verb/toggle_shield()
set name = "Toggle Shield"
set category = "Object"
var/mob/living/carbon/human/user = usr
if(user.last_special > world.time)
return
user.last_special = world.time + 10 //No spamming!
if(!bcell || !bcell.check_charge(generator_hit_cost) || !bcell.check_charge(generator_active_cost))
to_chat(user, "<span class='warning'>You require a charged cell to do this!</span>")
return
if(!slot_check())
to_chat(user, "<span class='warning'>You need to equip [src] before starting the shield up!</span>")
return
else
if(shield_active)
shield_active = !shield_active //Deactivate the shield!
to_chat(user, "<span class='warning'>You deactive the shield!</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
STOP_PROCESSING(SSobj, src)
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
else
shield_active = !shield_active
to_chat(user, "<span class='warning'>You activate the shield!</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection) //Just to make sure they aren't using two at once!
user.add_modifier(modifier_type)
user.update_modifier_visuals() //Forces coloration to WORK.
START_PROCESSING(SSobj, src) //Let's only bother draining power when we're being used!
playsound(src, 'sound/weapons/saberon.ogg', 50, 1) //Shield turning off! PLACEHOLDER
update_icon()
/obj/item/device/personal_shield_generator/verb/weapon_toggle() //Make this work on Alt-Click
set name = "Toggle Gun"
set category = "Object"
var/mob/living/carbon/human/user = usr
if(user.last_special > world.time)
return
user.last_special = world.time + 10 //No spamming!
if(!active_weapon)
to_chat(user, "<span class='warning'>The gun is missing!</span>")
return
if(!bcell)
to_chat(user, "<span class='warning'>The gun requires a power supply!</span>")
return
if(active_weapon.loc != src)
reattach_gun(user) //Remove from their hands and back onto the defib unit
return
if(!slot_check())
to_chat(user, "<span class='warning'>You need to equip [src] before taking out [active_weapon].</span>")
else
if(!usr.put_in_hands(active_weapon)) //Detach the gun into the user's hands
to_chat(user, "<span class='warning'>You need a free hand to hold the gun!</span>")
update_icon() //success
/obj/item/device/personal_shield_generator/process()
if(!bcell) //They removed the battery midway.
if(istype(loc, /mob/living/carbon/human)) //We on someone? Tell them it turned off.
var/mob/living/carbon/human/user = loc
to_chat(user, "<span class='warning'>The shield deactivates! An error message pops up on screen: 'Cell missing. Cell replacement required.'</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
shield_active = 0
STOP_PROCESSING(SSobj, src)
update_icon()
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
return
if(shield_active)
if(bcell.rigged) //They turned it back on after it was rigged to go boom.
if(istype(loc, /mob/living/carbon/human)) //Deactivate the shield, first. You're not getting reduced damage...
var/mob/living/carbon/human/user = loc
to_chat(user, "<span class='warning'>The shield deactivates, an error message popping up on screen: 'Cell Reactor Critically damaged. Cell replacement required.'</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
if(active_weapon) //Retract the gun. There's about to be no cell anymore.
reattach_gun()
active_weapon.power_supply = null
bcell.use(generator_active_cost) //Causes it to go boom.
bcell = null
shield_active = 0
STOP_PROCESSING(SSobj, src)
update_icon()
return
else //Normal operation.
bcell.use(generator_active_cost)
if(bcell.charge < generator_hit_cost || bcell.charge < generator_active_cost) //Out of charge...
shield_active = 0
if(istype(loc, /mob/living/carbon/human)) //We on someone? Tell them it turned off.
var/mob/living/carbon/human/user = loc
to_chat(user, "<span class='warning'>The shield deactivates, an error message popping up on screen: 'Cell out of charge.'</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
STOP_PROCESSING(SSobj, src)
update_icon()
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
return
//checks that the base unit is in the correct slot to be used
/obj/item/device/personal_shield_generator/proc/slot_check()
var/mob/M = loc
if(!istype(M))
return 0 //not equipped
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_back) == src)
return 1
if((slot_flags & SLOT_BELT) && M.get_equipped_item(slot_belt) == src)
return 1
//RIGSuit compatability. This shouldn't be possible, however, except for select RIGs.
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_s_store) == src)
return 1
if((slot_flags & SLOT_BELT) && M.get_equipped_item(slot_s_store) == src)
return 1
return 0
/obj/item/device/personal_shield_generator/dropped(mob/user)
..()
reattach_gun(user) //A gun attached to a base unit should never exist outside of their base unit or the mob equipping the base unit
/obj/item/device/personal_shield_generator/proc/reattach_gun(mob/user)
if(!active_weapon) return
if(ismob(active_weapon.loc))
var/mob/M = active_weapon.loc
if(M.drop_from_inventory(active_weapon, src))
to_chat(user, "<span class='notice'>\The [active_weapon] snaps back into the main unit.</span>")
else
active_weapon.forceMove(src)
update_icon()
//The gun
/obj/item/weapon/gun/energy/gun/generator //The gun attached to the personal shield generator.
name = "generator gun"
desc = "A gun that is attached to the battery of the personal shield generator."
icon_state = "egunstun"
item_state = null //so the human update icon uses the icon_state instead.
fire_delay = 8
use_external_power = TRUE
cell_type = null //No cell! It runs off the cell in the shield_gen!
projectile_type = /obj/item/projectile/beam/stun/med
modifystate = "egunstun"
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="egunstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="egunkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
)
var/obj/item/device/personal_shield_generator/shield_generator //The generator we are linked to!
var/wielded = 0
var/cooldown = 0
var/busy = 0
/obj/item/weapon/gun/energy/gun/generator/New(newloc, obj/item/device/personal_shield_generator/shield_gen)
..(newloc)
shield_generator = shield_gen
power_supply = shield_generator.bcell
/* //Unused. Use for large guns.
/obj/item/weapon/gun/energy/gun/generator/update_held_icon()
var/mob/living/M = loc
if(istype(M) && M.item_is_in_hands(src) && !M.hands_are_full())
wielded = 1
name = "[initial(name)] (wielded)"
else
wielded = 0
name = initial(name)
update_icon()
..()
*/
/obj/item/weapon/gun/energy/gun/generator/proc/can_use(mob/user, mob/M)
if(busy)
return 0
if(!check_charge(charge_cost))
to_chat(user, "<span class='warning'>\The [src] doesn't have enough charge left to do that.</span>")
return 0
if(!wielded && !isrobot(user))
to_chat(user, "<span class='warning'>You need to wield the gun with both hands before you can use it on someone!</span>")
return 0
if(cooldown)
to_chat(user, "<span class='warning'>\The [src] are re-energizing!</span>")
return 0
return 1
// TODO: EMP ACT
// The cell already gets hit and can have some nasty effects when EMP'd, so this isn't too much of a concern.
/*
/obj/item/weapon/gun/energy/gun/generator/emp_act(severity)
..()
*/
/obj/item/weapon/gun/energy/gun/generator/dropped(mob/user)
..() //update twohanding
if(shield_generator)
shield_generator.reattach_gun(user)
/obj/item/weapon/gun/energy/proc/check_charge(var/charge_amt) //In case using any other guns.
return 0
/obj/item/weapon/gun/energy/proc/checked_use(var/charge_amt) //In case using any other guns.
return 0
/obj/item/weapon/gun/energy/gun/generator/check_charge(var/charge_amt)
return (shield_generator.bcell && shield_generator.bcell.check_charge(charge_amt))
/obj/item/weapon/gun/energy/gun/generator/checked_use(var/charge_amt)
return (shield_generator.bcell && shield_generator.bcell.checked_use(charge_amt))
//VARIANTS.
/obj/item/device/personal_shield_generator/belt
name = "personal shield generator"
desc = "A personal shield generator."
icon_state = "shield_back_active"
item_state = "shield_pack"
w_class = ITEMSIZE_LARGE //No putting these in backpacks!
slot_flags = SLOT_BELT
has_weapon = 0 //No gun with the belt!
/obj/item/device/personal_shield_generator/belt/loaded
bcell = /obj/item/weapon/cell/device/shield_generator
/obj/item/device/personal_shield_generator/belt/update_icon()
if(shield_active)
icon_state = "shieldpack_basic_on"
else
icon_state = "shieldpack_basic"
/obj/item/device/personal_shield_generator/belt/bruteburn //Example of a modified generator.
modifier_type = /datum/modifier/shield_projection/bruteburn
/obj/item/device/personal_shield_generator/belt/bruteburn/loaded //If mapped in, ONLY put loaded ones down.
bcell = /obj/item/weapon/cell/device/shield_generator
// Mining belts
/obj/item/device/personal_shield_generator/belt/mining
name = "mining PSG"
desc = "A personal shield generator designed for mining. It has a warning on the back: 'Do NOT expose the shield to stun-based weaponry.'"
modifier_type = /datum/modifier/shield_projection/mining
/obj/item/device/personal_shield_generator/belt/mining/loaded
bcell = /obj/item/weapon/cell/device/shield_generator
/obj/item/device/personal_shield_generator/belt/mining/update_icon()
if(shield_active)
icon_state = "shieldpack_mining_on"
else
icon_state = "shieldpack_mining"
/obj/item/borg/upgrade/shield_upgrade
name = "mining PSG upgrade disk."
desc = "A upgrade disk that, when slotted into a mining shield generator, upgrades the efficiency of the internal software, providing a stronger shield \
in exchange for being weaker to stun-based weaponry."
icon = 'icons/obj/objects_vr.dmi'
icon_state = "modkit"
w_class = ITEMSIZE_SMALL
/obj/item/device/personal_shield_generator/belt/mining/attackby(obj/item/weapon/W, mob/user, params)
if(modifier_type == /datum/modifier/shield_projection/mining/strong)
to_chat(user, "<span class='warning'>This shield generator is already upgraded!</span>")
return
if(istype(W, /obj/item/borg/upgrade/shield_upgrade))
modifier_type = /datum/modifier/shield_projection/mining/strong
to_chat(user, "<span class='notice'>You upgrade the [src] with the [W]!</span>")
user.drop_from_inventory(W)
qdel(W)
else
..()
//Security belts
/obj/item/device/personal_shield_generator/belt/security
name = "security PSG"
desc = "A personal shield generator designed for security."
modifier_type = /datum/modifier/shield_projection/security/weak
/obj/item/device/personal_shield_generator/belt/security/loaded
bcell = /obj/item/weapon/cell/device/shield_generator
/obj/item/device/personal_shield_generator/belt/security/update_icon()
if(shield_active)
icon_state = "shieldpack_security_on"
else
icon_state = "shieldpack_security"
//Misc belts. Admin-spawn only atm.
/obj/item/device/personal_shield_generator/belt/adminbus
desc = "You should not see this. You REALLY should not see this. If you do, you have either been blessed or are about to be the target of some sick prank."
modifier_type = /datum/modifier/shield_projection/admin
generator_hit_cost = 0
generator_active_cost = 0
shield_active = 0
damage_cost = 0
bcell = /obj/item/weapon/cell/device/shield_generator
/obj/item/device/personal_shield_generator/belt/parry //The 'provides one second of pure immunity to brute/burn/halloss' belt.
name = "PSG variant-P" //Not meant to be used in any serious capacity.
desc = "A personal shield generator that sacrifices long-term usability in exchange for a strong, short-lived shield projection, enabling the user to be nigh \
impervious for a second."
modifier_type = /datum/modifier/shield_projection/parry
generator_hit_cost = 0 //No cost for being hit.
damage_cost = 0//No cost for blocking effects.
generator_active_cost = 100 //However, it disables the tick immediately after being turned on.
shield_active = 0
bcell = /obj/item/weapon/cell/device/shield_generator/parry
// Backpacks. These are meant to be MUCH stronger in exchange for the fact that you are giving up a backpack slot.
// HOWEVER, be careful with these. They come loaded with a gun in them, so they shouldn't be handed out willy-nilly.
/obj/item/device/personal_shield_generator/security
name = "security PSG"
desc = "A personal shield generator designed for security. Comes with a built in defense pistol."
modifier_type = /datum/modifier/shield_projection/security
/obj/item/device/personal_shield_generator/security/loaded
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
/obj/item/device/personal_shield_generator/security/strong
modifier_type = /datum/modifier/shield_projection/security/strong
/obj/item/device/personal_shield_generator/security/strong/loaded
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
/obj/item/device/personal_shield_generator/security/update_icon()
if(shield_active)
icon_state = "shieldpack_security_on"
else
icon_state = "shieldpack_security"
//Power cells.
/obj/item/weapon/cell/device/shield_generator //The base power cell the shield gen comes with.
name = "shield generator battery"
desc = "A self charging battery which houses a micro-nuclear reactor. Takes a while to start charging."
maxcharge = 2400
self_recharge = TRUE
charge_amount = 80 //After the charge_delay is over, charges the cell over 30 seconds.
charge_delay = 600 //Takes a minute before it starts to recharge.
/obj/item/weapon/cell/device/shield_generator/backpack //The base power cell the backpack units come with. Double the charge vs the belt.
maxcharge = 4800
charge_amount = 160
/obj/item/weapon/cell/device/shield_generator/upgraded //A stronger version of the normal cell. Double the maxcharge, halved charge time.
maxcharge = 4800
charge_amount = 320
charge_delay = 300
/obj/item/weapon/cell/device/shield_generator/parry //The cell for the 'parry' shield gen.
maxcharge = 100
charge_amount = 100
charge_delay = 20 //Starts charging two seconds after it's discharged.

View File

@@ -254,3 +254,8 @@
persist_storable = FALSE
/obj/item/weapon/spacecasinocash
persist_storable = FALSE
<<<<<<< HEAD
=======
/obj/item/device/personal_shield_generator
persist_storable = FALSE
>>>>>>> 95138e4672... Merge pull request #13696 from Cameron653/TEST

View File

@@ -29,4 +29,18 @@
/obj/item/device/assembly/electronic_assembly
description_info = "This is the casing for the 'device' type of electronic assembly. It behaves like any other 'assembly' type device such as an igniter or signaler \
and can be attached to others in the same way. Use the 'toggle-open' verb (right click) or a crowbar to pop the electronic device open to add components and close when finished."
and can be attached to others in the same way. Use the 'toggle-open' verb (right click) or a crowbar to pop the electronic device open to add components and close when finished."
/obj/item/device/personal_shield_generator
description_info = "This is a personal shield generator. Depending on the type, it can either be worn on your backpack slot, your belt slot, or in a rigsuit \
storage slot. It runs on an internal battery, which is usually self-charging. Some versions come with a gun. To active the shield, click the button in the upper \
right of the screen, use the 'Toggle Shield' command under your objects tab, or click the device itself while it is on you. Some units come with an active weapon \
which can be taken out at any time by Alt-clicking the device. If the device requires a cell, a screwdriver can be used. The shield slowly drains charge while \
active and becomes weaker with each individual strike taken. Additonally, the device can be colored via use of a multitool."
description_fluff = "A relatively new invention, made in a collaboration between Hephaestus Industries and a startup known as Kuznetsova Enterprise in the year \
2322. Numerous variants of the device have been made for specific tasks, ranging from riot control, mining, biohazard containment, and search and rescue, among \
others. Most of the devices share the flaw that electrical attacks can easily overload the device and cause a shield failure, encouraging combatants to swap to \
the use of stun-based electric weaponry when shield generators are in use. Most shield devices are self-charging, running off a micro-nuclear reactor built into \
the chassis itself, although some variants exist without this capability and can have normal cells inserted into them. Larger units boast the capability of \
storing a weapon, although without upgraded batteries the usage of said weapon is ill-advised."

View File

@@ -19,7 +19,7 @@
generate_loot()
/obj/structure/closet/crate/secure/loot/proc/generate_loot()
var/loot = rand(1, 99)
var/loot = rand(1, 100)
switch(loot)
if(1 to 5) // Common things go, 5%
new/obj/item/weapon/reagent_containers/food/drinks/bottle/rum(src)
@@ -140,6 +140,8 @@
if(99)
new/obj/item/weapon/storage/belt/champion(src)
new/obj/item/clothing/mask/luchador(src)
if(100)
new/obj/item/device/personal_shield_generator/belt/mining/loaded(src)
/obj/structure/closet/crate/secure/loot/togglelock(mob/user as mob)
if(!locked)

View File

@@ -126,6 +126,7 @@
EQUIPMENT("Thalers - 1000", /obj/item/weapon/spacecash/c1000, 10000),
EQUIPMENT("Umbrella", /obj/item/weapon/melee/umbrella/random, 200),
EQUIPMENT("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125),
EQUIPMENT("Mining PSG Upgrade Disk", /obj/item/borg/upgrade/shield_upgrade, 2500),
)
prize_list["Extra"] = list() // Used in child vendors
//VOREStation Edit End

View File

@@ -1,3 +1,51 @@
/datum/modifier
var/effect_color // Allows for coloring of modifiers.
var/coloration_applied = 0 // Tells the game is coloration has been applied already or not.
var/icon_override = 0 // Tells the game if it should use modifer_effects_vr.dmi or not.
// ENERGY CODE. Variables to allow for energy based modifiers.
var/energy_based // Sees if the modifier is based on something electronic based.
var/energy_cost // How much the modifier uses per action/special effect blocked. For base values.
var/damage_cost // How much energy is used when numbers are involed. For values, such as taking damage. Ex: (Damage*damage_cost)
var/obj/item/weapon/cell/energy_source = null // The source of the above.
// RESISTANCES CODE. Variable to enable external damage resistance modifiers. This is not unlike armor.
// 0 = immune || < 0 = heals || 1 = full damage || >1 = increased damage.
// It should never be below zero as it is not intended to do such, but you are free to experiment!
// Ex: Max_brute_resistance = 0. Min_brute resistance = 1. When started, provides 100% resistance to brute. When cell is dying, goes down to 0% resistance.
// Max is the MAXIMUM % multiplier that will be taken at a MAX charge. Min is the MINIMUM % multiplier that will be taken at a MINIMUM charge.
// Think of it like this: Minimum = what happens at minimum charge. Max = what happens at maximum charge.
// Why do I mention this so much? Because even /I/ got confused, and I wrote this thing!
var/min_damage_resistance
var/max_damage_resistance
var/effective_damage_resistance
var/min_brute_resistance
var/max_brute_resistance
var/effective_brute_resistance
var/min_fire_resistance
var/max_fire_resistance
var/effective_fire_resistance
var/min_tox_resistance
var/max_tox_resistance
var/effective_tox_resistance
var/min_oxy_resistance
var/max_oxy_resistance
var/effective_oxy_resistance
var/min_clone_resistance
var/max_clone_resistance
var/effective_clone_resistance
var/min_hal_resistance
var/max_hal_resistance
var/effective_hal_resistance
// Resistances end
/datum/modifier/underwater_stealth
name = "underwater stealth"
desc = "You are currently underwater, rendering it more difficult to see you and enabling you to move quicker, thanks to your aquatic nature."
@@ -30,4 +78,258 @@
if(water_floor.depth < 1) //You're not in deep enough water anymore.
expire(silent = FALSE)
else
expire(silent = FALSE)
expire(silent = FALSE)
/datum/modifier/shield_projection
name = "Shield Projection"
desc = "You are currently protected by a shield, rendering nigh impossible to hit you through conventional means."
on_created_text = "<span class='notice'>Your shield generator buzzes on.</span>"
on_expired_text = "<span class='warning'>Your shield generator buzzes off.</span>"
stacks = MODIFIER_STACK_FORBID //No stacking shields. If you put one one your belt and backpack it won't work.
icon_override = 1
mob_overlay_state = "deflect"
siemens_coefficient = 2 //Stun weapons drain 100% charge per point of damage. They're good at blocking lasers and bullets but not good at blocking stun beams!
energy_based = 1
energy_cost = 99999 //This is changed to the shield_generator's energy_cost.
damage_cost = 50 //This is how much battery is used per damage unit absorbed. Higher damage means higher charge use per damage absorbed. Changed below!
//Not actually in use until effective resistances are set. Just here so it doesn't have to be placed down for all the variants. Less lines.
max_damage_resistance = 1
max_brute_resistance = 1
max_fire_resistance = 1
max_tox_resistance = 1
max_oxy_resistance = 1
max_clone_resistance = 1
max_hal_resistance = 1
min_damage_resistance = 1
min_brute_resistance = 1
min_fire_resistance = 1
min_tox_resistance = 1
min_oxy_resistance = 1
min_clone_resistance = 1
min_hal_resistance = 1
/* // These are not set, but left here as an example. All three (min,max,effective) must be set or BAD THINGS will happen.
min_brute_resistance = 1 // Min = WHAT HAPPENS AT MINIMUM CHARGE
max_brute_resistance = 0 // MAX = WHAT HAPPENS AT MAXIMUM CHARGE
effective_brute_resistance = 1 //Just tells the game that it has vars. Done to use less checks.
min_fire_resistance = 1
max_fire_resistance = 0
effective_fire_resistance = 1
disable_duration_percent = 1 //THIS CAN ALSO BE USED! Don't be too afraid to use this one, but use it sparingly!
*/
var/obj/item/device/personal_shield_generator/shield_generator //This is the shield generator you're wearing!
/datum/modifier/shield_projection/on_applied()
return
/datum/modifier/shield_projection/on_expire() //Don't need to modify this!
return
/datum/modifier/shield_projection/check_if_valid() //Let's check to make sure you got the stuff and set the vars. Don't need to modify this for any subtypes!
if(ishuman(holder)) //Only humans can use this! Other things later down the line might use the same stuff this does, but the shield generator is human only!
var/mob/living/carbon/human/H = holder
if(istype(H.get_equipped_item(slot_back), /obj/item/device/personal_shield_generator))
shield_generator = H.get_equipped_item(slot_back) //Sets the var on the modifier that the shield gen is their back shield gen.
else if(istype(H.get_equipped_item(slot_belt), /obj/item/device/personal_shield_generator))
shield_generator = H.get_equipped_item(slot_belt) //No need for other checks. If they got hit by this, they just turned it on.
else if(istype(H.get_equipped_item(slot_s_store), /obj/item/device/personal_shield_generator) ) //Rigsuits.
shield_generator = H.get_equipped_item(slot_s_store)
else
expire(silent = TRUE)
if(shield_generator) //Sanity.
energy_source = shield_generator.bcell
energy_cost = shield_generator.generator_hit_cost
damage_cost = shield_generator.damage_cost
effect_color = shield_generator.effect_color
if(!coloration_applied) //Does a check if colors have been applied. If not, updates the color.
H.update_modifier_visuals() //This can only happen on the next tick, unfortunately, not the same tick the modifier is applied. Thus, must be done here.
coloration_applied = 1
else
expire(silent = TRUE)
/datum/modifier/shield_projection/tick() //When the shield generator runs out of charge, it'll remove this naturally.
if(holder.stat == DEAD)
expire(silent = TRUE) //If you're dead the generator stops protecting you but keeps running.
if(!shield_generator || !shield_generator.slot_check()) //No shield to begin with/shield is not on them any longer.
expire(silent = FALSE)
var/shield_efficiency = (energy_source.charge/energy_source.maxcharge) //1 = complete resistance. 0 = no resistance. Must be adjusted for subtypes!
if(!isnull(effective_damage_resistance))
effective_damage_resistance = min_damage_resistance + (max_damage_resistance - min_damage_resistance) * shield_efficiency
if(!isnull(effective_brute_resistance))
effective_brute_resistance = min_brute_resistance + (max_brute_resistance - min_brute_resistance) * shield_efficiency
if(!isnull(effective_fire_resistance))
effective_fire_resistance = min_fire_resistance + (max_fire_resistance - min_fire_resistance) * shield_efficiency
if(!isnull(effective_tox_resistance))
effective_tox_resistance = min_tox_resistance + (max_tox_resistance - min_tox_resistance) * shield_efficiency
if(!isnull(effective_oxy_resistance))
effective_oxy_resistance = min_oxy_resistance + (max_oxy_resistance - min_oxy_resistance) * shield_efficiency
if(!isnull(effective_clone_resistance))
effective_clone_resistance = min_clone_resistance + (max_clone_resistance - min_clone_resistance) * shield_efficiency
if(!isnull(effective_hal_resistance))
effective_hal_resistance = min_hal_resistance + (max_hal_resistance - min_hal_resistance) * shield_efficiency
//Shield variants.
//Simple. Goes from 100% resistance to 0% resistance depending on charge. This is mostly an example of a shield variant.
/datum/modifier/shield_projection/bruteburn
max_brute_resistance = 0
effective_brute_resistance = 1
max_fire_resistance = 0
effective_fire_resistance = 1
/datum/modifier/shield_projection/bruteburn/weak
max_brute_resistance = 0.5
max_fire_resistance = 0.5
//SECURITY VARIANTS
/datum/modifier/shield_projection/security // Security backpack. 50% resistance at full charge. 10% resistance for the last shot taken.
max_brute_resistance = 0.50
min_brute_resistance = 0.9
effective_brute_resistance = 1
max_fire_resistance = 0.5
min_fire_resistance = 0.9
effective_fire_resistance = 1
max_hal_resistance = 0.5
min_hal_resistance = 0.9
effective_hal_resistance = 1
disable_duration_percent = 0.75
/datum/modifier/shield_projection/security/weak // Security belt.
max_brute_resistance = 0.75
min_brute_resistance = 0.95
max_fire_resistance = 0.75
min_fire_resistance = 0.95
max_hal_resistance = 0.75
min_hal_resistance = 0.95
/datum/modifier/shield_projection/security/strong // Dunno. Upgraded variant of security backpack?
max_brute_resistance = 0.25
max_fire_resistance = 0.25
max_hal_resistance = 0.25
siemens_coefficient = 1.5 //Not as weak as normal, but still weak.
disable_duration_percent = 0.5
//MINING VARIANTS
/datum/modifier/shield_projection/mining //Base mining belt. 30% resistance that fades to 15% resistance
max_brute_resistance = 0.70
min_brute_resistance = 0.85
effective_brute_resistance = 1
max_fire_resistance = 0.70
min_brute_resistance = 0.85
effective_fire_resistance = 1
max_hal_resistance = 1.5 // No mobs should be shooting you with halloss. If this happens, it means you're using it wrong!!!
min_hal_resistance = 1.5
effective_hal_resistance = 1
disable_duration_percent = 0.75 //Miners often come into contact with things that can stun them.
/datum/modifier/shield_projection/mining/strong // Mining belt, but upgraded. Even weaker to halloss!
max_brute_resistance = 0.55
min_brute_resistance = 0.75
max_fire_resistance = 0.55
min_fire_resistance = 0.75
disable_duration_percent = 0.5
max_hal_resistance = 2
min_hal_resistance = 2
//MISC VARIANTS
/datum/modifier/shield_projection/biohazard //The odd-ball damage types. Provides near-complete immunity while it's up.
min_tox_resistance = 0.25
max_tox_resistance = 0
effective_tox_resistance = 1
min_oxy_resistance = 0.25
max_oxy_resistance = 0
effective_oxy_resistance = 1
min_clone_resistance = 0.25
max_clone_resistance = 0
effective_clone_resistance = 1
/datum/modifier/shield_projection/admin // Adminbus.
on_created_text = "<span class='notice'>Your shield generator activates and you feel the power of the tesla buzzing around you.</span>"
on_expired_text = "<span class='warning'>Your shield generator deactivates, leaving you feeling weak and vulnerable.</span>"
siemens_coefficient = 0
disable_duration_percent = 0
min_damage_resistance = 0
max_damage_resistance = 0
effective_damage_resistance = 0
min_brute_resistance = 0
max_brute_resistance = 0
effective_brute_resistance = 0
min_fire_resistance = 0
max_fire_resistance = 0
effective_fire_resistance = 0
min_tox_resistance = 0
max_tox_resistance = 0
effective_tox_resistance = 0
min_oxy_resistance = 0
max_oxy_resistance = 0
effective_oxy_resistance = 0
min_clone_resistance = 0
max_clone_resistance = 0
effective_clone_resistance = 0
min_hal_resistance = 0
max_hal_resistance = 0
effective_hal_resistance = 0
/datum/modifier/shield_projection/broken //For broken variants. Good if possible randomization is included for packs spawned on PoIs.
max_brute_resistance = 2
min_brute_resistance = 2
effective_brute_resistance = 1
max_fire_resistance = 2
min_fire_resistance = 2
effective_fire_resistance = 1
/datum/modifier/shield_projection/inverted //Becomes stronger the weaker the cell is. Means the last shot taken will be the weakest. Example just to show it can be done.
max_brute_resistance = 1
min_brute_resistance = 0
effective_brute_resistance = 1
max_fire_resistance = 1
min_fire_resistance = 0
effective_fire_resistance = 1
/datum/modifier/shield_projection/parry //Intended for 'parry' shields, which only last for a single second before running out of charge
max_brute_resistance = 0
min_brute_resistance = 0
effective_brute_resistance = 1
max_fire_resistance = 0
min_fire_resistance = 0
effective_fire_resistance = 1
max_hal_resistance = 0
min_hal_resistance = 0
effective_hal_resistance = 1

View File

@@ -115,8 +115,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_brute_damage_percent
if(nif && nif.flag_check(NIF_C_BRUTEARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
take_overall_damage(amount, 0)
@@ -133,8 +137,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_fire_damage_percent
if(nif && nif.flag_check(NIF_C_BURNARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
take_overall_damage(0, amount)
@@ -153,8 +161,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_brute_damage_percent
if(nif && nif.flag_check(NIF_C_BRUTEARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
@@ -175,8 +187,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_fire_damage_percent
if(nif && nif.flag_check(NIF_C_BURNARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
@@ -485,6 +501,53 @@ This function restores all organs.
if(!def_zone) def_zone = ran_zone(def_zone)
organ = get_organ(check_zone(def_zone))
for(var/datum/modifier/M in modifiers) //MODIFIER STUFF. It's best to do this RIGHT before armor is calculated, so it's done here! This is the 'forcefield' defence.
if(damagetype == BRUTE && (!isnull(M.effective_brute_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_brute_resistance
continue
if((damagetype == BURN || damagetype == ELECTROCUTE) && (!isnull(M.effective_fire_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_fire_resistance
continue
if(damagetype == TOX && (!isnull(M.effective_tox_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_tox_resistance
continue
if(damagetype == OXY && (!isnull(M.effective_oxy_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_oxy_resistance
continue
if(damagetype == CLONE && (!isnull(M.effective_clone_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_clone_resistance
continue
if(damagetype == HALLOSS && (!isnull(M.effective_hal_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_hal_resistance
continue
if(damagetype == SEARING && (!isnull(M.effective_fire_resistance) || !isnull(M.effective_brute_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
var/damage_mitigation = 0//Used for dual calculations.
if(!isnull(M.effective_fire_resistance))
damage_mitigation += round((1/3)*damage * M.effective_fire_resistance)
if(!isnull(M.effective_brute_resistance))
damage_mitigation += round((2/3)*damage * M.effective_brute_resistance)
damage -= damage_mitigation
continue
if(damagetype == BIOACID && (isSynthetic() && (!isnull(M.effective_fire_resistance))) || (!isSynthetic() && M.effective_tox_resistance))
if(isSynthetic())
damage = damage * M.effective_fire_resistance
else
damage = damage * M.effective_tox_resistance
continue
//Handle other types of damage
if((damagetype != BRUTE) && (damagetype != BURN))
if(damagetype == HALLOSS)
@@ -523,8 +586,12 @@ This function restores all organs.
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*damage)
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*damage)
damage *= M.incoming_brute_damage_percent
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
@@ -536,8 +603,12 @@ This function restores all organs.
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*damage)
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*damage)
damage *= M.incoming_fire_damage_percent
if(organ.take_damage(0, damage, sharp, edge, used_weapon))

View File

@@ -37,6 +37,18 @@ emp_act
var/armor = getarmor_organ(organ, "bullet")
if(!prob(armor/2)) //Even if the armor doesn't stop the bullet from hurting you, it might stop it from embedding.
var/hit_embed_chance = P.embed_chance + (P.damage - armor) //More damage equals more chance to embed
//Modifiers can make bullets less likely to embed! These are the normal modifiers and shouldn't be related to energy stuff, but they can be anyways!
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.energy_cost) //We use energy_cost here for special effects, such as embedding.
hit_embed_chance = hit_embed_chance*M.incoming_damage_percent
if(P.damage_type == BRUTE && (!isnull(M.incoming_brute_damage_percent)))
if(M.energy_based)
M.energy_source.use(M.energy_cost)
hit_embed_chance = hit_embed_chance*M.incoming_brute_damage_percent
if(prob(max(hit_embed_chance, 0)))
var/obj/item/weapon/material/shard/shrapnel/SP = new()
SP.name = (P.name != "shrapnel")? "[P.name] shrapnel" : "shrapnel"

View File

@@ -1137,8 +1137,14 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/image/effects = new()
for(var/datum/modifier/M in modifiers)
if(M.mob_overlay_state)
var/image/I = image(icon = 'icons/mob/modifier_effects.dmi', icon_state = M.mob_overlay_state)
effects.overlays += I // Leaving this as overlays +=
if(M.icon_override) //VOREStation Edit. Override for the modifer icon.
var/image/I = image(icon = 'icons/mob/modifier_effects_vr.dmi', icon_state = M.mob_overlay_state)
I.color = M.effect_color
effects.overlays += I // Leaving this as overlays +=
else
var/image/I = image(icon = 'icons/mob/modifier_effects.dmi', icon_state = M.mob_overlay_state)
I.color = M.effect_color
effects.overlays += I // Leaving this as overlays +=
overlays_standing[MODIFIER_EFFECTS_LAYER] = effects

View File

@@ -13,6 +13,53 @@
to_world_log("## DEBUG: apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked].")
if(!damage || (blocked >= 100))
return 0
for(var/datum/modifier/M in modifiers) //MODIFIER STUFF. It's best to do this RIGHT before armor is calculated, so it's done here! This is the 'forcefield' defence.
if(damagetype == BRUTE && (!isnull(M.effective_brute_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_brute_resistance
continue
if((damagetype == BURN || damagetype == ELECTROCUTE)&& (!isnull(M.effective_fire_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_fire_resistance
continue
if(damagetype == TOX && (!isnull(M.effective_tox_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_tox_resistance
continue
if(damagetype == OXY && (!isnull(M.effective_oxy_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_oxy_resistance
continue
if(damagetype == CLONE && (!isnull(M.effective_clone_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_clone_resistance
continue
if(damagetype == HALLOSS && (!isnull(M.effective_hal_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_hal_resistance
continue
if(damagetype == SEARING && (!isnull(M.effective_fire_resistance) || !isnull(M.effective_brute_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
var/damage_mitigation = 0//Used for dual calculations.
if(!isnull(M.effective_fire_resistance))
damage_mitigation += round((1/3)*damage * M.effective_fire_resistance)
if(!isnull(M.effective_brute_resistance))
damage_mitigation += round((2/3)*damage * M.effective_brute_resistance)
damage -= damage_mitigation
continue
if(damagetype == BIOACID && (isSynthetic() && (!isnull(M.effective_fire_resistance))) || (!isSynthetic() && M.effective_tox_resistance))
if(isSynthetic())
damage = damage * M.effective_fire_resistance
else
damage = damage * M.effective_tox_resistance
continue
if(soaked)
if(soaked >= round(damage*0.8))
damage -= round(damage*0.8)
@@ -55,6 +102,7 @@
/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/halloss = 0, var/def_zone = null, var/blocked = 0)
if(blocked >= 100)
return 0
// INSERT MODIFIER CODE HERE... But no, really, only two things in the game use it, quad and viruses. The former is admin-only and the latter wouldn't be affected logically, but would if shield code was inerted here. If you really want, you can copy&paste the above and modify it to adjust brute/burn/etc. I do not advise this however.
if(brute) apply_damage(brute, BRUTE, def_zone, blocked)
if(burn) apply_damage(burn, BURN, def_zone, blocked)
if(tox) apply_damage(tox, TOX, def_zone, blocked)

View File

@@ -192,8 +192,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_brute_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -219,8 +223,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_oxy_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_oxy_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -243,8 +251,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_tox_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_tox_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -273,8 +285,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_fire_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -298,8 +314,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_clone_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_clone_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -331,6 +351,9 @@
if(status_flags & GODMODE) return 0 //godmode
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(M.energy_based && (!isnull(M.incoming_hal_damage_percent) || !isnull(M.disable_duration_percent)))
M.energy_source.use(M.damage_cost*amount) // Cost of the Damage absorbed.
M.energy_source.use(M.energy_cost) // Cost of the Effect absorbed.
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_hal_damage_percent))

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1259,6 +1259,7 @@
#include "code\game\objects\items\devices\paicard.dm"
#include "code\game\objects\items\devices\paicard_ch.dm"
#include "code\game\objects\items\devices\paicard_vr.dm"
#include "code\game\objects\items\devices\personal_shield_generator_vr.dm"
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\spy_bug.dm"