Allowed pAIs and AIs loaded into hardsuits to move and rest when control is enabled or the user is unconcious/dead.

Allows AIs/pAIs in rigs to use the selected module via middle click.
This commit is contained in:
Zuhayr
2015-07-31 02:41:18 +09:30
parent 0d7b2570db
commit 59d0e28aff
16 changed files with 251 additions and 67 deletions
@@ -95,14 +95,14 @@
playsound(T, "sparks", 50, 1)
anim(T,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
/obj/item/rig_module/teleporter/engage(atom/target)
/obj/item/rig_module/teleporter/engage(var/atom/target, var/notify_ai)
if(!..()) return 0
var/mob/living/carbon/human/H = holder.wearer
if(!istype(H.loc, /turf))
H << "<span class='warning'>You cannot teleport out of your current location.</span>"
usr << "<span class='warning'>You cannot teleport out of your current location.</span>"
return 0
var/turf/T
@@ -112,15 +112,15 @@
T = get_teleport_loc(get_turf(H), H, rand(5, 9))
if(!T || T.density)
H << "<span class='warning'>You cannot teleport into solid walls.</span>"
usr << "<span class='warning'>You cannot teleport into solid walls.</span>"
return 0
if(T.z in config.admin_levels)
H << "<span class='warning'>You cannot use your teleporter on this Z-level.</span>"
usr << "<span class='warning'>You cannot use your teleporter on this Z-level.</span>"
return 0
if(T.contains_dense_objects())
H << "<span class='warning'>You cannot teleport to a location with solid objects.</span>"
usr << "<span class='warning'>You cannot teleport to a location with solid objects.</span>"
phase_out(H,get_turf(H))
H.loc = T
+133 -6
View File
@@ -27,6 +27,8 @@
var/interface_path = "hardsuit.tmpl"
var/ai_interface_path = "hardsuit.tmpl"
var/interface_title = "Hardsuit Controller"
var/wearer_move_delay //Used for AI moving.
var/ai_controlled_move_delay = 10
// Keeps track of what this rig should spawn with.
var/suit_type = "hardsuit"
@@ -326,6 +328,8 @@
else
if(offline)
offline = 0
if(istype(wearer) && !wearer.wearing_rig)
wearer.wearing_rig = src
chest.slowdown = initial(slowdown)
if(offline)
@@ -544,11 +548,13 @@
/obj/item/weapon/rig/proc/notify_ai(var/message)
if(!message || !installed_modules || !installed_modules.len)
return
return 0
. = 0
for(var/obj/item/rig_module/module in installed_modules)
for(var/mob/living/silicon/ai/ai in module.contents)
if(ai && ai.client && !ai.stat)
ai << "[message]"
. = 1
/obj/item/weapon/rig/equipped(mob/living/carbon/human/M)
..()
@@ -565,6 +571,7 @@
if(istype(M) && M.back == src)
M.visible_message("<font color='blue'><b>[M] struggles into \the [src].</b></font>", "<font color='blue'><b>You struggle into \the [src].</b></font>")
wearer = M
wearer.wearing_rig = src
update_icon()
/obj/item/weapon/rig/proc/toggle_piece(var/piece, var/mob/living/carbon/human/H, var/deploy_mode)
@@ -676,6 +683,7 @@
..()
for(var/piece in list("helmet","gauntlets","chest","boots"))
toggle_piece(piece, user, ONLY_RETRACT)
wearer.wearing_rig = null
wearer = null
//Todo
@@ -757,14 +765,133 @@
return 1
return 0
/*/obj/item/weapon/rig/proc/forced_move(dir)
if(locked_down)
/obj/item/weapon/rig/proc/ai_can_move_suit(var/mob/user, var/check_user_module = 0, var/check_for_ai = 0)
if(check_for_ai)
if(!(locate(/obj/item/rig_module/ai_container) in contents))
return 0
var/found_ai
for(var/obj/item/rig_module/ai_container/module in contents)
if(module.damage >= 2)
continue
if(module.integrated_ai && module.integrated_ai.client && !module.integrated_ai.stat)
found_ai = 1
break
if(!found_ai)
return 0
if(check_user_module)
world << "Checking user module"
if(!user)
world << "No user"
return 0
if(!user.loc || !user.loc.loc)
world << "No user loc"
return 0
var/obj/item/rig_module/ai_container/module = user.loc.loc
if(!istype(module) || module.damage >= 2)
user << "<span class='warning'>Your host module is unable to interface with the suit.</span>"
return 0
if(offline || !cell || !cell.charge || locked_down)
if(user) user << "<span class='warning'>Your host rig is unpowered and unresponsive.</span>"
return 0
if(!control_overridden)
return
if(!wearer || wearer.back != src)
if(user) user << "<span class='warning'>Your host rig is not being worn.</span>"
return 0
wearer.Move(null,dir)*/
if(!wearer.stat && !control_overridden && !ai_override_enabled)
if(user) user << "<span class='warning'>You are locked out of the suit servo controller.</span>"
return 0
return 1
/obj/item/weapon/rig/proc/force_rest(var/mob/user)
if(!ai_can_move_suit(user, check_user_module = 1))
return
wearer.lay_down()
user << "<span class='notice'>\The [wearer] is now [wearer.resting ? "resting" : "getting up"].</span>"
/obj/item/weapon/rig/proc/forced_move(var/direction, var/mob/user)
// Why is all this shit in client/Move()? Who knows?
if(world.time < wearer_move_delay)
return
if(!wearer.loc || !ai_can_move_suit(user, check_user_module = 1))
return
//This is sota the goto stop mobs from moving var
if(wearer.transforming || !wearer.canmove)
return
if(locate(/obj/effect/stop/, wearer.loc))
for(var/obj/effect/stop/S in wearer.loc)
if(S.victim == wearer)
return
if(!wearer.lastarea)
wearer.lastarea = get_area(wearer.loc)
if((istype(wearer.loc, /turf/space)) || (wearer.lastarea.has_gravity == 0))
if(!wearer.Process_Spacemove(0))
return 0
if(malfunctioning)
direction = pick(cardinal)
// Inside an object, tell it we moved.
if(isobj(wearer.loc) || ismob(wearer.loc))
var/atom/O = wearer.loc
return O.relaymove(wearer, direction)
if(isturf(wearer.loc))
if(wearer.restrained())//Why being pulled while cuffed prevents you from moving
for(var/mob/M in range(wearer, 1))
if(M.pulling == wearer)
if(!M.restrained() && M.stat == 0 && M.canmove && wearer.Adjacent(M))
user << "<span class='notice'>Your host is restrained! They can't move!</span>"
return 0
else
M.stop_pulling()
if(wearer.pinned.len)
src << "<span class='notice'>Your host is pinned to a wall by [wearer.pinned[1]]</span>!"
return 0
// AIs are a bit slower than regular and ignore move intent.
wearer.last_move_intent = world.time + ai_controlled_move_delay
wearer_move_delay = world.time + ai_controlled_move_delay
var/tickcomp = 0
if(config.Tickcomp)
tickcomp = ((1/(world.tick_lag))*1.3) - 1.3
wearer_move_delay += tickcomp
if(istype(wearer.buckled, /obj/vehicle))
//manually set move_delay for vehicles so we don't inherit any mob movement penalties
//specific vehicle move delays are set in code\modules\vehicles\vehicle.dm
wearer_move_delay = world.time + tickcomp
return wearer.buckled.relaymove(wearer, direction)
if(istype(wearer.machine, /obj/machinery))
if(wearer.machine.relaymove(wearer, direction))
return
if(wearer.pulledby || wearer.buckled) // Wheelchair driving!
if(istype(wearer.loc, /turf/space))
return // No wheelchair driving in space
if(istype(wearer.pulledby, /obj/structure/bed/chair/wheelchair))
return wearer.pulledby.relaymove(wearer, direction)
else if(istype(wearer.buckled, /obj/structure/bed/chair/wheelchair))
if(ishuman(wearer.buckled))
var/obj/item/organ/external/l_hand = wearer.get_organ("l_hand")
var/obj/item/organ/external/r_hand = wearer.get_organ("r_hand")
if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED)))
return // No hands to drive your chair? Tough luck!
wearer_move_delay += 2
return wearer.buckled.relaymove(wearer,direction)
cell.use(200) //Arbitrary, TODO
wearer.Move(get_step(get_turf(wearer),direction),direction)
/atom/proc/get_rig()
if(loc)
@@ -61,11 +61,13 @@
if(!gibbed && species.death_sound)
playsound(loc, species.death_sound, 80, 1, 1)
if(ticker && ticker.mode)
sql_report_death(src)
ticker.mode.check_win()
if(wearing_rig)
wearing_rig.notify_ai("<span class='danger'>Warning: user death event. Mobility control passed to integrated intelligence system.</span>")
return ..(gibbed,species.death_message)
/mob/living/carbon/human/proc/ChangeToHusk()
@@ -7,6 +7,7 @@
var/list/hud_list[10]
var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us.
var/obj/item/weapon/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
/mob/living/carbon/human/New(var/new_loc, var/new_species = null)
@@ -1373,3 +1374,7 @@
if(istype(shoes, /obj/item/clothing/shoes/magboots) && (shoes.flags & NOSLIP)) //magboots + dense_object = no floating
return 1
return 0
/mob/living/carbon/human/can_stand_overridden()
return wearing_rig && wearing_rig.ai_can_move_suit(check_for_ai = 1)
@@ -145,6 +145,9 @@
/mob/living/carbon/human/Paralyse(amount)
if(HULK in mutations) return
// Notify our AI if they can now control the suit.
if(wearing_rig && !stat && paralysis < amount) //We are passing out right this second.
wearing_rig.notify_ai("<span class='danger'>Warning: user consciousness failure. Mobility control passed to integrated intelligence system.</span>")
..()
/mob/living/carbon/human/getCloneLoss()
@@ -1,5 +1,9 @@
/mob/living/carbon/human/movement_delay()
// Used by the AI suit control proc.
if(stat)
return 20
var/tally = 0
if(species.slowdown)
@@ -52,6 +52,10 @@
// update the current life tick, can be used to e.g. only do something every 4 ticks
life_tick++
// This is not an ideal place for this but it will do for now.
if(wearing_rig && wearing_rig.offline)
wearing_rig = null
in_stasis = istype(loc, /obj/structure/closet/body_bag/cryobag) && loc:opened == 0
if(in_stasis) loc:used++
+1 -1
View File
@@ -657,7 +657,7 @@ default behaviour is:
set category = "IC"
resting = !resting
src << "\blue You are now [resting ? "resting" : "getting up"]"
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"].</span>"
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn
if(stat)
+10
View File
@@ -684,5 +684,15 @@ var/list/ai_verbs_default = list(
icon_state = selected_sprite.alive_icon
set_light(1, 1, selected_sprite.alive_light)
// Pass lying down or getting up to our pet human, if we're in a rig.
/mob/living/silicon/ai/lay_down()
set name = "Rest"
set category = "IC"
resting = 0
var/obj/item/weapon/rig/rig = src.get_rig()
if(istype(rig))
rig.force_rest(src)
#undef AI_CHECK_WIRELESS
#undef AI_CHECK_RADIO
+8 -7
View File
@@ -73,8 +73,6 @@
var/current_pda_messaging = null
/mob/living/silicon/pai/New(var/obj/item/device/paicard)
canmove = 0
src.loc = paicard
card = paicard
sradio = new(src)
@@ -277,8 +275,6 @@
var/obj/item/device/pda/holder = card.loc
holder.pai = null
canmove = 1
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = src
src.forceMove(get_turf(card))
@@ -340,12 +336,16 @@
set name = "Rest"
set category = "IC"
// Pass lying down or getting up to our pet human, if we're in a rig.
if(istype(src.loc,/obj/item/device/paicard))
resting = 0
var/obj/item/weapon/rig/rig = src.get_rig()
if(istype(rig))
rig.force_rest(src)
else
resting = !resting
icon_state = resting ? "[chassis]_rest" : "[chassis]"
src << "\blue You are now [resting ? "resting" : "getting up"]"
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>"
canmove = !resting
@@ -394,7 +394,8 @@
card.loc = get_turf(card)
src.forceMove(card)
card.forceMove(card.loc)
canmove = 0
canmove = 1
resting = 0
icon_state = "[chassis]"
/mob/living/silicon/pai/start_pulling(var/atom/movable/AM)
@@ -430,4 +431,4 @@
get_scooped(H)
return
else
return ..()
return ..()
+41 -29
View File
@@ -689,40 +689,52 @@
if(transforming) return 0
return 1
// Not sure what to call this. Used to check if humans are wearing an AI-controlled exosuit and hence don't need to fall over yet.
/mob/proc/can_stand_overridden()
return 0
/mob/proc/cannot_stand()
return stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH)
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
/mob/proc/update_canmove()
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
lying = 1
canmove = 0
pixel_y = V.mob_offset_y - 5
else
if(buckled.buckle_lying != -1) lying = buckled.buckle_lying
canmove = 1
pixel_y = V.mob_offset_y
else if(buckled)
anchored = 1
canmove = 0
if(istype(buckled))
if(buckled.buckle_lying != -1)
lying = buckled.buckle_lying
if(buckled.buckle_movable)
anchored = 0
canmove = 1
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
lying = 1
canmove = 0
else if(stunned)
canmove = 0
else if(captured)
anchored = 1
canmove = 0
lying = 0
else
if(!resting && cannot_stand() && can_stand_overridden())
lying = 0
canmove = 1
else
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(cannot_stand())
lying = 1
canmove = 0
pixel_y = V.mob_offset_y - 5
else
if(buckled.buckle_lying != -1) lying = buckled.buckle_lying
canmove = 1
pixel_y = V.mob_offset_y
else if(buckled)
anchored = 1
canmove = 0
if(istype(buckled))
if(buckled.buckle_lying != -1)
lying = buckled.buckle_lying
if(buckled.buckle_movable)
anchored = 0
canmove = 1
else if(cannot_stand())
lying = 1
canmove = 0
else if(stunned)
canmove = 0
else if(captured)
anchored = 1
canmove = 0
lying = 0
else
lying = 0
canmove = 1
if(lying)
density = 0
-2
View File
@@ -222,7 +222,6 @@
if(Process_Grab()) return
if(!mob.canmove)
return
@@ -235,7 +234,6 @@
if((istype(mob.loc, /turf/space)) || (mob.lastarea.has_gravity == 0))
if(!mob.Process_Spacemove(0)) return 0
if(isobj(mob.loc) || ismob(mob.loc))//Inside an object, tell it we moved
var/atom/O = mob.loc
return O.relaymove(mob, direct)