- Further work on mechs.

- Turrets should now target mechs (there's a possibility of nasty errors there).
- Global iterator datum (just for lulz. Check readme inside global_iterator.dm and mecha.dm for examples).

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@684 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
panurgomatic
2010-12-21 11:07:22 +00:00
parent 3938b34f66
commit 953bc5189e
11 changed files with 390 additions and 93 deletions

View File

@@ -8,14 +8,26 @@
nitrogen = 0 nitrogen = 0
temperature = TCMB temperature = TCMB
var/contains = null var/contains = null
var/max_amount = 1
var/min_amount = 0
/turf/simulated/wall/asteroid/iron /turf/simulated/wall/asteroid/iron
icon_state = "asteroid_i" icon_state = "asteroid_i"
contains = /obj/item/weapon/sheet/metal contains = /obj/item/weapon/sheet/metal
max_amount = 3
min_amount = 1
/turf/simulated/wall/asteroid/silicon /turf/simulated/wall/asteroid/silicon
icon_state = "asteroid_i" icon_state = "asteroid_i"
contains = /obj/item/weapon/sheet/glass contains = /obj/item/weapon/sheet/glass
max_amount = 3
min_amount = 1
/turf/simulated/wall/asteroid/facehugger
icon_state = "asteroid_i"
contains = /obj/alien/facehugger
max_amount = 1
min_amount = 0
/* /*
/turf/simulated/wall/asteroid/frozen_gas /turf/simulated/wall/asteroid/frozen_gas
@@ -55,13 +67,13 @@
/turf/simulated/wall/asteroid/dismantle_wall(devastated=0) /turf/simulated/wall/asteroid/dismantle_wall(devastated=0)
if(contains && ispath(contains)) if(contains && ispath(contains))
var/iterations = 0
if(!devastated) if(!devastated)
new contains(src) iterations = max_amount
new contains(src)
new contains(src)
else else
iterations = min_amount
for(var/i=0 to iterations)
new contains(src) new contains(src)
ReplaceWithSpace() ReplaceWithSpace()
@@ -70,4 +82,4 @@
/turf/simulated/wall/asteroid/relativewall()//TODO. /turf/simulated/wall/asteroid/relativewall()//TODO.
return return

View File

@@ -16,6 +16,11 @@
if (!istype(O, /mob/living/silicon)) if (!istype(O, /mob/living/silicon))
if (!(O in turretTargets)) if (!(O in turretTargets))
turretTargets += O turretTargets += O
else if (istype(O, /obj/mecha))
var/obj/mecha/M = O
if (M.occupant)
if (!(M in turretTargets))
turretTargets += M
return 1 return 1
/area/turret_protected/Exited(O) /area/turret_protected/Exited(O)
@@ -26,8 +31,13 @@
turretTargets -= O turretTargets -= O
//else //else
//O << "You aren't in our target list!" //O << "You aren't in our target list!"
if (turretTargets.len == 0)
popDownTurrets() else if (istype(O, /obj/mecha))
if (O in turretTargets)
turretTargets -= O
if (turretTargets.len == 0)
popDownTurrets()
return 1 return 1
@@ -113,14 +123,26 @@
if (isDown()) if (isDown())
popUp() popUp()
else else
var/mob/target = pick(tarea.turretTargets) var/mob/target
src.dir = get_dir(src, target) do
if (src.enabled) target = pick(tarea.turretTargets)
if (istype(target, /mob/living)) src.dir = get_dir(src, target)
if (target.stat!=2) if (src.enabled)
src.shootAt(target) if (istype(target, /mob/living))
else if (target.stat!=2)
tarea.subjectDied(target) src.shootAt(target)
else
tarea.subjectDied(target)
target = null
else if (istype(target, /obj/mecha))
var/obj/mecha/mecha = target
if(!mecha.occupant)
if (mecha in tarea.turretTargets)
tarea.turretTargets -= mecha
target = null
else
src.shootAt(target)
while(!target && tarea.turretTargets.len>0)
else else
if (src.wasvalid) if (src.wasvalid)

View File

@@ -11,6 +11,7 @@
var/melee_cooldown = 10 var/melee_cooldown = 10
var/melee_can_hit = 1 var/melee_can_hit = 1
var/list/destroyable_obj = list(/obj/mecha, /obj/window, /obj/grille, /turf/simulated/wall) var/list/destroyable_obj = list(/obj/mecha, /obj/window, /obj/grille, /turf/simulated/wall)
internal_damage_treshhold = 30
/* /*
/obj/mecha/combat/verb/switch_weapon() /obj/mecha/combat/verb/switch_weapon()
@@ -103,7 +104,7 @@
target:attackby(src,src.occupant) target:attackby(src,src.occupant)
else if(prob(2)) else if(prob(2))
target:dismantle_wall(1) target:dismantle_wall(1)
src.occupant << text("\blue You smash through the wall.") src.occupant_message("\blue You smash through the wall.")
src.visible_message("<b>[src.name] smashes through the wall</b>") src.visible_message("<b>[src.name] smashes through the wall</b>")
playsound(src, 'smash.ogg', 50, 1) playsound(src, 'smash.ogg', 50, 1)
melee_can_hit = 0 melee_can_hit = 0
@@ -173,6 +174,8 @@
src.occupant = usr src.occupant = usr
usr.loc = src usr.loc = src
src.add_fingerprint(usr) src.add_fingerprint(usr)
src.Entered(usr)
src.Move(src.loc)
if(usr.client) if(usr.client)
usr.client.mouse_pointer_icon = file("icons/misc/mecha_mouse.dmi") usr.client.mouse_pointer_icon = file("icons/misc/mecha_mouse.dmi")
return return
@@ -184,8 +187,10 @@
return return
/* //the garbage collector should handle this
/obj/mecha/combat/Del() /obj/mecha/combat/Del()
for(var/weapon in weapons) for(var/weapon in weapons)
del weapon del weapon
..() ..()
return return
*/

View File

@@ -30,7 +30,7 @@
if(connected_port) if(connected_port)
src.occupant << "Unable to move while connected to the air system port" src.occupant << "Unable to move while connected to the air system port"
return 0 return 0
if(!thrusters && src.inertia_dir) if(!thrusters && src.pr_inertial_movement.active())
return 0 return 0
if(state || !cell || cell.charge<=0) if(state || !cell || cell.charge<=0)
return 0 return 0
@@ -39,8 +39,7 @@
if(step(src,direction)) if(step(src,direction))
if(istype(src.loc, /turf/space)) if(istype(src.loc, /turf/space))
if(!src.check_for_support()) if(!src.check_for_support())
src.inertia_dir = direction src.pr_inertial_movement.start(list(src,direction))
src.inertial_movement()
if(thrusters) if(thrusters)
tmp_step_energy_drain = step_energy_drain*2 tmp_step_energy_drain = step_energy_drain*2

View File

@@ -58,6 +58,7 @@
icon = 'grenade.dmi' icon = 'grenade.dmi'
icon_state = "flashbang" icon_state = "flashbang"
var/primed = null var/primed = null
throwforce = 15
throw_impact(atom/hit_atom) throw_impact(atom/hit_atom)
if(primed) if(primed)

View File

@@ -0,0 +1,131 @@
/*
README:
The global_iterator datum is supposed to provide a simple and robust way to
create some constantly "looping" processes with ability to stop and restart them at will.
Generally, the only thing you want to play with (meaning, redefine) is the process() proc.
It must contain all the things you want done.
Control functions:
new - used to create datum. First argument (optional) - var list(to use in process() proc),
second (optional) - autostart control.
If autostart == TRUE, the loop will be started immediately after datum creation.
start(list/arguments) - starts the loop. Takes arguments(optional) as a list, which is then used
by process() proc. Returns null if datum already active, 1 if loop started succesfully and 0 if there's
an error in supplied arguments (not list or empty list).
stop() - stops the loop. Returns null if datum is already inactive and 1 on success.
set_delay(new_delay) - sets the delay between iterations. Pretty selfexplanatory.
Returns 0 on error(new_delay is not numerical), 1 otherwise.
set_process_args(list/arguments) - passes the supplied arguments to the process() proc.
active() - Returns 1 if datum is active, 0 otherwise.
Misc functions:
get_last_exec_time() - Returns the time of last iteration.
get_last_exec_time_as_text() - Returns the time of last iteration as text
Control vars:
delay - delay between iterations
check_for_null - if equals TRUE, on each iteration the supplied arguments will be checked for nulls.
If some varible equals null, the loop is stopped.
Usefull, if some var unexpectedly becomes null - due to object deletion, for example.
Of course, you can check the variables inside process() proc to prevent runtime errors.
Data storage vars:
result - stores the value returned by process() proc
*/
/datum/global_iterator
var/control_switch = 0
var/delay = 10
var/list/arg_list = new
var/last_exec = null
var/check_for_null = 1
var/forbid_garbage = 0
var/result
New(list/arguments=null,autostart=1)
if(forbid_garbage) //prevents garbage collection with tag != null
tag = "\ref[src]"
set_process_args(arguments)
if(autostart)
start()
return
proc/main()
while(src && control_switch)
last_exec = world.timeofday
if(check_for_null && has_null_args())
src.stop()
break
result = src.process(arglist(arg_list))
sleep(delay)
return
proc/start(list/arguments=null)
if(src.active())
return
if(arguments)
if(!set_process_args(arguments))
return 0
control_switch = 1
spawn(-1)
src.main()
return 1
proc/stop()
if(!src.active())
return
control_switch = 0
return 1
proc/process()
return
proc/active()
return control_switch
proc/has_null_args()
if(null in arg_list) //Hope no "" or 0 errors here.
return 1
/*
for(var/V in arg_list)
if(isnull(V))
return 1
*/
return 0
proc/set_delay(new_delay)
if(isnum(new_delay))
delay = new_delay
return 1
else
return 0
proc/get_last_exec_time()
return (last_exec||0)
proc/get_last_exec_time_as_text()
return (time2text(last_exec)||"Wasn't executed yet")
proc/set_process_args(list/arguments)
if(arguments && istype(arguments, /list) && arguments.len)
arg_list = arguments
return 1
else
// world << "\red Invalid arguments supplied for [src.type], ref = \ref[src]"
return 0

View File

@@ -1,3 +1,9 @@
#define MECHA_INT_FIRE 1
#define MECHA_INT_TEMP_CONTROL 2
#define MECHA_INT_SHORT_CIRCUIT 4
#define MECHA_INT_TANK_BREACH 8
/obj/mecha /obj/mecha
name = "Mecha" name = "Mecha"
desc = "Exosuit" desc = "Exosuit"
@@ -5,7 +11,7 @@
density = 1 //Dense. To raise the heat. density = 1 //Dense. To raise the heat.
opacity = 1 ///opaque. Menacing. opacity = 1 ///opaque. Menacing.
anchored = 1 //no pulling around. anchored = 1 //no pulling around.
layer = MOB_LAYER layer = MOB_LAYER //icon draw layer
var/can_move = 1 var/can_move = 1
var/mob/living/carbon/human/occupant = null var/mob/living/carbon/human/occupant = null
var/step_in = 10 //make a step in step_in/10 sec. var/step_in = 10 //make a step in step_in/10 sec.
@@ -14,7 +20,6 @@
var/deflect_chance = 2 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. var/deflect_chance = 2 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act.
var/obj/item/weapon/cell/cell = new var/obj/item/weapon/cell/cell = new
var/state = 0 var/state = 0
var/update_stats = null //used to auto-update stats window
var/datum/effects/system/spark_spread/spark_system = new var/datum/effects/system/spark_spread/spark_system = new
var/lights = 0 var/lights = 0
@@ -27,12 +32,20 @@
var/filled = 0.5 var/filled = 0.5
var/gas_tank_volume = 500 var/gas_tank_volume = 500
var/maximum_pressure = 30*ONE_ATMOSPHERE var/maximum_pressure = 30*ONE_ATMOSPHERE
var/operating_access = null
var/max_temperature = 2500 var/max_temperature = 2500
var/internal_damage_treshhold = 50 //health percentage below which internal damage is possible
var/internal_damage = 0 //contains bitflags
var/list/operation_req_access = list(access_engine)//required access level for mecha operation var/list/operation_req_access = list(access_engine)//required access level for mecha operation
var/list/internals_req_access = list(access_engine)//required access level to open cell compartment var/list/internals_req_access = list(access_engine)//required access level to open cell compartment
var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature
var/datum/global_iterator/pr_update_stats //used to auto-update stats window
var/datum/global_iterator/pr_inertial_movement //controls intertial movement in spesss
var/datum/global_iterator/pr_location_temp_check //processes location temperature damage
var/datum/global_iterator/pr_internal_damage //processes internal damage
/obj/mecha/New() /obj/mecha/New()
..() ..()
src.air_contents.volume = gas_tank_volume //liters src.air_contents.volume = gas_tank_volume //liters
@@ -42,12 +55,20 @@
src.spark_system.attach(src) src.spark_system.attach(src)
src.cell.charge = 15000 src.cell.charge = 15000
src.cell.maxcharge = 15000 src.cell.maxcharge = 15000
preserve_temp()
check_location_temp() //misc global_iteration datums
pr_int_temp_processor = new /datum/global_iterator/mecha_preserve_temp(list(src))
pr_update_stats = new /datum/global_iterator/mecha_view_stats(list(src),0)
pr_inertial_movement = new /datum/global_iterator/mecha_intertial_movement(null,0)
pr_location_temp_check = new /datum/global_iterator/mecha_location_temp_check(list(src))
pr_internal_damage = new /datum/global_iterator/mecha_internal_damage(list(src),0)
src.verbs -= /obj/mecha/verb/disconnect_from_port src.verbs -= /obj/mecha/verb/disconnect_from_port
src.verbs -= /atom/movable/verb/pull src.verbs -= /atom/movable/verb/pull
return return
/obj/mecha/Del()
src.go_out()
..()
/client/Click(object,location,control,params) /client/Click(object,location,control,params)
..() ..()
@@ -86,9 +107,9 @@
if(!can_move) if(!can_move)
return 0 return 0
if(connected_port) if(connected_port)
src.occupant << "Unable to move while connected to the air system port" src.occupant_message("Unable to move while connected to the air system port")
return 0 return 0
if(src.inertia_dir) if(src.pr_inertial_movement.active())
return 0 return 0
if(state || !cell || cell.charge<=0) if(state || !cell || cell.charge<=0)
return 0 return 0
@@ -98,19 +119,19 @@
cell.use(src.step_energy_drain) cell.use(src.step_energy_drain)
if(istype(src.loc, /turf/space)) if(istype(src.loc, /turf/space))
if(!src.check_for_support()) if(!src.check_for_support())
src.inertia_dir = direction src.pr_inertial_movement.start(list(src,direction))
src.inertial_movement()
return 1 return 1
return 0 return 0
/*
/obj/mecha/proc/inertial_movement() /obj/mecha/proc/inertial_movement(direction)
// set background = 1 src.inertia_dir = direction
spawn while(src && src.inertia_dir) spawn while(src && src.inertia_dir)
if(!step(src, src.inertia_dir)||check_for_support()) if(!step(src, src.inertia_dir)||check_for_support())
src.inertia_dir = null src.inertia_dir = null
sleep(7) sleep(7)
return
*/
/* /*
if(check_for_support()) if(check_for_support())
src.inertia_dir = null src.inertia_dir = null
@@ -149,10 +170,23 @@
if("brute") if("brute")
src.health -= amount src.health -= amount
if("fire") if("fire")
src.health -= amount*1.5 src.health -= amount*1.2
src.update_health() src.update_health()
return return
/obj/mecha/proc/check_for_internal_damage(var/list/possible_int_damage)//TODO
if(!src) return
if(prob(40) && (src.health*100/initial(src.health))<src.internal_damage_treshhold)
for(var/T in possible_int_damage)
if(internal_damage & T)
possible_int_damage -= T
if(possible_int_damage.len)
var/int_dam_flag = pick(possible_int_damage)
if(int_dam_flag)
internal_damage |= int_dam_flag
pr_internal_damage.start()
return
/obj/mecha/proc/update_health() /obj/mecha/proc/update_health()
if(src.health > 0) if(src.health > 0)
@@ -164,15 +198,11 @@
/obj/mecha/attack_hand(mob/user as mob) /obj/mecha/attack_hand(mob/user as mob)
if (user.mutations & 8 && !prob(src.deflect_chance)) if (user.mutations & 8 && !prob(src.deflect_chance))
src.take_damage(15) src.take_damage(15)
user << "\red You hit [src.name] with all your might. The metal creaks and bends." src.visible_message("<font color='red'><b>[user] hits [src.name], doing some damage.</b></font>")
for (var/mob/V in viewers(src)) user << "<font color='red'><b>You hit [src.name] with all your might. The metal creaks and bends.</b></font>"
if(V.client && V != user && !(V.blinded))
V.show_message("[user] hits [src.name], doing some damage.", 1)
else else
user << "\red You hit [src.name] with no visible effect." src.visible_message("<font color='red'><b>[user] hits [src.name]. Nothing happens</b></font>")
for (var/mob/V in viewers(src)) user << "<font color='red'><b>You hit [src.name] with no visible effect.</b></font>"
if(V.client && V != user && !(V.blinded))
V.show_message("[user] hits [src.name]. Nothing happens", 1)
return return
/obj/mecha/attack_paw(mob/user as mob) /obj/mecha/attack_paw(mob/user as mob)
@@ -190,8 +220,7 @@
/obj/mecha/hitby(A as mob|obj) /obj/mecha/hitby(A as mob|obj)
if(prob(src.deflect_chance) || istype(A, /mob)) if(prob(src.deflect_chance) || istype(A, /mob))
if(src.occupant && src.occupant.client) src.occupant_message("\blue The [A] bounces off the armor.")
src.occupant << "\blue The [A] bounces off the armor."
for (var/mob/V in viewers(src)) for (var/mob/V in viewers(src))
if(V.client && !(V.blinded)) if(V.client && !(V.blinded))
V.show_message("The [A] bounces off the [src.name] armor", 1) V.show_message("The [A] bounces off the [src.name] armor", 1)
@@ -210,8 +239,7 @@
/obj/mecha/bullet_act(flag) /obj/mecha/bullet_act(flag)
if(prob(src.deflect_chance)) if(prob(src.deflect_chance))
if(src.occupant && src.occupant.client) src.occupant_message("\blue The armor deflects the incoming projectile.")
src.occupant << "\blue The armor deflects the incoming projectile."
for (var/mob/V in viewers(src)) for (var/mob/V in viewers(src))
if(V.client && !(V.blinded)) if(V.client && !(V.blinded))
V.show_message("The [src.name] armor deflects the projectile", 1) V.show_message("The [src.name] armor deflects the projectile", 1)
@@ -222,19 +250,24 @@
damage = 40 damage = 40
if(PROJECTILE_LASER) if(PROJECTILE_LASER)
damage = 20 damage = 20
if(PROJECTILE_TASER)
damage = 5
src.cell.use(500)
else else
damage = 10 damage = 10
src.take_damage(damage) src.take_damage(damage)
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH))
return return
/obj/mecha/proc/destroy() /obj/mecha/proc/destroy()
if(src.occupant) if(src.occupant)
var/mob/M = src.occupant
src.go_out() src.go_out()
if(prob(20)) if(prob(20))
src.occupant.bruteloss += rand(10,20) M.bruteloss += rand(10,20)
src.occupant.updatehealth() M.updatehealth()
else else
src.occupant.gib() M.gib()
spawn() spawn()
explosion(src.loc, 0, 0, 1, 3) explosion(src.loc, 0, 0, 1, 3)
del(src) del(src)
@@ -246,19 +279,19 @@
switch(severity) switch(severity)
if(1.0) if(1.0)
destroy(src) destroy(src)
return
if(2.0) if(2.0)
if (prob(30)) if (prob(30))
destroy(src) destroy(src)
else else
src.take_damage(src.health/2) src.take_damage(initial(src.health)/2)
return src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH))
if(3.0) if(3.0)
if (prob(5)) if (prob(5))
destroy(src) destroy(src)
else else
src.take_damage(src.health/4) src.take_damage(initial(src.health)/4)
return src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH))
return
/obj/mecha/proc/check_location_temp() /obj/mecha/proc/check_location_temp()
spawn while(src) spawn while(src)
@@ -290,6 +323,7 @@
/obj/mecha/proc/return_pressure() /obj/mecha/proc/return_pressure()
return src.air_contents.return_pressure() return src.air_contents.return_pressure()
/*
/obj/mecha/proc/preserve_temp() /obj/mecha/proc/preserve_temp()
// set background = 1 // set background = 1
spawn while(src) spawn while(src)
@@ -299,6 +333,7 @@
src.occupant.bodytemperature += src.occupant.adjust_body_temperature(src.occupant.bodytemperature, 310.15, 10) src.occupant.bodytemperature += src.occupant.adjust_body_temperature(src.occupant.bodytemperature, 310.15, 10)
cell.charge-- cell.charge--
sleep(10) sleep(10)
*/
/obj/mecha/proc/connect(obj/machinery/atmospherics/portables_connector/new_port) /obj/mecha/proc/connect(obj/machinery/atmospherics/portables_connector/new_port)
//Make sure not already connected to something else //Make sure not already connected to something else
@@ -353,10 +388,10 @@
src.verbs -= /obj/mecha/verb/connect_to_port src.verbs -= /obj/mecha/verb/connect_to_port
return return
else else
src.occupant << "\red [name] failed to connect to the port." src.occupant_message("\red [name] failed to connect to the port.")
return return
else else
src.occupant << "Nothing happens" src.occupant_message("Nothing happens")
/obj/mecha/verb/disconnect_from_port() /obj/mecha/verb/disconnect_from_port()
@@ -371,7 +406,7 @@
src.verbs -= /obj/mecha/verb/disconnect_from_port src.verbs -= /obj/mecha/verb/disconnect_from_port
src.verbs += /obj/mecha/verb/connect_to_port src.verbs += /obj/mecha/verb/connect_to_port
else else
src.occupant << "\red [name] is not connected to the port at the moment." src.occupant_message("\red [name] is not connected to the port at the moment.")
/obj/mecha/verb/toggle_lights() /obj/mecha/verb/toggle_lights()
@@ -411,6 +446,8 @@
src.occupant = usr src.occupant = usr
usr.loc = src usr.loc = src
src.add_fingerprint(usr) src.add_fingerprint(usr)
src.Entered(usr)
src.Move(src.loc)
return return
@@ -420,11 +457,7 @@
set src in view(0) set src in view(0)
if(usr!=src.occupant) if(usr!=src.occupant)
return return
src.update_stats = 1 pr_update_stats.start()
spawn while(src && src.occupant && src.update_stats)
src.occupant << browse(get_stats_html(), "window=exosuit")
onclose(src.occupant, "exosuit", src)
sleep(10)
return return
/obj/mecha/verb/eject() /obj/mecha/verb/eject()
@@ -440,16 +473,24 @@
/obj/mecha/proc/go_out() /obj/mecha/proc/go_out()
if(!src.occupant) return if(!src.occupant) return
if (src.occupant.client) if(src.occupant.Move(src.loc))
src.occupant.client.eye = src.occupant.client.mob src.Exited(src.occupant)
src.occupant.client.perspective = MOB_PERSPECTIVE if (src.occupant.client)
src.occupant << browse(null, "window=exosuit") src.occupant.client.eye = src.occupant.client.mob
src.occupant.loc = src.loc src.occupant.client.perspective = MOB_PERSPECTIVE
src.occupant = null src.occupant << browse(null, "window=exosuit")
src.occupant = null
src.pr_update_stats.stop()
return return
////// Misc ////// Misc
/obj/mecha/proc/occupant_message(message as text)
if(message)
if(src.occupant && src.occupant.client)
src.occupant << "[message]"
return
/obj/mecha/proc/operation_allowed(mob/living/carbon/human/H) /obj/mecha/proc/operation_allowed(mob/living/carbon/human/H)
//check if it doesn't require any access at all //check if it doesn't require any access at all
if(src.check_operational_access(null)) if(src.check_operational_access(null))
@@ -553,15 +594,19 @@
if (W:get_fuel() < 2) if (W:get_fuel() < 2)
user << "\blue You need more welding fuel to complete this task." user << "\blue You need more welding fuel to complete this task."
return return
if(src.health>=initial(src.health)) if (src.internal_damage & MECHA_INT_TANK_BREACH)
user << "\blue The [src.name] is at full integrity." src.internal_damage &= ~MECHA_INT_TANK_BREACH
return user << "\blue You seal the breached gas tank."
W:use_fuel(1) W:use_fuel(1)
src.health += 20 if(src.health<initial(src.health))
user << "\blue You repair some damage to [src.name]."
src.health += min(20, initial(src.health)-src.health)
W:use_fuel(1)
else
user << "The [src.name] is at full integrity"
return return
else else
..()
if(prob(src.deflect_chance)) if(prob(src.deflect_chance))
user << "\red The [W] bounces off [src.name] armor." user << "\red The [W] bounces off [src.name] armor."
/* /*
@@ -571,6 +616,7 @@
*/ */
else else
src.take_damage(W.force,W.damtype) src.take_damage(W.force,W.damtype)
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH))
return return
@@ -587,9 +633,13 @@
return output return output
/obj/mecha/proc/get_stats_part() /obj/mecha/proc/get_stats_part()
var/output = {"<b>Integrity: </b> [health/initial(health)*100]%<br> var/output = {"[internal_damage&MECHA_INT_FIRE?"<font color='red'><b>INTERNAL FIRE</b></font><br>":null]
[internal_damage&MECHA_INT_TEMP_CONTROL?"<font color='red'><b>LIFE SUPPORT SYSTEM MALFUNCTION</b></font><br>":null]
[internal_damage&MECHA_INT_TANK_BREACH?"<font color='red'><b>GAS TANK BREACH</b></font><br>":null]
<b>Integrity: </b> [health/initial(health)*100]%<br>
<b>Powercell charge: </b>[cell.charge/cell.maxcharge*100]%<br> <b>Powercell charge: </b>[cell.charge/cell.maxcharge*100]%<br>
<b>Airtank pressure: </b>[src.return_pressure()]<br> <b>Airtank pressure: </b>[src.return_pressure()]<br>
<b>Internal temperature: </b> [src.air_contents.temperature]&deg;K|[src.air_contents.temperature - T0C]&deg;C<br>
<b>Lights: </b>[lights?"on":"off"]<br> <b>Lights: </b>[lights?"on":"off"]<br>
"} "}
return output return output
@@ -605,7 +655,7 @@
/obj/mecha/Topic(href, href_list) /obj/mecha/Topic(href, href_list)
..() ..()
if (href_list["close"]) if (href_list["close"])
src.update_stats = null src.pr_update_stats.stop()
return return
if (href_list["toggle_lights"]) if (href_list["toggle_lights"])
src.toggle_lights() src.toggle_lights()
@@ -627,4 +677,76 @@
return return
//////////////////////////////////////////
//////// Mecha global iterators ////////
//////////////////////////////////////////
/datum/global_iterator/mecha_preserve_temp //normalizing air contents temperature to 20 degrees celsium
delay = 20
process(var/obj/mecha/mecha)
if(mecha.air_contents && mecha.air_contents.volume > 0)
var/delta = mecha.air_contents.temperature - T20C
mecha.air_contents.temperature -= max(-10, min(10, round(delta/4,0.1)))
return
/datum/global_iterator/mecha_view_stats // open and update stats window
process(var/obj/mecha/mecha)
if(mecha.occupant)
mecha.occupant << browse(mecha.get_stats_html(), "window=exosuit")
onclose(mecha.occupant, "exosuit", mecha)
return
/datum/global_iterator/mecha_intertial_movement //inertial movement in space
delay = 7
process(var/obj/mecha/mecha,direction)
if(direction)
if(!step(mecha, direction)||mecha.check_for_support())
src.stop()
else
src.stop()
return
/datum/global_iterator/mecha_location_temp_check //mecha location temperature checks
process(var/obj/mecha/mecha)
if(istype(mecha.loc, /turf/simulated))
var/turf/simulated/T = mecha.loc
if(T.air)
if(T.air.temperature > mecha.max_temperature)
mecha.take_damage(5,"fire")
mecha.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL))
return
/datum/global_iterator/mecha_internal_damage // processing internal damage
process(var/obj/mecha/mecha)
if(!mecha.internal_damage)
src.stop()
return
if(mecha.internal_damage & MECHA_INT_FIRE)
if(mecha.return_pressure()>mecha.maximum_pressure*1.5 && !(mecha.internal_damage&MECHA_INT_TANK_BREACH))
mecha.internal_damage |= MECHA_INT_TANK_BREACH
if(prob(5))
mecha.internal_damage &= ~MECHA_INT_FIRE
mecha.occupant_message("<font color='blue'><b>Internal fire extinquished.</b></font>")
return
if(mecha.air_contents && mecha.air_contents.volume > 0) //heat the air_contents
mecha.air_contents.temperature = min(1500+T0C, mecha.air_contents.temperature+rand(10,15))
if(mecha.air_contents.temperature>mecha.max_temperature/2)
mecha.take_damage(1,"fire")
if(mecha.internal_damage & MECHA_INT_TEMP_CONTROL) //stop the mecha_preserve_temp loop datum
mecha.pr_int_temp_processor.stop()
if(mecha.internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank
var/datum/gas_mixture/environment = mecha.loc.return_air()
var/env_pressure = environment.return_pressure()
var/pressure_delta = min(115 - env_pressure, (mecha.air_contents.return_pressure() - env_pressure)/2)
var/transfer_moles = 0
if(mecha.air_contents.temperature > 0 && pressure_delta > 0)
transfer_moles = pressure_delta*environment.volume/(mecha.air_contents.temperature * R_IDEAL_GAS_EQUATION)
mecha.loc.assume_air(mecha.air_contents.remove(transfer_moles))
return

View File

@@ -3,7 +3,7 @@
name = "APLU \"Ripley\"" name = "APLU \"Ripley\""
icon_state = "ripley" icon_state = "ripley"
step_in = 8 step_in = 8
max_temperature = 500 max_temperature = 1000
health = 200 health = 200
cargo_capacity = 15 cargo_capacity = 15

View File

@@ -55,38 +55,40 @@
var/obj/O = target var/obj/O = target
if(!O.anchored) if(!O.anchored)
if(chassis.cargo.len < chassis.cargo_capacity) if(chassis.cargo.len < chassis.cargo_capacity)
chassis.occupant << "You lift [target] and start to load it into cargo compartment." chassis.occupant_message("You lift [target] and start to load it into cargo compartment.")
chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.")
tool_ready = 0 tool_ready = 0
chassis.cell.use(energy_drain) chassis.cell.use(energy_drain)
O.anchored = 1 O.anchored = 1
var/T = chassis.loc var/T = chassis.loc
spawn(tool_cooldown) spawn(tool_cooldown)
if(T == chassis.loc && src == chassis.selected_tool) if(chassis)
chassis.cargo += O if(T == chassis.loc && src == chassis.selected_tool)
O.loc = chassis chassis.cargo += O
O.anchored = 0 O.loc = chassis
chassis.occupant << "\blue [target] succesfully loaded." O.anchored = 0
else chassis.occupant_message("<font color='blue'>[target] succesfully loaded.</font>")
chassis.occupant << "\red You must hold still while handling objects." else
tool_ready = 1 chassis.occupant_message("<font color='red'>You must hold still while handling objects.</font>")
tool_ready = 1
else else
chassis.occupant << "\red Not enough room in cargo compartment." chassis.occupant << "<font color='red'>Not enough room in cargo compartment.</font>"
else else
chassis.occupant << "\red [target] is firmly secured." chassis.occupant << "<font color='red'>[target] is firmly secured.</font>"
else if(istype(target,/mob)) else if(istype(target,/mob))
var/mob/M = target var/mob/M = target
if(M.stat>1) return
if(chassis.occupant.a_intent == "hurt") if(chassis.occupant.a_intent == "hurt")
M.bruteloss += force M.bruteloss += force
M.oxyloss += round(force/2) M.oxyloss += round(force/2)
M.updatehealth() M.updatehealth()
chassis.occupant << "\red You squeese [target] with [src.name]. Something cracks." chassis.occupant_message("\red You squeese [target] with [src.name]. Something cracks.")
chassis.visible_message("\red [chassis] squeeses [target].") chassis.visible_message("\red [chassis] squeeses [target].")
else else
step_away(M,chassis) step_away(M,chassis)
chassis.occupant << "You push [target] out of the way." chassis.occupant_message("You push [target] out of the way.")
chassis.visible_message("[chassis] pushes [target] out of the way.") chassis.visible_message("[chassis] pushes [target] out of the way.")
tool_ready = 0 tool_ready = 0
chassis.cell.use(energy_drain) chassis.cell.use(energy_drain)
@@ -106,12 +108,13 @@
tool_ready = 0 tool_ready = 0
chassis.cell.use(energy_drain) chassis.cell.use(energy_drain)
chassis.visible_message("<font color='red'><b>[chassis] starts to drill [target]</b></font>", "You hear the drill.") chassis.visible_message("<font color='red'><b>[chassis] starts to drill [target]</b></font>", "You hear the drill.")
chassis.occupant << "<font color='red'><b>You start to drill [target]</b></font>" chassis.occupant_message("<font color='red'><b>You start to drill [target]</b></font>")
var/T = chassis.loc var/T = chassis.loc
spawn(tool_cooldown) spawn(tool_cooldown)
if(T == chassis.loc && src == chassis.selected_tool) if(chassis)
target.ex_act(2) if(T == chassis.loc && src == chassis.selected_tool)
tool_ready = 1 target.ex_act(2)
tool_ready = 1

View File

@@ -9,6 +9,7 @@
var/occupant_telekinesis = null var/occupant_telekinesis = null
operation_req_access = list(access_engine) operation_req_access = list(access_engine)
internals_req_access = list(access_engine) internals_req_access = list(access_engine)
internal_damage_treshhold = 60
/obj/mecha/working/melee_action(atom/target as obj|mob|turf) /obj/mecha/working/melee_action(atom/target as obj|mob|turf)

View File

@@ -420,6 +420,7 @@
#include "code\game\magic\cultist\rune8.dm" #include "code\game\magic\cultist\rune8.dm"
#include "code\game\magic\cultist\rune9.dm" #include "code\game\magic\cultist\rune9.dm"
#include "code\game\magic\cultist\specialtalisman.dm" #include "code\game\magic\cultist\specialtalisman.dm"
#include "code\game\mecha\global_iterator.dm"
#include "code\game\mecha\mecha.dm" #include "code\game\mecha\mecha.dm"
#include "code\game\mecha\combat\combat.dm" #include "code\game\mecha\combat\combat.dm"
#include "code\game\mecha\combat\gygax.dm" #include "code\game\mecha\combat\gygax.dm"