| [Bot.hacked ? "(!)" : ""] [Bot.name] ([Bot.model]) | "
//If the bot is on, it will display the bot's current mode status. If the bot is not mode, it will just report "Idle". "Inactive if it is not on at all.
- d += "[Bot.on ? "[Bot.mode ? "[ Bot.get_mode() ]": "Idle"]" : "Inactive"] | "
+ d += "[bot_mode] | "
d += "[bot_area.name] | "
d += "Interface | "
d += "Call | "
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index a4600e376e6..a97048584aa 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -1,26 +1,4 @@
-#define BOT_STEP_DELAY 4 //Delay between movemements
-
-#define DEFAULT_SCAN_RANGE 7 //default view range for finding targets.
-
-//Mode defines
-#define BOT_IDLE 0 // idle
-#define BOT_HUNT 1 // found target, hunting
-#define BOT_PREP_ARREST 2 // at target, preparing to arrest
-#define BOT_ARREST 3 // arresting target
-#define BOT_START_PATROL 4 // start patrol
-#define BOT_PATROL 5 // patrolling
-#define BOT_SUMMON 6 // summoned by PDA
-#define BOT_CLEANING 7 // cleaning (cleanbots)
-#define BOT_REPAIRING 8 // repairing hull breaches (floorbots)
-#define BOT_MOVING 9 // for clean/floor/med bots, when moving.
-#define BOT_HEALING 10 // healing people (medbots)
-#define BOT_RESPONDING 11 // responding to a call from the AI
-#define BOT_DELIVER 12 // moving to deliver
-#define BOT_GO_HOME 13 // returning to home
-#define BOT_BLOCKED 14 // blocked
-#define BOT_NAV 15 // computing navigation
-#define BOT_WAIT_FOR_NAV 16 // waiting for nav computation
-#define BOT_NO_ROUTE 17 // no destination beacon found (or no route)
+//Defines for bots are now found in code\__DEFINES\bots.dm
// AI (i.e. game AI, not the AI player) controlled bots
/mob/living/simple_animal/bot
@@ -92,17 +70,24 @@
"Waiting for clear path", "Calculating navigation path", "Pinging beacon network", "Unable to reach destination")
//This holds text for what the bot is mode doing, reported on the remote bot control interface.
+ hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD) //Diagnostic HUD views
+
/mob/living/simple_animal/bot/proc/get_mode()
- if(!mode)
- return "Idle"
+ if(client) //Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player.
+ return "Sentient"
+ else if(!on)
+ return "Inactive"
+ else if(!mode)
+ return "Idle"
else
- return mode_name[mode]
+ return "[mode_name[mode]]"
/mob/living/simple_animal/bot/proc/turn_on()
if(stat) return 0
on = 1
SetLuminosity(initial(luminosity))
update_icon()
+ diag_hud_set_botstat()
return 1
/mob/living/simple_animal/bot/proc/turn_off()
@@ -125,6 +110,13 @@
bot_core = new bot_core_type(src)
+ prepare_huds()
+ var/datum/atom_hud/data/diagnostic/diag_hud = huds[DATA_HUD_DIAGNOSTIC]
+ diag_hud.add_to_hud(src)
+ diag_hud_set_bothealth()
+ diag_hud_set_botstat()
+ diag_hud_set_botmode()
+
/mob/living/simple_animal/bot/update_canmove()
. = ..()
if(!on)
@@ -181,8 +173,13 @@
new /obj/effect/decal/cleanable/oil(loc)
return ..(amount)
+/mob/living/simple_animal/bot/updatehealth()
+ ..()
+ diag_hud_set_bothealth()
+
/mob/living/simple_animal/bot/handle_automated_action() //Master process which handles code common across most bots.
set background = BACKGROUND_ENABLED
+ diag_hud_set_botmode()
if(!on || client)
return
@@ -280,7 +277,7 @@
text_dehack_fail = "You fail to reset [name]."
/mob/living/simple_animal/bot/attack_ai(mob/user as mob)
- attack_hand(user)
+ show_controls(user)
/mob/living/simple_animal/bot/proc/speak(message,channel) //Pass a message to have the bot say() it. Pass a frequency to say it on the radio.
if((!on) || (!message))
@@ -376,7 +373,7 @@ Pass a positive integer as an argument to override a bot's default speed.
path = list()
return 0
var/step_count = move_speed ? move_speed : base_speed //If a value is passed into move_speed, use that instead of the default speed var.
-
+
if(step_count >= 1 && tries < 4)
for(var/step_number = 0, step_number < step_count,step_number++)
spawn(BOT_STEP_DELAY*step_number)
@@ -453,6 +450,8 @@ Pass a positive integer as an argument to override a bot's default speed.
access_card.access = prev_access
tries = 0
mode = BOT_IDLE
+ diag_hud_set_botstat()
+ diag_hud_set_botmode()
@@ -709,13 +708,12 @@ Pass a positive integer as an argument to override a bot's default speed.
//No ..() to prevent strip panel showing up - Todo: make that saner
if(topic_denied(usr))
usr << "[src]'s interface is not responding!"
- href_list = list()
- return
+ return 1
add_fingerprint(usr)
if(href_list["close"])// HUE HUE
if(usr in users)
users.Remove(usr)
- return
+ return 1
if((href_list["power"]) && (bot_core.allowed(usr) || !locked))
if (on)
turn_off()
@@ -761,12 +759,11 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/topic_denied(mob/user) //Access check proc for bot topics! Remember to place in a bot's individual Topic if desired.
// 0 for access, 1 for denied.
if(emagged == 2) //An emagged bot cannot be controlled by humans, silicons can if one hacked it.
- if(hacked) //Manually emagged by a human - access denied to all.
+ if(!hacked) //Manually emagged by a human - access denied to all.
return 1
else if(!issilicon(user) || IsAdminGhost(user)) //Bot is hacked, so only silicons and admins are allowed access.
return 1
- else
- return 0
+ return 0
/mob/living/simple_animal/bot/proc/hack(mob/user)
var/hack
@@ -780,6 +777,7 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/Login()
. = ..()
access_card.access += player_access
+ diag_hud_set_botmode()
/mob/living/simple_animal/bot/Logout()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index f018b94fb74..ff680cf7131 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -231,7 +231,8 @@ text("[on ? "On" : "Off"]"))
return dat
/mob/living/simple_animal/bot/cleanbot/Topic(href, href_list)
- ..()
+ if(..())
+ return 1
switch(href_list["operation"])
if("blood")
blood =!blood
diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
index b787b2d4bc8..f8a304ad3e3 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -130,7 +130,8 @@ Auto Patrol[]"},
return
else if((lasercolor == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag)))
return
- ..()
+ if(..())
+ return 1
switch(href_list["operation"])
if ("idcheck")
@@ -149,19 +150,27 @@ Auto Patrol[]"},
declare_arrests = !declare_arrests
update_controls()
+/mob/living/simple_animal/bot/ed209/proc/retaliate(mob/living/carbon/human/H)
+ threatlevel = H.assess_threat(src)
+ threatlevel += 6
+ if(threatlevel >= 4)
+ target = H
+ mode = BOT_HUNT
+
+/mob/living/simple_animal/bot/ed209/attack_hand(mob/living/carbon/human/H)
+ if(H.a_intent == "harm")
+ retaliate(H)
+ return ..()
+
/mob/living/simple_animal/bot/ed209/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") // Any intent but harm will heal, so we shouldn't get angry.
return
if (!istype(W, /obj/item/weapon/screwdriver) && (!target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
if(W.force && W.damtype != STAMINA)//If force is non-zero and damage type isn't stamina.
- threatlevel = user.assess_threat(src)
- threatlevel += 6
- if(threatlevel >= 4)
- target = user
- if(lasercolor)//To make up for the fact that lasertag bots don't hunt
- shootAt(user)
- mode = BOT_HUNT
+ retaliate(user)
+ if(lasercolor)//To make up for the fact that lasertag bots don't hunt
+ shootAt(user)
/mob/living/simple_animal/bot/ed209/Emag(mob/user)
..()
@@ -178,11 +187,7 @@ Auto Patrol[]"},
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if (!Proj.nodamage && Proj.damage < src.health)
- threatlevel = Proj.firer.assess_threat(src)
- threatlevel += 6
- if(threatlevel >= 4)
- target = Proj.firer
- mode = BOT_HUNT
+ retaliate(Proj.firer)
..()
/mob/living/simple_animal/bot/ed209/handle_automated_action()
@@ -522,10 +527,7 @@ Auto Patrol[]"},
/mob/living/simple_animal/bot/ed209/RangedAttack(atom/A)
if(!on)
return
- if(ismob(A))
- shootAt(A)
- else
- ..()
+ shootAt(A)
/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm
index 8e36d9fb65b..a8c3c93aaa5 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -118,7 +118,9 @@
user << "[src] buzzes and beeps."
/mob/living/simple_animal/bot/floorbot/Topic(href, href_list)
- ..()
+ if(..())
+ return 1
+
switch(href_list["operation"])
if("replace")
replacetiles = !replacetiles
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index 8eda5b8fd3c..3a9460174ec 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -157,7 +157,8 @@
return dat
/mob/living/simple_animal/bot/medbot/Topic(href, href_list)
- ..()
+ if(..())
+ return 1
if(href_list["adj_threshold"])
var/adjust_num = text2num(href_list["adj_threshold"])
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index a6f4bcaeb1b..49c59f60a18 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -106,8 +106,8 @@ Auto Patrol: []"},
return dat
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
-
- ..()
+ if(..())
+ return 1
switch(href_list["operation"])
if("idcheck")
@@ -126,16 +126,24 @@ Auto Patrol: []"},
declare_arrests = !declare_arrests
update_controls()
+/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
+ threatlevel = H.assess_threat(src)
+ threatlevel += 6
+ if(threatlevel >= 4)
+ target = H
+ mode = BOT_HUNT
+
+/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
+ if(H.a_intent == "harm")
+ retaliate(H)
+ return ..()
+
/mob/living/simple_animal/bot/secbot/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") // Any intent but harm will heal, so we shouldn't get angry.
return
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
- threatlevel = user.assess_threat(src)
- threatlevel += 6
- if(threatlevel >= 4)
- target = user
- mode = BOT_HUNT
+ retaliate(user)
/mob/living/simple_animal/bot/secbot/Emag(mob/user)
..()
@@ -152,11 +160,7 @@ Auto Patrol: []"},
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if (!Proj.nodamage && Proj.damage < src.health)
- threatlevel = Proj.firer.assess_threat(src)
- threatlevel += 6
- if(threatlevel >= 4)
- target = Proj.firer
- mode = BOT_HUNT
+ retaliate(Proj.firer)
..()
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 5dc4c2c0f5e..ee584f7cbbe 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -1,9 +1,8 @@
-/mob/living/simple_animal/construct
+/mob/living/simple_animal/hostile/construct
name = "Construct"
real_name = "Construct"
desc = ""
speak_emote = list("hisses")
- emote_hear = list("wails.","screeches.")
response_help = "thinks better of touching"
response_disarm = "flails at"
response_harm = "punches"
@@ -14,7 +13,6 @@
stop_automated_movement = 1
status_flags = CANPUSH
attack_sound = 'sound/weapons/punch1.ogg'
- environment_smash = 1
see_in_dark = 7
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
@@ -23,17 +21,19 @@
healable = 0
faction = list("cult")
flying = 1
+ pressure_resistance = 200
unique_name = 1
+ AIStatus = AI_OFF //normal constructs don't have AI
var/list/construct_spells = list()
- var/playstyle_string = "You are a generic construct! Your job is to not exist."
+ var/playstyle_string = "You are a generic construct! Your job is to not exist, and you should probably adminhelp this."
-/mob/living/simple_animal/construct/New()
+/mob/living/simple_animal/hostile/construct/New()
..()
for(var/spell in construct_spells)
AddSpell(new spell(null))
-/mob/living/simple_animal/construct/death()
+/mob/living/simple_animal/hostile/construct/death()
..(1)
new /obj/item/weapon/ectoplasm (src.loc)
visible_message("[src] collapses in a shattered heap.")
@@ -41,7 +41,7 @@
qdel(src)
return
-/mob/living/simple_animal/construct/examine(mob/user)
+/mob/living/simple_animal/hostile/construct/examine(mob/user)
var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
if (src.health < src.maxHealth)
msg += ""
@@ -54,17 +54,17 @@
user << msg
-/mob/living/simple_animal/construct/attack_animal(mob/living/simple_animal/M)
- if(istype(M, /mob/living/simple_animal/construct/builder))
+/mob/living/simple_animal/hostile/construct/attack_animal(mob/living/simple_animal/M)
+ if(istype(M, /mob/living/simple_animal/hostile/construct/builder))
if(health < maxHealth)
adjustBruteLoss(-5)
if(src != M)
Beam(M,icon_state="sendbeam",icon='icons/effects/effects.dmi',time=4)
M.visible_message("[M] repairs some of \the [src]'s dents.", \
- "You repair some of [src]'s dents, leaving [src] at [health]/[maxHealth] health.")
+ "You repair some of [src]'s dents, leaving [src] at [health]/[maxHealth] health.")
else
M.visible_message("[M] repairs some of its own dents.", \
- "You repair some of your own dents, leaving you at [M.health]/[M.maxHealth] health.")
+ "You repair some of your own dents, leaving you at [M.health]/[M.maxHealth] health.")
else
if(src != M)
M << "You cannot repair [src]'s dents, as it has none!"
@@ -73,16 +73,16 @@
else if(src != M)
..()
-/mob/living/simple_animal/construct/Process_Spacemove(movement_dir = 0)
+/mob/living/simple_animal/hostile/construct/Process_Spacemove(movement_dir = 0)
return 1
-/mob/living/simple_animal/construct/narsie_act()
+/mob/living/simple_animal/hostile/construct/narsie_act()
return
/////////////////Juggernaut///////////////
-/mob/living/simple_animal/construct/armored
+/mob/living/simple_animal/hostile/construct/armored
name = "Juggernaut"
real_name = "Juggernaut"
desc = "A massive, armored construct built to spearhead attacks and soak up enemy fire."
@@ -90,7 +90,7 @@
icon_living = "behemoth"
maxHealth = 250
health = 250
- response_harm = "harmlessly punches"
+ response_harm = "harmlessly punches"
harm_intent_damage = 0
melee_damage_lower = 30
melee_damage_upper = 30
@@ -105,7 +105,11 @@
playstyle_string = "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, \
create shield walls, rip apart enemies and walls alike, and even deflect energy weapons."
-/mob/living/simple_animal/construct/armored/bullet_act(obj/item/projectile/P)
+/mob/living/simple_animal/hostile/construct/armored/hostile //actually hostile, will move around, hit things
+ AIStatus = AI_ON
+ environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
+
+/mob/living/simple_animal/hostile/construct/armored/bullet_act(obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
var/reflectchance = 80 - round(P.damage/3)
if(prob(reflectchance))
@@ -134,7 +138,7 @@
////////////////////////Wraith/////////////////////////////////////////////
-/mob/living/simple_animal/construct/wraith
+/mob/living/simple_animal/hostile/construct/wraith
name = "Wraith"
real_name = "Wraith"
desc = "A wicked, clawed shell constructed to assassinate enemies and sow chaos behind enemy lines."
@@ -144,15 +148,19 @@
health = 75
melee_damage_lower = 25
melee_damage_upper = 25
+ retreat_distance = 2 //AI wraiths will move in and out of combat
attacktext = "slashes"
attack_sound = 'sound/weapons/bladeslice.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
playstyle_string = "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls."
+/mob/living/simple_animal/hostile/construct/wraith/hostile //actually hostile, will move around, hit things
+ AIStatus = AI_ON
+
/////////////////////////////Artificer/////////////////////////
-/mob/living/simple_animal/construct/builder
+/mob/living/simple_animal/hostile/construct/builder
name = "Artificer"
real_name = "Artificer"
desc = "A bulbous construct dedicated to building and maintaining the Cult of Nar-Sie's armies."
@@ -164,6 +172,8 @@
harm_intent_damage = 5
melee_damage_lower = 5
melee_damage_upper = 5
+ retreat_distance = 10
+ minimum_distance = 10 //AI artificers will flee like fuck
attacktext = "rams"
environment_smash = 2
attack_sound = 'sound/weapons/punch2.ogg'
@@ -177,10 +187,52 @@
and, most important of all, create new constructs by producing soulstones to capture souls, \
and shells to place those soulstones into."
+/mob/living/simple_animal/hostile/construct/builder/Found(atom/A) //what have we found here?
+ if(istype(A, /mob/living/simple_animal/hostile/construct)) //is it a construct?
+ var/mob/living/simple_animal/hostile/construct/C = A
+ if(C.health < C.maxHealth) //is it hurt? let's go heal it if it is
+ return 1
+ else
+ return 0
+ else
+ return 0
+
+/mob/living/simple_animal/hostile/construct/builder/CanAttack(atom/the_target)
+ if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
+ return 0
+ if(Found(the_target) || ..()) //If we Found it or Can_Attack it normally, we Can_Attack it as long as it wasn't invisible
+ return 1 //as a note this shouldn't be added to base hostile mobs because it'll mess up retaliate hostile mobs
+
+/mob/living/simple_animal/hostile/construct/builder/MoveToTarget(var/list/possible_targets)
+ ..()
+ if(isliving(target))
+ var/mob/living/L = target
+ if(istype(L, /mob/living/simple_animal/hostile/construct) && L.health >= L.maxHealth) //is this target an unhurt construct? stop trying to heal it
+ LoseTarget()
+ return 0
+ if(L.health <= melee_damage_lower+melee_damage_upper) //ey bucko you're hurt as fuck let's go hit you
+ retreat_distance = null
+ minimum_distance = 1
+
+/mob/living/simple_animal/hostile/construct/builder/Aggro()
+ ..()
+ if(istype(target, /mob/living/simple_animal/hostile/construct)) //oh the target is a construct no need to flee
+ retreat_distance = null
+ minimum_distance = 1
+
+/mob/living/simple_animal/hostile/construct/builder/LoseAggro()
+ ..()
+ retreat_distance = initial(retreat_distance)
+ minimum_distance = initial(minimum_distance)
+
+/mob/living/simple_animal/hostile/construct/builder/hostile //actually hostile, will move around, hit things, heal other constructs
+ AIStatus = AI_ON
+ environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
+
/////////////////////////////Harvester/////////////////////////
-/mob/living/simple_animal/construct/harvester
+/mob/living/simple_animal/hostile/construct/harvester
name = "Harvester"
real_name = "Harvester"
desc = "A long, thin construct built to herald Nar-Sie's rise. It'll be all over soon."
@@ -190,9 +242,16 @@
health = 60
melee_damage_lower = 1
melee_damage_upper = 5
+ retreat_distance = 2 //AI harvesters will move in and out of combat, like wraiths, but shittier
attacktext = "prods"
+ environment_smash = 3
attack_sound = 'sound/weapons/tap.ogg'
- construct_spells = list(/obj/effect/proc_holder/spell/targeted/smoke/disable)
+ construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
+ /obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
+ /obj/effect/proc_holder/spell/targeted/smoke/disable)
playstyle_string = "You are a Harvester. You are not strong, but your powers of domination will assist you in your role: \
Bring those who still cling to this world of illusion back to the Geometer so they may know Truth."
+/mob/living/simple_animal/hostile/construct/harvester/hostile //actually hostile, will move around, hit things
+ AIStatus = AI_ON
+ environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 2b11da4eda2..31ae1247d0a 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -182,7 +182,7 @@
/mob/living/simple_animal/hostile/adjustBruteLoss(damage)
..(damage)
- if(!ckey && !stat && search_objects < 3)//Not unconscious, and we don't ignore mobs
+ if(!ckey && !stat && search_objects < 3 && damage > 0)//Not unconscious, and we don't ignore mobs
if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight
search_objects = 0
target = null
@@ -221,10 +221,13 @@
/mob/living/simple_animal/hostile/proc/summon_backup(distance)
do_alert_animation(src)
playsound(loc, 'sound/machines/chime.ogg', 50, 1, -1)
- for (var/mob/living/simple_animal/hostile/M in oview(distance, src))
+ for(var/mob/living/simple_animal/hostile/M in oview(distance, src))
var/list/L = M.faction&faction
if(L.len)
- M.Goto(src,M.move_to_delay,M.minimum_distance)
+ if(M.AIStatus == AI_OFF)
+ return
+ else
+ M.Goto(src,M.move_to_delay,M.minimum_distance)
/mob/living/simple_animal/hostile/proc/OpenFire(atom/A)
diff --git a/code/modules/mob/living/simple_animal/morph/morph.dm b/code/modules/mob/living/simple_animal/morph/morph.dm
index 01653d3731c..784b7df12b6 100644
--- a/code/modules/mob/living/simple_animal/morph/morph.dm
+++ b/code/modules/mob/living/simple_animal/morph/morph.dm
@@ -37,11 +37,11 @@
var/morph_time = 0
var/playstyle_string = "You are a morph, an abomination of science created primarily with changeling cells. \
- You may take the form of anything nearby by middle-clicking it. This process will alert any nearby \
+ You may take the form of anything nearby by shift-clicking it. This process will alert any nearby \
observers, and can only be performed once every five seconds. While morphed, you move faster, but do \
less damage. In addition, anyone within three tiles will note an uncanny wrongness if examining you. \
You can attack any item or dead creature to consume it - creatures will fully restore your health. \
- Finally, you can restore yourself to your original form while morphed by middle-clicking yourself."
+ Finally, you can restore yourself to your original form while morphed by shift-clicking yourself."
/mob/living/simple_animal/hostile/morph/examine(mob/user)
if(morphed)
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm b/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm
index d21e9c04b03..ba32dba49ed 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm
@@ -4,7 +4,7 @@
name = "Spawn Revenant"
typepath = /datum/round_event/revenant
weight = 7
- max_occurrences = 3
+ max_occurrences = 1
earliest_start = 6000 //Meant to mix things up early-game.
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 404ccc92e8d..f4dc55f7dbf 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -536,7 +536,7 @@
if(!MP)
return 0 //Sanity, this should never happen.
- if(ispath(MP, /mob/living/simple_animal/construct))
+ if(ispath(MP, /mob/living/simple_animal/hostile/construct))
return 0 //Verbs do not appear for players.
//Good mobs!
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index c13223cd31e..55e57887ba6 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -1137,9 +1137,13 @@
lighting = 0
equipment = 0
environ = 0
+ update_icon()
+ update()
spawn(600)
equipment = 3
environ = 3
+ update_icon()
+ update()
..()
/obj/machinery/power/apc/ex_act(severity, target)
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 78564886196..a7eb8fac14b 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -39,7 +39,7 @@
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
- makeNewConstruct(/mob/living/simple_animal/construct/harvester, user, null, 0, loc_override = src.loc)
+ makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, user, null, 0, loc_override = src.loc)
PoolOrNew(/obj/effect/particle_effect/smoke/sleeping, src.loc)
diff --git a/code/modules/recycling/disposal-structures.dm b/code/modules/recycling/disposal-structures.dm
index 7ea048f1bf3..24e12478be0 100644
--- a/code/modules/recycling/disposal-structures.dm
+++ b/code/modules/recycling/disposal-structures.dm
@@ -278,9 +278,7 @@
for(var/atom/movable/AM in H)
AM.loc = T
AM.pipe_eject(direction)
- spawn(1)
- if(AM)
- AM.throw_at(target, 10, 1)
+ AM.throw_at_fast(target, 10, 1)
else // no specified direction, so throw in random direction
@@ -291,9 +289,7 @@
AM.loc = T
AM.pipe_eject(0)
- spawn(1)
- if(AM)
- AM.throw_at(target, 5, 1)
+ AM.throw_at_fast(target, 5, 1)
H.vent_gas(T)
qdel(H)
return
@@ -800,9 +796,7 @@
for(var/atom/movable/AM in H)
AM.loc = src.loc
AM.pipe_eject(dir)
- spawn(5)
- if(AM)
- AM.throw_at(target, eject_range, 1)
+ AM.throw_at_fast(target, eject_range, 1)
H.vent_gas(src.loc)
qdel(H)
return
diff --git a/code/modules/recycling/disposal-unit.dm b/code/modules/recycling/disposal-unit.dm
index 74be5a2317d..ed95abc4232 100644
--- a/code/modules/recycling/disposal-unit.dm
+++ b/code/modules/recycling/disposal-unit.dm
@@ -258,9 +258,7 @@
AM.loc = src.loc
AM.pipe_eject(0)
- spawn(1)
- if(AM)
- AM.throw_at(target, 5, 1)
+ AM.throw_at_fast(target, 5, 1)
H.vent_gas(loc)
qdel(H)
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index 8b058c4096c..346264b7354 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -457,10 +457,9 @@
visible_message("[src]'s crusher goes way too many levels too high, crushing right through space-time!")
playsound(src.loc, 'sound/effects/supermatter.ogg', 50, 1, -3)
investigate_log("Experimentor has triggered the 'throw things' reaction.", "experimentor")
- spawn(0)
- for(var/atom/movable/AM in oview(7,src))
- if(!AM.anchored)
- AM.throw_at(src,10,1)
+ for(var/atom/movable/AM in oview(7,src))
+ if(!AM.anchored)
+ AM.throw_at_fast(src,10,1)
if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("[src]'s crusher goes one level too high, crushing right into space-time!")
@@ -470,10 +469,9 @@
for(var/atom/movable/AM in oview(7,src))
if(!AM.anchored)
throwAt.Add(AM)
- spawn(0)
- for(var/counter = 1, counter < throwAt.len, ++counter)
- var/atom/movable/cast = throwAt[counter]
- cast.throw_at(pick(throwAt),10,1)
+ for(var/counter = 1, counter < throwAt.len, ++counter)
+ var/atom/movable/cast = throwAt[counter]
+ cast.throw_at_fast(pick(throwAt),10,1)
ejectItem(TRUE)
////////////////////////////////////////////////////////////////////////////////////////////////
if(exp == FAIL)
@@ -693,8 +691,7 @@
R.realProc = realProc
R.revealed = TRUE
dupes |= R
- spawn()
- R.throw_at(pick(oview(7,get_turf(src))),10,1)
+ R.throw_at_fast(pick(oview(7,get_turf(src))),10,1)
counter = 0
spawn(rand(10,100))
for(counter = 1; counter <= dupes.len; counter++)
diff --git a/html/changelog.html b/html/changelog.html
index a96327de807..50b532f92ee 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,25 @@
-->
+
07 December 2015
+
octareenroon91 updated:
+
+ - Wallets now use the access of all IDs stored inside them.
+ - As the accesses of all IDs are merged, two IDs in a wallet may grant access to a door that neither one alone would open.
+ - Wallets used to be useless for access if the first ID card put into it was taken out, until another ID card was put back in. That should not happen anymore.
+
+
+
06 December 2015
+
Gun Hog updated:
+
+ - Nanotrasen is proud to announce that it has improved its Diagnostic HUD firmware to include the station's automated robot population! New features include integrity tracking, Off/On status, and mode tracking! If your little robot friend suddenly manages to acquire free will, you will be able to track that as well!
+ - Artificial Intelligence units may find that their bot management interface now shows when a robot gains free will. This is also displayed on the Personal Data Assistant's bot control interface.
+
+
neersighted updated:
+
+ - Cryo now properly checks it is on before healing...
+
+
05 December 2015
Joan updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 3c39d7beaed..72baf0b9694 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -2740,3 +2740,22 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
2015-12-05:
Joan:
- rscdel: Magic missiles no longer do damage.
+2015-12-06:
+ Gun Hog:
+ - rscadd: Nanotrasen is proud to announce that it has improved its Diagnostic HUD
+ firmware to include the station's automated robot population! New features include
+ integrity tracking, Off/On status, and mode tracking! If your little robot friend
+ suddenly manages to acquire free will, you will be able to track that as well!
+ - tweak: Artificial Intelligence units may find that their bot management interface
+ now shows when a robot gains free will. This is also displayed on the Personal
+ Data Assistant's bot control interface.
+ neersighted:
+ - bugfix: Cryo now properly checks it is on before healing...
+2015-12-07:
+ octareenroon91:
+ - rscadd: Wallets now use the access of all IDs stored inside them.
+ - rscadd: As the accesses of all IDs are merged, two IDs in a wallet may grant access
+ to a door that neither one alone would open.
+ - bugfix: Wallets used to be useless for access if the first ID card put into it
+ was taken out, until another ID card was put back in. That should not happen
+ anymore.
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 90afe2db200..81d7d489e48 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 56c074acee9..45ec129db87 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -24,6 +24,7 @@
#include "code\__DATASTRUCTURES\stacks.dm"
#include "code\__DEFINES\admin.dm"
#include "code\__DEFINES\atmospherics.dm"
+#include "code\__DEFINES\bots.dm"
#include "code\__DEFINES\clothing.dm"
#include "code\__DEFINES\combat.dm"
#include "code\__DEFINES\flags.dm"