12/21 modernizations from TG live (#103)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes
This commit is contained in:
Poojawa
2016-12-22 03:57:55 -06:00
committed by GitHub
parent f5e143a452
commit cf59ac1c3d
2215 changed files with 707445 additions and 87041 deletions
+8 -9
View File
@@ -1,38 +1,37 @@
/obj/mecha/combat
force = 30
internal_damage_threshold = 50
damage_absorption = list("brute"=0.7,"fire"=1,"bullet"=0.7,"laser"=0.85,"energy"=1,"bomb"=0.8)
armor = list(melee = 30, bullet = 30, laser = 15, energy = 20, bomb = 20, bio = 0, rad = 0, fire = 100, acid = 100)
/obj/mecha/combat/CheckParts(atom/holder)
..()
var/obj/item/weapon/stock_parts/capacitor/C = locate() in holder
var/obj/item/weapon/stock_parts/scanning_module/SM = locate() in holder
step_energy_drain = 20 - (5 * SM.rating) //10 is normal, so on lowest part its worse, on second its ok and on higher its real good up to 0 on best
var/DR = damage_absorption["energy"]
damage_absorption["energy"] = DR - (C.rating / 10) //Each level of capacitor protects the mech against emp by 10%
armor["energy"] += (C.rating * 10) //Each level of capacitor protects the mech against emp by 10%
qdel(C)
qdel(SM)
/obj/mecha/combat/moved_inside(mob/living/carbon/human/H)
if(..())
if(H.client)
H.client.mouse_pointer_icon = file("icons/mecha/mecha_mouse.dmi")
if(H.client && H.client.mouse_pointer_icon == initial(H.client.mouse_pointer_icon))
H.client.mouse_pointer_icon = 'icons/mecha/mecha_mouse.dmi'
return 1
else
return 0
/obj/mecha/combat/mmi_moved_inside(obj/item/device/mmi/mmi_as_oc,mob/user)
if(..())
if(occupant.client)
occupant.client.mouse_pointer_icon = file("icons/mecha/mecha_mouse.dmi")
if(occupant.client && occupant.client.mouse_pointer_icon == initial(occupant.client.mouse_pointer_icon))
occupant.client.mouse_pointer_icon = 'icons/mecha/mecha_mouse.dmi'
return 1
else
return 0
/obj/mecha/combat/go_out()
if(src.occupant && src.occupant.client)
src.occupant.client.mouse_pointer_icon = initial(src.occupant.client.mouse_pointer_icon)
if(occupant && occupant.client && occupant.client.mouse_pointer_icon == 'icons/mecha/mecha_mouse.dmi')
occupant.client.mouse_pointer_icon = initial(occupant.client.mouse_pointer_icon)
..()
+3 -2
View File
@@ -4,9 +4,10 @@
icon_state = "durand"
step_in = 4
dir_in = 1 //Facing North.
health = 400
obj_integrity = 400
max_integrity = 400
deflect_chance = 20
damage_absorption = list("brute"=0.5,"fire"=1.1,"bullet"=0.65,"laser"=0.85,"energy"=0.9,"bomb"=0.8)
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
+4 -4
View File
@@ -4,9 +4,9 @@
icon_state = "gygax"
step_in = 3
dir_in = 1 //Facing North.
health = 250
obj_integrity = 250
deflect_chance = 5
damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1)
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
@@ -18,9 +18,9 @@
desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications."
name = "\improper Dark Gygax"
icon_state = "darkgygax"
health = 300
obj_integrity = 300
deflect_chance = 15
damage_absorption = list("brute"=0.6,"fire"=0.8,"bullet"=0.6,"laser"=0.5,"energy"=0.65,"bomb"=0.8)
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)
+4 -3
View File
@@ -3,10 +3,11 @@
name = "\improper H.O.N.K"
icon_state = "honker"
step_in = 3
health = 140
obj_integrity = 140
max_integrity = 140
deflect_chance = 60
internal_damage_threshold = 60
damage_absorption = list("brute"=1.2,"fire"=1.5,"bullet"=1,"laser"=1,"energy"=1,"bomb"=1)
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)
@@ -27,7 +28,7 @@
*/
/obj/mecha/combat/honker/get_stats_part()
var/integrity = health/initial(health)*100
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"
+5 -4
View File
@@ -3,11 +3,12 @@
name = "\improper Marauder"
icon_state = "marauder"
step_in = 5
health = 500
obj_integrity = 500
max_integrity = 500
deflect_chance = 25
damage_absorption = list("brute"=0.5,"fire"=0.7,"bullet"=0.45,"laser"=0.6,"energy"=0.7,"bomb"=0.7)
armor = list(melee = 50, bullet = 55, laser = 40, energy = 30, bomb = 30, bio = 0, rad = 0, fire = 100, acid = 100)
max_temperature = 60000
burn_state = LAVA_PROOF
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
infra_luminosity = 3
operation_req_access = list(access_cent_specops)
wreckage = /obj/structure/mecha_wreckage/marauder
@@ -46,7 +47,7 @@
icon_state = "seraph"
operation_req_access = list(access_cent_specops)
step_in = 3
health = 550
obj_integrity = 550
wreckage = /obj/structure/mecha_wreckage/seraph
internal_damage_threshold = 20
force = 55
+3 -2
View File
@@ -5,9 +5,10 @@
step_in = 2
dir_in = 2 //Facing South.
step_energy_drain = 3
health = 200
obj_integrity = 200
max_integrity = 200
deflect_chance = 30
damage_absorption = list("brute"=0.7,"fire"=0.7,"bullet"=0.7,"laser"=0.7,"energy"=0.7,"bomb"=0.7)
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
+5 -3
View File
@@ -4,9 +4,10 @@
icon_state = "reticence"
step_in = 2
dir_in = 1 //Facing North.
health = 100
obj_integrity = 100
max_integrity = 100
deflect_chance = 3
damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1)
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)
@@ -17,6 +18,7 @@
color = "#87878715"
stepsound = null
turnsound = null
opacity = 0
/obj/mecha/combat/reticence/loaded/New()
..()
@@ -24,4 +26,4 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/rcd //HAHA IT MAKES WALLS GET IT
ME.attach(src)
return
return
+3 -1
View File
@@ -7,6 +7,8 @@
icon_state = "mecha_equip"
force = 5
origin_tech = "materials=2;engineering=2"
obj_integrity = 300
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
@@ -85,7 +87,7 @@
/obj/item/mecha_parts/mecha_equipment/proc/start_cooldown()
set_ready_state(0)
chassis.use_power(energy_drain)
addtimer(src, "set_ready_state", equip_cooldown, FALSE, 1)
addtimer(src, "set_ready_state", equip_cooldown, TIMER_NORMAL, 1)
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target)
if(!chassis)
@@ -75,7 +75,7 @@
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target)
if(target.buckled)
occupant_message("<span class='warning'>[target] will not fit into the sleeper because they are buckled to [target.buckled]!</span>")
occupant_message("<span class='warning'>[target] will not fit into the sleeper because [target.p_they()] [target.p_are()] 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>")
@@ -212,7 +212,7 @@
return 1
return
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/container_resist()
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/container_resist(mob/living/user)
go_out()
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/process()
@@ -343,7 +343,7 @@
mechsyringe.icon = initial(mechsyringe.icon)
mechsyringe.reagents.reaction(M, INJECT)
mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume)
M.take_organ_damage(2)
M.take_bodypart_damage(2)
add_logs(originaloccupant, M, "shot", "syringegun")
break
else if(mechsyringe.loc == trg)
@@ -13,11 +13,11 @@
/obj/item/mecha_parts/mecha_equipment/drill/action(atom/target)
if(!action_checks(target))
return
if(istype(target, /turf/open/space))
if(isspaceturf(target))
return
if(isobj(target))
var/obj/target_obj = target
if(target_obj.unacidable)
if(target_obj.resistance_flags & UNACIDABLE)
return
target.visible_message("<span class='warning'>[chassis] starts to drill [target].</span>", \
"<span class='userdanger'>[chassis] starts to drill [target]...</span>", \
@@ -83,13 +83,11 @@
add_logs(user, target, "attacked", "[name]", "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/bodypart/affecting = H.get_bodypart("chest")
affecting.take_damage(drill_damage)
H.update_damage_overlays(0)
H.apply_damage(drill_damage, BRUTE, "chest")
else if(target.stat == DEAD && target.butcher_results)
target.harvest(chassis) // Butcher the mob with our drill.
else
target.take_organ_damage(drill_damage)
target.take_bodypart_damage(drill_damage)
if(target)
target.Paralyse(10)
@@ -64,8 +64,8 @@
P.icon_state = "anom"
P.name = "wormhole"
var/turf/T = get_turf(target)
message_admins("[key_name_admin(chassis.occupant, chassis.occupant.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[chassis.occupant]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[chassis.occupant]'>FLW</A>) used a Wormhole Generator in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
log_game("[key_name(chassis.occupant)] used a Wormhole Generator in ([T.x],[T.y],[T.z])")
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Wormhole Generator in [ADMIN_COORDJMP(T)]",0,1)
log_game("[key_name(chassis.occupant)] used a Wormhole Generator in [COORD(T)]")
src = null
spawn(rand(150,300))
qdel(P)
@@ -154,8 +154,8 @@
var/damage_coeff = 0.8
selectable = 0
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react(mob/user as mob)
if(action_checks(user))
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react()
if(action_checks(src))
start_cooldown()
return 1
@@ -248,8 +248,8 @@
chassis.clearInternalDamage(int_dam_flag)
repaired = 1
break
if(health_boost<0 || chassis.health < initial(chassis.health))
chassis.health += min(health_boost, initial(chassis.health)-chassis.health)
if(health_boost<0 || chassis.obj_integrity < chassis.max_integrity)
chassis.obj_integrity += min(health_boost, chassis.max_integrity-chassis.obj_integrity)
repaired = 1
if(repaired)
if(!chassis.use_power(energy_drain))
+20 -17
View File
@@ -31,7 +31,7 @@
return
if(!cargo_holder)
return
if(istype(target,/obj))
if(isobj(target))
var/obj/O = target
if(!O.anchored)
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
@@ -50,10 +50,10 @@
else
occupant_message("<span class='warning'>[target] is firmly secured!</span>")
else if(istype(target,/mob/living))
else if(isliving(target))
var/mob/living/M = target
if(M.stat == DEAD) return
if(chassis.occupant.a_intent == "harm")
if(chassis.occupant.a_intent == INTENT_HARM)
M.take_overall_damage(dam_force)
if(!M)
return
@@ -78,9 +78,11 @@
energy_drain = 0
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(atom/target)
if(!action_checks(target)) return
if(!cargo_holder) return
if(istype(target,/obj))
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)
@@ -99,13 +101,13 @@
else
occupant_message("<span class='warning'>[target] is firmly secured!</span>")
else if(istype(target,/mob/living))
else if(isliving(target))
var/mob/living/M = target
if(M.stat == DEAD) return
if(chassis.occupant.a_intent == "harm")
if(chassis.occupant.a_intent == INTENT_HARM)
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>")
if(chassis.occupant.a_intent == "disarm")
if(chassis.occupant.a_intent == INTENT_DISARM)
target.visible_message("<span class='danger'>[chassis] rips [target]'s arms off.</span>", \
"<span class='userdanger'>[chassis] rips [target]'s arms off.</span>")
else
@@ -208,7 +210,7 @@
if(istype(target, /turf/open/space/transit))//>implying these are ever made -Sieve
return
if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock))
if(!isturf(target) && !istype(target, /obj/machinery/door/airlock))
target = get_turf(target)
if(!action_checks(target) || get_dist(chassis, target)>3)
return
@@ -216,14 +218,14 @@
switch(mode)
if(0)
if (istype(target, /turf/closed/wall))
if(iswallturf(target))
var/turf/closed/wall/W = target
occupant_message("Deconstructing [W]...")
if(do_after_cooldown(W))
chassis.spark_system.start()
W.ChangeTurf(/turf/open/floor/plating)
playsound(W, 'sound/items/Deconstruct.ogg', 50, 1)
else if (istype(target, /turf/open/floor))
else if(isfloorturf(target))
var/turf/open/floor/F = target
occupant_message("Deconstructing [F]...")
if(do_after_cooldown(target))
@@ -237,14 +239,14 @@
qdel(target)
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
if(1)
if(istype(target, /turf/open/space))
if(isspaceturf(target))
var/turf/open/space/S = target
occupant_message("Building Floor...")
if(do_after_cooldown(S))
S.ChangeTurf(/turf/open/floor/plating)
playsound(S, 'sound/items/Deconstruct.ogg', 50, 1)
chassis.spark_system.start()
else if(istype(target, /turf/open/floor))
else if(isfloorturf(target))
var/turf/open/floor/F = target
occupant_message("Building Wall...")
if(do_after_cooldown(F))
@@ -252,7 +254,7 @@
playsound(F, 'sound/items/Deconstruct.ogg', 50, 1)
chassis.spark_system.start()
if(2)
if(istype(target, /turf/open/floor))
if(isfloorturf(target))
occupant_message("Building Airlock...")
if(do_after_cooldown(target))
chassis.spark_system.start()
@@ -319,7 +321,8 @@
return ..()
/obj/item/mecha_parts/mecha_equipment/cable_layer/Destroy()
chassis.events.clearEvent("onMove",event)
if(chassis)
chassis.events.clearEvent("onMove",event)
return ..()
/obj/item/mecha_parts/mecha_equipment/cable_layer/action(var/obj/item/stack/cable_coil/target)
@@ -385,7 +388,7 @@
last_piece = null
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/dismantleFloor(var/turf/new_turf)
if(istype(new_turf, /turf/open/floor))
if(isfloorturf(new_turf))
var/turf/open/floor/T = new_turf
if(!istype(T, /turf/open/floor/plating))
if(!T.broken && !T.burnt)
+14 -9
View File
@@ -8,6 +8,7 @@
var/variance = 0
var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter
var/projectile_delay = 0
var/firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect //the visual effect appearing when the weapon is fired.
/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/mecha/combat/M)
if(..())
@@ -35,6 +36,9 @@
A.firer = chassis.occupant
A.original = target
A.current = curloc
if(!A.suppressed && firing_effect_type)
PoolOrNew(firing_effect_type, list(get_turf(src), chassis.dir))
var/spread = 0
if(variance)
@@ -56,6 +60,7 @@
//Base energy weapon type
/obj/item/mecha_parts/mecha_equipment/weapon/energy
name = "general energy weapon"
firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect/energy
/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount()
return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot)
@@ -63,7 +68,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/energy/start_cooldown()
set_ready_state(0)
chassis.use_power(energy_drain*get_shot_amount())
addtimer(src, "set_ready_state", equip_cooldown, FALSE, 1)
addtimer(src, "set_ready_state", equip_cooldown, TIMER_NORMAL, 1)
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
equip_cooldown = 8
@@ -106,15 +111,15 @@
fire_sound = 'sound/weapons/marauder.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma
equip_cooldown = 20
equip_cooldown = 10
name = "217-D Heavy Plasma Cutter"
desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demloishing solid obstacles."
icon_state = "mecha_plasmacutter"
item_state = "plasmacutter"
energy_drain = 60
energy_drain = 30
origin_tech = "materials=3;plasmatech=4;engineering=3"
projectile = /obj/item/projectile/plasma/adv/mech
fire_sound = 'sound/weapons/Laser.ogg'
fire_sound = 'sound/weapons/plasma_cutter.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/mecha/working/M)
if(..()) //combat mech
@@ -154,7 +159,7 @@
playsound(chassis, 'sound/items/AirHorn.ogg', 100, 1)
chassis.occupant_message("<font color='red' size='5'>HONK</font>")
for(var/mob/living/carbon/M in ohearers(6, chassis))
if(istype(M, /mob/living/carbon/human))
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
continue
@@ -171,8 +176,8 @@
log_message("Honked from [src.name]. HONK!")
var/turf/T = get_turf(src)
message_admins("[key_name_admin(chassis.occupant, chassis.occupant.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[chassis.occupant]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[chassis.occupant]'>FLW</A>) used a Mecha Honker in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Mecha Honker in ([T.x],[T.y],[T.z])")
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Mecha Honker in [ADMIN_COORDJMP(T)]",0,1)
log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Mecha Honker in [COORD(T)]")
return 1
@@ -306,8 +311,8 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack/proj_init(var/obj/item/missile/M)
M.primed = 1
var/turf/T = get_turf(src)
message_admins("[key_name(chassis.occupant, chassis.occupant.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[chassis.occupant]'>?</A>) fired a [src] in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])")
message_admins("[ADMIN_LOOKUP(chassis.occupant)] fired a [src] in [ADMIN_COORDJMP(T)]",0,1)
log_game("[key_name(chassis.occupant)] fired a [src] [COORD(T)]")
/obj/item/missile
icon = 'icons/obj/grenade.dmi'
+1 -2
View File
@@ -85,7 +85,6 @@
icon_keyboard = "rd_key"
circuit = /obj/item/weapon/circuitboard/computer/mech_bay_power_console
var/obj/machinery/mech_bay_recharge_port/recharge_port
light_color = LIGHT_COLOR_PINK
/obj/machinery/computer/mech_bay_power_console/attack_ai(mob/user)
return interact(user)
@@ -115,7 +114,7 @@
if(recharge_port && !qdeleted(recharge_port))
data["recharge_port"] = list("mech" = null)
if(recharge_port.recharging_mech && !qdeleted(recharge_port.recharging_mech))
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.health, "maxhealth" = initial(recharge_port.recharging_mech.health), "cell" = null)
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "max_integrity" = recharge_port.recharging_mech.max_integrity, "cell" = null)
if(recharge_port.recharging_mech.cell && !qdeleted(recharge_port.recharging_mech.cell))
data["recharge_port"]["mech"]["cell"] = list(
"critfail" = recharge_port.recharging_mech.cell.crit_fail,
+3 -3
View File
@@ -37,7 +37,7 @@
/obj/machinery/mecha_part_fabricator/New()
..()
files = new /datum/research(src) //Setup the research data holder.
materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM))
materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM))
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/mechfab(null)
B.apply_default_parts(src)
@@ -143,7 +143,7 @@
return resources
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
if(D.reagents.len) // No reagents storage - no reagent designs.
if(D.reagents_list.len) // No reagents storage - no reagent designs.
return 0
if(materials.has_materials(get_resources_w_coeff(D)))
return 1
@@ -415,7 +415,7 @@
updateUsrDialog()
return
/obj/machinery/mecha_part_fabricator/deconstruction()
/obj/machinery/mecha_part_fabricator/on_deconstruction()
materials.retrieve_all()
..()
+37 -32
View File
@@ -19,7 +19,7 @@
density = 1 //Dense. To raise the heat.
opacity = 1 ///opaque. Menacing.
anchored = 1 //no pulling around.
unacidable = 1 //and no deleting hoomans inside
resistance_flags = FIRE_PROOF | ACID_PROOF
layer = BELOW_MOB_LAYER//icon draw layer
infra_luminosity = 15 //byond implementation is bugged.
force = 5
@@ -29,10 +29,11 @@
var/step_in = 10 //make a step in step_in/10 sec.
var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South.
var/step_energy_drain = 10
var/health = 300 //health is health
var/melee_energy_drain = 15
obj_integrity = 300 //obj_integrity is health
max_integrity = 300
var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act.
//the values in this list show how much damage will pass through, not how much will be absorbed.
var/list/damage_absorption = list("brute"=0.8,"fire"=1.2,"bullet"=0.9,"laser"=1,"energy"=1,"bomb"=1)
armor = list(melee = 20, bullet = 10, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100)
var/list/facing_modifiers = list(FRONT_ARMOUR = 1.5, SIDE_ARMOUR = 1, BACK_ARMOUR = 0.5)
var/obj/item/weapon/stock_parts/cell/cell
var/state = 0
@@ -58,6 +59,7 @@
var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port = null
var/obj/item/device/radio/radio = null
var/list/trackers = list()
var/max_temperature = 25000
var/internal_damage_threshold = 50 //health percentage below which internal damage is possible
@@ -110,6 +112,9 @@
var/phase_state = "" //icon_state when phasing
var/strafe = FALSE //If we are strafing
var/nextsmash = 0
var/smashcooldown = 3 //deciseconds
var/occupant_sight_flags = 0 //sight flags to give to the occupant (e.g. mech mining scanner gives meson-like vision)
hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD)
@@ -138,13 +143,14 @@
diag_hud_set_mechcell()
diag_hud_set_mechstat()
return
/obj/mecha/Destroy()
go_out()
var/mob/living/silicon/ai/AI
for(var/mob/M in src) //Let's just be ultra sure
if(isAI(M))
M.gib() //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. Forever.
occupant = null
AI = M //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. They can be recovered with an AI card from the wreck.
else
M.forceMove(loc)
@@ -152,7 +158,7 @@
explosion(get_turf(loc), 0, 0, 1, 3)
if(wreckage)
var/obj/structure/mecha_wreckage/WR = new wreckage(loc)
var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI)
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
if(E.salvageable && prob(30))
WR.crowbar_salvage += E
@@ -176,6 +182,8 @@
qdel(cell)
if(internal_tank)
qdel(internal_tank)
if(AI)
AI.gib() //No wreck, no AI to recover
STOP_PROCESSING(SSobj, src)
poi_list.Remove(src)
equipment.Cut()
@@ -240,7 +248,7 @@
/obj/mecha/examine(mob/user)
..()
var/integrity = health/initial(health)*100
var/integrity = obj_integrity*100/max_integrity
switch(integrity)
if(85 to 100)
user << "It's fully intact."
@@ -256,8 +264,6 @@
user << "It's equipped with:"
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
user << "\icon[ME] [ME]"
return
//processing internal damage, temperature, air regulation, alert updates, lights power use.
/obj/mecha/process()
@@ -276,7 +282,7 @@
if(cabin_air && cabin_air.return_volume()>0)
cabin_air.temperature = min(6000+T0C, cabin_air.return_temperature()+rand(10,15))
if(cabin_air.return_temperature() > max_temperature/2)
take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1),"fire")
take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0)
if(internal_damage & MECHA_INT_TEMP_CONTROL)
internal_temp_regulation = 0
@@ -342,7 +348,7 @@
else
occupant.throw_alert("charge",/obj/screen/alert/emptycell)
var/integrity = health/initial(health)*100
var/integrity = obj_integrity/max_integrity*100
switch(integrity)
if(30 to 45)
occupant.throw_alert("mech damage", /obj/screen/alert/low_mech_integrity, 1)
@@ -547,10 +553,12 @@
if(..()) //mech was thrown
return
if(bumpsmash && occupant) //Need a pilot to push the PUNCH button.
obstacle.mech_melee_attack(src)
if(!obstacle || (obstacle && !obstacle.density))
step(src,dir)
if(istype(obstacle, /obj))
if(nextsmash < world.time)
obstacle.mech_melee_attack(src)
if(!obstacle || !obstacle.density)
step(src,dir)
nextsmash = world.time + smashcooldown
if(isobj(obstacle))
var/obj/O = obstacle
if(!O.anchored)
step(obstacle, dir)
@@ -568,7 +576,7 @@
/obj/mecha/proc/check_for_internal_damage(list/possible_int_damage,ignore_threshold=null)
if(!islist(possible_int_damage) || isemptylist(possible_int_damage)) return
if(prob(20))
if(ignore_threshold || health*100/initial(health) < internal_damage_threshold)
if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold)
for(var/T in possible_int_damage)
if(internal_damage & T)
possible_int_damage -= T
@@ -576,7 +584,7 @@
if(int_dam_flag)
setInternalDamage(int_dam_flag)
if(prob(5))
if(ignore_threshold || health*100/initial(health)<internal_damage_threshold)
if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold)
var/obj/item/mecha_parts/mecha_equipment/ME = safepick(equipment)
if(ME)
qdel(ME)
@@ -611,10 +619,10 @@
//Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot.
if(user.can_dominate_mechs)
examine(user) //Get diagnostic information!
var/obj/item/mecha_parts/mecha_tracking/B = locate(/obj/item/mecha_parts/mecha_tracking) in src
if(B) //Beacons give the AI more detailed mech information.
for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)
user << "<span class='danger'>Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:"
user << "[B.get_mecha_info()]"
break
//Nothing like a big, red link to make the player feel powerful!
user << "<a href='?src=\ref[user];ai_take_control=\ref[src]'><span class='userdanger'>ASSUME DIRECT CONTROL?</span></a><br>"
@@ -632,13 +640,10 @@
if(!AI || !isAI(occupant)) //Mech does not have an AI for a pilot
user << "<span class='warning'>No AI detected in the [name] onboard computer.</span>"
return
if(AI.mind.special_role) //Malf AIs cannot leave mechs. Except through death.
user << "<span class='boldannounce'>ACCESS DENIED.</span>"
return
AI.ai_restore_power()//So the AI initially has power.
AI.control_disabled = 1
AI.radio_enabled = 0
AI.loc = card
AI.forceMove(card)
card.AI = AI
occupant = null
AI.controlled_mech = null
@@ -675,7 +680,7 @@
//Hack and From Card interactions share some code, so leave that here for both to use.
/obj/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI, interaction)
AI.ai_restore_power()
AI.loc = src
AI.forceMove(src)
occupant = AI
icon_state = initial(icon_state)
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
@@ -686,9 +691,9 @@
AI.remote_control = src
AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES.
AI << "[interaction == AI_MECH_HACK ? "<span class='announce'>Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!</span>" \
AI << "[interaction == AI_MECH_HACK ? "<span class='announce'>Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!</span>" \
: "<span class='notice'>You have been uploaded to a mech's onboard computer."]"
AI << "<span class='boldnotice'>Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.</span>"
AI << "<span class='reallybig boldnotice'>Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.</span>"
GrantActions(AI)
@@ -804,7 +809,7 @@
visible_message("[user] starts to climb into [name].")
if(do_after(user, 40, target = src))
if(health <= 0)
if(obj_integrity <= 0)
user << "<span class='warning'>You cannot get in the [name], it has been destroyed!</span>"
else if(occupant)
user << "<span class='danger'>[occupant] was faster! Try better next time, loser.</span>"
@@ -845,7 +850,7 @@
else if(occupant)
user << "<span class='warning'>Occupant detected!</span>"
return 0
else if(dna_lock && (!mmi_as_oc.brainmob.dna || dna_lock!=mmi_as_oc.brainmob.dna.unique_enzymes))
else if(dna_lock && (!mmi_as_oc.brainmob.stored_dna || dna_lock!=mmi_as_oc.brainmob.stored_dna.unique_enzymes))
user << "<span class='warning'>Access denied. [name] is secured with a DNA lock.</span>"
return 0
@@ -888,7 +893,7 @@
else
return 0
/obj/mecha/container_resist()
/obj/mecha/container_resist(mob/living/user)
go_out()
@@ -905,8 +910,8 @@
if(ishuman(occupant))
mob_container = occupant
RemoveActions(occupant, human_occupant=1)
else if(istype(occupant, /mob/living/carbon/brain))
var/mob/living/carbon/brain/brain = occupant
else if(istype(occupant, /mob/living/brain))
var/mob/living/brain/brain = occupant
RemoveActions(brain)
mob_container = brain.container
else if(isAI(occupant) && forced) //This should only happen if there are multiple AIs in a round, and at least one is Malf.
+2 -2
View File
@@ -106,10 +106,10 @@
return
chassis.lights = !chassis.lights
if(chassis.lights)
chassis.set_light(chassis.lights_power)
chassis.AddLuminosity(chassis.lights_power)
button_icon_state = "mech_lights_on"
else
chassis.set_light(0)
chassis.AddLuminosity(-chassis.lights_power)
button_icon_state = "mech_lights_off"
chassis.occupant_message("Toggled lights [chassis.lights?"on":"off"].")
chassis.log_message("Toggled lights [chassis.lights?"on":"off"].")
+14 -8
View File
@@ -10,13 +10,16 @@
else
return 0
else if(istype(used_atom, /obj/item/weapon/wrench))
playsound(holder, 'sound/items/Ratchet.ogg', 50, 1)
var/obj/item/weapon/W = used_atom
playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/screwdriver))
playsound(holder, 'sound/items/Screwdriver.ogg', 50, 1)
var/obj/item/weapon/W = used_atom
playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/wirecutters))
playsound(holder, 'sound/items/Wirecutter.ogg', 50, 1)
var/obj/item/weapon/W = used_atom
playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = used_atom
@@ -27,7 +30,7 @@
return 0
else if(istype(used_atom, /obj/item/stack))
var/obj/item/stack/S = used_atom
if(S.amount < 5)
if(S.get_amount() < 5)
user << ("<span class='warning'>There's not enough material in this stack!</span>")
return 0
else
@@ -42,13 +45,16 @@
else
return 0
else if(istype(used_atom, /obj/item/weapon/wrench))
playsound(holder, 'sound/items/Ratchet.ogg', 50, 1)
var/obj/item/weapon/W = used_atom
playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/screwdriver))
playsound(holder, 'sound/items/Screwdriver.ogg', 50, 1)
var/obj/item/weapon/W = used_atom
playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/wirecutters))
playsound(holder, 'sound/items/Wirecutter.ogg', 50, 1)
var/obj/item/weapon/W = used_atom
playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = used_atom
@@ -59,7 +65,7 @@
return 0
else if(istype(used_atom, /obj/item/stack))
var/obj/item/stack/S = used_atom
if(S.amount < 5)
if(S.get_amount() < 5)
user << ("<span class='warning'>There's not enough material in this stack!</span>")
return 0
else
+13 -8
View File
@@ -16,7 +16,10 @@
var/dat = "<html><head><title>[src.name]</title><style>h3 {margin: 0px; padding: 0px;}</style></head><body>"
if(screen == 0)
dat += "<h3>Tracking beacons data</h3>"
for(var/obj/item/mecha_parts/mecha_tracking/TR in world)
var/list/trackerlist = list()
for(var/obj/mecha/MC in mechas_list)
trackerlist += MC.trackers
for(var/obj/item/mecha_parts/mecha_tracking/TR in trackerlist)
var/answer = TR.get_mecha_info()
if(answer)
dat += {"<hr>[answer]<br/>
@@ -63,7 +66,7 @@
desc = "Device used to transmit exosuit data."
icon = 'icons/obj/device.dmi'
icon_state = "motion2"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
origin_tech = "programming=2;magnets=2"
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
@@ -72,7 +75,7 @@
var/obj/mecha/M = src.loc
var/cell_charge = M.get_charge()
var/answer = {"<b>Name:</b> [M.name]<br>
<b>Integrity:</b> [M.health/initial(M.health)*100]%<br>
<b>Integrity:</b> [M.obj_integrity/M.max_integrity*100]%<br>
<b>Cell charge:</b> [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]<br>
<b>Airtank:</b> [M.return_pressure()]kPa<br>
<b>Pilot:</b> [M.occupant||"None"]<br>
@@ -86,11 +89,13 @@
/obj/item/mecha_parts/mecha_tracking/emp_act()
qdel(src)
return
/obj/item/mecha_parts/mecha_tracking/ex_act()
qdel(src)
return
/obj/item/mecha_parts/mecha_tracking/Destroy()
if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc
if(src in M.trackers)
M.trackers -= src
return ..()
/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
if(istype(src.loc, /obj/mecha))
@@ -104,7 +109,7 @@
qdel(src)
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
if(!src.in_mecha())
if(!istype(loc, /obj/mecha))
return 0
var/obj/mecha/M = src.loc
return M.get_log_html()
+149 -150
View File
@@ -8,171 +8,145 @@
return facing_modifiers[FRONT_ARMOUR]
return 1 //always return non-0
/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/proc/take_damage(amount, type="brute", booster_deflection_modifier = 1, booster_damage_modifier = 1)
/obj/mecha/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
. = ..()
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(dir2angle(attack_dir) - dir2angle(src))
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(amount)
var/damage = absorbDamage(amount,type)
damage = damage * booster_damage_modifier
health -= damage
update_health()
occupant_message("<span class='userdanger'>Taking damage!</span>")
log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1)
return 1
if(.)
. *= booster_damage_modifier
/obj/mecha/proc/take_directional_damage(amount, type="brute", adir = 0, booster_deflection_modifier = 1, booster_damage_modifier = 1)
var/facing_modifier = get_armour_facing(dir2angle(adir) - dir2angle(src))
booster_damage_modifier /= facing_modifier
booster_deflection_modifier *= facing_modifier
return take_damage(amount, type, booster_deflection_modifier, booster_damage_modifier)
/obj/mecha/proc/absorbDamage(damage,damage_type)
var/coeff = 1
if(damage_absorption[damage_type])
coeff = damage_absorption[damage_type]
return damage*coeff
/obj/mecha/proc/update_health()
if(health > 0)
spark_system.start()
else
qdel(src)
/obj/mecha/attack_hulk(mob/living/carbon/human/user)
..(user, 1)
take_directional_damage(15, "brute", get_dir(src, user))
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
user.visible_message("<span class='danger'>[user] hits [name]. The metal creaks and bends.</span>")
/obj/mecha/attack_hand(mob/living/user as mob)
/obj/mecha/attack_hand(mob/living/user)
user.changeNext_move(CLICK_CD_MELEE) // Ugh. Ideally we shouldn't be setting cooldowns outside of click code.
user.do_attack_animation(src)
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)
log_message("Attack by hand/paw. Attacker - [user].",1)
user.visible_message("<span class='danger'>[user] hits [name]. Nothing happens</span>","<span class='danger'>You hit [name] with no visible effect.</span>")
log_append_to_last("Armor saved.")
return
/obj/mecha/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/mecha/attack_alien(mob/living/user as mob)
/obj/mecha/attack_alien(mob/living/user)
log_message("Attack by alien. Attacker - [user].",1)
user.changeNext_move(CLICK_CD_MELEE) //Now stompy alien killer mechs are actually scary to aliens!
user.do_attack_animation(src)
take_directional_damage(15, "brute", get_dir(src, user))
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
playsound(loc, 'sound/weapons/slash.ogg', 50, 1, -1)
visible_message("<span class='danger'>The [user] slashes at [name]'s armor!</span>")
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 as mob)
/obj/mecha/attack_animal(mob/living/simple_animal/user)
log_message("Attack by simple animal. Attacker - [user].",1)
user.changeNext_move(CLICK_CD_MELEE)
if(user.melee_damage_upper == 0)
if(!user.melee_damage_upper && !user.obj_damage)
user.emote("[user.friendly] [src]")
return 0
else
user.do_attack_animation(src)
var/damage = rand(user.melee_damage_lower, user.melee_damage_upper)
take_directional_damage(damage, "brute", get_dir(src, user))
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
visible_message("<span class='danger'>[user] [user.attacktext] [src]!</span>")
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)
add_logs(user, src, "attacked")
return 1
/obj/mecha/hulk_damage()
return 15
/obj/mecha/attack_hulk(mob/living/carbon/human/user)
. = ..()
if(.)
log_message("Attack by hulk. Attacker - [user].",1)
add_logs(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/A as mob|obj) //wrapper
log_message("Hit by [A].",1)
var/deflection = 1
var/dam_coeff = 1
var/counter_tracking = 0
for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment)
if(B.projectile_react())
deflection = B.deflect_coeff
dam_coeff = B.damage_coeff
counter_tracking = 1
break
if(istype(A, /obj/item/mecha_parts/mecha_tracking))
if(!counter_tracking)
A.forceMove(src)
visible_message("The [A] fastens firmly to [src].")
return
else
deflection = 100 //will bounce off
if(istype(A, /obj))
var/obj/O = A
if(O.throwforce)
visible_message("<span class='danger'>[name] is hit by [A].</span>")
take_directional_damage(O.throwforce, "brute", get_dir(src, A), deflection, dam_coeff)
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
return
. = ..()
/obj/mecha/bullet_act(var/obj/item/projectile/Proj) //wrapper
/obj/mecha/bullet_act(obj/item/projectile/Proj) //wrapper
log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).",1)
var/deflection = 1
var/dam_coeff = 1
for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment)
if(B.projectile_react())
deflection = B.deflect_coeff
dam_coeff = B.damage_coeff
break
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
visible_message("<span class='danger'>[name] is hit by [Proj].</span>")
take_directional_damage(Proj.damage*dam_coeff,Proj.flag, turn(Proj.dir, 180), deflection, dam_coeff)
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT))
Proj.on_hit(src)
. = ..()
/obj/mecha/ex_act(severity, target)
log_message("Affected by explosion of severity: [severity].",1)
if(prob(deflect_chance))
severity++
log_append_to_last("Armor saved, changing severity to [severity].")
switch(severity)
if(1)
qdel(src)
if(2)
if (prob(30))
qdel(src)
else
take_damage(initial(health)/2)
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
if(3)
if (prob(5))
qdel(src)
else
take_damage(initial(health)/5)
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
return
. = ..()
/obj/mecha/blob_act(obj/effect/blob/B)
take_directional_damage(30, "brute", get_dir(src, B))
/obj/mecha/contents_explosion(severity, target)
severity++
for(var/X in equipment)
var/obj/item/mecha_parts/mecha_equipment/ME = X
ME.ex_act(severity,target)
for(var/Y in trackers)
var/obj/item/mecha_parts/mecha_tracking/MT = Y
MT.ex_act(severity, target)
if(occupant)
occupant.ex_act(severity,target)
/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(get_charge())
use_power((cell.charge/3)/(severity*2))
take_damage(30 / severity,"energy")
take_damage(30 / severity, BURN, "energy", 1)
log_message("EMP detected",1)
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
return
/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature>max_temperature)
log_message("Exposed to dangerous temperature.",1)
take_damage(5,"fire")
check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL))
return
take_damage(5, BURN, 0, 1)
/obj/mecha/attackby(obj/item/W as obj, mob/user as mob, params)
@@ -234,7 +208,7 @@
else
user << "<span class='warning'>You need two lengths of cable to fix this mech!</span>"
return
else if(istype(W, /obj/item/weapon/screwdriver) && user.a_intent != "harm")
else if(istype(W, /obj/item/weapon/screwdriver) && user.a_intent != INTENT_HARM)
if(internal_damage & MECHA_INT_TEMP_CONTROL)
clearInternalDamage(MECHA_INT_TEMP_CONTROL)
user << "<span class='notice'>You repair the damaged temperature controller.</span>"
@@ -265,17 +239,17 @@
user << "<span class='notice'>There's already a powercell installed.</span>"
return
else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm")
else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM)
user.changeNext_move(CLICK_CD_MELEE)
var/obj/item/weapon/weldingtool/WT = W
if(health<initial(health))
if(obj_integrity<max_integrity)
if (WT.remove_fuel(0,user))
if (internal_damage & MECHA_INT_TANK_BREACH)
clearInternalDamage(MECHA_INT_TANK_BREACH)
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>")
health += min(10, initial(health)-health)
obj_integrity += min(10, max_integrity-obj_integrity)
else
user << "<span class='warning'>The welder must be on for this task!</span>"
return 1
@@ -288,6 +262,7 @@
user << "<span class='warning'>\the [W] is stuck to your hand, you cannot put it in \the [src]!</span>"
return
W.forceMove(src)
trackers += W
user.visible_message("[user] attaches [W] to [src].", "<span class='notice'>You attach [W] to [src].</span>")
return
else
@@ -295,21 +270,7 @@
/obj/mecha/attacked_by(obj/item/I, mob/living/user)
log_message("Attacked by [I]. Attacker - [user]")
var/deflection = deflect_chance
var/dam_coeff = 1
for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment)
if(B.attack_react(user))
deflection *= B.deflect_coeff
dam_coeff *= B.damage_coeff
break
if(prob(deflection))
user << "<span class='danger'>\The [I.name] bounces off [name]'s armor.</span>"
log_append_to_last("Armor saved.")
else
user.visible_message("<span class='danger'>[user] hits [src] with [I].</span>", "<span class='danger'>You hit [src] with [I].</span>")
take_directional_damage(round(I.force*dam_coeff),I.damtype, get_dir(src, user))
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
..()
/obj/mecha/proc/mech_toxin_damage(mob/living/target)
playsound(src, 'sound/effects/spray2.ogg', 50, 1)
@@ -320,17 +281,55 @@
target.reagents.add_reagent("toxin", force/2.5)
/atom/proc/mech_melee_attack(obj/mecha/M)
return
/obj/mecha/mech_melee_attack(obj/mecha/M)
if(M.damtype =="brute")
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
else if(M.damtype == "fire")
playsound(src, 'sound/items/Welder.ogg', 50, 1)
else
return
visible_message("<span class='danger'>[M.name] has hit [src].</span>")
take_directional_damage(M.force, damtype, get_dir(src, M))
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
return
if(!has_charge(melee_energy_drain))
return 0
use_power(melee_energy_drain)
if(M.damtype == BRUTE || M.damtype == BURN)
add_logs(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()
if(occupant)
var/mob/living/L = occupant
go_out(TRUE)
if(L)
L.narsie_act()
/obj/mecha/ratvar_act()
if(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, end_pixel_y)
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
..()
+2 -2
View File
@@ -6,7 +6,7 @@
name = "mecha part"
icon = 'icons/mecha/mech_construct.dmi'
icon_state = "blank"
w_class = 6
w_class = WEIGHT_CLASS_GIGANTIC
flags = CONDUCT
origin_tech = "programming=2;materials=2;engineering=2"
@@ -313,7 +313,7 @@
item_state = "electronic"
flags = CONDUCT
force = 5
w_class = 2
w_class = WEIGHT_CLASS_SMALL
throwforce = 0
throw_speed = 3
throw_range = 7
+1 -1
View File
@@ -69,7 +69,7 @@
/obj/mecha/proc/get_stats_part()
var/integrity = health/initial(health)*100
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"
+36
View File
@@ -14,6 +14,23 @@
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/New(loc, mob/living/silicon/ai/AI_pilot)
..()
if(AI_pilot) //Type-checking for this is already done in mecha/Destroy()
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(image('icons/obj/projectiles.dmi', icon_state = "green_laser")) //Overlay for the recovery beacon
AI.controlled_mech = null
AI.remote_control = null
/obj/structure/mecha_wreckage/examine(mob/user)
..()
if(AI)
user << "<span class='notice'>The AI recovery beacon is active.</span>"
/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/weldingtool))
@@ -58,6 +75,25 @@
else
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/device/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
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
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)
user << "<span class='boldnotice'>Backup files recovered</span>: [AI.name] ([rand(1000,9999)].exe) salvaged from [name] and stored within local memory."
else
return ..()
+1 -2
View File
@@ -1,7 +1,6 @@
/obj/mecha/medical/New()
..()
new /obj/item/mecha_parts/mecha_tracking(src)
return
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
/obj/mecha/medical/mechturn(direction)
+2 -1
View File
@@ -4,7 +4,8 @@
icon_state = "odysseus"
step_in = 3
max_temperature = 15000
health = 120
obj_integrity = 120
max_integrity = 120
wreckage = /obj/structure/mecha_wreckage/odysseus
internal_damage_threshold = 35
deflect_chance = 15
+23 -13
View File
@@ -2,12 +2,15 @@
desc = "Autonomous Power Loader Unit. This newer model is refitted with powerful armour against the dangers of the EVA mining process."
name = "\improper APLU \"Ripley\""
icon_state = "ripley"
step_in = 5
step_in = 4 //Move speed, lower is faster.
var/hi_pres_step_in = 4 //step_in while in high pressure.
var/lo_pres_step_in = 2 //step_in while in low/zero pressure.
max_temperature = 20000
health = 200
obj_integrity = 200
max_integrity = 200
lights_power = 7
deflect_chance = 15
damage_absorption = list("brute"=0.6,"fire"=1,"bullet"=0.8,"laser"=0.9,"energy"=1,"bomb"=0.6)
armor = list(melee = 40, bullet = 20, 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
@@ -26,9 +29,8 @@
/obj/mecha/working/ripley/Destroy()
for(var/i=1, i <= hides, i++)
new /obj/item/stack/sheet/animalhide/goliath_hide(loc) //If a goliath-plated ripley gets killed, all the plates drop
damage_absorption["brute"] = initial(damage_absorption["brute"])
for(var/atom/movable/A in cargo)
A.loc = loc
A.forceMove(loc)
step_rand(A)
cargo.Cut()
return ..()
@@ -60,10 +62,11 @@
name = "\improper APLU \"Firefighter\""
icon_state = "firefighter"
max_temperature = 65000
health = 250
burn_state = LAVA_PROOF
obj_integrity = 250
max_integrity = 250
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
lights_power = 7
damage_absorption = list("brute"=0.6,"fire"=0.5,"bullet"=0.7,"laser"=0.7,"energy"=1,"bomb"=0.4)
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
@@ -72,7 +75,7 @@
desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE"
name = "\improper DEATH-RIPLEY"
icon_state = "deathripley"
step_in = 3
hi_pres_step_in = 3
opacity=0
lights_power = 7
wreckage = /obj/structure/mecha_wreckage/ripley/deathripley
@@ -109,7 +112,7 @@
//Attach hydraulic clamp
var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp
HC.attach(src)
for(var/obj/item/mecha_parts/mecha_tracking/B in src.contents)//Deletes the beacon so it can't be found easily
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 /obj/item/mecha_parts/mecha_equipment/mining_scanner
@@ -126,12 +129,19 @@
var/obj/O = locate(href_list["drop_from_cargo"])
if(O && O in src.cargo)
src.occupant_message("<span class='notice'>You unload [O].</span>")
O.loc = loc
O.forceMove(loc)
src.cargo -= O
src.log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]")
return
/obj/mecha/working/ripley/contents_explosion(severity, target)
for(var/X in cargo)
var/obj/O = X
if(prob(30/severity))
cargo -= O
O.forceMove(loc)
. = ..()
/obj/mecha/working/ripley/get_stats_part()
var/output = ..()
@@ -150,11 +160,11 @@
var/pressure = environment.return_pressure()
if(pressure < 40)
step_in = 3
step_in = lo_pres_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 = 5
step_in = hi_pres_step_in
for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment)
drill.equip_cooldown = initial(drill.equip_cooldown)
+1 -2
View File
@@ -3,5 +3,4 @@
/obj/mecha/working/New()
..()
new /obj/item/mecha_parts/mecha_tracking(src)
return
trackers += new /obj/item/mecha_parts/mecha_tracking(src)