Upload files
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"d" = (
|
||||
/obj/mecha/working/ripley/mining,
|
||||
/obj/vehicle/sealed/mecha/working/ripley/mining,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"e" = (
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
/turf/open/floor/mineral/titanium/yellow/airless,
|
||||
/area/ruin/space/has_grav/powered/mechtransport)
|
||||
"A" = (
|
||||
/obj/mecha/working/ripley,
|
||||
/obj/vehicle/sealed/mecha/working/ripley,
|
||||
/turf/open/floor/mineral/titanium/yellow/airless,
|
||||
/area/ruin/space/has_grav/powered/mechtransport)
|
||||
"B" = (
|
||||
|
||||
@@ -14451,7 +14451,7 @@
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/awaymission/snowdin/post/mining_main/mechbay)
|
||||
"In" = (
|
||||
/obj/mecha/working/ripley/mining{
|
||||
/obj/vehicle/sealed/mecha/working/ripley/mining{
|
||||
dir = 1;
|
||||
icon_state = "ripley"
|
||||
},
|
||||
|
||||
@@ -2039,7 +2039,7 @@
|
||||
},
|
||||
/area/awaymission/caves/BMP_asteroid)
|
||||
"gC" = (
|
||||
/obj/mecha/working/ripley/mining,
|
||||
/obj/vehicle/sealed/mecha/working/ripley/mining,
|
||||
/turf/open/floor/plasteel/recharge_floor,
|
||||
/area/awaymission/caves/BMP_asteroid)
|
||||
"gD" = (
|
||||
|
||||
@@ -14452,7 +14452,7 @@
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/awaymission/snowdin/post/mining_main/mechbay)
|
||||
"In" = (
|
||||
/obj/mecha/working/ripley/mining{
|
||||
/obj/vehicle/sealed/mecha/working/ripley/mining{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
|
||||
@@ -31,12 +31,21 @@
|
||||
#define COOLDOWN_OBJECTIVES "objectives"
|
||||
#define COOLDOWN_OBJ_ADMIN_PING "obj_admin_ping"
|
||||
|
||||
|
||||
//Mecha cooldowns
|
||||
#define COOLDOWN_MECHA_MESSAGE "mecha_message"
|
||||
#define COOLDOWN_MECHA_EQUIPMENT "mecha_equipment"
|
||||
#define COOLDOWN_MECHA_ARMOR "mecha_armor"
|
||||
#define COOLDOWN_MECHA_MELEE_ATTACK "mecha_melee"
|
||||
#define COOLDOWN_MECHA_SMOKE "mecha_smoke"
|
||||
|
||||
//car cooldowns
|
||||
#define COOLDOWN_CAR_HONK "car_honk"
|
||||
|
||||
//clown car cooldowns
|
||||
#define COOLDOWN_CLOWNCAR_RANDOMNESS "clown_car_randomness"
|
||||
|
||||
|
||||
//TIMER COOLDOWN MACROS
|
||||
|
||||
#define COMSIG_CD_STOP(cd_index) "cooldown_[cd_index]"
|
||||
|
||||
@@ -526,7 +526,19 @@
|
||||
#define COMSIG_PROJECTILE_PREHIT "com_proj_prehit" ///sent to targets during the process_hit proc of projectiles
|
||||
|
||||
#define COMSIG_PELLET_CLOUD_INIT "pellet_cloud_init" // sent to targets during the process_hit proc of projectiles
|
||||
// /obj/vehicle/sealed/mecha signals
|
||||
// /sent from mecha action buttons to the mecha they're linked to
|
||||
#define COMSIG_MECHA_ACTION_TRIGGER "mecha_action_activate"
|
||||
|
||||
///sent from clicking while you have no equipment selected. Sent before cooldown and adjacency checks, so you can use this for infinite range things if you want.
|
||||
#define COMSIG_MECHA_MELEE_CLICK "mecha_action_melee_click"
|
||||
/// Prevents click from happening.
|
||||
#define COMPONENT_CANCEL_MELEE_CLICK (1<<0)
|
||||
///sent from clicking while you have equipment selected.
|
||||
#define COMSIG_MECHA_EQUIPMENT_CLICK "mecha_action_equipment_click"
|
||||
/// Prevents click from happening.
|
||||
#define COMPONENT_CANCEL_EQUIPMENT_CLICK (1<<0)
|
||||
|
||||
// /mob/living/carbon/human signals
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target)
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
|
||||
|
||||
@@ -207,7 +207,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
|
||||
|
||||
#define ismachinery(A) (istype(A, /obj/machinery))
|
||||
|
||||
#define ismecha(A) (istype(A, /obj/mecha))
|
||||
#define ismecha(A) (istype(A, /obj/vehicle/sealed/mecha))
|
||||
|
||||
#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#define LOG_ADMIN_PRIVATE (1 << 14)
|
||||
#define LOG_ASAY (1 << 15)
|
||||
#define LOG_VIRUS (1 << 16)
|
||||
#define LOG_MECHA (1 << 17)
|
||||
#define LOG_SHUTTLE (1 << 18)
|
||||
#define LOG_VICTIM (1 << 19)
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#define MECHA_INT_FIRE (1<<0)
|
||||
#define MECHA_INT_TEMP_CONTROL (1<<1)
|
||||
#define MECHA_INT_SHORT_CIRCUIT (1<<2)
|
||||
#define MECHA_INT_TANK_BREACH (1<<3)
|
||||
#define MECHA_INT_CONTROL_LOST (1<<4)
|
||||
|
||||
#define ADDING_ACCESS_POSSIBLE (1<<0)
|
||||
#define ADDING_MAINT_ACCESS_POSSIBLE (1<<1)
|
||||
#define CANSTRAFE (1<<2)
|
||||
#define LIGHTS_ON (1<<3)
|
||||
#define SILICON_PILOT (1<<4)
|
||||
#define IS_ENCLOSED (1<<5)
|
||||
#define HAS_LIGHTS (1<<6)
|
||||
#define QUIET_STEPS (1<<7)
|
||||
#define QUIET_TURNS (1<<8)
|
||||
///blocks using equipment and melee attacking.
|
||||
#define CANNOT_INTERACT (1<<9)
|
||||
/// posibrains can drive this mecha
|
||||
#define MMI_COMPATIBLE (1<<10)
|
||||
|
||||
#define MECHA_MELEE (1 << 0)
|
||||
#define MECHA_RANGED (1 << 1)
|
||||
|
||||
#define MECHA_FRONT_ARMOUR 1
|
||||
#define MECHA_SIDE_ARMOUR 2
|
||||
#define MECHA_BACK_ARMOUR 3
|
||||
|
||||
#define MECHA_LOCKED 0
|
||||
#define MECHA_SECURE_BOLTS 1
|
||||
#define MECHA_LOOSE_BOLTS 2
|
||||
#define MECHA_OPEN_HATCH 3
|
||||
@@ -11,6 +11,11 @@
|
||||
///changing around settings and the like.
|
||||
#define VEHICLE_CONTROL_SETTINGS (1<<4)
|
||||
|
||||
|
||||
///ez define for giving a single pilot mech all the flags it needs.
|
||||
#define FULL_MECHA_CONTROL ALL
|
||||
|
||||
|
||||
//car_traits flags
|
||||
///Will this car kidnap people by ramming into them?
|
||||
#define CAN_KIDNAP (1<<0)
|
||||
|
||||
@@ -55,11 +55,6 @@
|
||||
if(modifiers["shift"] && modifiers["ctrl"])
|
||||
CtrlShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["middle"])
|
||||
if(controlled_mech) //Are we piloting a mech? Placed here so the modifiers are not overridden.
|
||||
controlled_mech.click_action(A, src, params) //Override AI normal click behavior.
|
||||
return
|
||||
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
|
||||
@@ -82,11 +82,6 @@
|
||||
if(!modifiers["catcher"] && A.IsObscured())
|
||||
return
|
||||
|
||||
if(ismecha(loc))
|
||||
var/obj/mecha/M = loc
|
||||
M.click_action(A,src,params)
|
||||
return TRUE
|
||||
|
||||
if(restrained())
|
||||
DelayNextAction(CLICK_CD_HANDCUFFED)
|
||||
return RestrainedClickOn(A)
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
if(!modifiers["catcher"] && A.IsObscured())
|
||||
return
|
||||
|
||||
if(ismecha(loc))
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A,src,params)
|
||||
|
||||
if(restrained())
|
||||
DelayNextAction(CLICK_CD_HANDCUFFED)
|
||||
return RestrainedClickOn(A)
|
||||
|
||||
@@ -381,14 +381,14 @@
|
||||
/*~~~~~~~~~~~~~~~~~~~~
|
||||
BIG STOMPY MECHS
|
||||
~~~~~~~~~~~~~~~~~~~~~*/
|
||||
/obj/mecha/proc/diag_hud_set_mechhealth()
|
||||
/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechhealth()
|
||||
var/image/holder = hud_list[DIAG_MECH_HUD]
|
||||
var/icon/I = icon(icon, icon_state, dir)
|
||||
holder.pixel_y = I.Height() - world.icon_size
|
||||
holder.icon_state = "huddiag[RoundDiagBar(obj_integrity/max_integrity)]"
|
||||
|
||||
|
||||
/obj/mecha/proc/diag_hud_set_mechcell()
|
||||
/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechcell()
|
||||
var/image/holder = hud_list[DIAG_BATT_HUD]
|
||||
var/icon/I = icon(icon, icon_state, dir)
|
||||
holder.pixel_y = I.Height() - world.icon_size
|
||||
@@ -399,7 +399,7 @@
|
||||
holder.icon_state = "hudnobatt"
|
||||
|
||||
|
||||
/obj/mecha/proc/diag_hud_set_mechstat()
|
||||
/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechstat()
|
||||
var/image/holder = hud_list[DIAG_STAT_HUD]
|
||||
var/icon/I = icon(icon, icon_state, dir)
|
||||
holder.pixel_y = I.Height() - world.icon_size
|
||||
@@ -407,7 +407,7 @@
|
||||
if(internal_damage)
|
||||
holder.icon_state = "hudwarn"
|
||||
|
||||
/obj/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech
|
||||
/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech
|
||||
var/image/holder = hud_list[DIAG_TRACK_HUD]
|
||||
var/icon/I = icon(icon, icon_state, dir)
|
||||
holder.pixel_y = I.Height() - world.icon_size
|
||||
|
||||
@@ -159,7 +159,7 @@ SUBSYSTEM_DEF(traumas)
|
||||
/obj/item/storage/backpack/mime, /obj/item/reagent_containers/food/snacks/grown/banana/mime,
|
||||
/obj/item/grown/bananapeel/mimanapeel, /obj/item/cartridge/virus/mime, /obj/item/clothing/shoes/sneakers/mime,
|
||||
/obj/item/bedsheet/mime, /obj/item/reagent_containers/food/snacks/burger/mime, /obj/item/clothing/head/beret,
|
||||
/obj/item/toy/figure/mime, /obj/item/toy/crayon/mime, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced, /obj/mecha/combat/reticence)),
|
||||
/obj/item/toy/figure/mime, /obj/item/toy/crayon/mime, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced, /obj/vehicle/sealed/mecha/combat/reticence)),
|
||||
|
||||
"cats" = typecacheof(list(/obj/item/organ/ears/cat, /obj/item/organ/tail/cat, /obj/item/laser_pointer, /obj/item/toy/cattoy, /obj/item/clothing/head/kitty,
|
||||
/obj/item/clothing/head/collectable/kitty, /obj/item/melee/chainofcommand/tailwhip/kitty, /obj/item/stack/sheet/animalhide/cat)),
|
||||
@@ -169,7 +169,7 @@ SUBSYSTEM_DEF(traumas)
|
||||
/obj/structure/fluff/empty_sleeper/syndicate, /obj/item/implant/radio/syndicate, /obj/item/clothing/head/helmet/space/syndicate, /obj/machinery/nuclearbomb/syndicate, /obj/item/grenade/syndieminibomb, /obj/item/storage/backpack/duffelbag/syndie, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver,
|
||||
/obj/item/gun/ballistic/automatic/shotgun/bulldog, /obj/item/gun/ballistic/automatic/c20r, /obj/item/gun/ballistic/automatic/m90, /obj/item/gun/ballistic/automatic/l6_saw, /obj/item/storage/belt/grenade/full, /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate, /obj/item/gun/energy/kinetic_accelerator/crossbow,
|
||||
/obj/item/melee/transforming/energy/sword/saber, /obj/item/dualsaber, /obj/item/melee/powerfist, /obj/item/storage/box/syndie_kit, /obj/item/grenade/spawnergrenade/manhacks, /obj/item/grenade/chem_grenade/bioterrorfoam, /obj/item/reagent_containers/spray/chemsprayer/bioterror, /obj/item/ammo_box/magazine/m10mm,
|
||||
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/mecha/combat/gygax/dark, /obj/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate,
|
||||
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate,
|
||||
/obj/item/cartridge/virus/frame, /obj/item/chameleon, /obj/item/storage/box/syndie_kit/cutouts, /obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/card/emag, /obj/item/storage/toolbox/syndicate, /obj/item/storage/book/bible/syndicate, /obj/item/encryptionkey/binary, /obj/item/encryptionkey/syndicate, /obj/item/aiModule/syndicate,
|
||||
/obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited,
|
||||
/obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/fingerless/pugilist/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate,
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]-[wound]"
|
||||
|
||||
#define MELEE "melee"
|
||||
#define BULLET "bullet"
|
||||
#define LASER "laser"
|
||||
#define ENERGY "energy"
|
||||
#define BOMB "bomb"
|
||||
#define BIO "bio"
|
||||
#define RAD "rad"
|
||||
#define FIRE "fire"
|
||||
#define ACID "acid"
|
||||
#define MAGIC "magic"
|
||||
#define WOUND "wound"
|
||||
|
||||
|
||||
/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0)
|
||||
. = locate(ARMORID)
|
||||
if (!.)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/applyplate)
|
||||
RegisterSignal(parent, COMSIG_PARENT_PREQDELETED, .proc/dropplates)
|
||||
if(istype(parent, /obj/mecha/working/ripley))
|
||||
if(istype(parent, /obj/vehicle/sealed/mecha/working/ripley))
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_mech_overlays)
|
||||
|
||||
if(_maxamount)
|
||||
@@ -67,7 +67,7 @@
|
||||
O.armor = O.armor.attachArmor(added_armor)
|
||||
|
||||
if(ismecha(O))
|
||||
var/obj/mecha/R = O
|
||||
var/obj/vehicle/sealed/mecha/R = O
|
||||
R.update_icon()
|
||||
to_chat(user, "<span class='info'>You strengthen [R], improving its resistance against melee, bullet and laser damage.</span>")
|
||||
else
|
||||
@@ -80,11 +80,11 @@
|
||||
for(var/i in 1 to amount)
|
||||
new upgrade_item(get_turf(parent))
|
||||
|
||||
/datum/component/armor_plate/proc/apply_mech_overlays(obj/mecha/mech, list/overlays)
|
||||
/datum/component/armor_plate/proc/apply_mech_overlays(obj/vehicle/sealed/mecha/mech, list/overlays)
|
||||
if(amount)
|
||||
var/overlay_string = "ripley-g"
|
||||
if(amount >= 3)
|
||||
overlay_string += "-full"
|
||||
if(!mech.occupant)
|
||||
if(LAZYLEN(mech.occupants))
|
||||
overlay_string += "-open"
|
||||
overlays += overlay_string
|
||||
|
||||
@@ -896,9 +896,6 @@
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir)
|
||||
dir = newdir
|
||||
|
||||
/atom/proc/mech_melee_attack(obj/mecha/M)
|
||||
return
|
||||
|
||||
//If a mob logouts/logins in side of an object you can use this proc
|
||||
/atom/proc/on_log(login)
|
||||
if(loc)
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
projectiles = 8
|
||||
projectile_energy_cost = 1000
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana/can_attach(obj/mecha/combat/honker/M)
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana/can_attach(obj/vehicle/sealed/mecha/combat/honker/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return TRUE
|
||||
@@ -261,13 +261,13 @@
|
||||
equip_cooldown = 60
|
||||
det_time = 20
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache/can_attach(obj/mecha/combat/honker/M)
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache/can_attach(obj/vehicle/sealed/mecha/combat/honker/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/mecha/combat/honker/dark
|
||||
/obj/vehicle/sealed/mecha/combat/honker/dark
|
||||
desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. This one has been painted black for maximum fun. HONK!"
|
||||
name = "\improper Dark H.O.N.K"
|
||||
icon_state = "darkhonker"
|
||||
@@ -280,23 +280,14 @@
|
||||
wreckage = /obj/structure/mecha_wreckage/honker/dark
|
||||
max_equip = 3
|
||||
|
||||
/obj/mecha/combat/honker/dark/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Grant(user, src)
|
||||
|
||||
|
||||
/obj/mecha/combat/honker/dark/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/honker/dark/add_cell(obj/item/stock_parts/cell/C)
|
||||
/obj/vehicle/sealed/mecha/combat/honker/dark/add_cell(obj/item/stock_parts/cell/C)
|
||||
if(C)
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
return
|
||||
cell = new /obj/item/stock_parts/cell/hyper(src)
|
||||
|
||||
/obj/mecha/combat/honker/dark/loaded/Initialize()
|
||||
/obj/vehicle/sealed/mecha/combat/honker/dark/loaded/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/honker()
|
||||
ME.attach(src)
|
||||
|
||||
@@ -107,19 +107,6 @@
|
||||
return
|
||||
bumpopen(M)
|
||||
return
|
||||
|
||||
if(ismecha(AM))
|
||||
var/obj/mecha/mecha = AM
|
||||
if(density)
|
||||
if(mecha.occupant)
|
||||
if(world.time - mecha.occupant.last_bumped <= 10)
|
||||
return
|
||||
mecha.occupant.last_bumped = world.time
|
||||
if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access)))
|
||||
open()
|
||||
else
|
||||
do_animate("deny")
|
||||
return
|
||||
return
|
||||
|
||||
/obj/machinery/door/Move()
|
||||
@@ -362,7 +349,7 @@
|
||||
C.bleed(DOOR_CRUSH_DAMAGE)
|
||||
else
|
||||
L.add_splatter_floor(location)
|
||||
for(var/obj/mecha/M in get_turf(src))
|
||||
for(var/obj/vehicle/sealed/mecha/M in get_turf(src))
|
||||
M.take_damage(DOOR_CRUSH_DAMAGE)
|
||||
|
||||
/obj/machinery/door/proc/autoclose()
|
||||
|
||||
@@ -77,11 +77,13 @@
|
||||
return
|
||||
if (!( ismob(AM) ))
|
||||
if(ismecha(AM))
|
||||
var/obj/mecha/mecha = AM
|
||||
if(mecha.occupant && src.allowed(mecha.occupant))
|
||||
open_and_close()
|
||||
else
|
||||
do_animate("deny")
|
||||
var/obj/vehicle/sealed/mecha/mecha = AM
|
||||
for(var/O in mecha.occupants)
|
||||
var/mob/living/occupant = O
|
||||
if(allowed(occupant))
|
||||
open_and_close()
|
||||
return
|
||||
do_animate("deny")
|
||||
return
|
||||
if (!( SSticker ))
|
||||
return
|
||||
|
||||
@@ -478,10 +478,12 @@
|
||||
|
||||
for(var/A in GLOB.mechas_list)
|
||||
if((get_dist(A, base) < scan_range) && can_see(base, A, scan_range))
|
||||
var/obj/mecha/Mech = A
|
||||
if(Mech.occupant && !in_faction(Mech.occupant)) //If there is a user and they're not in our faction
|
||||
if(assess_perp(Mech.occupant) >= 4)
|
||||
targets += Mech
|
||||
var/obj/vehicle/sealed/mecha/mech = A
|
||||
for(var/O in mech.occupants)
|
||||
var/mob/living/occupant = O
|
||||
if(!in_faction(occupant)) //If there is a user and they're not in our faction
|
||||
if(assess_perp(occupant) >= 4)
|
||||
targets += mech
|
||||
|
||||
if((turret_flags & TURRET_FLAG_SHOOT_ANOMALOUS) && GLOB.blobs.len && (mode == TURRET_LETHAL))
|
||||
for(var/obj/structure/blob/B in view(scan_range, base))
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/obj/mecha/combat
|
||||
force = 30
|
||||
internal_damage_threshold = 50
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 15, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
|
||||
|
||||
/obj/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this
|
||||
for(var/obj/item/I in equipment)
|
||||
if(istype(I, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/))
|
||||
var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun = I
|
||||
gun.projectiles_cache = gun.projectiles_cache_max
|
||||
@@ -1,21 +0,0 @@
|
||||
/obj/mecha/combat/durand
|
||||
desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms."
|
||||
name = "\improper Durand"
|
||||
icon_state = "durand"
|
||||
step_in = 4
|
||||
dir_in = 1 //Facing North.
|
||||
max_integrity = 400
|
||||
deflect_chance = 20
|
||||
armor = list("melee" = 40, "bullet" = 35, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
max_temperature = 30000
|
||||
infra_luminosity = 8
|
||||
force = 40
|
||||
wreckage = /obj/structure/mecha_wreckage/durand
|
||||
|
||||
/obj/mecha/combat/durand/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
defense_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/durand/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
defense_action.Remove(user)
|
||||
@@ -1,68 +0,0 @@
|
||||
/obj/mecha/combat/gygax
|
||||
desc = "A lightweight, security exosuit. Popular among private and corporate security."
|
||||
name = "\improper Gygax"
|
||||
icon_state = "gygax"
|
||||
step_in = 3
|
||||
dir_in = 1 //Facing North.
|
||||
max_integrity = 250
|
||||
deflect_chance = 5
|
||||
force = 20
|
||||
armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
max_temperature = 25000
|
||||
infra_luminosity = 6
|
||||
wreckage = /obj/structure/mecha_wreckage/gygax
|
||||
internal_damage_threshold = 35
|
||||
max_equip = 3
|
||||
step_energy_drain = 3
|
||||
leg_overload_coeff = 300
|
||||
|
||||
/obj/mecha/combat/gygax/dark
|
||||
desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications."
|
||||
name = "\improper Dark Gygax"
|
||||
icon_state = "darkgygax"
|
||||
max_integrity = 300
|
||||
deflect_chance = 15
|
||||
force = 25
|
||||
armor = list("melee" = 40, "bullet" = 40, "laser" = 50, "energy" = 35, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
max_temperature = 35000
|
||||
leg_overload_coeff = 100
|
||||
operation_req_access = list(ACCESS_SYNDICATE)
|
||||
internals_req_access = list(ACCESS_SYNDICATE)
|
||||
wreckage = /obj/structure/mecha_wreckage/gygax/dark
|
||||
max_equip = 4
|
||||
|
||||
/obj/mecha/combat/gygax/dark/loaded/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/teleporter
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
|
||||
ME.attach(src)
|
||||
max_ammo()
|
||||
|
||||
/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null)
|
||||
if(C)
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
return
|
||||
cell = new /obj/item/stock_parts/cell/hyper(src)
|
||||
|
||||
/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
overload_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Grant(user, src)
|
||||
|
||||
|
||||
/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
overload_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Remove(user)
|
||||
@@ -1,29 +0,0 @@
|
||||
/obj/mecha/combat/phazon
|
||||
desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge bluespace technology and expensive materials."
|
||||
name = "\improper Phazon"
|
||||
icon_state = "phazon"
|
||||
step_in = 2
|
||||
dir_in = 2 //Facing South.
|
||||
step_energy_drain = 3
|
||||
max_integrity = 200
|
||||
deflect_chance = 30
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
max_temperature = 25000
|
||||
infra_luminosity = 3
|
||||
wreckage = /obj/structure/mecha_wreckage/phazon
|
||||
add_req_access = 1
|
||||
internal_damage_threshold = 25
|
||||
force = 15
|
||||
max_equip = 3
|
||||
phase_state = "phazon-phase"
|
||||
|
||||
/obj/mecha/combat/phazon/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
switch_damtype_action.Grant(user, src)
|
||||
phasing_action.Grant(user, src)
|
||||
|
||||
|
||||
/obj/mecha/combat/phazon/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
switch_damtype_action.Remove(user)
|
||||
phasing_action.Remove(user)
|
||||
@@ -1,171 +0,0 @@
|
||||
//DO NOT ADD MECHA PARTS TO THE GAME WITH THE DEFAULT "SPRITE ME" SPRITE!
|
||||
//I'm annoyed I even have to tell you this! SPRITE FIRST, then commit.
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment
|
||||
name = "mecha equipment"
|
||||
icon = 'icons/mecha/mecha_equipment.dmi'
|
||||
icon_state = "mecha_equip"
|
||||
force = 5
|
||||
max_integrity = 300
|
||||
var/equip_cooldown = 0 // cooldown after use
|
||||
var/equip_ready = 1 //whether the equipment is ready for use. (or deactivated/activated for static stuff)
|
||||
var/energy_drain = 0
|
||||
var/obj/mecha/chassis = null
|
||||
/// Bitflag. Determines the range of the equipment.
|
||||
var/range = MELEE
|
||||
/// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this.
|
||||
var/mech_flags = NONE
|
||||
var/salvageable = 1
|
||||
//var/detachable = TRUE // Set to FALSE for built-in equipment that cannot be removed
|
||||
var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates
|
||||
var/harmful = FALSE //Controls if equipment can be used to attack by a pacifist.
|
||||
//var/destroy_sound = 'sound/mecha/critdestr.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/update_chassis_page()
|
||||
if(chassis)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
||||
send_byjax(chassis.occupant,"exosuit.browser","equipment_menu",chassis.get_equipment_menu(),"dropdowns")
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/update_equip_info()
|
||||
if(chassis)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",get_equip_info())
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/Destroy()
|
||||
if(chassis)
|
||||
chassis.equipment -= src
|
||||
if(chassis.selected == src)
|
||||
chassis.selected = null
|
||||
src.update_chassis_page()
|
||||
//log_message("[src] is destroyed.", LOG_MECHA)
|
||||
chassis.log_append_to_last("[src] is destroyed.",1)
|
||||
if(chassis.occupant)
|
||||
chassis.occupant_message("<span class='danger'>[src] is destroyed!</span>")
|
||||
SEND_SOUND(chassis.occupant, sound(istype(src, /obj/item/mecha_parts/mecha_equipment/weapon) ? 'sound/mecha/weapdestr.ogg' : 'sound/mecha/critdestr.ogg', volume=50))
|
||||
//chassis.occupant.playsound_local(chassis, destroy_sound, 50)
|
||||
//if(!detachable) //If we're a built-in nondetachable equipment, let's lock up the slot that we were in.
|
||||
// chassis.max_equip--
|
||||
chassis = null
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/critfail()
|
||||
if(chassis)
|
||||
mecha_log_message("Critical failure", color="red")
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/get_equip_info()
|
||||
if(!chassis)
|
||||
return
|
||||
var/txt = "<span style=\"color:[equip_ready?"#0f0":"#f00"];\">*</span> "
|
||||
if(chassis.selected == src)
|
||||
txt += "<b>[src.name]</b>"
|
||||
else if(selectable)
|
||||
txt += "<a href='?src=[REF(chassis)];select_equip=[REF(src)]'>[src.name]</a>"
|
||||
else
|
||||
txt += "[src.name]"
|
||||
|
||||
return txt
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/is_ranged()//add a distance restricted equipment. Why not?
|
||||
return range&RANGED //rename to MECHA_RANGE and MECHA_MELEE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/is_melee()
|
||||
return range&MELEE
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target)
|
||||
if(!target)
|
||||
return 0
|
||||
if(!chassis)
|
||||
return 0
|
||||
if(!equip_ready)
|
||||
return 0
|
||||
if(energy_drain && !chassis.has_charge(energy_drain))
|
||||
return 0
|
||||
if(crit_fail)
|
||||
return 0
|
||||
if(chassis.equipment_disabled)
|
||||
to_chat(chassis.occupant, "<span=warn>Error -- Equipment control unit is unresponsive.</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/action(atom/target)
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/start_cooldown()
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain)
|
||||
addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target)
|
||||
if(!chassis)
|
||||
return
|
||||
var/C = chassis.loc
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain)
|
||||
. = do_after(chassis.occupant, equip_cooldown, target=target)
|
||||
set_ready_state(1)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, delay)
|
||||
if(!chassis)
|
||||
return
|
||||
var/C = chassis.loc
|
||||
. = do_after(chassis.occupant, delay, target=target)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M)
|
||||
if(M.equipment.len<M.max_equip)
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/attach(obj/mecha/M)
|
||||
M.equipment += src
|
||||
chassis = M
|
||||
forceMove(M)
|
||||
M.mecha_log_message("[src] initialized.")
|
||||
src.update_chassis_page()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/detach(atom/moveto=null)
|
||||
moveto = moveto || get_turf(chassis)
|
||||
if(src.Move(moveto))
|
||||
chassis.equipment -= src
|
||||
if(chassis.selected == src)
|
||||
chassis.selected = null
|
||||
update_chassis_page()
|
||||
chassis.mecha_log_message("[src] removed from equipment.")
|
||||
chassis = null
|
||||
set_ready_state(1)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/Topic(href,href_list)
|
||||
if(href_list["detach"])
|
||||
detach()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/set_ready_state(state)
|
||||
equip_ready = state
|
||||
if(chassis)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/occupant_message(message)
|
||||
if(chassis)
|
||||
chassis.occupant_message("[icon2html(src, chassis.occupant)] [message]")
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/mecha_log_message(message, color) //on tg this just overrides log_message
|
||||
log_message(message, LOG_GAME, color) //pass to default admin logging too
|
||||
if(chassis)
|
||||
chassis.mecha_log_message(message, color) //and pass to our chassis
|
||||
|
||||
//Used for reloading weapons/tools etc. that use some form of resource
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/rearm()
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/needs_rearm()
|
||||
return 0
|
||||
@@ -1,480 +0,0 @@
|
||||
|
||||
//Hydraulic clamp, Kill clamp, Extinguisher, RCD, Cable layer.
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp
|
||||
name = "hydraulic clamp"
|
||||
desc = "Equipment for engineering exosuits. Lifts objects and loads them into cargo."
|
||||
icon_state = "mecha_clamp"
|
||||
equip_cooldown = 15
|
||||
energy_drain = 10
|
||||
tool_behaviour = TOOL_RETRACTOR
|
||||
toolspeed = 0.8
|
||||
var/dam_force = 20
|
||||
var/obj/mecha/working/ripley/cargo_holder
|
||||
harmful = TRUE
|
||||
mech_flags = EXOSUIT_MODULE_RIPLEY
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/mecha/working/ripley/M as obj)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/attach(obj/mecha/M as obj)
|
||||
..()
|
||||
cargo_holder = M
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/detach(atom/moveto = null)
|
||||
..()
|
||||
cargo_holder = null
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/action(atom/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(!cargo_holder)
|
||||
return
|
||||
if(ismecha(target))
|
||||
var/obj/mecha/M = target
|
||||
var/have_ammo
|
||||
for(var/obj/item/mecha_ammo/box in cargo_holder.cargo)
|
||||
if(istype(box, /obj/item/mecha_ammo) && box.rounds)
|
||||
have_ammo = TRUE
|
||||
if(M.ammo_resupply(box, chassis.occupant, TRUE))
|
||||
return
|
||||
if(have_ammo)
|
||||
to_chat(chassis.occupant, "No further supplies can be provided to [M].")
|
||||
else
|
||||
to_chat(chassis.occupant, "No providable supplies found in cargo hold")
|
||||
return
|
||||
if(isobj(target))
|
||||
var/obj/O = target
|
||||
if(!O.anchored)
|
||||
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
|
||||
chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.")
|
||||
O.anchored = TRUE
|
||||
if(do_after_cooldown(target))
|
||||
cargo_holder.cargo += O
|
||||
O.forceMove(chassis)
|
||||
O.anchored = FALSE
|
||||
occupant_message("<span class='notice'>[target] successfully loaded.</span>")
|
||||
mecha_log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]")
|
||||
else
|
||||
O.anchored = initial(O.anchored)
|
||||
else
|
||||
occupant_message("<span class='warning'>Not enough room in cargo compartment!</span>")
|
||||
else
|
||||
occupant_message("<span class='warning'>[target] is firmly secured!</span>")
|
||||
|
||||
else if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
if(M.stat == DEAD)
|
||||
return
|
||||
if(chassis.occupant.a_intent == INTENT_HARM)
|
||||
M.take_overall_damage(dam_force)
|
||||
if(!M)
|
||||
return
|
||||
M.adjustOxyLoss(round(dam_force/2))
|
||||
M.updatehealth()
|
||||
target.visible_message("<span class='danger'>[chassis] squeezes [target].</span>", \
|
||||
"<span class='userdanger'>[chassis] squeezes [target].</span>",\
|
||||
"<span class='italics'>You hear something crack.</span>")
|
||||
log_combat(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])")
|
||||
else
|
||||
step_away(M,chassis)
|
||||
occupant_message("You push [target] out of the way.")
|
||||
chassis.visible_message("[chassis] pushes [target] out of the way.")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
//This is pretty much just for the death-ripley
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill
|
||||
name = "\improper KILL CLAMP"
|
||||
desc = "They won't know what clamped them!"
|
||||
energy_drain = 0
|
||||
dam_force = 0
|
||||
var/real_clamp = FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real
|
||||
desc = "They won't know what clamped them! This time for real!"
|
||||
energy_drain = 10
|
||||
dam_force = 20
|
||||
real_clamp = TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(atom/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(!cargo_holder)
|
||||
return
|
||||
if(isobj(target))
|
||||
var/obj/O = target
|
||||
if(!O.anchored)
|
||||
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
|
||||
chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.")
|
||||
O.anchored = TRUE
|
||||
if(do_after_cooldown(target))
|
||||
cargo_holder.cargo += O
|
||||
O.forceMove(chassis)
|
||||
O.anchored = FALSE
|
||||
occupant_message("<span class='notice'>[target] successfully loaded.</span>")
|
||||
mecha_log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]")
|
||||
else
|
||||
O.anchored = initial(O.anchored)
|
||||
else
|
||||
occupant_message("<span class='warning'>Not enough room in cargo compartment!</span>")
|
||||
else
|
||||
occupant_message("<span class='warning'>[target] is firmly secured!</span>")
|
||||
|
||||
else if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
if(M.stat == DEAD)
|
||||
return
|
||||
if(chassis.occupant.a_intent == INTENT_HARM)
|
||||
if(real_clamp)
|
||||
M.take_overall_damage(dam_force)
|
||||
if(!M)
|
||||
return
|
||||
M.adjustOxyLoss(round(dam_force/2))
|
||||
M.updatehealth()
|
||||
target.visible_message("<span class='danger'>[chassis] destroys [target] in an unholy fury.</span>", \
|
||||
"<span class='userdanger'>[chassis] destroys [target] in an unholy fury.</span>")
|
||||
log_combat(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])")
|
||||
else
|
||||
target.visible_message("<span class='danger'>[chassis] destroys [target] in an unholy fury.</span>", \
|
||||
"<span class='userdanger'>[chassis] destroys [target] in an unholy fury.</span>")
|
||||
else if(chassis.occupant.a_intent == INTENT_DISARM)
|
||||
if(real_clamp)
|
||||
var/mob/living/carbon/C = target
|
||||
var/play_sound = FALSE
|
||||
var/limbs_gone = ""
|
||||
var/obj/item/bodypart/affected = C.get_bodypart(BODY_ZONE_L_ARM)
|
||||
if(affected != null)
|
||||
affected.dismember(damtype)
|
||||
play_sound = TRUE
|
||||
limbs_gone = ", [affected]"
|
||||
affected = C.get_bodypart(BODY_ZONE_R_ARM)
|
||||
if(affected != null)
|
||||
affected.dismember(damtype)
|
||||
play_sound = TRUE
|
||||
limbs_gone = "[limbs_gone], [affected]"
|
||||
if(play_sound)
|
||||
playsound(src, get_dismember_sound(), 80, TRUE)
|
||||
target.visible_message("<span class='danger'>[chassis] rips [target]'s arms off.</span>", \
|
||||
"<span class='userdanger'>[chassis] rips [target]'s arms off.</span>")
|
||||
log_combat(chassis.occupant, M, "dismembered of[limbs_gone],", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])")
|
||||
else
|
||||
target.visible_message("<span class='danger'>[chassis] rips [target]'s arms off.</span>", \
|
||||
"<span class='userdanger'>[chassis] rips [target]'s arms off.</span>")
|
||||
else
|
||||
step_away(M,chassis)
|
||||
target.visible_message("[chassis] tosses [target] like a piece of paper.")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher
|
||||
name = "exosuit extinguisher"
|
||||
desc = "Equipment for engineering exosuits. A rapid-firing high capacity fire extinguisher."
|
||||
icon_state = "mecha_exting"
|
||||
equip_cooldown = 5
|
||||
energy_drain = 0
|
||||
range = MELEE|RANGED
|
||||
mech_flags = EXOSUIT_MODULE_WORKING
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize()
|
||||
. = ..()
|
||||
create_reagents(1000)
|
||||
reagents.add_reagent(/datum/reagent/water, 1000)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch.
|
||||
if(!action_checks(target) || get_dist(chassis, target)>3)
|
||||
return
|
||||
|
||||
if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1)
|
||||
var/obj/structure/reagent_dispensers/watertank/WT = target
|
||||
WT.reagents.trans_to(src, 1000)
|
||||
occupant_message("<span class='notice'>Extinguisher refilled.</span>")
|
||||
playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6)
|
||||
else
|
||||
if(reagents.total_volume > 0)
|
||||
playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3)
|
||||
var/direction = get_dir(chassis,target)
|
||||
var/turf/T = get_turf(target)
|
||||
var/turf/T1 = get_step(T,turn(direction, 90))
|
||||
var/turf/T2 = get_step(T,turn(direction, -90))
|
||||
|
||||
var/list/the_targets = list(T,T1,T2)
|
||||
spawn(0)
|
||||
for(var/a=0, a<5, a++)
|
||||
var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(chassis))
|
||||
if(!W)
|
||||
return
|
||||
var/turf/my_target = pick(the_targets)
|
||||
var/datum/reagents/R = new/datum/reagents(5)
|
||||
W.reagents = R
|
||||
R.my_atom = W
|
||||
reagents.trans_to(W,1)
|
||||
for(var/b=0, b<4, b++)
|
||||
if(!W)
|
||||
return
|
||||
step_towards(W,my_target)
|
||||
if(!W)
|
||||
return
|
||||
var/turf/W_turf = get_turf(W)
|
||||
W.reagents.reaction(W_turf)
|
||||
for(var/atom/atm in W_turf)
|
||||
W.reagents.reaction(atm)
|
||||
if(W.loc == my_target)
|
||||
break
|
||||
sleep(2)
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info()
|
||||
return "[..()] \[[src.reagents.total_volume]\]"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/can_attach(obj/mecha/working/M as obj)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd
|
||||
name = "mounted RCD"
|
||||
desc = "An exosuit-mounted Rapid Construction Device."
|
||||
icon_state = "mecha_rcd"
|
||||
equip_cooldown = 10
|
||||
energy_drain = 250
|
||||
range = MELEE|RANGED
|
||||
item_flags = NO_MAT_REDEMPTION
|
||||
var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock.
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/Initialize()
|
||||
. = ..()
|
||||
GLOB.rcd_list += src
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/Destroy()
|
||||
GLOB.rcd_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/action(atom/target)
|
||||
if(istype(target, /turf/open/space/transit))//>implying these are ever made -Sieve
|
||||
return
|
||||
|
||||
if(!isturf(target) && !istype(target, /obj/machinery/door/airlock))
|
||||
target = get_turf(target)
|
||||
if(!action_checks(target) || get_dist(chassis, target)>3)
|
||||
return
|
||||
playsound(chassis, 'sound/machines/click.ogg', 50, 1)
|
||||
|
||||
switch(mode)
|
||||
if(0)
|
||||
if(iswallturf(target))
|
||||
var/turf/closed/wall/W = target
|
||||
occupant_message("Deconstructing [W]...")
|
||||
if(do_after_cooldown(W))
|
||||
chassis.spark_system.start()
|
||||
W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(W, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
else if(isfloorturf(target))
|
||||
var/turf/open/floor/F = target
|
||||
occupant_message("Deconstructing [F]...")
|
||||
if(do_after_cooldown(target))
|
||||
chassis.spark_system.start()
|
||||
F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(F, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
else if (istype(target, /obj/machinery/door/airlock))
|
||||
occupant_message("Deconstructing [target]...")
|
||||
if(do_after_cooldown(target))
|
||||
chassis.spark_system.start()
|
||||
qdel(target)
|
||||
playsound(target, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
if(1)
|
||||
if(isspaceturf(target))
|
||||
var/turf/open/space/S = target
|
||||
occupant_message("Building Floor...")
|
||||
if(do_after_cooldown(S))
|
||||
S.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(S, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
else if(isfloorturf(target))
|
||||
var/turf/open/floor/F = target
|
||||
occupant_message("Building Wall...")
|
||||
if(do_after_cooldown(F))
|
||||
F.PlaceOnTop(/turf/closed/wall)
|
||||
playsound(F, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
if(2)
|
||||
if(isfloorturf(target))
|
||||
occupant_message("Building Airlock...")
|
||||
if(do_after_cooldown(target))
|
||||
chassis.spark_system.start()
|
||||
var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target)
|
||||
T.autoclose = TRUE
|
||||
playsound(target, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
playsound(target, 'sound/effects/sparks2.ogg', 50, 1)
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/do_after_cooldown(var/atom/target)
|
||||
. = ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/Topic(href,href_list)
|
||||
..()
|
||||
if(href_list["mode"])
|
||||
mode = text2num(href_list["mode"])
|
||||
switch(mode)
|
||||
if(0)
|
||||
occupant_message("Switched RCD to Deconstruct.")
|
||||
energy_drain = initial(energy_drain)
|
||||
if(1)
|
||||
occupant_message("Switched RCD to Construct.")
|
||||
energy_drain = 2*initial(energy_drain)
|
||||
if(2)
|
||||
occupant_message("Switched RCD to Construct Airlock.")
|
||||
energy_drain = 2*initial(energy_drain)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/get_equip_info()
|
||||
return "[..()] \[<a href='?src=[REF(src)];mode=0'>D</a>|<a href='?src=[REF(src)];mode=1'>C</a>|<a href='?src=[REF(src)];mode=2'>A</a>\]"
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer
|
||||
name = "cable layer"
|
||||
desc = "Equipment for engineering exosuits. Lays cable along the exosuit's path."
|
||||
icon_state = "mecha_wire"
|
||||
var/datum/callback/event
|
||||
var/turf/old_turf
|
||||
var/obj/structure/cable/last_piece
|
||||
var/obj/item/stack/cable_coil/cable
|
||||
var/max_cable = 1000
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/Initialize()
|
||||
. = ..()
|
||||
cable = new(src, 0)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/can_attach(obj/mecha/working/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/attach()
|
||||
..()
|
||||
event = chassis.events.addEvent("onMove", CALLBACK(src, .proc/layCable))
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/detach()
|
||||
chassis.events.clearEvent("onMove",event)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/Destroy()
|
||||
if(chassis)
|
||||
chassis.events.clearEvent("onMove",event)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/action(var/obj/item/stack/cable_coil/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(istype(target) && target.amount)
|
||||
var/cur_amount = cable? cable.amount : 0
|
||||
var/to_load = max(max_cable - cur_amount,0)
|
||||
if(to_load)
|
||||
to_load = min(target.amount, to_load)
|
||||
if(!cable)
|
||||
cable = new(src, 0)
|
||||
cable.amount += to_load
|
||||
target.use(to_load)
|
||||
occupant_message("<span class='notice'>[to_load] meters of cable successfully loaded.</span>")
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
else
|
||||
occupant_message("<span class='warning'>Reel is full.</span>")
|
||||
else
|
||||
occupant_message("<span class='warning'>Unable to load [target] - no cable found.</span>")
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/Topic(href,href_list)
|
||||
..()
|
||||
if(href_list["toggle"])
|
||||
set_ready_state(!equip_ready)
|
||||
occupant_message("[src] [equip_ready?"dea":"a"]ctivated.")
|
||||
mecha_log_message("[equip_ready?"Dea":"A"]ctivated.")
|
||||
return
|
||||
if(href_list["cut"])
|
||||
if(cable && cable.amount)
|
||||
var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1)
|
||||
m = min(m, cable.amount)
|
||||
if(m)
|
||||
use_cable(m)
|
||||
new /obj/item/stack/cable_coil(get_turf(chassis), m)
|
||||
else
|
||||
occupant_message("There's no more cable on the reel.")
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/get_equip_info()
|
||||
var/output = ..()
|
||||
if(output)
|
||||
return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- <a href='?src=[REF(src)];toggle=1'>[!equip_ready?"Dea":"A"]ctivate</a>|<a href='?src=[REF(src)];cut=1'>Cut</a>" : null]"
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/use_cable(amount)
|
||||
if(!cable || cable.amount<1)
|
||||
set_ready_state(1)
|
||||
occupant_message("Cable depleted, [src] deactivated.")
|
||||
mecha_log_message("Cable depleted, [src] deactivated.")
|
||||
return
|
||||
if(cable.amount < amount)
|
||||
occupant_message("No enough cable to finish the task.")
|
||||
return
|
||||
cable.use(amount)
|
||||
update_equip_info()
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/reset()
|
||||
last_piece = null
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/dismantleFloor(var/turf/new_turf)
|
||||
if(isfloorturf(new_turf))
|
||||
var/turf/open/floor/T = new_turf
|
||||
if(!isplatingturf(T))
|
||||
if(!T.broken && !T.burnt)
|
||||
new T.floor_tile(T)
|
||||
T.make_plating()
|
||||
return !new_turf.intact
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/layCable(var/turf/new_turf)
|
||||
if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf))
|
||||
return reset()
|
||||
var/fdirn = turn(chassis.dir,180)
|
||||
for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already
|
||||
if(LC.d1 == fdirn || LC.d2 == fdirn)
|
||||
return reset()
|
||||
if(!use_cable(1))
|
||||
return reset()
|
||||
var/obj/structure/cable/NC = new(new_turf, "red")
|
||||
NC.d1 = 0
|
||||
NC.d2 = fdirn
|
||||
NC.update_icon()
|
||||
|
||||
var/datum/powernet/PN
|
||||
if(last_piece && last_piece.d2 != chassis.dir)
|
||||
last_piece.d1 = min(last_piece.d2, chassis.dir)
|
||||
last_piece.d2 = max(last_piece.d2, chassis.dir)
|
||||
last_piece.update_icon()
|
||||
PN = last_piece.powernet
|
||||
|
||||
if(!PN)
|
||||
PN = new()
|
||||
GLOB.powernets += PN
|
||||
NC.powernet = PN
|
||||
PN.cables += NC
|
||||
NC.mergeConnectedNetworks(NC.d2)
|
||||
|
||||
//NC.mergeConnectedNetworksOnTurf()
|
||||
last_piece = NC
|
||||
return 1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,285 +0,0 @@
|
||||
//////////////////////////////////////// Action Buttons ///////////////////////////////////////////////
|
||||
|
||||
/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0)
|
||||
if(human_occupant)
|
||||
eject_action.Grant(user, src)
|
||||
internals_action.Grant(user, src)
|
||||
cycle_action.Grant(user, src)
|
||||
lights_action.Grant(user, src)
|
||||
stats_action.Grant(user, src)
|
||||
strafing_action.Grant(user, src)
|
||||
|
||||
|
||||
/obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
if(human_occupant)
|
||||
eject_action.Remove(user)
|
||||
internals_action.Remove(user)
|
||||
cycle_action.Remove(user)
|
||||
lights_action.Remove(user)
|
||||
stats_action.Remove(user)
|
||||
strafing_action.Remove(user)
|
||||
|
||||
|
||||
/datum/action/innate/mecha
|
||||
check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS
|
||||
icon_icon = 'icons/mob/actions/actions_mecha.dmi'
|
||||
var/obj/mecha/chassis
|
||||
|
||||
/datum/action/innate/mecha/Grant(mob/living/L, obj/mecha/M)
|
||||
if(M)
|
||||
chassis = M
|
||||
..()
|
||||
|
||||
/datum/action/innate/mecha/Destroy()
|
||||
chassis = null
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/mecha/mech_eject
|
||||
name = "Eject From Mech"
|
||||
button_icon_state = "mech_eject"
|
||||
|
||||
/datum/action/innate/mecha/mech_eject/Activate()
|
||||
if(!owner)
|
||||
return
|
||||
if(!chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.go_out()
|
||||
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_internals
|
||||
name = "Toggle Internal Airtank Usage"
|
||||
button_icon_state = "mech_internals_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_internals/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.use_internal_tank = !chassis.use_internal_tank
|
||||
button_icon_state = "mech_internals_[chassis.use_internal_tank ? "on" : "off"]"
|
||||
chassis.occupant_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].")
|
||||
chassis.mecha_log_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].")
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_cycle_equip
|
||||
name = "Cycle Equipment"
|
||||
button_icon_state = "mech_cycle_equip_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_cycle_equip/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
|
||||
var/list/available_equipment = list()
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/M in chassis.equipment)
|
||||
if(M.selectable)
|
||||
available_equipment += M
|
||||
|
||||
if(available_equipment.len == 0)
|
||||
chassis.occupant_message("No equipment available.")
|
||||
return
|
||||
if(!chassis.selected)
|
||||
chassis.selected = available_equipment[1]
|
||||
chassis.occupant_message("You select [chassis.selected]")
|
||||
send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
||||
button_icon_state = "mech_cycle_equip_on"
|
||||
UpdateButtonIcon()
|
||||
return
|
||||
var/number = 0
|
||||
for(var/A in available_equipment)
|
||||
number++
|
||||
if(A == chassis.selected)
|
||||
if(available_equipment.len == number)
|
||||
chassis.selected = null
|
||||
chassis.occupant_message("You switch to no equipment")
|
||||
button_icon_state = "mech_cycle_equip_off"
|
||||
else
|
||||
chassis.selected = available_equipment[number+1]
|
||||
chassis.occupant_message("You switch to [chassis.selected]")
|
||||
button_icon_state = "mech_cycle_equip_on"
|
||||
send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
||||
UpdateButtonIcon()
|
||||
return
|
||||
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_lights
|
||||
name = "Toggle Lights"
|
||||
button_icon_state = "mech_lights_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_lights/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.lights = !chassis.lights
|
||||
if(chassis.lights)
|
||||
chassis.set_light(chassis.lights_power)
|
||||
button_icon_state = "mech_lights_on"
|
||||
else
|
||||
chassis.set_light(-chassis.lights_power)
|
||||
button_icon_state = "mech_lights_off"
|
||||
chassis.occupant_message("Toggled lights [chassis.lights?"on":"off"].")
|
||||
chassis.mecha_log_message("Toggled lights [chassis.lights?"on":"off"].")
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_view_stats
|
||||
name = "View Stats"
|
||||
button_icon_state = "mech_view_stats"
|
||||
|
||||
/datum/action/innate/mecha/mech_view_stats/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.occupant << browse(chassis.get_stats_html(), "window=exosuit")
|
||||
|
||||
|
||||
/datum/action/innate/mecha/strafe
|
||||
name = "Toggle Strafing. Disabled when Alt is held."
|
||||
button_icon_state = "strafe"
|
||||
|
||||
/datum/action/innate/mecha/strafe/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
|
||||
chassis.toggle_strafe()
|
||||
|
||||
/obj/mecha/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if((user == occupant) && user.canUseTopic(src))
|
||||
toggle_strafe()
|
||||
return TRUE
|
||||
|
||||
/obj/mecha/proc/toggle_strafe()
|
||||
strafe = !strafe
|
||||
|
||||
occupant_message("Toggled strafing mode [strafe?"on":"off"].")
|
||||
mecha_log_message("Toggled strafing mode [strafe?"on":"off"].")
|
||||
strafing_action.UpdateButtonIcon()
|
||||
|
||||
//////////////////////////////////////// Specific Ability Actions ///////////////////////////////////////////////
|
||||
//Need to be granted by the mech type, Not default abilities.
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_thrusters
|
||||
name = "Toggle Thrusters"
|
||||
button_icon_state = "mech_thrusters_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_thrusters/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(chassis.get_charge() > 0)
|
||||
chassis.thrusters_active = !chassis.thrusters_active
|
||||
button_icon_state = "mech_thrusters_[chassis.thrusters_active ? "on" : "off"]"
|
||||
chassis.mecha_log_message("Toggled thrusters.")
|
||||
chassis.occupant_message("<font color='[chassis.thrusters_active ?"blue":"red"]'>Thrusters [chassis.thrusters_active ?"en":"dis"]abled.")
|
||||
|
||||
|
||||
/datum/action/innate/mecha/mech_defence_mode
|
||||
name = "Toggle Defence Mode"
|
||||
button_icon_state = "mech_defense_mode_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_defence_mode/Activate(forced_state = null)
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(!isnull(forced_state))
|
||||
chassis.defence_mode = forced_state
|
||||
else
|
||||
chassis.defence_mode = !chassis.defence_mode
|
||||
button_icon_state = "mech_defense_mode_[chassis.defence_mode ? "on" : "off"]"
|
||||
if(chassis.defence_mode)
|
||||
chassis.deflect_chance = chassis.defence_mode_deflect_chance
|
||||
chassis.occupant_message("<span class='notice'>You enable [chassis] defence mode.</span>")
|
||||
else
|
||||
chassis.deflect_chance = initial(chassis.deflect_chance)
|
||||
chassis.occupant_message("<span class='danger'>You disable [chassis] defence mode.</span>")
|
||||
chassis.mecha_log_message("Toggled defence mode.")
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_overload_mode
|
||||
name = "Toggle leg actuators overload"
|
||||
button_icon_state = "mech_overload_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_overload_mode/Activate(forced_state = null)
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(!isnull(forced_state))
|
||||
chassis.leg_overload_mode = forced_state
|
||||
else
|
||||
chassis.leg_overload_mode = !chassis.leg_overload_mode
|
||||
button_icon_state = "mech_overload_[chassis.leg_overload_mode ? "on" : "off"]"
|
||||
chassis.mecha_log_message("Toggled leg actuators overload.")
|
||||
if(chassis.leg_overload_mode)
|
||||
chassis.leg_overload_mode = 1
|
||||
chassis.bumpsmash = 1
|
||||
chassis.step_in = min(1, round(chassis.step_in/2))
|
||||
chassis.step_energy_drain = max(chassis.overload_step_energy_drain_min,chassis.step_energy_drain*chassis.leg_overload_coeff)
|
||||
chassis.occupant_message("<span class='danger'>You enable leg actuators overload.</span>")
|
||||
else
|
||||
chassis.leg_overload_mode = 0
|
||||
chassis.bumpsmash = 0
|
||||
chassis.step_in = initial(chassis.step_in)
|
||||
chassis.step_energy_drain = chassis.normal_step_energy_drain
|
||||
chassis.occupant_message("<span class='notice'>You disable leg actuators overload.</span>")
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_smoke
|
||||
name = "Smoke"
|
||||
button_icon_state = "mech_smoke"
|
||||
|
||||
/datum/action/innate/mecha/mech_smoke/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(chassis.smoke_ready && chassis.smoke>0)
|
||||
chassis.smoke_system.start()
|
||||
chassis.smoke--
|
||||
chassis.smoke_ready = 0
|
||||
spawn(chassis.smoke_cooldown)
|
||||
chassis.smoke_ready = 1
|
||||
|
||||
|
||||
/datum/action/innate/mecha/mech_zoom
|
||||
name = "Zoom"
|
||||
button_icon_state = "mech_zoom_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_zoom/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(owner.client)
|
||||
chassis.zoom_mode = !chassis.zoom_mode
|
||||
button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]"
|
||||
chassis.mecha_log_message("Toggled zoom mode.")
|
||||
chassis.occupant_message("<font color='[chassis.zoom_mode?"blue":"red"]'>Zoom mode [chassis.zoom_mode?"en":"dis"]abled.</font>")
|
||||
if(chassis.zoom_mode)
|
||||
owner.client.view_size.setTo(4.5)
|
||||
SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50))
|
||||
else
|
||||
owner.client.view_size.resetToDefault()
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_switch_damtype
|
||||
name = "Reconfigure arm microtool arrays"
|
||||
button_icon_state = "mech_damtype_brute"
|
||||
|
||||
/datum/action/innate/mecha/mech_switch_damtype/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
var/new_damtype
|
||||
switch(chassis.damtype)
|
||||
if("tox")
|
||||
new_damtype = "brute"
|
||||
chassis.occupant_message("Your exosuit's hands form into fists.")
|
||||
if("brute")
|
||||
new_damtype = "fire"
|
||||
chassis.occupant_message("A torch tip extends from your exosuit's hand, glowing red.")
|
||||
if("fire")
|
||||
new_damtype = "tox"
|
||||
chassis.occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.")
|
||||
chassis.damtype = new_damtype
|
||||
button_icon_state = "mech_damtype_[new_damtype]"
|
||||
playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1)
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_phasing
|
||||
name = "Toggle Phasing"
|
||||
button_icon_state = "mech_phasing_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_phasing/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.phasing = !chassis.phasing
|
||||
button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]"
|
||||
chassis.occupant_message("<font color=\"[chassis.phasing?"#00f\">En":"#f00\">Dis"]abled phasing.</font>")
|
||||
UpdateButtonIcon()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,334 +0,0 @@
|
||||
/obj/mecha/proc/get_armour_facing(relative_dir)
|
||||
switch(relative_dir)
|
||||
if(180) // BACKSTAB!
|
||||
return facing_modifiers[BACK_ARMOUR]
|
||||
if(0, 45) // direct or 45 degrees off
|
||||
return facing_modifiers[FRONT_ARMOUR]
|
||||
return facing_modifiers[SIDE_ARMOUR] //if its not a front hit or back hit then assume its from the side
|
||||
|
||||
/obj/mecha/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
. = ..()
|
||||
if(. && obj_integrity > 0)
|
||||
spark_system.start()
|
||||
switch(damage_flag)
|
||||
if("fire")
|
||||
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL))
|
||||
if("melee")
|
||||
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
else
|
||||
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT))
|
||||
if(. >= 5 || prob(33))
|
||||
occupant_message("<span class='userdanger'>Taking damage!</span>")
|
||||
log_append_to_last("Took [damage_amount] points of damage. Damage type: \"[damage_type]\".",1)
|
||||
|
||||
/obj/mecha/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
|
||||
. = ..()
|
||||
if(!damage_amount)
|
||||
return 0
|
||||
var/booster_deflection_modifier = 1
|
||||
var/booster_damage_modifier = 1
|
||||
if(damage_flag == "bullet" || damage_flag == "laser" || damage_flag == "energy")
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment)
|
||||
if(B.projectile_react())
|
||||
booster_deflection_modifier = B.deflect_coeff
|
||||
booster_damage_modifier = B.damage_coeff
|
||||
break
|
||||
else if(damage_flag == "melee")
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment)
|
||||
if(B.attack_react())
|
||||
booster_deflection_modifier *= B.deflect_coeff
|
||||
booster_damage_modifier *= B.damage_coeff
|
||||
break
|
||||
|
||||
if(attack_dir)
|
||||
var/facing_modifier = get_armour_facing(abs(dir2angle(dir) - dir2angle(attack_dir)))
|
||||
booster_damage_modifier /= facing_modifier
|
||||
booster_deflection_modifier *= facing_modifier
|
||||
if(prob(deflect_chance * booster_deflection_modifier))
|
||||
visible_message("<span class='danger'>[src]'s armour deflects the attack!</span>")
|
||||
log_append_to_last("Armor saved.")
|
||||
return 0
|
||||
if(.)
|
||||
. *= booster_damage_modifier
|
||||
|
||||
|
||||
/obj/mecha/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1)
|
||||
user.visible_message("<span class='danger'>[user] hits [name]. Nothing happens</span>", null, null, COMBAT_MESSAGE_RANGE)
|
||||
mecha_log_message("Attack by hand/paw. Attacker - [user].", color="red")
|
||||
log_append_to_last("Armor saved.")
|
||||
|
||||
/obj/mecha/attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
|
||||
/obj/mecha/attack_alien(mob/living/user)
|
||||
mecha_log_message("Attack by alien. Attacker - [user].", color="red")
|
||||
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
|
||||
attack_generic(user, 15, BRUTE, "melee", 0)
|
||||
|
||||
/obj/mecha/attack_animal(mob/living/simple_animal/user)
|
||||
mecha_log_message("Attack by simple animal. Attacker - [user].", color="red")
|
||||
if(!user.melee_damage_upper && !user.obj_damage)
|
||||
user.emote("custom", message = "[user.friendly_verb_continuous] [src].")
|
||||
return 0
|
||||
else
|
||||
var/play_soundeffect = 1
|
||||
if(user.environment_smash)
|
||||
play_soundeffect = 0
|
||||
playsound(src, 'sound/effects/bang.ogg', 50, 1)
|
||||
var/animal_damage = rand(user.melee_damage_lower,user.melee_damage_upper)
|
||||
if(user.obj_damage)
|
||||
animal_damage = user.obj_damage
|
||||
animal_damage = min(animal_damage, 20*user.environment_smash)
|
||||
attack_generic(user, animal_damage, user.melee_damage_type, "melee", play_soundeffect)
|
||||
log_combat(user, src, "attacked")
|
||||
return 1
|
||||
|
||||
|
||||
/obj/mecha/hulk_damage()
|
||||
return 15
|
||||
|
||||
/obj/mecha/attack_hulk(mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
mecha_log_message("Attack by hulk. Attacker - [user].", color="red")
|
||||
log_combat(user, src, "punched", "hulk powers")
|
||||
|
||||
/obj/mecha/blob_act(obj/structure/blob/B)
|
||||
take_damage(30, BRUTE, "melee", 0, get_dir(src, B))
|
||||
|
||||
/obj/mecha/attack_tk()
|
||||
return
|
||||
|
||||
/obj/mecha/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) //wrapper
|
||||
mecha_log_message("Hit by [AM].", color="red")
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/mecha/bullet_act(obj/item/projectile/Proj) //wrapper
|
||||
mecha_log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).", color="red")
|
||||
. = ..()
|
||||
|
||||
/obj/mecha/ex_act(severity, target, origin)
|
||||
mecha_log_message("Affected by explosion of severity: [severity].", color="red")
|
||||
if(prob(deflect_chance))
|
||||
severity++
|
||||
log_append_to_last("Armor saved, changing severity to [severity].")
|
||||
. = ..()
|
||||
|
||||
/obj/mecha/contents_explosion(severity, target, origin)
|
||||
severity++
|
||||
for(var/X in equipment)
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = X
|
||||
ME.ex_act(severity, target, origin)
|
||||
for(var/Y in trackers)
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = Y
|
||||
MT.ex_act(severity, target, origin)
|
||||
if(occupant)
|
||||
occupant.ex_act(severity, target, origin)
|
||||
|
||||
/obj/mecha/handle_atom_del(atom/A)
|
||||
if(A == occupant)
|
||||
occupant = null
|
||||
icon_state = initial(icon_state)+"-open"
|
||||
setDir(dir_in)
|
||||
|
||||
/obj/mecha/emp_act(severity)
|
||||
. = ..()
|
||||
if (. & EMP_PROTECT_SELF)
|
||||
return
|
||||
if(get_charge())
|
||||
use_power((cell.charge/3)*(severity*0.005))
|
||||
take_damage(severity/3, BURN, "energy", 1)
|
||||
mecha_log_message("EMP detected", color="red")
|
||||
|
||||
if(istype(src, /obj/mecha/combat))
|
||||
mouse_pointer = 'icons/mecha/mecha_mouse-disable.dmi'
|
||||
occupant?.update_mouse_pointer()
|
||||
if(!equipment_disabled && occupant) //prevent spamming this message with back-to-back EMPs
|
||||
to_chat(occupant, "<span=danger>Error -- Connection to equipment control unit has been lost.</span>")
|
||||
addtimer(CALLBACK(src, /obj/mecha/proc/restore_equipment), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
|
||||
equipment_disabled = 1
|
||||
|
||||
/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature>max_temperature)
|
||||
mecha_log_message("Exposed to dangerous temperature.", color="red")
|
||||
take_damage(5, BURN, 0, 1)
|
||||
|
||||
/obj/mecha/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
|
||||
if(istype(W, /obj/item/mmi))
|
||||
if(mmi_move_inside(W,user))
|
||||
to_chat(user, "[src]-[W] interface initialized successfully.")
|
||||
else
|
||||
to_chat(user, "[src]-[W] interface initialization failed.")
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/mecha_ammo))
|
||||
ammo_resupply(W, user)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/mecha_parts/mecha_equipment))
|
||||
var/obj/item/mecha_parts/mecha_equipment/E = W
|
||||
spawn()
|
||||
if(E.can_attach(src))
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
E.attach(src)
|
||||
user.visible_message("[user] attaches [W] to [src].", "<span class='notice'>You attach [W] to [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You were unable to attach [W] to [src]!</span>")
|
||||
return
|
||||
if(W.GetID())
|
||||
if(add_req_access || maint_access)
|
||||
if(internals_access_allowed(user))
|
||||
var/obj/item/card/id/id_card
|
||||
if(istype(W, /obj/item/card/id))
|
||||
id_card = W
|
||||
else
|
||||
var/obj/item/pda/pda = W
|
||||
id_card = pda.id
|
||||
output_maintenance_dialog(id_card, user)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Invalid ID: Access denied.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Maintenance protocols disabled by operator.</span>")
|
||||
else if(W.tool_behaviour == TOOL_WRENCH)
|
||||
if(state==1)
|
||||
state = 2
|
||||
to_chat(user, "<span class='notice'>You undo the securing bolts.</span>")
|
||||
else if(state==2)
|
||||
state = 1
|
||||
to_chat(user, "<span class='notice'>You tighten the securing bolts.</span>")
|
||||
return
|
||||
else if(W.tool_behaviour == TOOL_CROWBAR)
|
||||
if(state==2)
|
||||
state = 3
|
||||
to_chat(user, "<span class='notice'>You open the hatch to the power unit.</span>")
|
||||
else if(state==3)
|
||||
state=2
|
||||
to_chat(user, "<span class='notice'>You close the hatch to the power unit.</span>")
|
||||
return
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
if(state == 3 && (internal_damage & MECHA_INT_SHORT_CIRCUIT))
|
||||
if(W.use_tool(src, user, 0, 2))
|
||||
clearInternalDamage(MECHA_INT_SHORT_CIRCUIT)
|
||||
to_chat(user, "<span class='notice'>You replace the fused wires.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need two lengths of cable to fix this mech!</span>")
|
||||
return
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER && user.a_intent != INTENT_HARM)
|
||||
if(internal_damage & MECHA_INT_TEMP_CONTROL)
|
||||
clearInternalDamage(MECHA_INT_TEMP_CONTROL)
|
||||
to_chat(user, "<span class='notice'>You repair the damaged temperature controller.</span>")
|
||||
else if(state==3 && cell)
|
||||
cell.forceMove(loc)
|
||||
cell = null
|
||||
state = 4
|
||||
to_chat(user, "<span class='notice'>You unscrew and pry out the powercell.</span>")
|
||||
mecha_log_message("Powercell removed")
|
||||
else if(state==4 && cell)
|
||||
state=3
|
||||
to_chat(user, "<span class='notice'>You screw the cell in place.</span>")
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/stock_parts/cell))
|
||||
if(state==4)
|
||||
if(!cell)
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
var/obj/item/stock_parts/cell/C = W
|
||||
to_chat(user, "<span class='notice'>You install the powercell.</span>")
|
||||
cell = C
|
||||
mecha_log_message("Powercell installed")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There's already a powercell installed.</span>")
|
||||
return
|
||||
|
||||
else if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
if(obj_integrity < max_integrity)
|
||||
if(W.use_tool(src, user, 0, volume=50, amount=1))
|
||||
if (internal_damage & MECHA_INT_TANK_BREACH)
|
||||
clearInternalDamage(MECHA_INT_TANK_BREACH)
|
||||
to_chat(user, "<span class='notice'>You repair the damaged gas tank.</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] repairs some damage to [name].</span>", "<span class='notice'>You repair some damage to [src].</span>")
|
||||
obj_integrity += min(10, max_integrity-obj_integrity)
|
||||
if(obj_integrity == max_integrity)
|
||||
to_chat(user, "<span class='notice'>It looks to be fully repaired now.</span>")
|
||||
return 1
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The [name] is at full integrity!</span>")
|
||||
return 1
|
||||
|
||||
else if(istype(W, /obj/item/mecha_parts/mecha_tracking))
|
||||
var/obj/item/mecha_parts/mecha_tracking/tracker = W
|
||||
tracker.try_attach_part(user, src)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/mecha/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
mecha_log_message("Attacked by [I]. Attacker - [user]")
|
||||
return ..()
|
||||
|
||||
/obj/mecha/proc/mech_toxin_damage(mob/living/target)
|
||||
playsound(src, 'sound/effects/spray2.ogg', 50, 1)
|
||||
if(target.reagents)
|
||||
if(target.reagents.get_reagent_amount(/datum/reagent/cryptobiolin) + force < force*2)
|
||||
target.reagents.add_reagent(/datum/reagent/cryptobiolin, force/2)
|
||||
if(target.reagents.get_reagent_amount(/datum/reagent/toxin) + force < force*2)
|
||||
target.reagents.add_reagent(/datum/reagent/toxin, force/2.5)
|
||||
|
||||
|
||||
/obj/mecha/mech_melee_attack(obj/mecha/M)
|
||||
if(!has_charge(melee_energy_drain))
|
||||
return 0
|
||||
use_power(melee_energy_drain)
|
||||
if(M.damtype == BRUTE || M.damtype == BURN)
|
||||
log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
. = ..()
|
||||
|
||||
/obj/mecha/proc/full_repair(charge_cell)
|
||||
obj_integrity = max_integrity
|
||||
if(cell && charge_cell)
|
||||
cell.charge = cell.maxcharge
|
||||
if(internal_damage & MECHA_INT_FIRE)
|
||||
clearInternalDamage(MECHA_INT_FIRE)
|
||||
if(internal_damage & MECHA_INT_TEMP_CONTROL)
|
||||
clearInternalDamage(MECHA_INT_TEMP_CONTROL)
|
||||
if(internal_damage & MECHA_INT_SHORT_CIRCUIT)
|
||||
clearInternalDamage(MECHA_INT_SHORT_CIRCUIT)
|
||||
if(internal_damage & MECHA_INT_TANK_BREACH)
|
||||
clearInternalDamage(MECHA_INT_TANK_BREACH)
|
||||
if(internal_damage & MECHA_INT_CONTROL_LOST)
|
||||
clearInternalDamage(MECHA_INT_CONTROL_LOST)
|
||||
|
||||
/obj/mecha/narsie_act()
|
||||
emp_act(100)
|
||||
|
||||
/obj/mecha/ratvar_act()
|
||||
if((GLOB.ratvar_awakens || GLOB.clockwork_gateway_activated) && occupant)
|
||||
if(is_servant_of_ratvar(occupant)) //reward the minion that got a mech by repairing it
|
||||
full_repair(TRUE)
|
||||
else
|
||||
var/mob/living/L = occupant
|
||||
go_out(TRUE)
|
||||
if(L)
|
||||
L.ratvar_act()
|
||||
|
||||
/obj/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
|
||||
if(!no_effect)
|
||||
if(selected)
|
||||
used_item = selected
|
||||
else if(!visual_effect_icon)
|
||||
visual_effect_icon = ATTACK_EFFECT_SMASH
|
||||
if(damtype == BURN)
|
||||
visual_effect_icon = ATTACK_EFFECT_MECHFIRE
|
||||
else if(damtype == TOX)
|
||||
visual_effect_icon = ATTACK_EFFECT_MECHTOXIN
|
||||
..()
|
||||
@@ -1,360 +0,0 @@
|
||||
|
||||
////////////////////////////////////
|
||||
///// Rendering stats window ///////
|
||||
////////////////////////////////////
|
||||
|
||||
/obj/mecha/proc/get_stats_html()
|
||||
. = {"<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
<title>[name] data</title>
|
||||
<style>
|
||||
body {color: #00ff00; background: #000000; font-family:"Lucida Console",monospace; font-size: 12px;}
|
||||
hr {border: 1px solid #0f0; color: #0f0; background-color: #0f0;}
|
||||
a {padding:2px 5px;;color:#0f0;}
|
||||
.wr {margin-bottom: 5px;}
|
||||
.header {cursor:pointer;}
|
||||
.open, .closed {background: #32CD32; color:#000; padding:1px 2px;}
|
||||
.links a {margin-bottom: 2px;padding-top:3px;}
|
||||
.visible {display: block;}
|
||||
.hidden {display: none;}
|
||||
</style>
|
||||
<script language='javascript' type='text/javascript'>
|
||||
[js_byjax]
|
||||
[js_dropdowns]
|
||||
function SSticker() {
|
||||
setInterval(function(){
|
||||
window.location='byond://?src=[REF(src)]&update_content=1';
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
dropdowns();
|
||||
SSticker();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id='content'>
|
||||
[src.get_stats_part()]
|
||||
</div>
|
||||
<div id='eq_list'>
|
||||
[src.get_equipment_list()]
|
||||
</div>
|
||||
<hr>
|
||||
<div id='commands'>
|
||||
[src.get_commands()]
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
|
||||
|
||||
/obj/mecha/proc/report_internal_damage()
|
||||
. = ""
|
||||
var/list/dam_reports = list(
|
||||
"[MECHA_INT_FIRE]" = "<span class='userdanger'>INTERNAL FIRE</span>",
|
||||
"[MECHA_INT_TEMP_CONTROL]" = "<span class='userdanger'>LIFE SUPPORT SYSTEM MALFUNCTION</span>",
|
||||
"[MECHA_INT_TANK_BREACH]" = "<span class='userdanger'>GAS TANK BREACH</span>",
|
||||
"[MECHA_INT_CONTROL_LOST]" = "<span class='userdanger'>COORDINATION SYSTEM CALIBRATION FAILURE</span> - <a href='?src=[REF(src)];repair_int_control_lost=1'>Recalibrate</a>",
|
||||
"[MECHA_INT_SHORT_CIRCUIT]" = "<span class='userdanger'>SHORT CIRCUIT</span>"
|
||||
)
|
||||
for(var/tflag in dam_reports)
|
||||
var/intdamflag = text2num(tflag)
|
||||
if(internal_damage & intdamflag)
|
||||
. += dam_reports[tflag]
|
||||
. += "<br />"
|
||||
if(return_pressure() > WARNING_HIGH_PRESSURE)
|
||||
. += "<span class='userdanger'>DANGEROUSLY HIGH CABIN PRESSURE</span><br />"
|
||||
|
||||
|
||||
|
||||
/obj/mecha/proc/get_stats_part()
|
||||
var/integrity = obj_integrity/max_integrity*100
|
||||
var/cell_charge = get_charge()
|
||||
var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
|
||||
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
|
||||
var/tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown"
|
||||
var/cabin_pressure = round(return_pressure(),0.01)
|
||||
. = {"[report_internal_damage()]
|
||||
[integrity<30?"<span class='userdanger'>DAMAGE LEVEL CRITICAL</span><br>":null]
|
||||
<b>Integrity: </b> [integrity]%<br>
|
||||
<b>Powercell charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br>
|
||||
<b>Air source: </b>[use_internal_tank?"Internal Airtank":"Environment"]<br>
|
||||
<b>Airtank pressure: </b>[tank_pressure]kPa<br>
|
||||
<b>Airtank temperature: </b>[tank_temperature]°K|[tank_temperature - T0C]°C<br>
|
||||
<b>Cabin pressure: </b>[cabin_pressure>WARNING_HIGH_PRESSURE ? "<span class='danger'>[cabin_pressure]</span>": cabin_pressure]kPa<br>
|
||||
<b>Cabin temperature: </b> [return_temperature()]°K|[return_temperature() - T0C]°C<br>
|
||||
[dna_lock?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[dna_lock]</span> \[<a href='?src=[REF(src)];reset_dna=1'>Reset</a>\]<br>":""]<br>
|
||||
[thrusters_action.owner ? "<b>Thrusters: </b> [thrusters_active ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
[defense_action.owner ? "<b>Defence Mode: </b> [defence_mode ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
[overload_action.owner ? "<b>Leg Actuators Overload: </b> [leg_overload_mode ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
[smoke_action.owner ? "<b>Smoke: </b> [smoke]<br>" : ""]
|
||||
[zoom_action.owner ? "<b>Zoom: </b> [zoom_mode ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
[switch_damtype_action.owner ? "<b>Damtype: </b> [damtype]<br>" : ""]
|
||||
[phasing_action.owner ? "<b>Phase Modulator: </b> [phasing ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
"}
|
||||
|
||||
|
||||
/obj/mecha/proc/get_commands()
|
||||
. = {"<div class='wr'>
|
||||
<div class='header'>Electronics</div>
|
||||
<div class='links'>
|
||||
<b>Radio settings:</b><br>
|
||||
Microphone: <a href='?src=[REF(src)];rmictoggle=1'><span id="rmicstate">[radio.broadcasting?"Engaged":"Disengaged"]</span></a><br>
|
||||
Speaker: <a href='?src=[REF(src)];rspktoggle=1'><span id="rspkstate">[radio.listening?"Engaged":"Disengaged"]</span></a><br>
|
||||
Frequency:
|
||||
<a href='?src=[REF(src)];rfreq=-10'>-</a>
|
||||
<a href='?src=[REF(src)];rfreq=-2'>-</a>
|
||||
<span id="rfreq">[format_frequency(radio.frequency)]</span>
|
||||
<a href='?src=[REF(src)];rfreq=2'>+</a>
|
||||
<a href='?src=[REF(src)];rfreq=10'>+</a><br>
|
||||
</div>
|
||||
</div>
|
||||
<div class='wr'>
|
||||
<div class='header'>Permissions & Logging</div>
|
||||
<div class='links'>
|
||||
<a href='?src=[REF(src)];toggle_id_upload=1'><span id='t_id_upload'>[add_req_access?"L":"Unl"]ock ID upload panel</span></a><br>
|
||||
<a href='?src=[REF(src)];toggle_maint_access=1'><span id='t_maint_access'>[maint_access?"Forbid":"Permit"] maintenance protocols</span></a><br>
|
||||
<a href='?src=[REF(src)];toggle_port_connection=1'><span id='t_port_connection'>[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port</span></a><br>
|
||||
<a href='?src=[REF(src)];dna_lock=1'>DNA-lock</a><br>
|
||||
<a href='?src=[REF(src)];view_log=1'>View internal log</a><br>
|
||||
<a href='?src=[REF(src)];change_name=1'>Change exosuit name</a><br>
|
||||
</div>
|
||||
</div>
|
||||
<div id='equipment_menu'>[get_equipment_menu()]</div>
|
||||
"}
|
||||
|
||||
|
||||
/obj/mecha/proc/get_equipment_menu() //outputs mecha html equipment menu
|
||||
. = ""
|
||||
if(equipment.len)
|
||||
. += {"<div class='wr'>
|
||||
<div class='header'>Equipment</div>
|
||||
<div class='links'>"}
|
||||
for(var/X in equipment)
|
||||
var/obj/item/mecha_parts/mecha_equipment/W = X
|
||||
. += "[W.name] <a href='?src=[REF(W)];detach=1'>Detach</a><br>"
|
||||
. += "<b>Available equipment slots:</b> [max_equip-equipment.len]"
|
||||
. += "</div></div>"
|
||||
|
||||
|
||||
/obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html
|
||||
if(!equipment.len)
|
||||
return
|
||||
. = "<b>Equipment:</b><div style=\"margin-left: 15px;\">"
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment)
|
||||
. += "<div id='[REF(MT)]'>[MT.get_equip_info()]</div>"
|
||||
. += "</div>"
|
||||
|
||||
|
||||
|
||||
/obj/mecha/proc/get_log_html()
|
||||
. = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[src.name] Log</title></head><body style='font: 13px 'Courier', monospace;'>"
|
||||
for(var/list/entry in log)
|
||||
. += {"<div style='font-weight: bold;'>[entry["time"]] [time2text(entry["date"],"MMM DD")] [entry["year"]]</div>
|
||||
<div style='margin-left:15px; margin-bottom:10px;'>[entry["message"]]</div>
|
||||
"}
|
||||
. += "</body></html>"
|
||||
|
||||
|
||||
|
||||
/obj/mecha/proc/output_access_dialog(obj/item/card/id/id_card, mob/user)
|
||||
if(!id_card || !user)
|
||||
return
|
||||
. = {"<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
<style>
|
||||
h1 {font-size:15px;margin-bottom:4px;}
|
||||
body {color: #00ff00; background: #000000; font-family:"Courier New", Courier, monospace; font-size: 12px;}
|
||||
a {color:#0f0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Following keycodes are present in this system:</h1>"}
|
||||
for(var/a in operation_req_access)
|
||||
. += "[get_access_desc(a)] - <a href='?src=[REF(src)];del_req_access=[a];user=[REF(user)];id_card=[REF(id_card)]'>Delete</a><br>"
|
||||
. += "<hr><h1>Following keycodes were detected on portable device:</h1>"
|
||||
for(var/a in id_card.access)
|
||||
if(a in operation_req_access)
|
||||
continue
|
||||
var/a_name = get_access_desc(a)
|
||||
if(!a_name)
|
||||
continue //there's some strange access without a name
|
||||
. += "[a_name] - <a href='?src=[REF(src)];add_req_access=[a];user=[REF(user)];id_card=[REF(id_card)]'>Add</a><br>"
|
||||
. += "<hr><a href='?src=[REF(src)];finish_req_access=1;user=[REF(user)]'>Finish</a> "
|
||||
. += "<span class='danger'>(Warning! The ID upload panel will be locked. It can be unlocked only through Exosuit Interface.)</span>"
|
||||
. += "</body></html>"
|
||||
user << browse(., "window=exosuit_add_access")
|
||||
onclose(user, "exosuit_add_access")
|
||||
|
||||
|
||||
/obj/mecha/proc/output_maintenance_dialog(obj/item/card/id/id_card,mob/user)
|
||||
if(!id_card || !user)
|
||||
return
|
||||
. = {"<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
<style>
|
||||
body {color: #00ff00; background: #000000; font-family:"Courier New", Courier, monospace; font-size: 12px;}
|
||||
a {padding:2px 5px; background:#32CD32;color:#000;display:block;margin:2px;text-align:center;text-decoration:none;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
[add_req_access?"<a href='?src=[REF(src)];req_access=1;id_card=[REF(id_card)];user=[REF(user)]'>Edit operation keycodes</a>":null]
|
||||
[maint_access?"<a href='?src=[REF(src)];maint_access=1;id_card=[REF(id_card)];user=[REF(user)]'>[(state>0) ? "Terminate" : "Initiate"] maintenance protocol</a>":null]
|
||||
[(state>0) ?"<a href='?src=[REF(src)];set_internal_tank_valve=1;user=[REF(user)]'>Set Cabin Air Pressure</a>":null]
|
||||
</body>
|
||||
</html>"}
|
||||
user << browse(., "window=exosuit_maint_console")
|
||||
onclose(user, "exosuit_maint_console")
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////
|
||||
///// Topic /////
|
||||
/////////////////
|
||||
|
||||
/obj/mecha/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["close"])
|
||||
return
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
if(in_range(src, usr))
|
||||
var/obj/item/card/id/id_card
|
||||
if (href_list["id_card"])
|
||||
id_card = locate(href_list["id_card"])
|
||||
if (!istype(id_card))
|
||||
return
|
||||
|
||||
if(href_list["req_access"] && add_req_access)
|
||||
output_access_dialog(id_card, usr)
|
||||
|
||||
if(href_list["maint_access"] && maint_access)
|
||||
if(state==0)
|
||||
state = 1
|
||||
to_chat(usr, "The securing bolts are now exposed.")
|
||||
else if(state==1)
|
||||
state = 0
|
||||
to_chat(usr, "The securing bolts are now hidden.")
|
||||
output_maintenance_dialog(id_card, usr)
|
||||
|
||||
if(href_list["set_internal_tank_valve"] && state >=1)
|
||||
var/new_pressure = input(usr,"Input new output pressure","Pressure setting",internal_tank_valve) as num
|
||||
if(new_pressure)
|
||||
internal_tank_valve = new_pressure
|
||||
to_chat(usr, "The internal pressure valve has been set to [internal_tank_valve]kPa.")
|
||||
|
||||
if(href_list["add_req_access"] && add_req_access)
|
||||
operation_req_access += text2num(href_list["add_req_access"])
|
||||
output_access_dialog(id_card, usr)
|
||||
|
||||
if(href_list["del_req_access"] && add_req_access)
|
||||
operation_req_access -= text2num(href_list["del_req_access"])
|
||||
output_access_dialog(id_card, usr)
|
||||
|
||||
if(href_list["finish_req_access"])
|
||||
add_req_access = 0
|
||||
usr << browse(null,"window=exosuit_add_access")
|
||||
|
||||
if(usr != occupant)
|
||||
return
|
||||
|
||||
if(href_list["update_content"])
|
||||
send_byjax(usr,"exosuit.browser","content",src.get_stats_part())
|
||||
|
||||
if(href_list["select_equip"])
|
||||
var/obj/item/mecha_parts/mecha_equipment/equip = locate(href_list["select_equip"]) in src
|
||||
if(equip && equip.selectable)
|
||||
selected = equip
|
||||
occupant_message("You switch to [equip]")
|
||||
visible_message("[src] raises [equip]")
|
||||
send_byjax(usr, "exosuit.browser","eq_list", get_equipment_list())
|
||||
|
||||
if(href_list["rmictoggle"])
|
||||
radio.broadcasting = !radio.broadcasting
|
||||
send_byjax(usr,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged"))
|
||||
|
||||
if(href_list["rspktoggle"])
|
||||
radio.listening = !radio.listening
|
||||
send_byjax(usr,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged"))
|
||||
|
||||
if(href_list["rfreq"])
|
||||
var/new_frequency = (radio.frequency + text2num(href_list["rfreq"]))
|
||||
if (!radio.freerange || (radio.frequency < MIN_FREE_FREQ || radio.frequency > MAX_FREE_FREQ))
|
||||
new_frequency = sanitize_frequency(new_frequency)
|
||||
radio.set_frequency(new_frequency)
|
||||
send_byjax(usr,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]")
|
||||
|
||||
if (href_list["view_log"])
|
||||
src.occupant << browse(src.get_log_html(), "window=exosuit_log")
|
||||
onclose(occupant, "exosuit_log")
|
||||
|
||||
if (href_list["change_name"])
|
||||
var/userinput = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN)
|
||||
if(!userinput || usr != occupant || usr.incapacitated())
|
||||
return
|
||||
name = userinput
|
||||
return
|
||||
|
||||
if (href_list["toggle_id_upload"])
|
||||
add_req_access = !add_req_access
|
||||
send_byjax(usr,"exosuit.browser","t_id_upload","[add_req_access?"L":"Unl"]ock ID upload panel")
|
||||
|
||||
if(href_list["toggle_maint_access"])
|
||||
if(state)
|
||||
occupant_message("<span class='danger'>Maintenance protocols in effect</span>")
|
||||
return
|
||||
maint_access = !maint_access
|
||||
send_byjax(usr,"exosuit.browser","t_maint_access","[maint_access?"Forbid":"Permit"] maintenance protocols")
|
||||
|
||||
if (href_list["toggle_port_connection"])
|
||||
if(internal_tank.connected_port)
|
||||
if(internal_tank.disconnect())
|
||||
occupant_message("Disconnected from the air system port.")
|
||||
mecha_log_message("Disconnected from gas port.")
|
||||
else
|
||||
occupant_message("<span class='warning'>Unable to disconnect from the air system port!</span>")
|
||||
return
|
||||
else
|
||||
var/obj/machinery/atmospherics/components/unary/portables_connector/possible_port = locate() in loc
|
||||
if(internal_tank.connect(possible_port))
|
||||
occupant_message("Connected to the air system port.")
|
||||
mecha_log_message("Connected to gas port.")
|
||||
else
|
||||
occupant_message("<span class='warning'>Unable to connect with air system port!</span>")
|
||||
return
|
||||
send_byjax(occupant,"exosuit.browser","t_port_connection","[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port")
|
||||
|
||||
if(href_list["dna_lock"])
|
||||
if(!occupant)
|
||||
return
|
||||
var/mob/living/carbon/C = occupant
|
||||
if(!istype(C) || !C.dna)
|
||||
to_chat(C, "<span class='danger'> You do not have any DNA!</span>")
|
||||
return
|
||||
dna_lock = C.dna.unique_enzymes
|
||||
occupant_message("You feel a prick as the needle takes your DNA sample.")
|
||||
|
||||
if(href_list["reset_dna"])
|
||||
dna_lock = null
|
||||
|
||||
if(href_list["repair_int_control_lost"])
|
||||
occupant_message("Recalibrating coordination system...")
|
||||
mecha_log_message("Recalibration of coordination system started.")
|
||||
var/T = loc
|
||||
spawn(100)
|
||||
if(T == loc)
|
||||
clearInternalDamage(MECHA_INT_CONTROL_LOST)
|
||||
occupant_message("<span class='notice'>Recalibration successful.</span>")
|
||||
mecha_log_message("Recalibration of coordination system finished with 0 errors.")
|
||||
else
|
||||
occupant_message("<span class='warning'>Recalibration failed!</span>")
|
||||
mecha_log_message("Recalibration of coordination system failed with 1 error.", color="red")
|
||||
|
||||
@@ -1,271 +0,0 @@
|
||||
///////////////////////////////////
|
||||
//////// Mecha wreckage ////////
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage
|
||||
name = "exosuit wreckage"
|
||||
desc = "Remains of some unfortunate mecha. Completely irreparable, but perhaps something can be salvaged."
|
||||
icon = 'icons/mecha/mecha.dmi'
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
opacity = 0
|
||||
var/list/welder_salvage = list(/obj/item/stack/sheet/plasteel, /obj/item/stack/sheet/metal, /obj/item/stack/rods)
|
||||
var/list/wirecutters_salvage = list(/obj/item/stack/cable_coil)
|
||||
var/list/crowbar_salvage = list()
|
||||
var/salvage_num = 5
|
||||
var/mob/living/silicon/ai/AI //AIs to be salvaged
|
||||
|
||||
/obj/structure/mecha_wreckage/Initialize(mapload, mob/living/silicon/ai/AI_pilot)
|
||||
. = ..()
|
||||
if(!AI_pilot) //Type-checking for this is already done in mecha/Destroy()
|
||||
return
|
||||
|
||||
AI = AI_pilot
|
||||
AI.apply_damage(150, BURN) //Give the AI a bit of damage from the "shock" of being suddenly shut down
|
||||
AI.death() //The damage is not enough to kill the AI, but to be 'corrupted files' in need of repair.
|
||||
AI.forceMove(src) //Put the dead AI inside the wreckage for recovery
|
||||
add_overlay(mutable_appearance('icons/obj/projectiles.dmi', "green_laser")) //Overlay for the recovery beacon
|
||||
AI.controlled_mech = null
|
||||
AI.remote_control = null
|
||||
|
||||
/obj/structure/mecha_wreckage/examine(mob/user)
|
||||
. = ..()
|
||||
if(AI)
|
||||
. += "<span class='notice'>The AI recovery beacon is active.</span>"
|
||||
|
||||
/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
if(salvage_num <= 0 || !length(welder_salvage))
|
||||
to_chat(user, "<span class='warning'>You don't see anything that can be cut with [I]!</span>")
|
||||
return
|
||||
|
||||
if(!I.use_tool(src, user, 0, volume=50))
|
||||
return
|
||||
|
||||
var/type = prob(70) ? pick(welder_salvage) : null
|
||||
if(type)
|
||||
var/N = new type(get_turf(user))
|
||||
user.visible_message("[user] cuts [N] from [src].", "<span class='notice'>You cut [N] from [src].</span>")
|
||||
if(istype(N, /obj/item/mecha_parts/part))
|
||||
welder_salvage -= type
|
||||
salvage_num--
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to salvage anything valuable from [src]!</span>")
|
||||
return
|
||||
|
||||
else if(I.tool_behaviour == TOOL_WIRECUTTER)
|
||||
if(salvage_num <= 0)
|
||||
to_chat(user, "<span class='warning'>You don't see anything that can be cut with [I]!</span>")
|
||||
return
|
||||
else if(wirecutters_salvage && wirecutters_salvage.len)
|
||||
var/type = prob(70) ? pick(wirecutters_salvage) : null
|
||||
if(type)
|
||||
var/N = new type(get_turf(user))
|
||||
user.visible_message("[user] cuts [N] from [src].", "<span class='notice'>You cut [N] from [src].</span>")
|
||||
salvage_num--
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to salvage anything valuable from [src]!</span>")
|
||||
|
||||
else if(I.tool_behaviour == TOOL_CROWBAR)
|
||||
if(crowbar_salvage && crowbar_salvage.len)
|
||||
var/obj/S = pick(crowbar_salvage)
|
||||
if(S)
|
||||
S.forceMove(user.drop_location())
|
||||
crowbar_salvage -= S
|
||||
user.visible_message("[user] pries [S] from [src].", "<span class='notice'>You pry [S] from [src].</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You don't see anything that can be pried with [I]!</span>")
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/transfer_ai(interaction, mob/user, null, obj/item/aicard/card)
|
||||
if(!..())
|
||||
return
|
||||
|
||||
//Proc called on the wreck by the AI card.
|
||||
if(interaction == AI_TRANS_TO_CARD) //AIs can only be transferred in one direction, from the wreck to the card.
|
||||
if(!AI) //No AI in the wreck
|
||||
to_chat(user, "<span class='warning'>No AI backups found.</span>")
|
||||
return
|
||||
cut_overlays() //Remove the recovery beacon overlay
|
||||
AI.forceMove(card) //Move the dead AI to the card.
|
||||
card.AI = AI
|
||||
if(AI.client) //AI player is still in the dead AI and is connected
|
||||
to_chat(AI, "The remains of your file system have been recovered on a mobile storage device.")
|
||||
else //Give the AI a heads-up that it is probably going to get fixed.
|
||||
AI.notify_ghost_cloning("You have been recovered from the wreckage!", source = card)
|
||||
to_chat(user, "<span class='boldnotice'>Backup files recovered</span>: [AI.name] ([rand(1000,9999)].exe) salvaged from [name] and stored within local memory.")
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/gygax
|
||||
name = "\improper Gygax wreckage"
|
||||
icon_state = "gygax-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/gygax/Initialize()
|
||||
. = ..()
|
||||
var/list/parts = list(/obj/item/mecha_parts/part/gygax_torso,
|
||||
/obj/item/mecha_parts/part/gygax_head,
|
||||
/obj/item/mecha_parts/part/gygax_left_arm,
|
||||
/obj/item/mecha_parts/part/gygax_right_arm,
|
||||
/obj/item/mecha_parts/part/gygax_left_leg,
|
||||
/obj/item/mecha_parts/part/gygax_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/gygax/dark
|
||||
name = "\improper Dark Gygax wreckage"
|
||||
icon_state = "darkgygax-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/medigax
|
||||
name = "\improper Medical Gygax wreckage"
|
||||
icon_state = "medigax-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/medigax/Initialize()
|
||||
. = ..()
|
||||
var/list/parts = list(/obj/item/mecha_parts/part/medigax_torso,
|
||||
/obj/item/mecha_parts/part/medigax_head,
|
||||
/obj/item/mecha_parts/part/medigax_left_arm,
|
||||
/obj/item/mecha_parts/part/medigax_right_arm,
|
||||
/obj/item/mecha_parts/part/medigax_left_leg,
|
||||
/obj/item/mecha_parts/part/medigax_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
/obj/structure/mecha_wreckage/marauder
|
||||
name = "\improper Marauder wreckage"
|
||||
icon_state = "marauder-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/mauler
|
||||
name = "\improper Mauler wreckage"
|
||||
icon_state = "mauler-broken"
|
||||
desc = "The syndicate won't be very happy about this..."
|
||||
|
||||
/obj/structure/mecha_wreckage/seraph
|
||||
name = "\improper Seraph wreckage"
|
||||
icon_state = "seraph-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/reticence
|
||||
name = "\improper Reticence wreckage"
|
||||
icon_state = "reticence-broken"
|
||||
color = "#87878715"
|
||||
desc = "..."
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley
|
||||
name = "\improper Ripley wreckage"
|
||||
icon_state = "ripley-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley/Initialize()
|
||||
. = ..()
|
||||
var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso,
|
||||
/obj/item/mecha_parts/part/ripley_left_arm,
|
||||
/obj/item/mecha_parts/part/ripley_right_arm,
|
||||
/obj/item/mecha_parts/part/ripley_left_leg,
|
||||
/obj/item/mecha_parts/part/ripley_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley/firefighter
|
||||
name = "\improper Firefighter wreckage"
|
||||
icon_state = "firefighter-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley/firefighter/Initialize()
|
||||
. = ..()
|
||||
var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso,
|
||||
/obj/item/mecha_parts/part/ripley_left_arm,
|
||||
/obj/item/mecha_parts/part/ripley_right_arm,
|
||||
/obj/item/mecha_parts/part/ripley_left_leg,
|
||||
/obj/item/mecha_parts/part/ripley_right_leg,
|
||||
/obj/item/clothing/suit/fire)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley/deathripley
|
||||
name = "\improper Death-Ripley wreckage"
|
||||
icon_state = "deathripley-broken"
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/honker
|
||||
name = "\improper H.O.N.K wreckage"
|
||||
icon_state = "honker-broken"
|
||||
desc = "All is right in the universe."
|
||||
|
||||
/obj/structure/mecha_wreckage/honker/Initialize()
|
||||
. = ..()
|
||||
var/list/parts = list(
|
||||
/obj/item/mecha_parts/chassis/honker,
|
||||
/obj/item/mecha_parts/part/honker_torso,
|
||||
/obj/item/mecha_parts/part/honker_head,
|
||||
/obj/item/mecha_parts/part/honker_left_arm,
|
||||
/obj/item/mecha_parts/part/honker_right_arm,
|
||||
/obj/item/mecha_parts/part/honker_left_leg,
|
||||
/obj/item/mecha_parts/part/honker_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/durand
|
||||
name = "\improper Durand wreckage"
|
||||
icon_state = "durand-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/durand/Initialize()
|
||||
. = ..()
|
||||
var/list/parts = list(
|
||||
/obj/item/mecha_parts/part/durand_torso,
|
||||
/obj/item/mecha_parts/part/durand_head,
|
||||
/obj/item/mecha_parts/part/durand_left_arm,
|
||||
/obj/item/mecha_parts/part/durand_right_arm,
|
||||
/obj/item/mecha_parts/part/durand_left_leg,
|
||||
/obj/item/mecha_parts/part/durand_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/phazon
|
||||
name = "\improper Phazon wreckage"
|
||||
icon_state = "phazon-broken"
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/odysseus
|
||||
name = "\improper Odysseus wreckage"
|
||||
icon_state = "odysseus-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/odysseus/Initialize()
|
||||
. = ..()
|
||||
var/list/parts = list(
|
||||
/obj/item/mecha_parts/part/odysseus_torso,
|
||||
/obj/item/mecha_parts/part/odysseus_head,
|
||||
/obj/item/mecha_parts/part/odysseus_left_arm,
|
||||
/obj/item/mecha_parts/part/odysseus_right_arm,
|
||||
/obj/item/mecha_parts/part/odysseus_left_leg,
|
||||
/obj/item/mecha_parts/part/odysseus_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
@@ -1,16 +0,0 @@
|
||||
/obj/mecha/medical/mechturn(direction)
|
||||
setDir(direction)
|
||||
playsound(src,'sound/mecha/mechmove01.ogg',40,1)
|
||||
return 1
|
||||
|
||||
/obj/mecha/medical/mechstep(direction)
|
||||
var/result = step(src,direction)
|
||||
if(result)
|
||||
playsound(src,'sound/mecha/mechstep.ogg',25,1)
|
||||
return result
|
||||
|
||||
/obj/mecha/medical/mechsteprand()
|
||||
var/result = step_rand(src)
|
||||
if(result)
|
||||
playsound(src,'sound/mecha/mechstep.ogg',25,1)
|
||||
return result
|
||||
@@ -1,188 +0,0 @@
|
||||
/obj/mecha/working/ripley
|
||||
desc = "Autonomous Power Loader Unit. This newer model is refitted with powerful armour against the dangers of planetary mining."
|
||||
name = "\improper APLU \"Ripley\""
|
||||
icon_state = "ripley"
|
||||
step_in = 3 //Move speed, lower is faster.
|
||||
var/fast_pressure_step_in = 2
|
||||
var/slow_pressure_step_in = 3
|
||||
max_temperature = 20000
|
||||
max_integrity = 200
|
||||
lights_power = 8
|
||||
deflect_chance = 15
|
||||
armor = list("melee" = 30, "bullet" = 15, "laser" = 10, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
max_equip = 6
|
||||
wreckage = /obj/structure/mecha_wreckage/ripley
|
||||
var/list/cargo = new
|
||||
var/cargo_capacity = 15
|
||||
var/hides = 0
|
||||
|
||||
/obj/mecha/working/ripley/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
collect_ore()
|
||||
update_pressure()
|
||||
|
||||
/obj/mecha/working/ripley/proc/collect_ore()
|
||||
if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in equipment)
|
||||
var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in cargo
|
||||
if(ore_box)
|
||||
for(var/obj/item/stack/ore/ore in range(1, src))
|
||||
if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it!
|
||||
ore.forceMove(ore_box)
|
||||
|
||||
/obj/mecha/working/ripley/Destroy()
|
||||
for(var/atom/movable/A in cargo)
|
||||
A.forceMove(drop_location())
|
||||
step_rand(A)
|
||||
cargo.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/mecha/working/ripley/go_out()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/mecha/working/ripley/moved_inside(mob/living/carbon/human/H)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/mecha/working/ripley/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/armor_plate,3,/obj/item/stack/sheet/animalhide/goliath_hide,list("melee" = 10, "bullet" = 5, "laser" = 5))
|
||||
|
||||
|
||||
/obj/mecha/working/ripley/firefighter
|
||||
desc = "Autonomous Power Loader Unit. This model is refitted with additional thermal protection."
|
||||
name = "\improper APLU \"Firefighter\""
|
||||
icon_state = "firefighter"
|
||||
step_in = 4
|
||||
fast_pressure_step_in = 2
|
||||
slow_pressure_step_in = 4
|
||||
max_temperature = 65000
|
||||
max_integrity = 250
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
lights_power = 7
|
||||
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
max_equip = 5 // More armor, less tools
|
||||
wreckage = /obj/structure/mecha_wreckage/ripley/firefighter
|
||||
|
||||
|
||||
/obj/mecha/working/ripley/deathripley
|
||||
desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE"
|
||||
name = "\improper DEATH-RIPLEY"
|
||||
icon_state = "deathripley"
|
||||
armor = list("melee" = 40, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
slow_pressure_step_in = 3
|
||||
opacity=0
|
||||
lights_power = 7
|
||||
wreckage = /obj/structure/mecha_wreckage/ripley/deathripley
|
||||
step_energy_drain = 0
|
||||
|
||||
/obj/mecha/working/ripley/deathripley/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/working/ripley/deathripley/real
|
||||
desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE. FOR REAL"
|
||||
|
||||
/obj/mecha/working/ripley/deathripley/real/Initialize()
|
||||
. = ..()
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
|
||||
E.detach()
|
||||
qdel(E)
|
||||
equipment.Cut()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/working/ripley/mining
|
||||
desc = "An old, dusty mining Ripley."
|
||||
name = "\improper APLU \"Miner\""
|
||||
obj_integrity = 75 //Low starting health
|
||||
|
||||
/obj/mecha/working/ripley/mining/Initialize()
|
||||
. = ..()
|
||||
if(cell)
|
||||
cell.charge = FLOOR(cell.charge * 0.25, 1) //Starts at very low charge
|
||||
if(prob(70)) //Maybe add a drill
|
||||
if(prob(15)) //Possible diamond drill... Feeling lucky?
|
||||
var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new
|
||||
D.attach(src)
|
||||
else
|
||||
var/obj/item/mecha_parts/mecha_equipment/drill/D = new
|
||||
D.attach(src)
|
||||
|
||||
else //Add plasma cutter if no drill
|
||||
var/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/P = new
|
||||
P.attach(src)
|
||||
|
||||
//Add ore box to cargo
|
||||
cargo.Add(new /obj/structure/ore_box(src))
|
||||
|
||||
//Attach hydraulic clamp
|
||||
var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new
|
||||
HC.attach(src)
|
||||
for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)//Deletes the beacon so it can't be found easily
|
||||
qdel(B)
|
||||
|
||||
var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new
|
||||
scanner.attach(src)
|
||||
|
||||
/obj/mecha/working/ripley/Exit(atom/movable/O)
|
||||
if(O in cargo)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/mecha/working/ripley/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["drop_from_cargo"])
|
||||
var/obj/O = locate(href_list["drop_from_cargo"])
|
||||
if(O && (O in cargo))
|
||||
occupant_message("<span class='notice'>You unload [O].</span>")
|
||||
O.forceMove(drop_location())
|
||||
cargo -= O
|
||||
mecha_log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]")
|
||||
return
|
||||
|
||||
|
||||
/obj/mecha/working/ripley/contents_explosion(severity, target, origin)
|
||||
for(var/X in cargo)
|
||||
var/obj/O = X
|
||||
if(prob(30/severity))
|
||||
cargo -= O
|
||||
O.forceMove(drop_location())
|
||||
. = ..()
|
||||
|
||||
/obj/mecha/working/ripley/get_stats_part()
|
||||
var/output = ..()
|
||||
output += "<b>Cargo Compartment Contents:</b><div style=\"margin-left: 15px;\">"
|
||||
if(cargo.len)
|
||||
for(var/obj/O in cargo)
|
||||
output += "<a href='?src=[REF(src)];drop_from_cargo=[REF(O)]'>Unload</a> : [O]<br>"
|
||||
else
|
||||
output += "Nothing"
|
||||
output += "</div>"
|
||||
return output
|
||||
|
||||
/obj/mecha/working/ripley/proc/update_pressure()
|
||||
var/turf/T = get_turf(loc)
|
||||
|
||||
if(lavaland_equipment_pressure_check(T))
|
||||
step_in = fast_pressure_step_in
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment)
|
||||
drill.equip_cooldown = initial(drill.equip_cooldown)/2
|
||||
else
|
||||
step_in = slow_pressure_step_in
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment)
|
||||
drill.equip_cooldown = initial(drill.equip_cooldown)
|
||||
|
||||
/obj/mecha/working/ripley/relay_container_resist(mob/living/user, obj/O)
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [O] and start pushing so it falls out of [src].</span>")
|
||||
if(do_after(user, 300, target = O))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src )
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You successfully pushed [O] out of [src]!</span>")
|
||||
O.forceMove(drop_location())
|
||||
cargo -= O
|
||||
else
|
||||
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
|
||||
to_chat(user, "<span class='warning'>You fail to push [O] out of [src]!</span>")
|
||||
@@ -1,3 +0,0 @@
|
||||
/obj/mecha/working
|
||||
internal_damage_threshold = 60
|
||||
|
||||
@@ -18,9 +18,6 @@
|
||||
/obj/effect/acid_act()
|
||||
return
|
||||
|
||||
/obj/effect/mech_melee_attack(obj/mecha/M)
|
||||
return 0
|
||||
|
||||
/obj/effect/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
|
||||
@@ -132,11 +132,15 @@
|
||||
L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!"))
|
||||
log_combat(user, L, "struck with a volt blast")
|
||||
hit_amount++
|
||||
for(var/obj/mecha/M in T)
|
||||
if(M.occupant)
|
||||
if(is_servant_of_ratvar(M.occupant))
|
||||
continue
|
||||
to_chat(M.occupant, "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>")
|
||||
for(var/obj/vehicle/sealed/mecha/M in T)
|
||||
if(LAZYLEN(M.occupants))
|
||||
for(var/mob/living/MB in M.occupants)
|
||||
if(is_servant_of_ratvar(MB))
|
||||
continue
|
||||
else
|
||||
to_chat(MB, "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>")
|
||||
continue
|
||||
|
||||
M.visible_message("<span class='warning'>[M] is struck by a [name]!</span>")
|
||||
M.take_damage(damage, BURN, 0, 0)
|
||||
hit_amount++
|
||||
|
||||
@@ -841,9 +841,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
/obj/item/mech_melee_attack(obj/mecha/M)
|
||||
return 0
|
||||
|
||||
/obj/item/burn()
|
||||
if(!QDELETED(src))
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
dat += " (Stage [stage])"
|
||||
dat += " <a href='?[REF(src)];track=[REF(S)]'>\[Track\]</a><br>"
|
||||
|
||||
for(var/obj/mecha/M in seen)
|
||||
for(var/obj/vehicle/sealed/mecha/M in seen)
|
||||
if(M.name in names)
|
||||
names[M.name]++
|
||||
dat += "[M.name] ([names[M.name]])"
|
||||
|
||||
@@ -171,26 +171,6 @@
|
||||
|
||||
#undef BLACKLISTED_OBJECTS
|
||||
|
||||
/obj/mech_melee_attack(obj/mecha/M)
|
||||
M.do_attack_animation(src)
|
||||
var/play_soundeffect = 0
|
||||
var/mech_damtype = M.damtype
|
||||
if(M.selected)
|
||||
mech_damtype = M.selected.damtype
|
||||
play_soundeffect = 1
|
||||
else
|
||||
switch(M.damtype)
|
||||
if(BRUTE)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if(BURN)
|
||||
playsound(src, 'sound/items/welder.ogg', 50, 1)
|
||||
if(TOX)
|
||||
playsound(src, 'sound/effects/spray2.ogg', 50, 1)
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
visible_message("<span class='danger'>[M.name] has hit [src].</span>", null, null, COMBAT_MESSAGE_RANGE)
|
||||
return take_damage(M.force*3, mech_damtype, "melee", play_soundeffect, get_dir(src, M)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs.
|
||||
|
||||
/obj/singularity_act()
|
||||
ex_act(EXPLODE_DEVASTATE)
|
||||
|
||||
@@ -445,11 +445,6 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
/obj/structure/window/proc/check_state_and_anchored(checked_state, checked_anchored)
|
||||
return check_state(checked_state) && check_anchored(checked_anchored)
|
||||
|
||||
/obj/structure/window/mech_melee_attack(obj/mecha/M)
|
||||
if(!can_be_reached())
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/structure/window/proc/can_be_reached(mob/user)
|
||||
if(!fulltile)
|
||||
if(get_dir(user,src) & dir)
|
||||
|
||||
@@ -145,10 +145,11 @@
|
||||
user.adjustFireLoss(5)
|
||||
playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE)
|
||||
|
||||
/turf/closed/wall/clockwork/mech_melee_attack(obj/mecha/M)
|
||||
/turf/closed/wall/clockwork/mech_melee_attack(obj/vehicle/sealed/mecha/M)
|
||||
..()
|
||||
if(heated)
|
||||
to_chat(M.occupant, "<span class='userdanger'>The wall's intense heat completely reflects your [M.name]'s attack!</span>")
|
||||
for(var/mob/living/MB in M.occupants)
|
||||
to_chat(MB, "<span class='userdanger'>The wall's intense heat completely reflects your [M.name]'s attack!</span>")
|
||||
M.take_damage(20, BURN)
|
||||
|
||||
/turf/closed/wall/clockwork/proc/turn_up_the_heat()
|
||||
|
||||
@@ -115,23 +115,6 @@
|
||||
else
|
||||
add_dent(WALL_DENT_HIT)
|
||||
|
||||
/turf/closed/wall/mech_melee_attack(obj/mecha/M)
|
||||
M.do_attack_animation(src)
|
||||
switch(M.damtype)
|
||||
if(BRUTE)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", null, null, COMBAT_MESSAGE_RANGE)
|
||||
if(prob(hardness + M.force) && M.force > 20)
|
||||
dismantle_wall(1)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
|
||||
else
|
||||
add_dent(WALL_DENT_HIT)
|
||||
if(BURN)
|
||||
playsound(src, 'sound/items/welder.ogg', 100, 1)
|
||||
if(TOX)
|
||||
playsound(src, 'sound/effects/spray2.ogg', 100, 1)
|
||||
return FALSE
|
||||
|
||||
/turf/closed/wall/attack_paw(mob/living/user)
|
||||
return attack_hand(user)
|
||||
|
||||
|
||||
@@ -379,7 +379,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
continue//Will not harm U. Since null != M, can be excluded to kill everyone.
|
||||
M.adjustBruteLoss(damage)
|
||||
M.Unconscious(damage * 4)
|
||||
for(var/obj/mecha/M in src)
|
||||
for(var/obj/vehicle/sealed/mecha/M in src)
|
||||
M.take_damage(damage*2, BRUTE, "melee", 1)
|
||||
|
||||
/turf/proc/Bless()
|
||||
|
||||
@@ -72,8 +72,11 @@ drain_amount: How much is drained by default; Influenced by a multiplier on most
|
||||
cell.use(.)
|
||||
spark_system.start()
|
||||
|
||||
/obj/mecha/power_drain(clockcult_user, drain_weapons = FALSE, recursive = FALSE, drain_amount = MIN_CLOCKCULT_POWER)
|
||||
if(!clockcult_user || (occupant && !is_servant_of_ratvar(occupant)))
|
||||
/obj/vehicle/sealed/mecha/power_drain(clockcult_user, drain_weapons = FALSE, recursive = FALSE, drain_amount = MIN_CLOCKCULT_POWER)
|
||||
if(!clockcult_user || LAZYLEN(occupants))
|
||||
for(var/mob/living/MB in occupants)
|
||||
if(is_servant_of_ratvar(MB))
|
||||
return
|
||||
if(recursive)
|
||||
var/succ = 0
|
||||
for(var/atom/movable/target in contents) //Hiding in your mech won't save you.
|
||||
|
||||
@@ -207,20 +207,20 @@
|
||||
/datum/clockwork_scripture/create_object/summon_arbiter
|
||||
descname = "Powerful Assault Mech"
|
||||
name = "Summon Neovgre, the Anima Bulwark"
|
||||
desc = "Calls forth the mighty Anima Bulwark, a mech with superior defensive and offensive capabilities. It will \
|
||||
desc = "Calls forth the mighty Anima Bulwark, a two-person mech with superior defensive and offensive capabilities. It will \
|
||||
steadily regenerate HP and triple its regeneration speed while standing \
|
||||
on a clockwork tile. It will automatically draw power from nearby sigils of \
|
||||
transmission should the need arise. Its Arbiter laser cannon can decimate foes \
|
||||
from a range and is capable of smashing through any barrier presented to it. \
|
||||
Be warned however, choosing to pilot Neovgre is a lifetime commitment, once you are \
|
||||
in you cannot leave and when it is destroyed it will explode catastrophically, with you inside."
|
||||
Be warned however, choosing to pilot or man Neovgre is a lifetime commitment, once you are \
|
||||
in you cannot leave and when it is destroyed it will explode catastrophically, with everyone inside."
|
||||
invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!")
|
||||
channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya.
|
||||
power_cost = 75000 //75 KW
|
||||
usage_tip = "Neovgre is a powerful mech that will crush your enemies!"
|
||||
invokers_required = 5
|
||||
multiple_invokers_used = TRUE
|
||||
object_path = /obj/mecha/combat/neovgre
|
||||
object_path = /obj/vehicle/sealed/mecha/combat/neovgre
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
primary_component = BELLIGERENT_EYE
|
||||
sort_priority = 8
|
||||
|
||||
@@ -72,11 +72,6 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant && is_servant_of_ratvar(M.occupant) && immune_to_servant_attacks)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/proc/get_efficiency_mod()
|
||||
if(GLOB.ratvar_awakens)
|
||||
return 2
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
L.adjust_fire_stacks(damage_per_tick)
|
||||
L.IgniteMob()
|
||||
else if(ismecha(target))
|
||||
var/obj/mecha/M = target
|
||||
var/obj/vehicle/sealed/mecha/M = target
|
||||
M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M))
|
||||
|
||||
new /obj/effect/temp_visual/ratvar/ocular_warden(get_turf(target))
|
||||
@@ -91,8 +91,8 @@
|
||||
var/mob/living/L = target
|
||||
to_chat(L, "<span class='neovgre'>\"I SEE YOU!\"</span>\n<span class='userdanger'>[src]'s gaze [GLOB.ratvar_awakens ? "melts you alive" : "burns you"]!</span>")
|
||||
else if(ismecha(target))
|
||||
var/obj/mecha/M = target
|
||||
to_chat(M.occupant, "<span class='neovgre'>\"I SEE YOU!\"</span>" )
|
||||
var/obj/vehicle/sealed/mecha/M = target
|
||||
to_chat(M.occupants, "<span class='neovgre'>\"I SEE YOU!\"</span>" )
|
||||
else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes
|
||||
if(prob(50))
|
||||
visible_message("<span class='notice'>[src][pick(idle_messages)]</span>")
|
||||
@@ -131,8 +131,11 @@
|
||||
. += L
|
||||
var/list/viewcache = list()
|
||||
for(var/N in GLOB.mechas_list)
|
||||
var/obj/mecha/M = N
|
||||
if(get_dist(M, src) <= sight_range && M.occupant && !is_servant_of_ratvar(M.occupant))
|
||||
var/obj/vehicle/sealed/mecha/M = N
|
||||
if(get_dist(M, src) <= sight_range && LAZYLEN(M.occupants))
|
||||
for(var/mob/living/MB in M.occupants)
|
||||
if(is_servant_of_ratvar(MB))
|
||||
return
|
||||
if(!length(viewcache))
|
||||
for (var/obj/Z in view(sight_range, src))
|
||||
viewcache += Z
|
||||
|
||||
+6
-4
@@ -9,12 +9,14 @@
|
||||
|
||||
/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(!istype(AM,/obj/mecha/))
|
||||
if(!istype(AM,/obj/vehicle/sealed/mecha/))
|
||||
return
|
||||
|
||||
var/obj/mecha/M = AM
|
||||
if(M.occupant && is_servant_of_ratvar(M.occupant))
|
||||
return
|
||||
var/obj/vehicle/sealed/mecha/M = AM
|
||||
if(LAZYLEN(M.occupants))
|
||||
for(var/mob/living/MB in M.occupants)
|
||||
if(is_servant_of_ratvar(MB))
|
||||
return
|
||||
audible_message("<i>*click*</i>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE)
|
||||
activate()
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE //So players can interact with the tile it's on to pull them off
|
||||
buckle_mob(squirrel, TRUE)
|
||||
else
|
||||
var/obj/mecha/M = locate() in get_turf(src)
|
||||
var/obj/vehicle/sealed/mecha/M = locate() in get_turf(src)
|
||||
if(M)
|
||||
M.take_damage(50,BRUTE,"melee")
|
||||
M.visible_message("<span class='danger'>A massive brass spike erupts from the ground, penetrating \the [M] and shattering the trap into pieces!</span>")
|
||||
|
||||
@@ -402,7 +402,7 @@
|
||||
new /obj/effect/hotspot(T)
|
||||
T.hotspot_expose(700,50,1)
|
||||
// deals damage to mechs
|
||||
for(var/obj/mecha/M in T.contents)
|
||||
for(var/obj/vehicle/sealed/mecha/M in T.contents)
|
||||
if(M in hit_list)
|
||||
continue
|
||||
hit_list += M
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
/datum/bounty/item/mech/ship(obj/O)
|
||||
if(!applies_to(O))
|
||||
return
|
||||
if(istype(O, /obj/mecha))
|
||||
var/obj/mecha/M = O
|
||||
if(istype(O, /obj/vehicle/sealed/mecha))
|
||||
var/obj/vehicle/sealed/mecha/M = O
|
||||
M.wreckage = null // So the mech doesn't explode.
|
||||
..()
|
||||
|
||||
@@ -16,30 +16,30 @@
|
||||
/datum/bounty/item/mech/ripley
|
||||
name = "APLU \"Ripley\""
|
||||
reward = 13000
|
||||
wanted_types = list(/obj/mecha/working/ripley)
|
||||
exclude_types = list(/obj/mecha/working/ripley/firefighter)
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley)
|
||||
exclude_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter)
|
||||
|
||||
/datum/bounty/item/mech/firefighter
|
||||
name = "APLU \"Firefighter\""
|
||||
reward = 18000
|
||||
wanted_types = list(/obj/mecha/working/ripley/firefighter)
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter)
|
||||
|
||||
/datum/bounty/item/mech/odysseus
|
||||
name = "Odysseus"
|
||||
reward = 11000
|
||||
wanted_types = list(/obj/mecha/medical/odysseus)
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/medical/odysseus)
|
||||
|
||||
/datum/bounty/item/mech/gygax
|
||||
name = "Gygax"
|
||||
reward = 28000
|
||||
wanted_types = list(/obj/mecha/combat/gygax)
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/combat/gygax)
|
||||
|
||||
/datum/bounty/item/mech/durand
|
||||
name = "Durand"
|
||||
reward = 20000
|
||||
wanted_types = list(/obj/mecha/combat/durand)
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/combat/durand)
|
||||
|
||||
/datum/bounty/item/mech/phazon
|
||||
name = "Phazon"
|
||||
reward = 50000
|
||||
wanted_types = list(/obj/mecha/combat/phazon)
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/combat/phazon)
|
||||
|
||||
@@ -61,7 +61,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
if(ismob(thing))
|
||||
thing.investigate_log("deleted through cargo export",INVESTIGATE_CARGO)
|
||||
if(ismecha(thing))
|
||||
var/obj/mecha/mech = thing
|
||||
var/obj/vehicle/sealed/mecha/mech = thing
|
||||
mech.wreckage = null // why a mech left a wreck when sold i will never know
|
||||
qdel(thing)
|
||||
|
||||
|
||||
@@ -278,69 +278,69 @@
|
||||
/datum/export/large/mech/odysseus
|
||||
cost = 7500
|
||||
unit_name = "working odysseus"
|
||||
export_types = list(/obj/mecha/medical/odysseus)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/medical/odysseus)
|
||||
|
||||
/datum/export/large/mech/ripley
|
||||
cost = 12000
|
||||
unit_name = "working ripley"
|
||||
export_types = list(/obj/mecha/working/ripley)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/working/ripley)
|
||||
|
||||
/datum/export/large/mech/firefighter
|
||||
cost = 14000
|
||||
unit_name = "working firefighter"
|
||||
export_types = list(/obj/mecha/working/ripley/firefighter)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter)
|
||||
|
||||
/datum/export/large/mech/gygax
|
||||
cost = 19000
|
||||
unit_name = "working gygax"
|
||||
export_types = list(/obj/mecha/combat/gygax)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/gygax)
|
||||
|
||||
/datum/export/large/mech/durand
|
||||
cost = 16000
|
||||
unit_name = "working durand"
|
||||
export_types = list(/obj/mecha/combat/durand)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/durand)
|
||||
|
||||
/datum/export/large/mech/phazon
|
||||
cost = 35000 //Little over half due to needing a core
|
||||
unit_name = "working phazon"
|
||||
export_types = list(/obj/mecha/combat/phazon)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/phazon)
|
||||
|
||||
/datum/export/large/mech/marauder
|
||||
cost = 15000 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price.
|
||||
unit_name = "working marauder"
|
||||
export_types = list(/obj/mecha/combat/marauder)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/marauder)
|
||||
|
||||
/datum/export/large/mech/deathripley
|
||||
cost = 18500 //Still a "Combat class" mech - Illegal tech as well! 165% "normal" boundy price.
|
||||
unit_name = "working illegally modified"
|
||||
export_types = list(/obj/mecha/working/ripley/deathripley)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/working/ripley/deathripley)
|
||||
|
||||
/datum/export/large/mech/gygaxdark
|
||||
cost = 28500 //Still a Combat class mech - Illegal tech as well! 150% "normal" boundy price.
|
||||
unit_name = "working illegally modified gygax"
|
||||
export_types = list(/obj/mecha/combat/gygax/dark)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/gygax/dark)
|
||||
|
||||
/datum/export/large/mech/oldripley
|
||||
cost = 6250 //old mech - Scrap metal ! 50% "normal" boundy price.
|
||||
unit_name = "working miner ripley"
|
||||
export_types = list(/obj/mecha/working/ripley/mining)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/working/ripley/mining)
|
||||
|
||||
/datum/export/large/mech/honk
|
||||
cost = 16000 //Still a "Combat class" mech - Comats bordem honk!
|
||||
unit_name = "working honker"
|
||||
export_types = list(/obj/mecha/combat/honker)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/honker)
|
||||
|
||||
/datum/export/large/mech/reticence
|
||||
cost = 16000 //Still a "Combat class" mech - Has cloking and lethal weaponds.
|
||||
unit_name = "working reticence"
|
||||
export_types = list(/obj/mecha/combat/reticence)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/reticence)
|
||||
|
||||
/datum/export/large/mech/seraph
|
||||
cost = 25500 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price.
|
||||
unit_name = "working seraph"
|
||||
export_types = list(/obj/mecha/combat/marauder/seraph)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/marauder/seraph)
|
||||
|
||||
/datum/export/large/mech/mauler
|
||||
cost = 25000 //Still a Combat class mech - CC lethal weaponds.
|
||||
unit_name = "working legally modified marauder"
|
||||
export_types = list(/obj/mecha/combat/marauder/mauler)
|
||||
export_types = list(/obj/vehicle/sealed/mecha/combat/marauder/mauler)
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
cost = 150
|
||||
unit_name = "mech based tool"
|
||||
include_subtypes = TRUE
|
||||
export_types = list(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/extinguisher, /obj/item/mecha_parts/mecha_equipment/rcd, /obj/item/mecha_parts/mecha_equipment/cable_layer, \
|
||||
export_types = list(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/extinguisher, /obj/item/mecha_parts/mecha_equipment/rcd, \
|
||||
/obj/item/mecha_parts/mecha_equipment/drill, /obj/item/mecha_parts/mecha_equipment/mining_scanner, /obj/item/mecha_parts/mecha_equipment/medical/sleeper)
|
||||
|
||||
/datum/export/robotics/mech_blue_space
|
||||
|
||||
@@ -274,8 +274,8 @@
|
||||
if(isliving(A)) //Gettem boys!
|
||||
L = A
|
||||
else if(ismecha(A))
|
||||
var/obj/mecha/M = A
|
||||
L = M.occupant
|
||||
var/obj/vehicle/sealed/mecha/M = A
|
||||
L = pick(M.occupants)
|
||||
if(L && L.stat != DEAD && !HAS_TRAIT(L, TRAIT_DEATHCOMA)) //Taking revenge on the deads would be proposterous.
|
||||
addtimer(CALLBACK(src, .proc/clear_grudge, L), 2 MINUTES, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
if(!book_of_grudges[L])
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
freeze_mob(A)
|
||||
else if(istype(A, /obj/item/projectile))
|
||||
freeze_projectile(A)
|
||||
else if(istype(A, /obj/mecha))
|
||||
else if(istype(A, /obj/vehicle/sealed/mecha))
|
||||
freeze_mecha(A)
|
||||
else if((ismachinery(A) && !istype(A, /obj/machinery/light)) || isstructure(A)) //Special exception for light fixtures since recoloring causes them to change light
|
||||
freeze_structure(A)
|
||||
@@ -120,7 +120,7 @@
|
||||
unfreeze_mob(A)
|
||||
else if(istype(A, /obj/item/projectile))
|
||||
unfreeze_projectile(A)
|
||||
else if(istype(A, /obj/mecha))
|
||||
else if(istype(A, /obj/vehicle/sealed/mecha))
|
||||
unfreeze_mecha(A)
|
||||
|
||||
UnregisterSignal(A, COMSIG_MOVABLE_PRE_MOVE)
|
||||
@@ -131,10 +131,10 @@
|
||||
global_frozen_atoms -= A
|
||||
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/mecha/M)
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/vehicle/sealed/mecha/M)
|
||||
M.completely_disabled = TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/mecha/M)
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/vehicle/sealed/mecha/M)
|
||||
M.completely_disabled = FALSE
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
var/obj/item/radio/radio = null //Let's give it a radio.
|
||||
var/mob/living/brain/brainmob = null //The current occupant.
|
||||
var/mob/living/silicon/robot = null //Appears unused.
|
||||
var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm.
|
||||
var/obj/vehicle/sealed/mecha = null //This does not appear to be used outside of reference in mecha.dm.
|
||||
var/obj/item/organ/brain/brain = null //The actual brain
|
||||
var/datum/ai_laws/laws = new()
|
||||
var/force_replace_ai_name = FALSE
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/brain/update_mobility()
|
||||
return ((mobility_flags = (container?.in_contents_of(/obj/mecha)? MOBILITY_FLAGS_DEFAULT : NONE)))
|
||||
return ((mobility_flags = (container?.in_contents_of(/obj/vehicle/sealed/mecha)? MOBILITY_FLAGS_DEFAULT : NONE)))
|
||||
|
||||
/mob/living/brain/ex_act(severity, target, origin) //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
|
||||
return
|
||||
@@ -71,13 +71,6 @@
|
||||
if(stored_dna)
|
||||
stored_dna.real_name = real_name
|
||||
|
||||
/mob/living/brain/ClickOn(atom/A, params)
|
||||
..()
|
||||
if(container)
|
||||
var/obj/mecha/M = container.mecha
|
||||
if(istype(M))
|
||||
return M.click_action(A,src,params)
|
||||
|
||||
/mob/living/brain/forceMove(atom/destination)
|
||||
if(container)
|
||||
return container.forceMove(destination)
|
||||
@@ -98,7 +91,7 @@
|
||||
if(!container)
|
||||
return
|
||||
if (container.mecha)
|
||||
var/obj/mecha/M = container.mecha
|
||||
var/obj/vehicle/sealed/mecha/M = container.mecha
|
||||
if(M.mouse_pointer)
|
||||
client.mouse_pointer_icon = M.mouse_pointer
|
||||
if (client && ranged_ability && ranged_ability.ranged_mousepointer)
|
||||
|
||||
@@ -43,10 +43,6 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift)
|
||||
if(client && !suiciding && !(client in GLOB.dead_players_during_shift))
|
||||
GLOB.dead_players_during_shift += client
|
||||
GLOB.deaths_during_shift++
|
||||
if(ismecha(loc))
|
||||
var/obj/mecha/M = loc
|
||||
if(M.occupant == src)
|
||||
M.go_out()
|
||||
|
||||
if(!QDELETED(dna)) //The gibbed param is bit redundant here since dna won't exist at this point if they got deleted.
|
||||
dna.species.spec_death(gibbed, src)
|
||||
|
||||
@@ -256,48 +256,6 @@
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block, wound_bonus=wound_mod)
|
||||
|
||||
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM))
|
||||
to_chat(M.occupant, "<span class='warning'>You don't want to harm other living beings!</span>")
|
||||
return
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
var/obj/item/bodypart/temp = get_bodypart(pick(BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_HEAD))
|
||||
if(temp)
|
||||
var/update = 0
|
||||
var/dmg = rand(M.force/2, M.force)
|
||||
var/atom/throw_target = get_edge_target_turf(src, M.dir)
|
||||
switch(M.damtype)
|
||||
if("brute")
|
||||
if(M.force > 35) // durand and other heavy mechas
|
||||
DefaultCombatKnockdown(50)
|
||||
src.throw_at(throw_target, rand(1,5), 7)
|
||||
else if(M.force >= 20 && CHECK_MOBILITY(src, MOBILITY_STAND)) // lightweight mechas like gygax
|
||||
DefaultCombatKnockdown(30)
|
||||
src.throw_at(throw_target, rand(1,3), 7)
|
||||
update |= temp.receive_damage(dmg, 0)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if("fire")
|
||||
update |= temp.receive_damage(0, dmg)
|
||||
playsound(src, 'sound/items/welder.ogg', 50, 1)
|
||||
if("tox")
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
updatehealth()
|
||||
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit you!</span>", null, COMBAT_MESSAGE_RANGE, target = M,
|
||||
target_message = "<span class='danger'>You have hit [src]!</span>")
|
||||
log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/ex_act(severity, target, origin)
|
||||
if(TRAIT_BOMBIMMUNE in dna.species.species_traits)
|
||||
|
||||
@@ -149,39 +149,6 @@
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM))
|
||||
to_chat(M.occupant, "<span class='warning'>You don't want to harm other living beings!</span>")
|
||||
return
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
switch(M.damtype)
|
||||
if(BRUTE)
|
||||
Unconscious(20)
|
||||
take_overall_damage(rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if(BURN)
|
||||
take_overall_damage(0, rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/items/welder.ogg', 50, 1)
|
||||
if(TOX)
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
updatehealth()
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit you!</span>", null, COMBAT_MESSAGE_RANGE, null,
|
||||
M.occupant, "<span class='danger'>You hit [src] with your [M.name]!</span>")
|
||||
log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
else
|
||||
step_away(src,M)
|
||||
log_combat(M.occupant, src, "pushed", M)
|
||||
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>", \
|
||||
"<span class='warning'>[M] pushes you out of the way.</span>", null, COMBAT_MESSAGE_RANGE, null,
|
||||
M.occupant, "<span class='warning'>You push [src] out of the way with your [M.name].</span>")
|
||||
|
||||
/mob/living/fire_act()
|
||||
adjust_fire_stacks(3)
|
||||
IgniteMob()
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
|
||||
var/viewalerts = 0
|
||||
var/icon/holo_icon//Female is assigned when AI is created.
|
||||
var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
|
||||
var/obj/vehicle/sealed/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
|
||||
var/radio_enabled = TRUE //Determins if a carded AI can speak with its built in radio or not.
|
||||
radiomod = ";" //AIs will, by default, state their laws on the internal radio.
|
||||
var/obj/item/pda/ai/aiPDA
|
||||
@@ -408,7 +408,7 @@
|
||||
return
|
||||
|
||||
if (href_list["ai_take_control"]) //Mech domination
|
||||
var/obj/mecha/M = locate(href_list["ai_take_control"])
|
||||
var/obj/vehicle/sealed/mecha/M = locate(href_list["ai_take_control"])
|
||||
if(controlled_mech)
|
||||
to_chat(src, "<span class='warning'>You are already loaded into an onboard computer!</span>")
|
||||
return
|
||||
|
||||
@@ -53,11 +53,11 @@
|
||||
if(NONE)
|
||||
return FALSE
|
||||
if(POWER_REQ_ALL)
|
||||
return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
|
||||
return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/vehicle/sealed/mecha)))
|
||||
if(POWER_REQ_CLOCKCULT)
|
||||
for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, SIGIL_ACCESS_RANGE))
|
||||
return FALSE
|
||||
return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
|
||||
return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/vehicle/sealed/mecha)))
|
||||
|
||||
/mob/living/silicon/ai/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
if(!search_objects)
|
||||
. = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide
|
||||
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly))
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly))
|
||||
|
||||
for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines))
|
||||
if(can_see(targets_from, HM, vision_range))
|
||||
@@ -236,9 +236,9 @@
|
||||
return TRUE
|
||||
|
||||
if(ismecha(the_target))
|
||||
var/obj/mecha/M = the_target
|
||||
if(M.occupant)//Just so we don't attack empty mechs
|
||||
if(CanAttack(M.occupant))
|
||||
var/obj/vehicle/sealed/mecha/M = the_target
|
||||
for(var/occupant in M.occupants)
|
||||
if(CanAttack(occupant))
|
||||
return TRUE
|
||||
|
||||
if(istype(the_target, /obj/machinery/porta_turret))
|
||||
@@ -604,7 +604,7 @@
|
||||
toggle_ai(AI_ON)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/ListTargetsLazy(var/_Z)//Step 1, find out what we can see
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden))
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha, /obj/structure/destructible/clockwork/ocular_warden))
|
||||
. = list()
|
||||
for (var/I in SSmobs.clients_by_zlevel[_Z])
|
||||
var/mob/M = I
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
search_objects = 0
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
|
||||
var/spawn_mecha_type = /obj/mecha/combat/marauder/mauler/loaded
|
||||
var/obj/mecha/mecha //Ref to pilot's mecha instance
|
||||
var/spawn_mecha_type = /obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded
|
||||
var/obj/vehicle/sealed/mecha/mecha //Ref to pilot's mecha instance
|
||||
var/required_mecha_charge = 7500 //If the pilot doesn't have a mecha, what charge does a potential Grand Theft Mecha need? (Defaults to half a battery)
|
||||
var/mecha_charge_evacuate = 50 //Amount of charge at which the pilot tries to abandon the mecha
|
||||
|
||||
//Vars that control when the pilot uses their mecha's abilities (if the mecha has that ability)
|
||||
var/threat_use_mecha_smoke = 5 //5 mobs is enough to engage crowd control
|
||||
var/defence_mode_chance = 35 //Chance to engage Defence mode when damaged
|
||||
var/defense_mode_chance = 35 //Chance to engage Defense mode when damaged
|
||||
var/smoke_chance = 20 //Chance to deploy smoke for crowd control
|
||||
var/retreat_chance = 40 //Chance to run away
|
||||
|
||||
@@ -42,18 +42,18 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/Initialize()
|
||||
. = ..()
|
||||
wanted_objects = typecacheof(/obj/mecha/combat, TRUE)
|
||||
wanted_objects = typecacheof(/obj/vehicle/sealed/mecha/combat, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/nanotrasen //nanotrasen are syndies! no it's just a weird path.
|
||||
name = "Nanotrasen Mecha Pilot"
|
||||
name = "\improper Nanotrasen Mecha Pilot"
|
||||
desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour."
|
||||
icon_living = "nanotrasen"
|
||||
icon_state = "nanotrasen"
|
||||
faction = list("nanotrasen")
|
||||
spawn_mecha_type = /obj/mecha/combat/marauder/loaded
|
||||
spawn_mecha_type = /obj/vehicle/sealed/mecha/combat/marauder/loaded
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/nanotrasen
|
||||
name = "Nanotrasen Mecha Pilot"
|
||||
name = "\improper Nanotrasen Mecha Pilot"
|
||||
desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour."
|
||||
icon_living = "nanotrasen"
|
||||
icon_state = "nanotrasen"
|
||||
@@ -63,12 +63,12 @@
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/Initialize()
|
||||
. = ..()
|
||||
if(spawn_mecha_type)
|
||||
var/obj/mecha/M = new spawn_mecha_type (get_turf(src))
|
||||
var/obj/vehicle/sealed/mecha/M = new spawn_mecha_type (get_turf(src))
|
||||
if(istype(M))
|
||||
enter_mecha(M)
|
||||
INVOKE_ASYNC(src, .proc/enter_mecha, M)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/mecha/M)
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/vehicle/sealed/mecha/M)
|
||||
if(!M)
|
||||
return 0
|
||||
target = null //Target was our mecha, so null it out
|
||||
@@ -78,7 +78,7 @@
|
||||
var/do_ranged = 0
|
||||
for(var/equip in mecha.equipment)
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = equip
|
||||
if(ME.range & RANGED)
|
||||
if(ME.range & MECHA_RANGED)
|
||||
do_ranged = 1
|
||||
break
|
||||
if(do_ranged)
|
||||
@@ -89,11 +89,11 @@
|
||||
ranged = 0
|
||||
wanted_objects = list()
|
||||
search_objects = 0
|
||||
if(mecha && mecha.lights_action) //an AI mecha is an EVIL EVIL thing, so let's not hide them in the dark
|
||||
mecha.lights_action.Activate()
|
||||
if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_defense_mode) && !mecha.defense_mode)
|
||||
var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_defense_mode]
|
||||
action.Trigger(TRUE)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/exit_mecha(obj/mecha/M)
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/exit_mecha(obj/vehicle/sealed/mecha/M)
|
||||
if(!M)
|
||||
return 0
|
||||
|
||||
@@ -102,9 +102,9 @@
|
||||
targets_from = src
|
||||
|
||||
//Find a new mecha
|
||||
wanted_objects = typecacheof(/obj/mecha/combat, TRUE)
|
||||
wanted_objects = typecacheof(/obj/vehicle/sealed/mecha/combat, TRUE)
|
||||
var/search_aggressiveness = 2
|
||||
for(var/obj/mecha/combat/C in range(vision_range,src))
|
||||
for(var/obj/vehicle/sealed/mecha/combat/C in range(vision_range,src))
|
||||
if(is_valid_mecha(C))
|
||||
target = C
|
||||
search_aggressiveness = 3 //We can see a mech? RUN FOR IT, IGNORE MOBS!
|
||||
@@ -116,23 +116,23 @@
|
||||
walk(M,0)//end any lingering movement loops, to prevent the haunted mecha bug
|
||||
|
||||
//Checks if a mecha is valid for theft
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/is_valid_mecha(obj/mecha/M)
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/is_valid_mecha(obj/vehicle/sealed/mecha/M)
|
||||
if(!M)
|
||||
return 0
|
||||
if(M.occupant)
|
||||
return 0
|
||||
return FALSE
|
||||
if(LAZYLEN(M.occupants))
|
||||
return FALSE
|
||||
if(!M.has_charge(required_mecha_charge))
|
||||
return 0
|
||||
return FALSE
|
||||
if(M.obj_integrity < M.max_integrity*0.5)
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/mecha_face_target(atom/A)
|
||||
if(mecha)
|
||||
var/dirto = get_dir(mecha,A)
|
||||
if(mecha.dir != dirto) //checking, because otherwise the mecha makes too many turn noises
|
||||
mecha.mechturn(dirto)
|
||||
mecha.vehicle_move(dirto, TRUE)
|
||||
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
ME.rearm()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/get_mecha_equip_by_flag(flag = RANGED)
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/get_mecha_equip_by_flag(flag = MECHA_RANGED)
|
||||
. = list()
|
||||
if(mecha)
|
||||
for(var/equip in mecha.equipment)
|
||||
@@ -160,11 +160,10 @@
|
||||
if(mecha)
|
||||
mecha_reload()
|
||||
mecha_face_target(A)
|
||||
var/list/possible_weapons = get_mecha_equip_by_flag(RANGED)
|
||||
var/list/possible_weapons = get_mecha_equip_by_flag(MECHA_RANGED)
|
||||
if(possible_weapons.len)
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = pick(possible_weapons) //so we don't favor mecha.equipment[1] forever
|
||||
if(ME.action(A))
|
||||
ME.start_cooldown()
|
||||
if(ME.action(src,A))
|
||||
return
|
||||
|
||||
else
|
||||
@@ -173,20 +172,19 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/AttackingTarget()
|
||||
if(mecha)
|
||||
var/list/possible_weapons = get_mecha_equip_by_flag(MELEE)
|
||||
var/list/possible_weapons = get_mecha_equip_by_flag(MECHA_MELEE)
|
||||
if(possible_weapons.len)
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = pick(possible_weapons)
|
||||
mecha_face_target(target)
|
||||
if(ME.action(target))
|
||||
ME.start_cooldown()
|
||||
if(ME.action(src,target))
|
||||
return
|
||||
|
||||
if(mecha.melee_can_hit)
|
||||
if(!TIMER_COOLDOWN_CHECK(mecha, COOLDOWN_MECHA_MELEE_ATTACK))
|
||||
mecha_face_target(target)
|
||||
target.mech_melee_attack(mecha)
|
||||
target.mech_melee_attack(mecha, src)
|
||||
else
|
||||
if(ismecha(target))
|
||||
var/obj/mecha/M = target
|
||||
var/obj/vehicle/sealed/mecha/M = target
|
||||
if(is_valid_mecha(M))
|
||||
enter_mecha(M)
|
||||
return
|
||||
@@ -199,50 +197,54 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/handle_automated_action()
|
||||
if(..())
|
||||
if(!mecha)
|
||||
for(var/obj/mecha/combat/C in range(src,vision_range))
|
||||
if(is_valid_mecha(C))
|
||||
target = C //Let's nab it!
|
||||
minimum_distance = 1
|
||||
ranged = 0
|
||||
break
|
||||
if(mecha)
|
||||
var/list/L = PossibleThreats()
|
||||
var/threat_count = L.len
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!mecha)
|
||||
for(var/obj/vehicle/sealed/mecha/combat/mecha_in_range in range(src,vision_range))
|
||||
if(is_valid_mecha(mecha_in_range))
|
||||
target = mecha_in_range //Let's nab it!
|
||||
minimum_distance = 1
|
||||
ranged = 0
|
||||
break
|
||||
if(mecha)
|
||||
var/list/L = PossibleThreats()
|
||||
var/threat_count = L.len
|
||||
|
||||
//Low Charge - Eject
|
||||
if(!mecha.has_charge(mecha_charge_evacuate))
|
||||
exit_mecha(mecha)
|
||||
return
|
||||
//Low Charge - Eject
|
||||
if(!mecha.has_charge(mecha_charge_evacuate))
|
||||
exit_mecha(mecha)
|
||||
return
|
||||
|
||||
//Too Much Damage - Eject
|
||||
if(mecha.obj_integrity < mecha.max_integrity*0.1)
|
||||
exit_mecha(mecha)
|
||||
return
|
||||
if(mecha.obj_integrity < mecha.max_integrity*0.1)
|
||||
exit_mecha(mecha)
|
||||
return
|
||||
|
||||
//Smoke if there's too many targets - Smoke Power
|
||||
if(threat_count >= threat_use_mecha_smoke && prob(smoke_chance))
|
||||
if(mecha.smoke_action && mecha.smoke_action.owner && mecha.smoke)
|
||||
mecha.smoke_action.Activate()
|
||||
//Smoke if there's too many targets - Smoke Power
|
||||
if(threat_count >= threat_use_mecha_smoke && prob(smoke_chance))
|
||||
if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_smoke) && !mecha.smoke_charges)
|
||||
var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_smoke]
|
||||
action.Trigger()
|
||||
|
||||
//Heavy damage - Defence Power or Retreat
|
||||
if(mecha.obj_integrity < mecha.max_integrity*0.25)
|
||||
if(prob(defence_mode_chance))
|
||||
if(mecha.defense_action && mecha.defense_action.owner && !mecha.defence_mode)
|
||||
mecha.leg_overload_mode = 0
|
||||
mecha.defense_action.Activate(TRUE)
|
||||
addtimer(CALLBACK(mecha.defense_action, /datum/action/innate/mecha/mech_defence_mode.proc/Activate, FALSE), 100) //10 seconds of defence, then toggle off
|
||||
//Heavy damage - Defense Power or Retreat
|
||||
if(mecha.obj_integrity < mecha.max_integrity*0.25)
|
||||
if(prob(defense_mode_chance))
|
||||
if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_defense_mode) && !mecha.defense_mode)
|
||||
var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_defense_mode]
|
||||
action.Trigger(TRUE)
|
||||
addtimer(CALLBACK(action, /datum/action/vehicle/sealed/mecha/mech_defense_mode.proc/Trigger, FALSE), 100) //10 seconds of defense, then toggle off
|
||||
|
||||
else if(prob(retreat_chance))
|
||||
//Speed boost if possible
|
||||
if(mecha.overload_action && mecha.overload_action.owner && !mecha.leg_overload_mode)
|
||||
mecha.overload_action.Activate(TRUE)
|
||||
addtimer(CALLBACK(mecha.overload_action, /datum/action/innate/mecha/mech_defence_mode.proc/Activate, FALSE), 100) //10 seconds of speeeeed, then toggle off
|
||||
else if(prob(retreat_chance))
|
||||
//Speed boost if possible
|
||||
if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_overload_mode) && !mecha.leg_overload_mode)
|
||||
var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_overload_mode]
|
||||
mecha.leg_overload_mode = FALSE
|
||||
action.Trigger(TRUE)
|
||||
addtimer(CALLBACK(action, /datum/action/vehicle/sealed/mecha/mech_overload_mode.proc/Trigger, FALSE), 100) //10 seconds of speeeeed, then toggle off
|
||||
|
||||
retreat_distance = 50
|
||||
spawn(100)
|
||||
retreat_distance = 0
|
||||
retreat_distance = 50
|
||||
addtimer(VARSET_CALLBACK(src, retreat_distance, 0), 10 SECONDS)
|
||||
|
||||
|
||||
|
||||
@@ -261,17 +263,17 @@
|
||||
//~simple animals~
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/CanAttack(atom/the_target)
|
||||
if(ismecha(the_target))
|
||||
var/obj/mecha/M = the_target
|
||||
var/obj/vehicle/sealed/mecha/M = the_target
|
||||
if(mecha)
|
||||
if(M == mecha || !CanAttack(M.occupant))
|
||||
return 0
|
||||
if(M == mecha) //Dont kill yourself
|
||||
return FALSE
|
||||
else //we're not in a mecha, so we check if we can steal it instead.
|
||||
if(is_valid_mecha(M))
|
||||
return 1
|
||||
else if (M.occupant && CanAttack(M.occupant))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
return TRUE
|
||||
for(var/occupant in M.occupants)
|
||||
if(CanAttack(occupant))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
. = ..()
|
||||
|
||||
@@ -290,6 +292,6 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/Goto(target, delay, minimum_distance)
|
||||
if(mecha)
|
||||
walk_to(mecha, target, minimum_distance, mecha.step_in)
|
||||
walk_to(mecha, target, minimum_distance, mecha.movedelay)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -195,7 +195,7 @@ Difficulty: Medium
|
||||
if(L.client)
|
||||
empty += pick(((RANGE_TURFS(2, L) - RANGE_TURFS(1, L)) & turfs) - empty) // picks a turf within 2 of the creature not outside or in the shield
|
||||
any_attack = 1
|
||||
for(var/obj/mecha/M in T.contents)
|
||||
for(var/obj/vehicle/sealed/mecha/M in T.contents)
|
||||
empty += pick(((RANGE_TURFS(2, M) - RANGE_TURFS(1, M)) & turfs) - empty)
|
||||
any_attack = 1
|
||||
if(!any_attack)
|
||||
@@ -264,7 +264,7 @@ Difficulty: Medium
|
||||
to_chat(L, "<span class='userdanger'>You're hit by [src]'s fire breath!</span>")
|
||||
|
||||
// deals damage to mechs
|
||||
for(var/obj/mecha/M in T.contents)
|
||||
for(var/obj/vehicle/sealed/mecha/M in T.contents)
|
||||
if(M in hit_list)
|
||||
continue
|
||||
hit_list += M
|
||||
@@ -350,7 +350,7 @@ Difficulty: Medium
|
||||
var/throwtarget = get_edge_target_turf(src, throw_dir)
|
||||
L.throw_at(throwtarget, 3)
|
||||
visible_message("<span class='warning'>[L] is thrown clear of [src]!</span>")
|
||||
for(var/obj/mecha/M in orange(1, src))
|
||||
for(var/obj/vehicle/sealed/mecha/M in orange(1, src))
|
||||
M.take_damage(75, BRUTE, "melee", 1)
|
||||
|
||||
for(var/mob/M in range(7, src))
|
||||
@@ -409,7 +409,7 @@ Difficulty: Medium
|
||||
to_chat(L, "<span class='userdanger'>You fall directly into the pool of lava!</span>")
|
||||
|
||||
// deals damage to mechs
|
||||
for(var/obj/mecha/M in T.contents)
|
||||
for(var/obj/vehicle/sealed/mecha/M in T.contents)
|
||||
M.take_damage(45, BRUTE, "melee", 1)
|
||||
|
||||
// changes turf to lava temporarily
|
||||
@@ -538,7 +538,7 @@ Difficulty: Medium
|
||||
to_chat(L, "<span class='userdanger'>You're hit by [source]'s fire breath!</span>")
|
||||
|
||||
// deals damage to mechs
|
||||
for(var/obj/mecha/M in T.contents)
|
||||
for(var/obj/vehicle/sealed/mecha/M in T.contents)
|
||||
if(M in hit_list)
|
||||
continue
|
||||
hit_list += M
|
||||
|
||||
@@ -656,14 +656,16 @@ Difficulty: Normal
|
||||
if(monster_damage_boost && (ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid)))
|
||||
L.adjustBruteLoss(damage)
|
||||
log_combat(caster, L, "struck with a [name]")
|
||||
for(var/obj/mecha/M in T.contents - hit_things) //also damage mechs.
|
||||
for(var/obj/vehicle/sealed/mecha/M in T.contents - hit_things) //also damage mechs.
|
||||
hit_things += M
|
||||
if(M.occupant)
|
||||
if(friendly_fire_check && caster && caster.faction_check_mob(M.occupant))
|
||||
for(var/O in M.occupants)
|
||||
var/mob/living/occupant = O
|
||||
if(friendly_fire_check && caster && caster.faction_check_mob(occupant))
|
||||
continue
|
||||
to_chat(M.occupant, "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>")
|
||||
playsound(M,'sound/weapons/sear.ogg', 50, 1, -4)
|
||||
M.take_damage(damage, BURN, 0, 0, null, 50)
|
||||
to_chat(occupant, "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>")
|
||||
playsound(M,'sound/weapons/sear.ogg', 50, TRUE, -4)
|
||||
M.take_damage(damage, BURN, 0, 0)
|
||||
|
||||
|
||||
/obj/effect/hierophant
|
||||
name = "hierophant beacon"
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
L.Stun(75)
|
||||
L.adjustBruteLoss(rand(15,20)) // Less stun more harm
|
||||
latched = TRUE
|
||||
for(var/obj/mecha/M in loc)
|
||||
for(var/obj/vehicle/sealed/mecha/M in loc)
|
||||
M.take_damage(20, BRUTE, null, null, null, 25)
|
||||
if(!latched)
|
||||
retract()
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
else
|
||||
enemies -= L
|
||||
else if(ismecha(A))
|
||||
var/obj/mecha/M = A
|
||||
if(M.occupant)
|
||||
var/obj/vehicle/sealed/mecha/M = A
|
||||
if(LAZYLEN(M.occupants))
|
||||
return A
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/ListTargets()
|
||||
@@ -31,10 +31,10 @@
|
||||
if(faction_check_mob(M) && attack_same || !faction_check_mob(M))
|
||||
enemies |= M
|
||||
else if(ismecha(A))
|
||||
var/obj/mecha/M = A
|
||||
if(M.occupant)
|
||||
var/obj/vehicle/sealed/mecha/M = A
|
||||
if(LAZYLEN(M.occupants))
|
||||
enemies |= M
|
||||
enemies |= M.occupant
|
||||
enemies |= M.occupants
|
||||
|
||||
for(var/mob/living/simple_animal/hostile/retaliate/H in around)
|
||||
if(faction_check_mob(H) && !attack_same && !H.attack_same)
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
if(!chosen_color)
|
||||
dragon_name()
|
||||
color_selection()
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/space_dragon/Life()
|
||||
. = ..()
|
||||
@@ -158,8 +158,8 @@
|
||||
adjustHealth(-L.maxHealth * 0.5)
|
||||
return
|
||||
. = ..()
|
||||
if(istype(target, /obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
if(istype(target, /obj/vehicle/sealed/mecha))
|
||||
var/obj/vehicle/sealed/mecha/M = target
|
||||
M.take_damage(50, BRUTE, MELEE, 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/space_dragon/AltClickOn(atom/A)
|
||||
@@ -322,7 +322,7 @@
|
||||
L.adjustFireLoss(30)
|
||||
to_chat(L, "<span class='userdanger'>You're hit by [src]'s fire breath!</span>")
|
||||
// deals damage to mechs
|
||||
for(var/obj/mecha/M in T.contents)
|
||||
for(var/obj/vehicle/sealed/mecha/M in T.contents)
|
||||
if(M in hit_list)
|
||||
continue
|
||||
hit_list += M
|
||||
|
||||
@@ -394,8 +394,8 @@
|
||||
if(L.stat != CONSCIOUS)
|
||||
return FALSE
|
||||
if (ismecha(the_target))
|
||||
var/obj/mecha/M = the_target
|
||||
if (M.occupant)
|
||||
var/obj/vehicle/sealed/mecha/M = the_target
|
||||
if(LAZYLEN(M.occupants))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -879,7 +879,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
return
|
||||
client.mouse_pointer_icon = initial(client.mouse_pointer_icon)
|
||||
if (ismecha(loc))
|
||||
var/obj/mecha/M = loc
|
||||
var/obj/vehicle/sealed/mecha/M = loc
|
||||
if(M.mouse_pointer)
|
||||
client.mouse_pointer_icon = M.mouse_pointer
|
||||
|
||||
|
||||
@@ -241,16 +241,18 @@
|
||||
|
||||
return drain_total
|
||||
|
||||
//MECH//
|
||||
/obj/mecha/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
|
||||
/obj/vehicle/sealed/mecha/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
|
||||
return INVALID_DRAIN
|
||||
|
||||
var/maxcapacity = FALSE //Safety check
|
||||
var/drain = 0 //Drain amount
|
||||
var/drain_total = 0
|
||||
|
||||
occupant_message("<span class='danger'>Warning: Unauthorized access through sub-route 4, block H, detected.</span>")
|
||||
for(var/mob/living/MB in occupants)
|
||||
to_chat(MB, "[icon2html(src, occupants)]<span class='danger'>Warning: Unauthorized access through sub-route 4, block H, detected.</span>")
|
||||
if(get_charge())
|
||||
while(ninja_gloves.candrain && cell.charge > 0 && !maxcapacity)
|
||||
drain = rand(ninja_gloves.mindrain, ninja_gloves.maxdrain)
|
||||
|
||||
@@ -28,3 +28,7 @@
|
||||
/obj/item/projectile/energy/tesla/cannon
|
||||
name = "tesla orb"
|
||||
power = 20000
|
||||
|
||||
/obj/item/projectile/energy/tesla/sphere
|
||||
name = "tesla sphere"
|
||||
power = 100000
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
explosion(target, -1, 1, 3, 1, 0, flame_range = 4)
|
||||
|
||||
if(ismecha(target))
|
||||
var/obj/mecha/M = target
|
||||
var/obj/vehicle/sealed/mecha/M = target
|
||||
M.take_damage(anti_armour_damage)
|
||||
if(issilicon(target))
|
||||
var/mob/living/silicon/S = target
|
||||
@@ -53,7 +53,7 @@
|
||||
ricochets_max = 0 //it's a MISSILE
|
||||
var/sturdy = list(
|
||||
/turf/closed,
|
||||
/obj/mecha,
|
||||
/obj/vehicle/sealed/mecha,
|
||||
/obj/machinery/door/,
|
||||
/obj/machinery/door/poddoor/shutters
|
||||
)
|
||||
|
||||
@@ -524,7 +524,7 @@
|
||||
/obj/effect/CanEnterDisposals()
|
||||
return
|
||||
|
||||
/obj/mecha/CanEnterDisposals()
|
||||
/obj/vehicle/sealed/mecha/CanEnterDisposals()
|
||||
return
|
||||
|
||||
/obj/machinery/disposal/deliveryChute/newHolderDestination(obj/structure/disposalholder/H)
|
||||
|
||||
@@ -585,15 +585,6 @@
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
|
||||
/datum/design/mech_cable_layer
|
||||
name = "Exosuit Engineering Equipment (Cable Layer)"
|
||||
id = "mech_cable_layer"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/cable_layer
|
||||
materials = list(/datum/material/iron=10000)
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
|
||||
/datum/design/mech_generator
|
||||
name = "Exosuit Equipment (Plasma Generator)"
|
||||
id = "mech_generator"
|
||||
|
||||
@@ -261,7 +261,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
|
||||
matched_bounty = TRUE
|
||||
// ignore mech checks because the mech is ONLY for bounty
|
||||
continue
|
||||
if(!AM.anchored || istype(AM, /obj/mecha))
|
||||
if(!AM.anchored || istype(AM, /obj/vehicle/sealed/mecha))
|
||||
export_item_and_contents(AM, export_categories , dry_run = FALSE, external_report = ex)
|
||||
|
||||
if(ex.exported_atoms)
|
||||
|
||||
@@ -51,6 +51,6 @@
|
||||
|
||||
/obj/effect/spawner/lootdrop/whiteship_cere_ripley
|
||||
name = "25% mech 75% wreckage ripley spawner"
|
||||
loot = list(/obj/mecha/working/ripley/mining = 1,
|
||||
loot = list(/obj/vehicle/sealed/mecha/working/ripley/mining = 1,
|
||||
/obj/structure/mecha_wreckage/ripley = 5)
|
||||
lootdoubles = FALSE
|
||||
|
||||
@@ -58,13 +58,13 @@
|
||||
name = "Dark Gygax Exosuit"
|
||||
desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \
|
||||
for hit-and-run style attacks. Features an incendiary carbine, flash bang launcher, teleporter, ion thrusters and a Tesla energy array."
|
||||
item = /obj/mecha/combat/gygax/dark/loaded
|
||||
item = /obj/vehicle/sealed/mecha/combat/gygax/dark/loaded
|
||||
cost = 80
|
||||
|
||||
/datum/uplink_item/support/honker
|
||||
name = "Dark H.O.N.K."
|
||||
desc = "A clown combat mech equipped with bombanana peel and tearstache grenade launchers, as well as the ubiquitous HoNkER BlAsT 5000."
|
||||
item = /obj/mecha/combat/honker/dark/loaded
|
||||
item = /obj/vehicle/sealed/mecha/combat/honker/dark/loaded
|
||||
cost = 80
|
||||
purchasable_from = UPLINK_CLOWN_OPS
|
||||
|
||||
@@ -72,5 +72,5 @@
|
||||
name = "Mauler Exosuit"
|
||||
desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring \
|
||||
and deployable smoke. Comes equipped with an LMG, scattershot carbine, missile rack, an antiprojectile armor booster and a Tesla energy array."
|
||||
item = /obj/mecha/combat/marauder/mauler/loaded
|
||||
item = /obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded
|
||||
cost = 140
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60)
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
COOLDOWN_DECLARE(cooldown_vehicle_move)
|
||||
var/list/mob/occupants //mob = bitflags of their control level.
|
||||
var/max_occupants = 1
|
||||
var/max_drivers = 1
|
||||
@@ -23,6 +24,7 @@
|
||||
var/list/autogrant_actions_controller //assoc list "[bitflag]" = list(typepaths)
|
||||
var/list/mob/occupant_actions //assoc list mob = list(type = action datum assigned to mob)
|
||||
var/obj/vehicle/trailer
|
||||
var/mouse_pointer //do we have a special mouse
|
||||
|
||||
/obj/vehicle/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -121,9 +123,9 @@
|
||||
vehicle_move(direction)
|
||||
|
||||
/obj/vehicle/proc/vehicle_move(direction)
|
||||
if(lastmove + movedelay > world.time)
|
||||
if(!COOLDOWN_FINISHED(src, cooldown_vehicle_move))
|
||||
return FALSE
|
||||
lastmove = world.time
|
||||
COOLDOWN_START(src, cooldown_vehicle_move, movedelay)
|
||||
if(trailer)
|
||||
var/dir_to_move = get_dir(trailer.loc, loc)
|
||||
var/did_move = step(src, direction)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
/obj/vehicle/sealed/mecha/combat
|
||||
force = 30
|
||||
internals_req_access = list(ACCESS_ROBOTICS, ACCESS_SECURITY)
|
||||
internal_damage_threshold = 50
|
||||
armor = list(MELEE = 30, BULLET = 30, LASER = 15, ENERGY = 20, BOMB = 20, BIO = 0, RAD = 0, FIRE = 100, ACID = 100)
|
||||
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
|
||||
destruction_sleep_duration = 40
|
||||
exit_delay = 40
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/restore_equipment()
|
||||
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
|
||||
. = ..()
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/moved_inside(mob/living/carbon/human/H)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this
|
||||
for(var/obj/item/I in equipment)
|
||||
if(istype(I, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/))
|
||||
var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun = I
|
||||
gun.projectiles_cache = gun.projectiles_cache_max
|
||||
@@ -0,0 +1,241 @@
|
||||
/obj/vehicle/sealed/mecha/combat/durand
|
||||
desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms."
|
||||
name = "\improper Durand"
|
||||
icon_state = "durand"
|
||||
movedelay = 4
|
||||
dir_in = 1 //Facing North.
|
||||
max_integrity = 400
|
||||
deflect_chance = 20
|
||||
armor = list(MELEE = 40, BULLET = 35, LASER = 15, ENERGY = 10, BOMB = 20, BIO = 0, RAD = 50, FIRE = 100, ACID = 100)
|
||||
max_temperature = 30000
|
||||
force = 40
|
||||
wreckage = /obj/structure/mecha_wreckage/durand
|
||||
var/obj/durand_shield/shield
|
||||
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/Initialize()
|
||||
. = ..()
|
||||
shield = new /obj/durand_shield(loc, src, layer, dir)
|
||||
RegisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER, .proc/relay)
|
||||
RegisterSignal(src, COMSIG_PROJECTILE_PREHIT, .proc/prehit)
|
||||
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/Destroy()
|
||||
if(shield)
|
||||
QDEL_NULL(shield)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/generate_actions()
|
||||
. = ..()
|
||||
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_defense_mode)
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/process()
|
||||
. = ..()
|
||||
if(defense_mode && !use_power(100)) //Defence mode can only be on with a occupant so we check if one of them can toggle it and toggle
|
||||
for(var/O in occupants)
|
||||
var/mob/living/occupant = O
|
||||
var/datum/action/action = LAZYACCESSASSOC(occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/mech_defense_mode)
|
||||
if(action)
|
||||
INVOKE_ASYNC(action, /datum/action.proc/Trigger)
|
||||
break
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/Move(direction)
|
||||
. = ..()
|
||||
if(shield)
|
||||
shield.forceMove(loc)
|
||||
shield.setDir(dir)
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/forceMove(turf/T)
|
||||
. = ..()
|
||||
shield.forceMove(T)
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/mob_exit(mob/M, silent, randomstep, forced)
|
||||
if(defense_mode)
|
||||
var/datum/action/action = LAZYACCESSASSOC(occupant_actions, M, /datum/action/vehicle/sealed/mecha/mech_defense_mode)
|
||||
if(action)
|
||||
INVOKE_ASYNC(action, /datum/action.proc/Trigger, FALSE)
|
||||
return ..()
|
||||
|
||||
///Relays the signal from the action button to the shield, and creates a new shield if the old one is MIA.
|
||||
/obj/vehicle/sealed/mecha/combat/durand/proc/relay(datum/source, mob/owner, list/signal_args)
|
||||
SIGNAL_HANDLER
|
||||
if(!shield) //if the shield somehow got deleted
|
||||
stack_trace("Durand triggered relay without a shield")
|
||||
shield = new /obj/durand_shield(loc, src, layer)
|
||||
shield.setDir(dir)
|
||||
SEND_SIGNAL(shield, COMSIG_MECHA_ACTION_TRIGGER, owner, signal_args)
|
||||
|
||||
//Redirects projectiles to the shield if defense_check decides they should be blocked and returns true.
|
||||
/obj/vehicle/sealed/mecha/combat/durand/proc/prehit(obj/item/projectile/source, list/signal_args)
|
||||
if(defense_check(source.loc) && shield)
|
||||
signal_args[2] = shield
|
||||
|
||||
|
||||
/**Checks if defense mode is enabled, and if the attacker is standing in an area covered by the shield.
|
||||
Expects a turf. Returns true if the attack should be blocked, false if not.*/
|
||||
/obj/vehicle/sealed/mecha/combat/durand/proc/defense_check(turf/aloc)
|
||||
if (!defense_mode || !shield || shield.switching)
|
||||
return FALSE
|
||||
. = FALSE
|
||||
switch(dir)
|
||||
if (1)
|
||||
if(abs(x - aloc.x) <= (y - aloc.y) * -2)
|
||||
. = TRUE
|
||||
if (2)
|
||||
if(abs(x - aloc.x) <= (y - aloc.y) * 2)
|
||||
. = TRUE
|
||||
if (4)
|
||||
if(abs(y - aloc.y) <= (x - aloc.x) * -2)
|
||||
. = TRUE
|
||||
if (8)
|
||||
if(abs(y - aloc.y) <= (x - aloc.x) * 2)
|
||||
. = TRUE
|
||||
return
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0)
|
||||
if(defense_check(user.loc))
|
||||
log_message("Attack absorbed by defense field. Attacker - [user].", LOG_MECHA, color="orange")
|
||||
shield.attack_generic(user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/blob_act(obj/structure/blob/B)
|
||||
if(defense_check(B.loc))
|
||||
log_message("Attack by blob. Attacker - [B].", LOG_MECHA, color="red")
|
||||
log_message("Attack absorbed by defense field.", LOG_MECHA, color="orange")
|
||||
shield.blob_act(B)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
if(defense_check(user.loc))
|
||||
log_message("Attack absorbed by defense field. Attacker - [user], with [W]", LOG_MECHA, color="orange")
|
||||
shield.attackby(W, user, params)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/durand/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
||||
if(defense_check(AM.loc))
|
||||
log_message("Impact with [AM] absorbed by defense field.", LOG_MECHA, color="orange")
|
||||
shield.hitby(AM, skipcatch, hitpush, blocked, throwingdatum)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
////////////////////////////
|
||||
///// Shield processing ////
|
||||
////////////////////////////
|
||||
|
||||
/**An object to take the hit for us when using the Durand's defense mode.
|
||||
It is spawned in during the durand's initilization, and always stays on the same tile.
|
||||
Normally invisible, until defense mode is actvated. When the durand detects an attack that should be blocked, the
|
||||
attack is passed to the shield. The shield takes the damage, uses it to calculate charge cost, and then sets its
|
||||
own integrity back to max. Shield is automatically dropped if we run out of power or the user gets out.*/
|
||||
|
||||
/obj/durand_shield //projectiles get passed to this when defense mode is enabled
|
||||
name = "defense grid"
|
||||
icon = 'icons/mecha/durand_shield.dmi'
|
||||
icon_state = "shield_null"
|
||||
invisibility = INVISIBILITY_MAXIMUM //no showing on right-click
|
||||
pixel_y = 4
|
||||
max_integrity = 10000
|
||||
obj_integrity = 10000
|
||||
anchored = TRUE
|
||||
light_range = MINIMUM_USEFUL_LIGHT_RANGE
|
||||
light_power = 5
|
||||
light_color = COLOR_CYAN
|
||||
///Our link back to the durand
|
||||
var/obj/vehicle/sealed/mecha/combat/durand/chassis
|
||||
///To keep track of things during the animation
|
||||
var/switching = FALSE
|
||||
var/currentuser
|
||||
|
||||
|
||||
/obj/durand_shield/Initialize(mapload, _chassis, _layer, _dir)
|
||||
. = ..()
|
||||
chassis = _chassis
|
||||
layer = _layer
|
||||
setDir(_dir)
|
||||
RegisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER, .proc/activate)
|
||||
|
||||
|
||||
/obj/durand_shield/Destroy()
|
||||
if(chassis)
|
||||
chassis.shield = null
|
||||
chassis = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
*Handles activating and deactivating the shield. This proc is called by a signal sent from the mech's action button
|
||||
*and relayed by the mech itself. The "forced" variabe, signal_args[1], will skip the to-pilot text and is meant for when
|
||||
*the shield is disabled by means other than the action button (like running out of power)
|
||||
* Arguments:
|
||||
* * source: the shield
|
||||
* * owner: mob that activated the shield
|
||||
* * signal_args: whether it's forced
|
||||
*/
|
||||
/obj/durand_shield/proc/activate(datum/source, mob/owner, list/signal_args)
|
||||
SIGNAL_HANDLER
|
||||
currentuser = owner
|
||||
if(!chassis?.occupants)
|
||||
return
|
||||
if(switching && !signal_args[1])
|
||||
return
|
||||
if(!chassis.defense_mode && (!chassis.cell || chassis.cell.charge < 100)) //If it's off, and we have less than 100 units of power
|
||||
to_chat(currentuser, "[icon2html(src, currentuser)]<span class='warn'>Insufficient power; cannot activate defense mode.</span>")
|
||||
return
|
||||
switching = TRUE
|
||||
chassis.defense_mode = !chassis.defense_mode
|
||||
if(!signal_args[1])
|
||||
to_chat(currentuser, "[icon2html(src, currentuser)]<span class='notice'>Defense mode [chassis.defense_mode?"enabled":"disabled"].</span>")
|
||||
chassis.log_message("User has toggled defense mode -- now [chassis.defense_mode?"enabled":"disabled"].", LOG_MECHA)
|
||||
else
|
||||
chassis.log_message("defense mode state changed -- now [chassis.defense_mode?"enabled":"disabled"].", LOG_MECHA)
|
||||
for(var/occupant in chassis.occupants)
|
||||
var/datum/action/button = chassis.occupant_actions[occupant][/datum/action/vehicle/sealed/mecha/mech_defense_mode]
|
||||
button.button_icon_state = "mech_defense_mode_[chassis.defense_mode ? "on" : "off"]"
|
||||
button.UpdateButtonIcon()
|
||||
|
||||
set_light(light_range, light_power, light_color)
|
||||
|
||||
if(chassis.defense_mode)
|
||||
invisibility = 0
|
||||
flick("shield_raise", src)
|
||||
playsound(src, 'sound/mecha/mech_shield_raise.ogg', 50, FALSE)
|
||||
set_light(l_range = MINIMUM_USEFUL_LIGHT_RANGE , l_power = 5, l_color = "#00FFFF")
|
||||
icon_state = "shield"
|
||||
RegisterSignal(chassis, COMSIG_ATOM_DIR_CHANGE, .proc/resetdir)
|
||||
else
|
||||
flick("shield_drop", src)
|
||||
playsound(src, 'sound/mecha/mech_shield_drop.ogg', 50, FALSE)
|
||||
set_light(0)
|
||||
icon_state = "shield_null"
|
||||
invisibility = INVISIBILITY_MAXIMUM //no showing on right-click
|
||||
UnregisterSignal(chassis, COMSIG_ATOM_DIR_CHANGE)
|
||||
switching = FALSE
|
||||
|
||||
/obj/durand_shield/proc/resetdir(datum/source, olddir, newdir)
|
||||
setDir(newdir)
|
||||
|
||||
/obj/durand_shield/take_damage()
|
||||
if(!chassis)
|
||||
qdel(src)
|
||||
return
|
||||
if(!chassis.defense_mode) //if defense mode is disabled, we're taking damage that we shouldn't be taking
|
||||
return
|
||||
. = ..()
|
||||
flick("shield_impact", src)
|
||||
if(!chassis.use_power((max_integrity - obj_integrity) * 100))
|
||||
chassis.cell?.charge = 0
|
||||
for(var/O in chassis.occupants)
|
||||
var/mob/living/occupant = O
|
||||
var/datum/action/action = LAZYACCESSASSOC(chassis.occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/mech_defense_mode)
|
||||
action.Trigger(FALSE)
|
||||
obj_integrity = 10000
|
||||
|
||||
/obj/durand_shield/play_attack_sound()
|
||||
playsound(src, 'sound/mecha/mech_shield_deflect.ogg', 100, TRUE)
|
||||
|
||||
/obj/durand_shield/bullet_act()
|
||||
play_attack_sound()
|
||||
. = ..()
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/obj/mecha/combat/five_stars
|
||||
/obj/vehicle/sealed/mecha/combat/five_stars
|
||||
desc = "A state of the art tank deployed by the Spinward Stellar Coalition National Guard."
|
||||
name = "\improper Tank"
|
||||
icon = 'icons/mecha/mecha_96x96.dmi'
|
||||
@@ -10,7 +10,7 @@
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
/obj/mecha/combat/five_stars/Initialize()
|
||||
/obj/vehicle/sealed/mecha/combat/five_stars/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/spacecops(src)
|
||||
ME.attach(src)
|
||||
@@ -0,0 +1,59 @@
|
||||
/obj/vehicle/sealed/mecha/combat/gygax
|
||||
desc = "A lightweight, security exosuit. Popular among private and corporate security."
|
||||
name = "\improper Gygax"
|
||||
icon_state = "gygax"
|
||||
allow_diagonal_movement = TRUE
|
||||
movedelay = 3
|
||||
dir_in = 1 //Facing North.
|
||||
max_integrity = 250
|
||||
deflect_chance = 5
|
||||
armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100)
|
||||
max_temperature = 25000
|
||||
leg_overload_coeff = 80
|
||||
force = 25
|
||||
wreckage = /obj/structure/mecha_wreckage/gygax
|
||||
internal_damage_threshold = 35
|
||||
max_equip = 3
|
||||
step_energy_drain = 3
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/gygax/dark
|
||||
desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications."
|
||||
name = "\improper Dark Gygax"
|
||||
icon_state = "darkgygax"
|
||||
max_integrity = 300
|
||||
deflect_chance = 20
|
||||
armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 35, BOMB = 20, BIO = 0, RAD =20, FIRE = 100, ACID = 100)
|
||||
max_temperature = 35000
|
||||
leg_overload_coeff = 70
|
||||
force = 30
|
||||
operation_req_access = list(ACCESS_SYNDICATE)
|
||||
internals_req_access = list(ACCESS_SYNDICATE)
|
||||
wreckage = /obj/structure/mecha_wreckage/gygax/dark
|
||||
max_equip = 5
|
||||
destruction_sleep_duration = 20
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/gygax/dark/loaded/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
|
||||
ME.attach(src)
|
||||
max_ammo()
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null)
|
||||
if(C)
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
return
|
||||
cell = new /obj/item/stock_parts/cell/bluespace(src)
|
||||
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/gygax/generate_actions()
|
||||
. = ..()
|
||||
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_overload_mode)
|
||||
@@ -1,22 +1,21 @@
|
||||
/obj/mecha/combat/honker
|
||||
/obj/vehicle/sealed/mecha/combat/honker
|
||||
desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. Used to spread the fun and joy of life. HONK!"
|
||||
name = "\improper H.O.N.K"
|
||||
icon_state = "honker"
|
||||
step_in = 3
|
||||
movedelay = 3
|
||||
max_integrity = 140
|
||||
deflect_chance = 60
|
||||
internal_damage_threshold = 60
|
||||
armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100)
|
||||
max_temperature = 25000
|
||||
infra_luminosity = 5
|
||||
operation_req_access = list(ACCESS_THEATRE)
|
||||
internals_req_access = list(ACCESS_THEATRE, ACCESS_ROBOTICS)
|
||||
internals_req_access = list(ACCESS_ROBOTICS, ACCESS_THEATRE)
|
||||
wreckage = /obj/structure/mecha_wreckage/honker
|
||||
add_req_access = 0
|
||||
mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS
|
||||
max_equip = 3
|
||||
var/squeak = 0
|
||||
var/squeak = TRUE
|
||||
|
||||
/obj/mecha/combat/honker/get_stats_part()
|
||||
/obj/vehicle/sealed/mecha/combat/honker/get_stats_part(mob/user)
|
||||
var/integrity = obj_integrity/max_integrity*100
|
||||
var/cell_charge = get_charge()
|
||||
var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
|
||||
@@ -29,18 +28,18 @@
|
||||
[internal_damage&MECHA_INT_TANK_BREACH?"<font color='red'><b>GAS TANK HONK</b></font><br>":null]
|
||||
[internal_damage&MECHA_INT_CONTROL_LOST?"<font color='red'><b>HONK-A-DOODLE</b></font> - <a href='?src=[REF(src)];repair_int_control_lost=1'>Recalibrate</a><br>":null]
|
||||
<b>IntegriHONK: </b> [integrity]%<br>
|
||||
<b>PowerHONK charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br>
|
||||
<b>PowerHONK charge: </b>[isnull(cell_charge)?"No power cell installed":"[cell.percent()]%"]<br>
|
||||
<b>Air source: </b>[use_internal_tank?"Internal Airtank":"Environment"]<br>
|
||||
<b>AirHONK pressure: </b>[tank_pressure]kPa<br>
|
||||
<b>AirHONK temperature: </b>[tank_temperature]°K|[tank_temperature - T0C]°C<br>
|
||||
<b>HONK pressure: </b>[cabin_pressure>WARNING_HIGH_PRESSURE ? "<font color='red'>[cabin_pressure]</font>": cabin_pressure]kPa<br>
|
||||
<b>HONK temperature: </b> [return_temperature()]°K|[return_temperature() - T0C]°C<br>
|
||||
<b>Lights: </b>[lights?"on":"off"]<br>
|
||||
<b>Lights: </b>[(mecha_flags & LIGHTS_ON)?"on":"off"]<br>
|
||||
[dna_lock?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[dna_lock]</span> \[<a href='?src=[REF(src)];reset_dna=1'>Reset</a>\]<br>":null]
|
||||
"}
|
||||
return output
|
||||
|
||||
/obj/mecha/combat/honker/get_stats_html()
|
||||
/obj/vehicle/sealed/mecha/combat/honker/get_stats_html(mob/user)
|
||||
var/output = {"<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
@@ -60,19 +59,19 @@
|
||||
[js_byjax]
|
||||
[js_dropdowns]
|
||||
function SSticker() {
|
||||
setInterval(function(){
|
||||
window.location='byond://?src=[REF(src)]&update_content=1';
|
||||
document.body.style.color = get_rand_color_string();
|
||||
document.body.style.background = get_rand_color_string();
|
||||
}, 1000);
|
||||
setInterval(function(){
|
||||
window.location='byond://?src=[REF(src)]&update_content=1';
|
||||
document.body.style.color = get_rand_color_string();
|
||||
document.body.style.background = get_rand_color_string();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function get_rand_color_string() {
|
||||
var color = new Array;
|
||||
for(var i=0;i<3;i++){
|
||||
color.push(Math.floor(Math.random()*255));
|
||||
}
|
||||
return "rgb("+color.toString()+")";
|
||||
var color = new Array;
|
||||
for(var i=0;i<3;i++){
|
||||
color.push(Math.floor(Math.random()*255));
|
||||
}
|
||||
return "rgb("+color.toString()+")";
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
@@ -83,7 +82,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id='content'>
|
||||
[src.get_stats_part()]
|
||||
[src.get_stats_part(user)]
|
||||
</div>
|
||||
<div id='eq_list'>
|
||||
[src.get_equipment_list()]
|
||||
@@ -97,7 +96,7 @@
|
||||
"}
|
||||
return output
|
||||
|
||||
/obj/mecha/combat/honker/get_commands()
|
||||
/obj/vehicle/sealed/mecha/combat/honker/get_commands()
|
||||
var/output = {"<div class='wr'>
|
||||
<div class='header'>Sounds of HONK:</div>
|
||||
<div class='links'>
|
||||
@@ -106,6 +105,14 @@
|
||||
<a href='?src=[REF(src)];play_sound=airhorn2'>Air Horn</a>
|
||||
<a href='?src=[REF(src)];play_sound=carhorn'>Car Horn</a>
|
||||
<a href='?src=[REF(src)];play_sound=party_horn'>Party Horn</a>
|
||||
<a href='?src=[REF(src)];play_sound=reee'>Reee</a>
|
||||
<a href='?src=[REF(src)];play_sound=weeoo1'>Siren</a>
|
||||
<a href='?src=[REF(src)];play_sound=hiss1'>Hissing Creature</a>
|
||||
<a href='?src=[REF(src)];play_sound=armbomb'>Armed Grenade</a>
|
||||
<a href='?src=[REF(src)];play_sound=saberon'>Energy Sword</a>
|
||||
<a href='?src=[REF(src)];play_sound=airlock_alien_prying'>Airlock Prying</a>
|
||||
<a href='?src=[REF(src)];play_sound=lightningbolt'>Lightning Bolt</a>
|
||||
<a href='?src=[REF(src)];play_sound=explosionfar'>Distant Explosion</a>
|
||||
</div>
|
||||
</div>
|
||||
"}
|
||||
@@ -113,8 +120,8 @@
|
||||
return output
|
||||
|
||||
|
||||
/obj/mecha/combat/honker/get_equipment_list()
|
||||
if(!equipment.len)
|
||||
/obj/vehicle/sealed/mecha/combat/honker/get_equipment_list()
|
||||
if(!LAZYLEN(equipment))
|
||||
return
|
||||
var/output = "<b>Honk-ON-Systems:</b><div style=\"margin-left: 15px;\">"
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment)
|
||||
@@ -122,19 +129,12 @@
|
||||
output += "</div>"
|
||||
return output
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/honker/play_stepsound()
|
||||
if(squeak)
|
||||
playsound(src, "clownstep", 70, 1)
|
||||
squeak = !squeak
|
||||
|
||||
|
||||
/obj/mecha/combat/honker/mechstep(direction)
|
||||
var/result = step(src,direction)
|
||||
if(result)
|
||||
if(!squeak)
|
||||
playsound(src, "clownstep", 70, 1)
|
||||
squeak = 1
|
||||
else
|
||||
squeak = 0
|
||||
return result
|
||||
|
||||
/obj/mecha/combat/honker/Topic(href, href_list)
|
||||
/obj/vehicle/sealed/mecha/combat/honker/Topic(href, href_list)
|
||||
..()
|
||||
if (href_list["play_sound"])
|
||||
switch(href_list["play_sound"])
|
||||
@@ -148,11 +148,20 @@
|
||||
playsound(src, 'sound/items/carhorn.ogg', 80) //soundfile has lower than average volume
|
||||
if("party_horn")
|
||||
playsound(src, 'sound/items/party_horn.ogg', 50)
|
||||
if("reee")
|
||||
playsound(src, 'sound/effects/reee.ogg', 50)
|
||||
if("weeoo1")
|
||||
playsound(src, 'sound/items/weeoo1.ogg', 50)
|
||||
if("hiss1")
|
||||
playsound(src, 'sound/voice/hiss1.ogg', 50)
|
||||
if("armbomb")
|
||||
playsound(src, 'sound/weapons/armbomb.ogg', 50)
|
||||
if("saberon")
|
||||
playsound(src, 'sound/weapons/saberon.ogg', 50)
|
||||
if("airlock_alien_prying")
|
||||
playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50)
|
||||
if("lightningbolt")
|
||||
playsound(src, 'sound/magic/lightningbolt.ogg', 50)
|
||||
if("explosionfar")
|
||||
playsound(src, 'sound/effects/explosionfar.ogg', 50)
|
||||
return
|
||||
|
||||
/proc/rand_hex_color()
|
||||
var/list/colors = list("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f")
|
||||
var/color=""
|
||||
for (var/i=0;i<6;i++)
|
||||
color = color+pick(colors)
|
||||
return color
|
||||
+33
-32
@@ -1,38 +1,32 @@
|
||||
/obj/mecha/combat/marauder
|
||||
/obj/vehicle/sealed/mecha/combat/marauder
|
||||
desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations."
|
||||
name = "\improper Marauder"
|
||||
icon_state = "marauder"
|
||||
step_in = 5
|
||||
movedelay = 5
|
||||
max_integrity = 500
|
||||
deflect_chance = 25
|
||||
armor = list("melee" = 50, "bullet" = 55, "laser" = 40, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
armor = list(MELEE = 50, BULLET = 55, LASER = 40, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 60, FIRE = 100, ACID = 100)
|
||||
max_temperature = 60000
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
infra_luminosity = 3
|
||||
operation_req_access = list(ACCESS_CENT_SPECOPS)
|
||||
internals_req_access = list(ACCESS_CENT_SPECOPS, ACCESS_ROBOTICS)
|
||||
internals_req_access = list(ACCESS_CENT_SPECOPS)
|
||||
wreckage = /obj/structure/mecha_wreckage/marauder
|
||||
add_req_access = 0
|
||||
mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS
|
||||
internal_damage_threshold = 25
|
||||
force = 45
|
||||
max_equip = 4
|
||||
bumpsmash = 1
|
||||
max_equip = 5
|
||||
bumpsmash = TRUE
|
||||
|
||||
/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
smoke_action.Grant(user, src)
|
||||
thrusters_action.Grant(user, src)
|
||||
zoom_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
smoke_action.Remove(user)
|
||||
thrusters_action.Remove(user)
|
||||
zoom_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/marauder/loaded/Initialize()
|
||||
/obj/vehicle/sealed/mecha/combat/marauder/generate_actions()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src)
|
||||
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_smoke)
|
||||
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_zoom)
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/marauder/loaded/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src)
|
||||
ME.attach(src)
|
||||
@@ -42,23 +36,24 @@
|
||||
ME.attach(src)
|
||||
max_ammo()
|
||||
|
||||
/obj/mecha/combat/marauder/seraph
|
||||
/obj/vehicle/sealed/mecha/combat/marauder/seraph
|
||||
desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
|
||||
name = "\improper Seraph"
|
||||
icon_state = "seraph"
|
||||
operation_req_access = list(ACCESS_CENT_SPECOPS)
|
||||
internals_req_access = list(ACCESS_CENT_SPECOPS, ACCESS_ROBOTICS)
|
||||
step_in = 3
|
||||
internals_req_access = list(ACCESS_CENT_SPECOPS)
|
||||
movedelay = 3
|
||||
max_integrity = 550
|
||||
wreckage = /obj/structure/mecha_wreckage/seraph
|
||||
internal_damage_threshold = 20
|
||||
force = 55
|
||||
max_equip = 5
|
||||
max_equip = 6
|
||||
|
||||
/obj/mecha/combat/marauder/seraph/Initialize()
|
||||
/obj/vehicle/sealed/mecha/combat/marauder/seraph/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src)
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src)
|
||||
ME.attach(src)
|
||||
@@ -70,16 +65,22 @@
|
||||
ME.attach(src)
|
||||
max_ammo()
|
||||
|
||||
/obj/mecha/combat/marauder/mauler
|
||||
/obj/vehicle/sealed/mecha/combat/marauder/mauler
|
||||
desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model."
|
||||
name = "\improper Mauler"
|
||||
icon_state = "mauler"
|
||||
operation_req_access = list(ACCESS_SYNDICATE)
|
||||
internals_req_access = list(ACCESS_SYNDICATE)
|
||||
wreckage = /obj/structure/mecha_wreckage/mauler
|
||||
max_equip = 5
|
||||
max_equip = 6
|
||||
destruction_sleep_duration = 20
|
||||
|
||||
/obj/mecha/combat/marauder/mauler/loaded/Initialize()
|
||||
/obj/vehicle/sealed/mecha/combat/marauder/mauler/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src)
|
||||
ME.attach(src)
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src)
|
||||
ME.attach(src)
|
||||
+16
-14
@@ -1,34 +1,36 @@
|
||||
/obj/mecha/medical/medigax
|
||||
/obj/vehicle/sealed/mecha/medical/medigax
|
||||
desc = "A Gygax with it's actuator overload stripped and a slick white paint scheme, for medical use, These exosuits are developed and produced by Vey-Med. (© All rights reserved)."
|
||||
name = "\improper Medical Gygax"
|
||||
icon_state = "medigax"
|
||||
step_in = 1.75 // a little faster than an odysseus
|
||||
max_temperature = 25000
|
||||
allow_diagonal_movement = TRUE
|
||||
movedelay = 2
|
||||
dir_in = 1 //Facing North.
|
||||
max_integrity = 250
|
||||
wreckage = /obj/structure/mecha_wreckage/odysseus
|
||||
armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
internal_damage_threshold = 35
|
||||
deflect_chance = 15
|
||||
armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100)
|
||||
max_temperature = 25000
|
||||
wreckage = /obj/structure/mecha_wreckage/odysseus
|
||||
internal_damage_threshold = 35
|
||||
step_energy_drain = 6
|
||||
infra_luminosity = 6
|
||||
internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL)
|
||||
|
||||
|
||||
/obj/mecha/medical/medigax/moved_inside(mob/living/carbon/human/H)
|
||||
/obj/vehicle/sealed/mecha/medical/medigax/moved_inside(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
hud.add_hud_to(H)
|
||||
|
||||
/obj/mecha/medical/medigax/go_out()
|
||||
if(isliving(occupant))
|
||||
var/mob/living/carbon/human/L = occupant
|
||||
/obj/vehicle/sealed/mecha/medical/medigax/remove_occupant(mob/M)
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
hud.remove_hud_from(L)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/mecha/medical/medigax/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user)
|
||||
/obj/vehicle/sealed/mecha/medical/medigax/mmi_moved_inside(obj/item/mmi/M, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
var/mob/living/brain/B = mmi_as_oc.brainmob
|
||||
var/mob/living/brain/B = M.brainmob
|
||||
hud.add_hud_to(B)
|
||||
@@ -1,52 +1,43 @@
|
||||
/obj/mecha/combat/neovgre
|
||||
/obj/vehicle/sealed/mecha/combat/neovgre
|
||||
name = "Neovgre, the Anima Bulwark"
|
||||
desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night."
|
||||
desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night. Armed with a heavy laser and a tesla sphere generator. Requires a pilot and a gunner."
|
||||
icon = 'icons/mecha/neovgre.dmi'
|
||||
icon_state = "neovgre"
|
||||
max_integrity = 500 //This is THE ratvarian superweaon, its deployment is an investment
|
||||
armor = list("melee" = 50, "bullet" = 40, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) //Its similar to the clockwork armour albeit with a few buffs becuase RATVARIAN SUPERWEAPON!!
|
||||
force = 50 //SMASHY SMASHY!!
|
||||
movedelay = 3
|
||||
internal_damage_threshold = 0
|
||||
step_in = 3
|
||||
pixel_x = -16
|
||||
layer = ABOVE_MOB_LAYER
|
||||
breach_time = 100 //ten seconds till all goes to shit
|
||||
recharge_rate = 100
|
||||
var/breach_time = 100 //ten seconds till all goes to shit
|
||||
var/recharge_rate = 100
|
||||
internals_req_access = list()
|
||||
add_req_access = 0
|
||||
wreckage = /obj/structure/mecha_wreckage/durand/neovgre
|
||||
stepsound = 'sound/mecha/neostep2.ogg'
|
||||
turnsound = 'sound/mecha/powerloader_step.ogg'
|
||||
|
||||
/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
|
||||
internals_action.Grant(user, src)
|
||||
cycle_action.Grant(user, src)
|
||||
lights_action.Grant(user, src)
|
||||
stats_action.Grant(user, src)
|
||||
strafing_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/neovgre/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
internals_action.Remove(user)
|
||||
cycle_action.Remove(user)
|
||||
lights_action.Remove(user)
|
||||
stats_action.Remove(user)
|
||||
strafing_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user)
|
||||
/obj/vehicle/sealed/mecha/neovgre/mob_exit(mob/M, silent, forced)
|
||||
if(forced)
|
||||
..()
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
to_chat(user, "<span class='neovgre'>BEGONE HEATHEN!</span>")
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H)
|
||||
/obj/vehicle/sealed/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H)
|
||||
var/list/Itemlist = H.get_contents()
|
||||
for(var/obj/item/clockwork/slab/W in Itemlist)
|
||||
to_chat(H, "<span class='brass'>You safely store [W] inside [src].</span>")
|
||||
qdel(W)
|
||||
. = ..()
|
||||
|
||||
/obj/mecha/combat/neovgre/obj_destruction()
|
||||
/obj/vehicle/sealed/mecha/combat/neovgre/obj_destruction()
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='brass'>You are consumed by the fires raging within Neovgre...</span>")
|
||||
M.dust()
|
||||
@@ -54,15 +45,15 @@
|
||||
src.visible_message("<span class = 'userdanger'>The reactor has gone critical, its going to blow!</span>")
|
||||
addtimer(CALLBACK(src,.proc/go_critical),breach_time)
|
||||
|
||||
/obj/mecha/combat/neovgre/proc/go_critical()
|
||||
/obj/vehicle/sealed/mecha/combat/neovgre/proc/go_critical()
|
||||
explosion(get_turf(loc), 3, 5, 10, 20, 30)
|
||||
Destroy(src)
|
||||
|
||||
/obj/mecha/combat/neovgre/container_resist(mob/living/user)
|
||||
/obj/vehicle/sealed/mecha/combat/neovgre/container_resist(mob/living/user)
|
||||
to_chat(user, "<span class='brass'>Neovgre requires a lifetime commitment friend, no backing out now!</span>")
|
||||
return
|
||||
|
||||
/obj/mecha/combat/neovgre/process()
|
||||
/obj/vehicle/sealed/mecha/combat/neovgre/process()
|
||||
..()
|
||||
if(!obj_integrity) //Integrity is zero but we would heal out of that state if we went into this before it recognises it being zero
|
||||
return
|
||||
@@ -80,7 +71,7 @@
|
||||
if(obj_integrity < max_integrity && istype(loc, /turf/open/floor/clockwork))
|
||||
obj_integrity += min(max_integrity - obj_integrity, max_integrity / 200)
|
||||
|
||||
/obj/mecha/combat/neovgre/Initialize()
|
||||
/obj/vehicle/sealed/mecha/combat/neovgre/Initialize()
|
||||
.=..()
|
||||
GLOB.neovgre_exists ++
|
||||
var/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/N = new
|
||||
@@ -97,7 +88,7 @@
|
||||
desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere"
|
||||
fire_sound = 'sound/weapons/neovgre_laser.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/mecha/combat/neovgre/M)
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/vehicle/sealed/mecha/combat/neovgre/M)
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
@@ -0,0 +1,21 @@
|
||||
/obj/vehicle/sealed/mecha/combat/phazon
|
||||
desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge bluespace technology and expensive materials."
|
||||
name = "\improper Phazon"
|
||||
icon_state = "phazon"
|
||||
movedelay = 2
|
||||
dir_in = 2 //Facing South.
|
||||
step_energy_drain = 3
|
||||
max_integrity = 200
|
||||
deflect_chance = 30
|
||||
armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 50, FIRE = 100, ACID = 100)
|
||||
max_temperature = 25000
|
||||
wreckage = /obj/structure/mecha_wreckage/phazon
|
||||
internal_damage_threshold = 25
|
||||
force = 15
|
||||
max_equip = 3
|
||||
phase_state = "phazon-phase"
|
||||
|
||||
/obj/vehicle/sealed/mecha/combat/phazon/generate_actions()
|
||||
. = ..()
|
||||
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_phasing)
|
||||
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_switch_damtype)
|
||||
+6
-7
@@ -1,26 +1,25 @@
|
||||
/obj/mecha/combat/reticence
|
||||
/obj/vehicle/sealed/mecha/combat/reticence
|
||||
desc = "A silent, fast, and nigh-invisible miming exosuit. Popular among mimes and mime assassins."
|
||||
name = "\improper reticence"
|
||||
icon_state = "reticence"
|
||||
step_in = 2
|
||||
movedelay = 2
|
||||
dir_in = 1 //Facing North.
|
||||
max_integrity = 100
|
||||
deflect_chance = 3
|
||||
armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100)
|
||||
max_temperature = 15000
|
||||
wreckage = /obj/structure/mecha_wreckage/reticence
|
||||
operation_req_access = list(ACCESS_THEATRE)
|
||||
internals_req_access = list(ACCESS_THEATRE, ACCESS_ROBOTICS)
|
||||
add_req_access = 0
|
||||
internals_req_access = list(ACCESS_ROBOTICS, ACCESS_THEATRE)
|
||||
mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS
|
||||
internal_damage_threshold = 25
|
||||
max_equip = 2
|
||||
step_energy_drain = 3
|
||||
color = "#87878715"
|
||||
stepsound = null
|
||||
turnsound = null
|
||||
opacity = 0
|
||||
|
||||
/obj/mecha/combat/reticence/loaded/Initialize()
|
||||
/obj/vehicle/sealed/mecha/combat/reticence/loaded/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
|
||||
ME.attach(src)
|
||||
@@ -0,0 +1,157 @@
|
||||
//DO NOT ADD MECHA PARTS TO THE GAME WITH THE DEFAULT "SPRITE ME" SPRITE!
|
||||
//I'm annoyed I even have to tell you this! SPRITE FIRST, then commit.
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment
|
||||
name = "mecha equipment"
|
||||
icon = 'icons/mecha/mecha_equipment.dmi'
|
||||
icon_state = "mecha_equip"
|
||||
force = 5
|
||||
max_integrity = 300
|
||||
var/equip_cooldown = 0
|
||||
var/equip_ready = TRUE //whether the equipment is ready for use. (or deactivated/activated for static stuff)
|
||||
var/energy_drain = 0
|
||||
var/obj/vehicle/sealed/mecha/chassis = null
|
||||
///Bitflag. Determines the range of the equipment.
|
||||
var/range = MECHA_MELEE
|
||||
/// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this.
|
||||
var/mech_flags = NONE
|
||||
var/salvageable = 1
|
||||
var/detachable = TRUE // Set to FALSE for built-in equipment that cannot be removed
|
||||
var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates
|
||||
var/harmful = FALSE //Controls if equipment can be used to attack by a pacifist.
|
||||
var/destroy_sound = 'sound/mecha/critdestr.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/update_chassis_page()
|
||||
if(chassis)
|
||||
send_byjax(chassis.occupants,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
||||
send_byjax(chassis.occupants,"exosuit.browser","equipment_menu",chassis.get_equipment_menu(),"dropdowns")
|
||||
return TRUE
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/update_equip_info()
|
||||
if(chassis)
|
||||
send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",get_equip_info())
|
||||
return TRUE
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/Destroy()
|
||||
if(chassis)
|
||||
LAZYREMOVE(chassis.equipment, src)
|
||||
if(chassis.selected == src)
|
||||
chassis.selected = null
|
||||
update_chassis_page()
|
||||
log_message("[src] is destroyed.", LOG_MECHA)
|
||||
if(chassis.occupants)
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='danger'>[src] is destroyed!</span>")
|
||||
playsound(chassis, destroy_sound, 50)
|
||||
if(!detachable) //If we're a built-in nondetachable equipment, let's lock up the slot that we were in.
|
||||
chassis.max_equip--
|
||||
chassis = null
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M)
|
||||
if(can_attach(M))
|
||||
if(!user.temporarilyRemoveItemFromInventory(src))
|
||||
return FALSE
|
||||
attach(M)
|
||||
user.visible_message("<span class='notice'>[user] attaches [src] to [M].</span>", "<span class='notice'>You attach [src] to [M].</span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You are unable to attach [src] to [M]!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/get_equip_info()
|
||||
if(!chassis)
|
||||
return
|
||||
var/txt = "<span style=\"color:[equip_ready?"#0f0":"#f00"];\">*</span> "
|
||||
if(chassis.selected == src)
|
||||
txt += "<b>[src.name]</b>"
|
||||
else if(selectable)
|
||||
txt += "<a href='?src=[REF(chassis)];select_equip=[REF(src)]'>[src.name]</a>"
|
||||
else
|
||||
txt += "[src.name]"
|
||||
|
||||
return txt
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target)
|
||||
if(!target)
|
||||
return FALSE
|
||||
if(!chassis)
|
||||
return FALSE
|
||||
if(!equip_ready)
|
||||
return FALSE
|
||||
if(energy_drain && !chassis.has_charge(energy_drain))
|
||||
return FALSE
|
||||
if(chassis.is_currently_ejecting)
|
||||
return FALSE
|
||||
if(chassis.equipment_disabled)
|
||||
to_chat(chassis.occupants, "<span=warn>Error -- Equipment control unit is unresponsive.</span>")
|
||||
return FALSE
|
||||
if(TIMER_COOLDOWN_CHECK(chassis, COOLDOWN_MECHA_EQUIPMENT))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/action(mob/source, atom/target, params)
|
||||
TIMER_COOLDOWN_START(chassis, COOLDOWN_MECHA_EQUIPMENT, equip_cooldown)//Cooldown is on the MECH so people dont bypass it by switching equipment
|
||||
send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
chassis.use_power(energy_drain)
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target, mob/user)
|
||||
if(!chassis)
|
||||
return
|
||||
var/C = chassis.loc
|
||||
chassis.use_power(energy_drain)
|
||||
. = do_after(user, equip_cooldown, target=target)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, mob/user, delay)
|
||||
if(!chassis)
|
||||
return
|
||||
var/C = chassis.loc
|
||||
. = do_after(user, delay, target=target)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/vehicle/sealed/mecha/M)
|
||||
if(LAZYLEN(M.equipment)<M.max_equip)
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/attach(obj/vehicle/sealed/mecha/M)
|
||||
LAZYADD(M.equipment, src)
|
||||
chassis = M
|
||||
forceMove(M)
|
||||
log_message("[src] initialized.", LOG_MECHA)
|
||||
update_chassis_page()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/detach(atom/moveto=null)
|
||||
moveto = moveto || get_turf(chassis)
|
||||
if(src.Move(moveto))
|
||||
LAZYREMOVE(chassis.equipment, src)
|
||||
if(chassis.selected == src)
|
||||
chassis.selected = null
|
||||
update_chassis_page()
|
||||
log_message("[src] removed from equipment.", LOG_MECHA)
|
||||
chassis = null
|
||||
return
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/Topic(href,href_list)
|
||||
if(href_list["detach"])
|
||||
detach()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/log_message(message, message_type=LOG_GAME, color=null, log_globally)
|
||||
if(chassis)
|
||||
chassis.log_message("ATTACHMENT: [src] [message]", message_type, color)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
//Used for reloading weapons/tools etc. that use some form of resource
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/rearm()
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/needs_rearm()
|
||||
return FALSE
|
||||
+97
-97
@@ -7,12 +7,12 @@
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/can_attach(obj/mecha/medical/M)
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/can_attach(obj/vehicle/sealed/mecha/medical/M)
|
||||
if(..() && istype(M))
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/attach(obj/mecha/M)
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/attach(obj/vehicle/sealed/mecha/M)
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/process()
|
||||
if(!chassis)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return 1
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
@@ -35,7 +34,7 @@
|
||||
icon = 'icons/obj/machines/sleeper.dmi'
|
||||
icon_state = "sleeper"
|
||||
energy_drain = 20
|
||||
range = MELEE
|
||||
range = MECHA_MELEE
|
||||
equip_cooldown = 20
|
||||
var/mob/living/carbon/patient = null
|
||||
var/inject_amount = 10
|
||||
@@ -49,51 +48,54 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Exit(atom/movable/O)
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/action(mob/living/carbon/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/action(mob/source, mob/living/carbon/target, params)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(!istype(target))
|
||||
return
|
||||
if(!patient_insertion_check(target))
|
||||
return
|
||||
occupant_message("<span class='notice'>You start putting [target] into [src]...</span>")
|
||||
to_chat(source, "[icon2html(src, source)]<span class='notice'>You start putting [target] into [src]...</span>")
|
||||
chassis.visible_message("<span class='warning'>[chassis] starts putting [target] into \the [src].</span>")
|
||||
if(do_after_cooldown(target))
|
||||
if(!patient_insertion_check(target))
|
||||
if(do_after(source, equip_cooldown, target=target))
|
||||
if(!chassis || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return
|
||||
if(!patient_insertion_check(target, source))
|
||||
return
|
||||
target.forceMove(src)
|
||||
patient = target
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_equip_info()
|
||||
occupant_message("<span class='notice'>[target] successfully loaded into [src]. Life support functions engaged.</span>")
|
||||
to_chat(source, "[icon2html(src, source)]<span class='notice'>[target] successfully loaded into [src]. Life support functions engaged.</span>")
|
||||
chassis.visible_message("<span class='warning'>[chassis] loads [target] into [src].</span>")
|
||||
mecha_log_message("[target] loaded. Life support functions engaged.")
|
||||
log_message("[target] loaded. Life support functions engaged.", LOG_MECHA)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target, mob/user)
|
||||
if(target.buckled)
|
||||
occupant_message("<span class='warning'>[target] will not fit into the sleeper because [target.p_theyre()] buckled to [target.buckled]!</span>")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>[target] will not fit into the sleeper because [target.p_theyre()] buckled to [target.buckled]!</span>")
|
||||
return
|
||||
if(target.has_buckled_mobs())
|
||||
occupant_message("<span class='warning'>[target] will not fit into the sleeper because of the creatures attached to it!</span>")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>[target] will not fit into the sleeper because of the creatures attached to it!</span>")
|
||||
return
|
||||
if(patient)
|
||||
occupant_message("<span class='warning'>The sleeper is already occupied!</span>")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>The sleeper is already occupied!</span>")
|
||||
return
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/go_out()
|
||||
if(!patient)
|
||||
return
|
||||
patient.forceMove(get_turf(src))
|
||||
occupant_message("[patient] ejected. Life support functions disabled.")
|
||||
mecha_log_message("[patient] ejected. Life support functions disabled.")
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>[patient] ejected. Life support functions disabled.</span>")
|
||||
log_message("[patient] ejected. Life support functions disabled.", LOG_MECHA)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
patient = null
|
||||
update_equip_info()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/detach()
|
||||
if(patient)
|
||||
occupant_message("<span class='warning'>Unable to detach [src] - equipment occupied!</span>")
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='warning'>Unable to detach [src] - equipment occupied!</span>")
|
||||
return
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
@@ -105,20 +107,23 @@
|
||||
if(patient)
|
||||
temp = "<br />\[Occupant: [patient] ([patient.stat > 1 ? "*DECEASED*" : "Health: [patient.health]%"])\]<br /><a href='?src=[REF(src)];view_stats=1'>View stats</a>|<a href='?src=[REF(src)];eject=1'>Eject</a>"
|
||||
return "[output] [temp]"
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Topic(href,href_list)
|
||||
..()
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!(usr in chassis.occupants))
|
||||
return
|
||||
if(href_list["eject"])
|
||||
go_out()
|
||||
if(href_list["view_stats"])
|
||||
chassis.occupant << browse(get_patient_stats(),"window=msleeper")
|
||||
onclose(chassis.occupant, "msleeper")
|
||||
usr << browse(get_patient_stats(),"window=msleeper")
|
||||
onclose(usr, "msleeper")
|
||||
return
|
||||
if(href_list["inject"])
|
||||
var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG = locate() in chassis
|
||||
var/datum/reagent/R = locate(href_list["inject"]) in SG.reagents.reagent_list
|
||||
if (istype(R))
|
||||
if(istype(R))
|
||||
inject_reagent(R, SG)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_stats()
|
||||
@@ -186,7 +191,7 @@
|
||||
if(SG && SG.reagents && islist(SG.reagents.reagent_list))
|
||||
for(var/datum/reagent/R in SG.reagents.reagent_list)
|
||||
if(R.volume > 0)
|
||||
output += "<a href=\"?src=[REF(src)];inject=[REF(R)];source=[REF(SG)]\">Inject [R.name]</a><br />"
|
||||
output += "<a href=\"?src=[REF(src)];inject=[REF(R)]\">Inject [R.name]</a><br />"
|
||||
return output
|
||||
|
||||
|
||||
@@ -195,9 +200,9 @@
|
||||
return 0
|
||||
var/to_inject = min(R.volume, inject_amount)
|
||||
if(to_inject && patient.reagents.get_reagent_amount(R.type) + to_inject <= inject_amount*2)
|
||||
occupant_message("Injecting [patient] with [to_inject] units of [R.name].")
|
||||
mecha_log_message("Injecting [patient] with [to_inject] units of [R.name].")
|
||||
log_combat(chassis.occupant, patient, "injected", "[name] ([R] - [to_inject] units)")
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>Injecting [patient] with [to_inject] units of [R.name].</span>")
|
||||
log_message("Injecting [patient] with [to_inject] units of [R.name].", LOG_MECHA)
|
||||
log_combat(chassis.occupants, patient, "injected", "[name] ([R] - [to_inject] units)")
|
||||
SG.reagents.trans_id_to(patient,R.type,to_inject)
|
||||
update_equip_info()
|
||||
return
|
||||
@@ -205,9 +210,9 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/update_equip_info()
|
||||
if(..())
|
||||
if(patient)
|
||||
send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_patient_dam())
|
||||
send_byjax(chassis.occupant,"msleeper.browser","reagents",get_patient_reagents())
|
||||
send_byjax(chassis.occupant,"msleeper.browser","injectwith",get_available_reagents())
|
||||
send_byjax(chassis.occupants,"msleeper.browser","lossinfo",get_patient_dam())
|
||||
send_byjax(chassis.occupants,"msleeper.browser","reagents",get_patient_reagents())
|
||||
send_byjax(chassis.occupants,"msleeper.browser","injectwith",get_available_reagents())
|
||||
return 1
|
||||
return
|
||||
|
||||
@@ -218,9 +223,8 @@
|
||||
if(..())
|
||||
return
|
||||
if(!chassis.has_charge(energy_drain))
|
||||
set_ready_state(1)
|
||||
mecha_log_message("Deactivated.")
|
||||
occupant_message("[src] deactivated - no power.")
|
||||
log_message("Deactivated.", LOG_MECHA)
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='warning'>[src] deactivated - no power.</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
var/mob/living/carbon/M = patient
|
||||
@@ -228,7 +232,10 @@
|
||||
return
|
||||
if(M.health > 0)
|
||||
M.adjustOxyLoss(-1)
|
||||
M.AdjustAllImmobility(-80)
|
||||
M.AdjustStun(-80)
|
||||
M.AdjustKnockdown(-80)
|
||||
M.AdjustParalyzed(-80)
|
||||
M.AdjustImmobilized(-80)
|
||||
M.AdjustUnconscious(-80)
|
||||
if(M.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine) < 5)
|
||||
M.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5)
|
||||
@@ -254,15 +261,14 @@
|
||||
var/synth_speed = 5 //[num] reagent units per cycle
|
||||
energy_drain = 10
|
||||
var/mode = 0 //0 - fire syringe, 1 - analyze reagents.
|
||||
range = MELEE|RANGED
|
||||
range = MECHA_MELEE|MECHA_RANGED
|
||||
equip_cooldown = 10
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Initialize()
|
||||
. = ..()
|
||||
create_reagents(max_volume, NO_REACT)
|
||||
syringes = new
|
||||
known_reagents = list(/datum/reagent/medicine/epinephrine = "Epinephrine", /datum/reagent/medicine/charcoal = "Charcoal", /datum/reagent/medicine/prussian_blue = "Prussian Blue", \
|
||||
/datum/reagent/medicine/dexalin = "Dexalin", /datum/reagent/medicine/insulin = "Insulin", /datum/reagent/medicine/kelotane = "Kelotane", /datum/reagent/medicine/bicaridine = "Bicaridine")
|
||||
known_reagents = list(/datum/reagent/medicine/epinephrine="Epinephrine")
|
||||
processed_reagents = new
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/detach()
|
||||
@@ -273,39 +279,35 @@
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail()
|
||||
..()
|
||||
if(reagents)
|
||||
reagents.reagents_holder_flags &= ~(NO_REACT)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/vehicle/sealed/mecha/medical/M)
|
||||
. = ..()
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/get_equip_info()
|
||||
var/output = ..()
|
||||
if(output)
|
||||
return "[output] \[<a href=\"?src=[REF(src)];toggle_mode=1\">[mode? "Analyze" : "Launch"]</a>\]<br />\[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]<br /><a href='?src=[REF(src)];show_reagents=1'>Reagents list</a>"
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(atom/movable/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(mob/source, atom/movable/target, params)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(istype(target, /obj/item/reagent_containers/syringe))
|
||||
return load_syringe(target)
|
||||
if(istype(target, /obj/item/storage))//Loads syringes from boxes
|
||||
for(var/obj/item/reagent_containers/syringe/S in target.contents)
|
||||
load_syringe(S)
|
||||
load_syringe(S, source)
|
||||
return
|
||||
if(mode)
|
||||
return analyze_reagents(target)
|
||||
return analyze_reagents(target, source)
|
||||
if(!syringes.len)
|
||||
occupant_message("<span class=\"alert\">No syringes loaded.</span>")
|
||||
to_chat(source, "[icon2html(src, source)]<span class=\"alert\">No syringes loaded.</span>")
|
||||
return
|
||||
if(reagents.total_volume<=0)
|
||||
occupant_message("<span class=\"alert\">No available reagents to load syringe with.</span>")
|
||||
to_chat(source, "[icon2html(src, source)]<span class=\"alert\">No available reagents to load syringe with.</span>")
|
||||
return
|
||||
if(HAS_TRAIT(source, TRAIT_PACIFISM))
|
||||
to_chat(source, "<span class=\"alert\">The [src] is lethally chambered! You don't want to risk harming anyone...</span>")
|
||||
return
|
||||
var/turf/trg = get_turf(target)
|
||||
var/obj/item/reagent_containers/syringe/mechsyringe = syringes[1]
|
||||
@@ -314,11 +316,9 @@
|
||||
syringes -= mechsyringe
|
||||
mechsyringe.icon = 'icons/obj/chemical.dmi'
|
||||
mechsyringe.icon_state = "syringeproj"
|
||||
playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1)
|
||||
mecha_log_message("Launched [mechsyringe] from [src], targeting [target].")
|
||||
var/mob/originaloccupant = chassis.occupant
|
||||
spawn(0)
|
||||
src = null //if src is deleted, still process the syringe
|
||||
playsound(chassis, 'sound/items/syringeproj.ogg', 50, TRUE)
|
||||
log_message("Launched [mechsyringe] from [src] by [source], targeting [target].", LOG_MECHA)
|
||||
spawn(0) //This code is trash and whoever wrote it should feel bad
|
||||
for(var/i=0, i<6, i++)
|
||||
if(!mechsyringe)
|
||||
break
|
||||
@@ -326,10 +326,10 @@
|
||||
var/list/mobs = new
|
||||
for(var/mob/living/carbon/M in mechsyringe.loc)
|
||||
mobs += M
|
||||
var/mob/living/carbon/M = safepick(mobs)
|
||||
if(M)
|
||||
if(length(mobs))
|
||||
var/mob/living/carbon/M = pick(mobs)
|
||||
var/R
|
||||
mechsyringe.visible_message("<span class=\"attack\"> [M] was hit by the syringe!</span>")
|
||||
mechsyringe.visible_message("<span class=\"attack\"> [M] is hit by the syringe!</span>")
|
||||
if(M.can_inject(null, 1))
|
||||
if(mechsyringe.reagents)
|
||||
for(var/datum/reagent/A in mechsyringe.reagents.reagent_list)
|
||||
@@ -337,9 +337,9 @@
|
||||
mechsyringe.icon_state = initial(mechsyringe.icon_state)
|
||||
mechsyringe.icon = initial(mechsyringe.icon)
|
||||
mechsyringe.reagents.reaction(M, INJECT)
|
||||
mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume)
|
||||
mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume, log = TRUE)
|
||||
M.take_bodypart_damage(2)
|
||||
log_combat(originaloccupant, M, "shot", "syringegun")
|
||||
log_combat(source, M, "shot", "syringegun")
|
||||
break
|
||||
else if(mechsyringe.loc == trg)
|
||||
mechsyringe.icon_state = initial(mechsyringe.icon_state)
|
||||
@@ -352,7 +352,7 @@
|
||||
mechsyringe.update_icon()
|
||||
break
|
||||
sleep(1)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Topic(href,href_list)
|
||||
@@ -376,12 +376,14 @@
|
||||
if(processed_reagents.len)
|
||||
message += " added to production"
|
||||
START_PROCESSING(SSobj, src)
|
||||
occupant_message(message)
|
||||
occupant_message("<span class='notice'>Reagent processing started.</span>")
|
||||
mecha_log_message("Reagent processing started.")
|
||||
to_chat(usr, message)
|
||||
to_chat(usr, "[icon2html(src, usr)]<span class='notice'>Reagent processing started.</span>")
|
||||
log_message("Reagent processing started.", LOG_MECHA)
|
||||
return
|
||||
if (href_list["show_reagents"])
|
||||
chassis.occupant << browse(get_reagents_page(),"window=msyringegun")
|
||||
if(!(usr in chassis.occupants))
|
||||
return
|
||||
usr << browse(get_reagents_page(),"window=msyringegun")
|
||||
if (href_list["purge_reagent"])
|
||||
var/reagent = href_list["purge_reagent"]
|
||||
if(reagent)
|
||||
@@ -445,74 +447,72 @@
|
||||
var/output
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.volume > 0)
|
||||
output += "[R]: [round(R.volume,0.001)] - <a href=\"?src=[REF(src)];purge_reagent=[R.type]\">Purge Reagent</a><br />"
|
||||
output += "[R]: [round(R.volume,0.001)] - <a href=\"?src=[REF(src)];purge_reagent=[R]\">Purge Reagent</a><br />"
|
||||
if(output)
|
||||
output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - <a href=\"?src=[REF(src)];purge_all=1\">Purge All</a>"
|
||||
return output || "None"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/reagent_containers/syringe/S)
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/reagent_containers/syringe/S, mob/user)
|
||||
if(syringes.len<max_syringes)
|
||||
if(get_dist(src,S) >= 2)
|
||||
occupant_message("The syringe is too far away.")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>The syringe is too far away!</span>")
|
||||
return 0
|
||||
for(var/obj/structure/D in S.loc)//Basic level check for structures in the way (Like grilles and windows)
|
||||
if(!(D.CanPass(S,src.loc)))
|
||||
occupant_message("Unable to load syringe.")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>Unable to load syringe!</span>")
|
||||
return 0
|
||||
for(var/obj/machinery/door/D in S.loc)//Checks for doors
|
||||
if(!(D.CanPass(S,src.loc)))
|
||||
occupant_message("Unable to load syringe.")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>Unable to load syringe!</span>")
|
||||
return 0
|
||||
S.reagents.trans_to(src, S.reagents.total_volume)
|
||||
S.forceMove(src)
|
||||
syringes += S
|
||||
occupant_message("Syringe loaded.")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='notice'>Syringe loaded.</span>")
|
||||
update_equip_info()
|
||||
return 1
|
||||
occupant_message("[src]'s syringe chamber is full.")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>[src]'s syringe chamber is full!</span>")
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A)
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A, mob/user)
|
||||
if(get_dist(src,A) >= 4)
|
||||
occupant_message("The object is too far away.")
|
||||
return 0
|
||||
to_chat(user, "[icon2html(src, user)]<span class='notice'>The object is too far away!</span>")
|
||||
return FALSE
|
||||
if(!A.reagents || ismob(A))
|
||||
occupant_message("<span class=\"alert\">No reagent info gained from [A].</span>")
|
||||
return 0
|
||||
occupant_message("Analyzing reagents...")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>No reagent info gained from [A].</span>")
|
||||
return FALSE
|
||||
to_chat(user, "[icon2html(src, user)]<span class='notice'>Analyzing reagents...</span>")
|
||||
for(var/datum/reagent/R in A.reagents.reagent_list)
|
||||
if(R.can_synth && add_known_reagent(R.type,R.name))
|
||||
occupant_message("Reagent analyzed, identified as [R.name] and added to database.")
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
occupant_message("Analyzis complete.")
|
||||
return 1
|
||||
to_chat(user, "[icon2html(src, user)]<span class='notice'>Reagent analyzed, identified as [R.name] and added to database.</span>")
|
||||
send_byjax(chassis.occupants,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
to_chat(user, "[icon2html(src, user)]<span class='notice'>Analysis complete.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/add_known_reagent(r_id,r_name)
|
||||
if(!(r_id in known_reagents))
|
||||
known_reagents += r_id
|
||||
known_reagents[r_id] = r_name
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/update_equip_info()
|
||||
if(..())
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents())
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
return 1
|
||||
return
|
||||
send_byjax(chassis.occupants,"msyringegun.browser","reagents",get_current_reagents())
|
||||
send_byjax(chassis.occupants,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/on_reagent_change(changetype)
|
||||
..()
|
||||
update_equip_info()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/process()
|
||||
if(..())
|
||||
return
|
||||
if(!processed_reagents.len || reagents.total_volume >= reagents.maximum_volume || !chassis.has_charge(energy_drain))
|
||||
occupant_message("<span class=\"alert\">Reagent processing stopped.</a>")
|
||||
mecha_log_message("Reagent processing stopped.")
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='alert'>Reagent processing stopped.</span>")
|
||||
log_message("Reagent processing stopped.", LOG_MECHA)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
var/amount = synth_speed / processed_reagents.len
|
||||
@@ -527,7 +527,7 @@
|
||||
desc = "Equipment for medical exosuits. Generates a focused beam of medical nanites."
|
||||
icon_state = "mecha_medigun"
|
||||
energy_drain = 10
|
||||
range = MELEE|RANGED
|
||||
range = MECHA_MELEE|MECHA_RANGED
|
||||
equip_cooldown = 0
|
||||
var/obj/item/gun/medbeam/mech/medigun
|
||||
custom_materials = list(/datum/material/iron = 15000, /datum/material/glass = 8000, /datum/material/plasma = 3000, /datum/material/gold = 8000, /datum/material/diamond = 2000)
|
||||
@@ -546,7 +546,7 @@
|
||||
return
|
||||
medigun.process()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(atom/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(mob/source, atom/movable/target, params)
|
||||
medigun.process_fire(target, loc)
|
||||
|
||||
|
||||
+40
-36
@@ -13,6 +13,7 @@
|
||||
energy_drain = 10
|
||||
force = 15
|
||||
harmful = TRUE
|
||||
range = MECHA_MELEE
|
||||
tool_behaviour = TOOL_DRILL
|
||||
toolspeed = 0.9
|
||||
var/drill_delay = 7
|
||||
@@ -23,7 +24,7 @@
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 50, 100, null, null, TRUE)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/action(atom/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/action(mob/source, atom/target, params)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(isspaceturf(target))
|
||||
@@ -34,72 +35,69 @@
|
||||
return
|
||||
target.visible_message("<span class='warning'>[chassis] starts to drill [target].</span>", \
|
||||
"<span class='userdanger'>[chassis] starts to drill [target]...</span>", \
|
||||
"<span class='italics'>You hear drilling.</span>")
|
||||
"<span class='hear'>You hear drilling.</span>")
|
||||
|
||||
if(do_after_cooldown(target))
|
||||
set_ready_state(FALSE)
|
||||
mecha_log_message("Started drilling [target]")
|
||||
if(do_after_cooldown(target, source))
|
||||
log_message("Started drilling [target]", LOG_MECHA)
|
||||
if(isturf(target))
|
||||
var/turf/T = target
|
||||
T.drill_act(src)
|
||||
set_ready_state(TRUE)
|
||||
T.drill_act(src, source)
|
||||
return
|
||||
while(do_after_mecha(target, drill_delay))
|
||||
while(do_after_mecha(target, source, drill_delay))
|
||||
if(isliving(target))
|
||||
drill_mob(target, chassis.occupant)
|
||||
playsound(src,'sound/weapons/drill.ogg',40,1)
|
||||
drill_mob(target, source)
|
||||
playsound(src,'sound/weapons/drill.ogg',40,TRUE)
|
||||
else if(isobj(target))
|
||||
var/obj/O = target
|
||||
O.take_damage(15, BRUTE, 0, FALSE, get_dir(chassis, target))
|
||||
playsound(src,'sound/weapons/drill.ogg',40,1)
|
||||
playsound(src,'sound/weapons/drill.ogg',40,TRUE)
|
||||
else
|
||||
set_ready_state(TRUE)
|
||||
return
|
||||
set_ready_state(TRUE)
|
||||
return ..()
|
||||
|
||||
/turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
/turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user)
|
||||
return
|
||||
|
||||
/turf/closed/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
if(drill.do_after_mecha(src, 60 / drill.drill_level))
|
||||
drill.mecha_log_message("Drilled through [src]")
|
||||
/turf/closed/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user)
|
||||
if(drill.do_after_mecha(src, user, 60 / drill.drill_level))
|
||||
drill.log_message("Drilled through [src]", LOG_MECHA)
|
||||
dismantle_wall(TRUE, FALSE)
|
||||
|
||||
/turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
/turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user)
|
||||
if(drill.drill_level >= DRILL_HARDENED)
|
||||
if(drill.do_after_mecha(src, 120 / drill.drill_level))
|
||||
drill.mecha_log_message("Drilled through [src]")
|
||||
if(drill.do_after_mecha(src, user, 120 / drill.drill_level))
|
||||
drill.log_message("Drilled through [src]", LOG_MECHA)
|
||||
dismantle_wall(TRUE, FALSE)
|
||||
else
|
||||
drill.occupant_message("<span class='danger'>[src] is too durable to drill through.</span>")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='danger'>[src] is too durable to drill through.</span>")
|
||||
|
||||
/turf/closed/mineral/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
/turf/closed/mineral/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user)
|
||||
for(var/turf/closed/mineral/M in range(drill.chassis,1))
|
||||
if(get_dir(drill.chassis,M)&drill.chassis.dir)
|
||||
M.gets_drilled()
|
||||
drill.mecha_log_message("Drilled through [src]")
|
||||
drill.log_message("[user] drilled through [src]", LOG_MECHA)
|
||||
drill.move_ores()
|
||||
|
||||
/turf/open/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
for(var/turf/open/floor/plating/asteroid/M in range(1, drill.chassis))
|
||||
if((get_dir(drill.chassis,M)&drill.chassis.dir) && !M.dug)
|
||||
M.getDug()
|
||||
drill.mecha_log_message("Drilled through [src]")
|
||||
drill.log_message("Drilled through [src]", LOG_MECHA)
|
||||
drill.move_ores()
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/proc/move_ores()
|
||||
if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment && istype(chassis, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/R = chassis //we could assume that it's a ripley because it has a clamp, but that's ~unsafe~ and ~bad practice~
|
||||
if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment && istype(chassis, /obj/vehicle/sealed/mecha/working/ripley))
|
||||
var/obj/vehicle/sealed/mecha/working/ripley/R = chassis //we could assume that it's a ripley because it has a clamp, but that's ~unsafe~ and ~bad practice~
|
||||
R.collect_ore()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/mecha/M as obj)
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/vehicle/sealed/mecha/M as obj)
|
||||
if(..())
|
||||
if(istype(M, /obj/mecha/working) || istype(M, /obj/mecha/combat))
|
||||
return 1
|
||||
return 0
|
||||
if(istype(M, /obj/vehicle/sealed/mecha/working) || istype(M, /obj/vehicle/sealed/mecha/combat))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/attach(obj/mecha/M)
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/attach(obj/vehicle/sealed/mecha/M)
|
||||
..()
|
||||
var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
|
||||
butchering.butchering_enabled = TRUE
|
||||
@@ -123,7 +121,7 @@
|
||||
else
|
||||
//drill makes a hole
|
||||
var/obj/item/bodypart/target_part = target.get_bodypart(ran_zone(BODY_ZONE_CHEST))
|
||||
target.apply_damage(10, BRUTE, BODY_ZONE_CHEST, target.run_armor_check(target_part, "melee"))
|
||||
target.apply_damage(10, BRUTE, BODY_ZONE_CHEST, target.run_armor_check(target_part, MELEE))
|
||||
|
||||
//blood splatters
|
||||
var/splatter_dir = get_dir(chassis, target)
|
||||
@@ -153,7 +151,7 @@
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner
|
||||
name = "exosuit mining scanner"
|
||||
desc = "Equipment for engineering and combat exosuits. It will automatically check surrounding rock for useful minerals."
|
||||
desc = "Equipment for working exosuits. It will automatically check surrounding rock for useful minerals."
|
||||
icon_state = "mecha_analyzer"
|
||||
selectable = 0
|
||||
equip_cooldown = 15
|
||||
@@ -164,13 +162,19 @@
|
||||
. = ..()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/can_attach(obj/vehicle/sealed/mecha/M as obj)
|
||||
if(..())
|
||||
if(istype(M, /obj/vehicle/sealed/mecha/working))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/process()
|
||||
if(!loc)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
qdel(src)
|
||||
if(istype(loc, /obj/mecha/working) && scanning_time <= world.time)
|
||||
var/obj/mecha/working/mecha = loc
|
||||
if(!mecha.occupant)
|
||||
if(istype(loc, /obj/vehicle/sealed/mecha/working) && scanning_time <= world.time)
|
||||
var/obj/vehicle/sealed/mecha/working/mecha = loc
|
||||
if(!mecha.occupants)
|
||||
return
|
||||
scanning_time = world.time + equip_cooldown
|
||||
mineral_scan_pulse(get_turf(src))
|
||||
+190
-99
@@ -10,15 +10,16 @@
|
||||
icon_state = "mecha_teleport"
|
||||
equip_cooldown = 150
|
||||
energy_drain = 1000
|
||||
range = RANGED
|
||||
range = MECHA_RANGED
|
||||
var/teleport_range = 7
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/teleporter/action(mob/source, atom/target, params)
|
||||
if(!action_checks(target) || is_centcom_level(loc.z))
|
||||
return
|
||||
var/turf/T = get_turf(target)
|
||||
if(T)
|
||||
if(T && (loc.z == T.z) && (get_dist(loc, T) <= teleport_range))
|
||||
do_teleport(chassis, T, 4, channel = TELEPORT_CHANNEL_BLUESPACE)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
@@ -30,10 +31,10 @@
|
||||
icon_state = "mecha_wholegen"
|
||||
equip_cooldown = 50
|
||||
energy_drain = 300
|
||||
range = RANGED
|
||||
range = MECHA_RANGED
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(atom/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(mob/source, atom/target, params)
|
||||
if(!action_checks(target) || is_centcom_level(loc.z))
|
||||
return
|
||||
var/list/theareas = get_areas_in_range(100, chassis)
|
||||
@@ -44,10 +45,10 @@
|
||||
var/turf/pos = get_turf(src)
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(!T.density && pos.z == T.z)
|
||||
var/clear = 1
|
||||
var/clear = TRUE
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
clear = 0
|
||||
clear = FALSE
|
||||
break
|
||||
if(clear)
|
||||
L+=T
|
||||
@@ -58,11 +59,11 @@
|
||||
return
|
||||
var/list/obj/effect/portal/created = create_portal_pair(get_turf(src), target_turf, 300, 1, /obj/effect/portal/anom)
|
||||
var/turf/T = get_turf(target)
|
||||
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Wormhole Generator in [ADMIN_VERBOSEJMP(T)]")
|
||||
log_game("[key_name(chassis.occupant)] used a Wormhole Generator in [AREACOORD(T)]")
|
||||
message_admins("[ADMIN_LOOKUPFLW(source)] used a Wormhole Generator in [ADMIN_VERBOSEJMP(T)]")
|
||||
log_game("[key_name(source)] used a Wormhole Generator in [AREACOORD(T)]")
|
||||
src = null
|
||||
QDEL_LIST_IN(created, rand(150,300))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
|
||||
/////////////////////////////////////// GRAVITATIONAL CATAPULT ///////////////////////////////////////////
|
||||
@@ -73,36 +74,41 @@
|
||||
icon_state = "mecha_teleport"
|
||||
equip_cooldown = 10
|
||||
energy_drain = 100
|
||||
range = MELEE|RANGED
|
||||
range = MECHA_MELEE|MECHA_RANGED
|
||||
var/atom/movable/locked
|
||||
var/mode = 1 //1 - gravsling 2 - gravpush
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(atom/movable/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(mob/source, atom/movable/target, params)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
switch(mode)
|
||||
if(1)
|
||||
if(!locked)
|
||||
if(!istype(target) || target.anchored || target.move_resist >= MOVE_FORCE_EXTREMELY_STRONG)
|
||||
occupant_message("Unable to lock on [target]")
|
||||
to_chat(source, "[icon2html(src, source)]<span class='warning'>Unable to lock on [target]!</span>")
|
||||
return
|
||||
if(ismob(target))
|
||||
var/mob/M = target
|
||||
if(M.mob_negates_gravity())
|
||||
to_chat(source, "[icon2html(src, source)]<span class='warning'>Unable to lock on [target]!</span>")
|
||||
return
|
||||
locked = target
|
||||
occupant_message("Locked on [target]")
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
to_chat(source, "[icon2html(src, source)]<span class='notice'>Locked on [target].</span>")
|
||||
send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
else if(target!=locked)
|
||||
if(locked in view(chassis))
|
||||
var/turf/targ = get_turf(target)
|
||||
var/turf/orig = get_turf(locked)
|
||||
locked.throw_at(target, 14, 1.5)
|
||||
locked = null
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
log_game("[key_name(chassis.occupant)] used a Gravitational Catapult to throw [locked] (From [AREACOORD(orig)]) at [target] ([AREACOORD(targ)]).")
|
||||
return TRUE
|
||||
send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
log_game("[key_name(source)] used a Gravitational Catapult to throw [locked] (From [AREACOORD(orig)]) at [target] ([AREACOORD(targ)]).")
|
||||
return ..()
|
||||
else
|
||||
locked = null
|
||||
occupant_message("Lock on [locked] disengaged.")
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
to_chat(source, "[icon2html(src, source)]<span class='notice'>Lock on [locked] disengaged.</span>")
|
||||
send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
if(2)
|
||||
var/list/atoms = list()
|
||||
if(isturf(target))
|
||||
@@ -112,15 +118,21 @@
|
||||
for(var/atom/movable/A in atoms)
|
||||
if(A.anchored || A.move_resist >= MOVE_FORCE_EXTREMELY_STRONG)
|
||||
continue
|
||||
spawn(0)
|
||||
var/iter = 5-get_dist(A,target)
|
||||
for(var/i=0 to iter)
|
||||
step_away(A,target)
|
||||
sleep(2)
|
||||
var/turf/T = get_turf(target)
|
||||
log_game("[key_name(chassis.occupant)] used a Gravitational Catapult repulse wave on [AREACOORD(T)]")
|
||||
return TRUE
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(M.mob_negates_gravity())
|
||||
continue
|
||||
INVOKE_ASYNC(src, .proc/do_scatter, A, target)
|
||||
|
||||
var/turf/T = get_turf(target)
|
||||
log_game("[key_name(source)] used a Gravitational Catapult repulse wave on [AREACOORD(T)]")
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult/proc/do_scatter(atom/movable/A, atom/movable/target)
|
||||
var/iter = 5-get_dist(A,target)
|
||||
for(var/i in 0 to iter)
|
||||
step_away(A,target)
|
||||
sleep(2)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info()
|
||||
return "[..()] [mode==1?"([locked||"Nothing"])":null] \[<a href='?src=[REF(src)];mode=1'>S</a>|<a href='?src=[REF(src)];mode=2'>P</a>\]"
|
||||
@@ -129,7 +141,7 @@
|
||||
..()
|
||||
if(href_list["mode"])
|
||||
mode = text2num(href_list["mode"])
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
return
|
||||
|
||||
|
||||
@@ -150,9 +162,10 @@
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react()
|
||||
if(action_checks(src))
|
||||
start_cooldown()
|
||||
return 1
|
||||
if(energy_drain && !chassis.has_charge(energy_drain))
|
||||
return FALSE
|
||||
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_ARMOR, equip_cooldown)
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
@@ -168,9 +181,10 @@
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/projectile_react()
|
||||
if(action_checks(src))
|
||||
start_cooldown()
|
||||
return 1
|
||||
if(energy_drain && !chassis.has_charge(energy_drain))
|
||||
return FALSE
|
||||
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_ARMOR, equip_cooldown)
|
||||
return TRUE
|
||||
|
||||
|
||||
////////////////////////////////// REPAIR DROID //////////////////////////////////////////////////
|
||||
@@ -193,7 +207,7 @@
|
||||
chassis.cut_overlay(droid_overlay)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/mecha/M as obj)
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/vehicle/sealed/mecha/M)
|
||||
..()
|
||||
droid_overlay = new(src.icon, icon_state = "repair_droid")
|
||||
M.add_overlay(droid_overlay)
|
||||
@@ -216,21 +230,18 @@
|
||||
if(equip_ready)
|
||||
START_PROCESSING(SSobj, src)
|
||||
droid_overlay = new(src.icon, icon_state = "repair_droid_a")
|
||||
mecha_log_message("Activated.")
|
||||
set_ready_state(0)
|
||||
log_message("Activated.", LOG_MECHA)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
droid_overlay = new(src.icon, icon_state = "repair_droid")
|
||||
mecha_log_message("Deactivated.")
|
||||
set_ready_state(1)
|
||||
log_message("Deactivated.", LOG_MECHA)
|
||||
chassis.add_overlay(droid_overlay)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
send_byjax(chassis.occupants,"exosuit.browser", "[REF(src)]", get_equip_info())
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/process()
|
||||
if(!chassis)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
return
|
||||
var/h_boost = health_boost
|
||||
var/repaired = 0
|
||||
@@ -242,16 +253,14 @@
|
||||
chassis.clearInternalDamage(int_dam_flag)
|
||||
repaired = 1
|
||||
break
|
||||
if(health_boost<0 || chassis.obj_integrity < chassis.max_integrity)
|
||||
chassis.obj_integrity += min(health_boost, chassis.max_integrity-chassis.obj_integrity)
|
||||
if(h_boost<0 || chassis.obj_integrity < chassis.max_integrity)
|
||||
chassis.obj_integrity += min(h_boost, chassis.max_integrity-chassis.obj_integrity)
|
||||
repaired = 1
|
||||
if(repaired)
|
||||
if(!chassis.use_power(energy_drain))
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
else //no repair needed, we turn off
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
chassis.cut_overlay(droid_overlay)
|
||||
droid_overlay = new(src.icon, icon_state = "repair_droid")
|
||||
chassis.add_overlay(droid_overlay)
|
||||
@@ -284,12 +293,12 @@
|
||||
if(equip_ready) //disabled
|
||||
return
|
||||
var/area/A = get_area(chassis)
|
||||
var/pow_chan = get_MUTATION_POWER_channel(A)
|
||||
var/pow_chan = GET_MUTATION_POWER_channel(A)
|
||||
if(pow_chan)
|
||||
return 1000 //making magic
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_MUTATION_POWER_channel(var/area/A)
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/GET_MUTATION_POWER_channel(area/A)
|
||||
var/pow_chan
|
||||
if(A)
|
||||
for(var/c in use_channels)
|
||||
@@ -303,12 +312,10 @@
|
||||
if(href_list["toggle_relay"])
|
||||
if(equip_ready) //inactive
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_ready_state(0)
|
||||
mecha_log_message("Activated.")
|
||||
log_message("Activated.", LOG_MECHA)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
mecha_log_message("Deactivated.")
|
||||
log_message("Deactivated.", LOG_MECHA)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info()
|
||||
if(!chassis)
|
||||
@@ -319,19 +326,17 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/process()
|
||||
if(!chassis || chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
return
|
||||
var/cur_charge = chassis.get_charge()
|
||||
if(isnull(cur_charge) || !chassis.cell)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
occupant_message("No powercell detected.")
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>No power cell detected.</span>")
|
||||
return
|
||||
if(cur_charge < chassis.cell.maxcharge)
|
||||
var/area/A = get_base_area(chassis)
|
||||
var/area/A = get_area(chassis)
|
||||
if(A)
|
||||
var/pow_chan
|
||||
for(var/c in list(EQUIP,ENVIRON,LIGHT))
|
||||
for(var/c in use_channels)
|
||||
if(A.powered(c))
|
||||
pow_chan = c
|
||||
break
|
||||
@@ -350,7 +355,7 @@
|
||||
name = "exosuit plasma converter"
|
||||
desc = "An exosuit module that generates power using solid plasma as fuel. Pollutes the environment."
|
||||
icon_state = "tesla"
|
||||
range = MELEE
|
||||
range = MECHA_MELEE
|
||||
var/coeff = 100
|
||||
var/obj/item/stack/sheet/fuel
|
||||
var/max_fuel = 150000
|
||||
@@ -377,77 +382,54 @@
|
||||
..()
|
||||
if(href_list["toggle"])
|
||||
if(equip_ready) //inactive
|
||||
set_ready_state(0)
|
||||
START_PROCESSING(SSobj, src)
|
||||
mecha_log_message("Activated.")
|
||||
log_message("Activated.", LOG_MECHA)
|
||||
else
|
||||
set_ready_state(1)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
mecha_log_message("Deactivated.")
|
||||
log_message("Deactivated.", LOG_MECHA)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/get_equip_info()
|
||||
var/output = ..()
|
||||
if(output)
|
||||
return "[output] \[[fuel]: [round(fuel.amount*MINERAL_MATERIAL_AMOUNT,0.1)] cm<sup>3</sup>\] - <a href='?src=[REF(src)];toggle=1'>[equip_ready?"A":"Dea"]ctivate</a>"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/action(target)
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/action(mob/source, atom/movable/target, params)
|
||||
if(chassis)
|
||||
var/result = load_fuel(target)
|
||||
if(result)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
if(load_fuel(target, source))
|
||||
send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info())
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(var/obj/item/stack/sheet/P)
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(obj/item/stack/sheet/P, mob/user)
|
||||
if(P.type == fuel.type && P.amount > 0)
|
||||
var/to_load = max(max_fuel - fuel.amount*MINERAL_MATERIAL_AMOUNT,0)
|
||||
if(to_load)
|
||||
var/units = min(max(round(to_load / MINERAL_MATERIAL_AMOUNT),1),P.amount)
|
||||
fuel.amount += units
|
||||
P.use(units)
|
||||
occupant_message("[units] unit\s of [fuel] successfully loaded.")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='notice'>[units] unit\s of [fuel] successfully loaded.</span>")
|
||||
return units
|
||||
else
|
||||
occupant_message("Unit is full.")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='notice'>Unit is full.</span>")
|
||||
return 0
|
||||
else
|
||||
occupant_message("<span class='warning'>[fuel] traces in target minimal! [P] cannot be used as fuel.</span>")
|
||||
to_chat(user, "[icon2html(src, user)]<span class='warning'>[fuel] traces in target minimal! [P] cannot be used as fuel.</span>")
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/attackby(weapon,mob/user, params)
|
||||
load_fuel(weapon)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/critfail()
|
||||
..()
|
||||
var/turf/open/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
var/datum/gas_mixture/GM = new
|
||||
if(prob(10))
|
||||
GM.adjust_moles(GAS_PLASMA,100)
|
||||
GM.set_temperature(1500+T0C) //should be enough to start a fire
|
||||
T.visible_message("[src] suddenly disgorges a cloud of heated plasma.")
|
||||
qdel(src)
|
||||
else
|
||||
GM.adjust_moles(GAS_PLASMA,5)
|
||||
GM.set_temperature(istype(T) ? T.air.return_temperature() : T20C)
|
||||
T.visible_message("[src] suddenly disgorges a cloud of plasma.")
|
||||
T.assume_air(GM)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/process()
|
||||
if(!chassis)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
return
|
||||
if(fuel.amount<=0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
mecha_log_message("Deactivated - no fuel.")
|
||||
set_ready_state(1)
|
||||
log_message("Deactivated - no fuel.", LOG_MECHA)
|
||||
return
|
||||
var/cur_charge = chassis.get_charge()
|
||||
if(isnull(cur_charge))
|
||||
set_ready_state(1)
|
||||
occupant_message("No powercell detected.")
|
||||
mecha_log_message("Deactivated.")
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>No power cell detected.</span>")
|
||||
log_message("Deactivated.", LOG_MECHA)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
var/use_fuel = fuel_per_cycle_idle
|
||||
@@ -456,7 +438,7 @@
|
||||
chassis.give_power(power_per_cycle)
|
||||
fuel.amount -= min(use_fuel/MINERAL_MATERIAL_AMOUNT,fuel.amount)
|
||||
update_equip_info()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear
|
||||
@@ -472,9 +454,118 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear/generator_init()
|
||||
fuel = new /obj/item/stack/sheet/mineral/uranium(src, 0)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear/critfail()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear/process()
|
||||
if(..())
|
||||
radiation_pulse(get_turf(src), rad_per_cycle)
|
||||
|
||||
|
||||
/////////////////////////////////////////// THRUSTERS /////////////////////////////////////////////
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters
|
||||
name = "generic exosuit thrusters" //parent object, in-game sources will be a child object
|
||||
desc = "A generic set of thrusters, from an unknown source. Uses not-understood methods to propel exosuits seemingly for free."
|
||||
icon_state = "thrusters"
|
||||
selectable = FALSE
|
||||
var/effect_type = /obj/effect/particle_effect/sparks
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M)
|
||||
for(var/obj/item/I in M.equipment)
|
||||
if(istype(I, src))
|
||||
to_chat(user, "<span class='warning'>[M] already has this thruster package!</span>")
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/attach(obj/vehicle/sealed/mecha/M)
|
||||
M.active_thrusters = src //Enable by default
|
||||
. = ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/detach()
|
||||
if(chassis?.active_thrusters == src)
|
||||
chassis.active_thrusters = null
|
||||
. = ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/Destroy()
|
||||
if(chassis?.active_thrusters == src)
|
||||
chassis.active_thrusters = null
|
||||
. = ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/Topic(href,href_list)
|
||||
..()
|
||||
if(!chassis)
|
||||
return
|
||||
if(href_list["mode"])
|
||||
var/mode = text2num(href_list["mode"])
|
||||
switch(mode)
|
||||
if(0)
|
||||
enable()
|
||||
if(1)
|
||||
disable()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/proc/enable()
|
||||
if (chassis.active_thrusters == src)
|
||||
return
|
||||
chassis.active_thrusters = src
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>[src] enabled.</span>")
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/proc/disable()
|
||||
if(chassis.active_thrusters != src)
|
||||
return
|
||||
chassis.active_thrusters = null
|
||||
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>[src] disabled.</span>")
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/get_equip_info()
|
||||
return "[..()] \[<a href='?src=[REF(src)];mode=0'>Enable</a>|<a href='?src=[REF(src)];mode=1'>Disable</a>\]"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/proc/thrust(movement_dir)
|
||||
if(!chassis)
|
||||
return FALSE
|
||||
generate_effect(movement_dir)
|
||||
return TRUE //This parent should never exist in-game outside admeme use, so why not let it be a creative thruster?
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/proc/generate_effect(movement_dir)
|
||||
var/obj/effect/particle_effect/E = new effect_type(get_turf(chassis))
|
||||
E.dir = turn(movement_dir, 180)
|
||||
step(E, turn(movement_dir, 180))
|
||||
QDEL_IN(E, 5)
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/gas
|
||||
name = "RCS thruster package"
|
||||
desc = "A set of thrusters that allow for exosuit movement in zero-gravity environments, by expelling gas from the internal life support tank."
|
||||
effect_type = /obj/effect/particle_effect/smoke
|
||||
var/move_cost = 20 //moles per step
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/gas/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M)
|
||||
if(!M.internal_tank)
|
||||
to_chat(user, "<span class='warning'>[M] does not have an internal tank and cannot support this upgrade!</span>")
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/gas/thrust(movement_dir)
|
||||
if(!chassis || !chassis.internal_tank)
|
||||
return FALSE
|
||||
var/moles = chassis.internal_tank.air_contents.total_moles()
|
||||
if(moles < move_cost)
|
||||
chassis.internal_tank.air_contents.remove(moles)
|
||||
return FALSE
|
||||
chassis.internal_tank.air_contents.remove(move_cost)
|
||||
generate_effect(movement_dir)
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/ion //for mechs with built-in thrusters, should never really exist un-attached to a mech
|
||||
name = "Ion thruster package"
|
||||
desc = "A set of thrusters that allow for exosuit movement in zero-gravity environments."
|
||||
detachable = FALSE
|
||||
salvageable = FALSE
|
||||
effect_type = /obj/effect/particle_effect/ion_trails
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/thrusters/ion/thrust(movement_dir)
|
||||
if(!chassis)
|
||||
return FALSE
|
||||
if(chassis.use_power(chassis.step_energy_drain))
|
||||
generate_effect(movement_dir)
|
||||
return TRUE
|
||||
return FALSE
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user