Upload files

This commit is contained in:
SandPoot
2022-03-16 14:00:31 -03:00
parent a9bd8c3e94
commit a8f454bd72
125 changed files with 6439 additions and 6600 deletions
@@ -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" = (
+1 -1
View File
@@ -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"
},
+1 -1
View File
@@ -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" = (
+1 -1
View File
@@ -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,
+9
View File
@@ -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]"
+12
View File
@@ -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)
+1 -1
View File
@@ -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
+1
View File
@@ -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)
+31
View File
@@ -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
+5
View File
@@ -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)
-5
View File
@@ -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
-5
View File
@@ -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)
-4
View File
@@ -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)
+4 -4
View File
@@ -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
+2 -2
View File
@@ -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,
+13
View File
@@ -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 (!.)
+4 -4
View File
@@ -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
-3
View File
@@ -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)
+5 -14
View File
@@ -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)
+1 -14
View File
@@ -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()
+7 -5
View File
@@ -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))
-11
View File
@@ -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
-21
View File
@@ -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)
-68
View File
@@ -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)
-29
View File
@@ -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>&nbsp;"
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
-285
View File
@@ -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
-334
View File
@@ -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
..()
-360
View File
@@ -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]&deg;K|[tank_temperature - T0C]&deg;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()]&deg;K|[return_temperature() - T0C]&deg;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")
-271
View File
@@ -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
-16
View File
@@ -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
-188
View File
@@ -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>")
-3
View File
@@ -1,3 +0,0 @@
/obj/mecha/working
internal_damage_threshold = 60
-3
View File
@@ -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++
-3
View File
@@ -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]])"
-20
View File
@@ -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)
-5
View File
@@ -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)
+3 -2
View File
@@ -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()
-17
View File
@@ -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)
+1 -1
View File
@@ -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
@@ -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
+9 -9
View File
@@ -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)
+1 -1
View File
@@ -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)
+14 -14
View File
@@ -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
+2 -2
View File
@@ -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])
+4 -4
View File
@@ -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
+1 -1
View File
@@ -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
+2 -9
View File
@@ -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)
-33
View File
@@ -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()
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+5 -3
View File
@@ -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
)
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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
+4 -2
View File
@@ -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()
. = ..()
@@ -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]&deg;K|[tank_temperature - T0C]&deg;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()]&deg;K|[return_temperature() - T0C]&deg;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
@@ -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)
@@ -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. (&copy; 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)
@@ -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>&nbsp;"
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
@@ -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)
@@ -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))
@@ -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