Merge branch 'master' of https://github.com/tgstation/-tg-station into Aghost_control

This commit is contained in:
Shadowlight213
2015-12-07 13:10:53 -08:00
44 changed files with 355 additions and 173 deletions
@@ -59,15 +59,16 @@
/obj/machinery/atmospherics/components/unary/cryo_cell/process()
..()
if(occupant && occupant.health >= 100 && autoEject)
if(occupant && occupant.health >= 100)
on = 0
open_machine()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
if(autoEject)
open_machine()
if(!NODE1 || !is_operational())
return
if(AIR1)
if (occupant)
if(on && occupant)
process_occupant()
expel_gas()
@@ -82,7 +83,7 @@
return
/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist()
usr << "<span class='notice'>Release sequence activated. This will take a few seconds.</span>"
usr << "<span class='notice'>You struggle inside the cryotube, kicking the release with your foot.</span>"
sleep(150)
if(!src || !usr || (!occupant && !contents.Find(usr))) // Make sure they didn't disappear.
return
@@ -260,6 +261,8 @@
/obj/machinery/atmospherics/components/unary/cryo_cell/proc/process_occupant()
var/datum/gas_mixture/air_contents = AIR1
if(!on)
return
if(air_contents.total_moles() < 10)
return
if(occupant)
+25
View File
@@ -0,0 +1,25 @@
//Bot defines, placed here so they can be read by other things!
#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)
+1
View File
@@ -13,6 +13,7 @@
#define DIAG_HUD "9" // Silicon health bar
#define DIAG_BATT_HUD "10"// Borg/Mech power meter
#define DIAG_MECH_HUD "11"// Mech health bar
#define DIAG_BOT_HUD "12"// Bot HUDs
//for antag huds. these are used at the /mob level
#define ANTAG_HUD "12"
+1 -1
View File
@@ -1797,7 +1797,7 @@
mind.assigned_role = "Shade"
mind.special_role = "Shade"
/mob/living/simple_animal/construct/mind_initialize()
/mob/living/simple_animal/hostile/construct/mind_initialize()
..()
mind.assigned_role = "[initial(name)]"
mind.special_role = "Cultist"
+3 -3
View File
@@ -31,7 +31,7 @@
var/mob/living/shape = new shapeshift_type(caster.loc)
caster.loc = shape
caster.status_flags |= GODMODE
current_shapes |= shape
current_casters |= caster
clothes_req = 0
@@ -54,7 +54,7 @@
human_req = initial(human_req)
current_casters.Remove(caster)
current_shapes.Remove(shape)
shape.mind.transfer_to(caster)
qdel(shape) //Gib it maybe ?
@@ -65,7 +65,7 @@
var/list/possible_shapes = list(/mob/living/simple_animal/pet/dog/corgi,\
/mob/living/simple_animal/hostile/poison/giant_spider/hunter,\
/mob/living/simple_animal/hostile/carp/megacarp,\
/mob/living/simple_animal/construct/armored)
/mob/living/simple_animal/hostile/construct/armored)
/obj/effect/proc_holder/spell/targeted/shapeshift/wild/New()
..()
+1 -1
View File
@@ -333,7 +333,7 @@
var/mob/living/M = AM
M.Weaken(2)
M << "<span class='userdanger'>You're thrown back by [user]!</span>"
spawn(0) AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time.
AM.throw_at_fast(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time.
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?!
+4
View File
@@ -165,6 +165,10 @@
step(src, AM.dir)
..()
/atom/movable/proc/throw_at_fast(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0)
set waitfor = 0
throw_at(target, range, speed, thrower, spin, diagonals_first)
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0)
if(!target || !src || (flags & NODROP)) return 0
//use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target
+38 -2
View File
@@ -45,7 +45,7 @@
hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD)
/datum/atom_hud/data/diagnostic
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD)
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD)
/* MED/SEC/DIAG HUD HOOKS */
@@ -248,4 +248,40 @@
var/image/holder = hud_list[DIAG_STAT_HUD]
holder.icon_state = null
if(internal_damage)
holder.icon_state = "hudwarn"
holder.icon_state = "hudwarn"
/*~~~~~~~~~
Bots!
~~~~~~~~~~*/
/mob/living/simple_animal/bot/proc/diag_hud_set_bothealth()
var/image/holder = hud_list[DIAG_HUD]
holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]"
/mob/living/simple_animal/bot/proc/diag_hud_set_botstat() //On (With wireless on or off), Off, EMP'ed
var/image/holder = hud_list[DIAG_STAT_HUD]
if(on)
holder.icon_state = "hudstat"
else if(stat) //Generally EMP causes this
holder.icon_state = "hudoffline"
else //Bot is off
holder.icon_state = "huddead2"
/mob/living/simple_animal/bot/proc/diag_hud_set_botmode() //Shows a bot's current operation
var/image/holder = hud_list[DIAG_BOT_HUD]
if(client) //If the bot is player controlled, it will not be following mode logic!
holder.icon_state = "hudsentient"
return
switch(mode)
if(BOT_SUMMON, BOT_RESPONDING) //Responding to PDA or AI summons
holder.icon_state = "hudcalled"
if(BOT_CLEANING, BOT_REPAIRING, BOT_HEALING) //Cleanbot cleaning, Floorbot fixing, or Medibot Healing
holder.icon_state = "hudworking"
if(BOT_PATROL, BOT_START_PATROL) //Patrol mode
holder.icon_state = "hudpatrol"
if(BOT_PREP_ARREST, BOT_ARREST, BOT_HUNT) //STOP RIGHT THERE, CRIMINAL SCUM!
holder.icon_state = "hudalert"
if(BOT_MOVING, BOT_DELIVER, BOT_GO_HOME, BOT_NAV) //Moving to target for normal bots, moving to deliver or go home for MULES.
holder.icon_state = "hudmove"
else
holder.icon_state = ""
+2
View File
@@ -183,6 +183,7 @@
if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind))
cult_mind.current.Paralyse(5)
cult += cult_mind
cult_mind.current.faction |= "cult"
cult_mind.current.cult_add_comm()
update_cult_icons_added(cult_mind)
cult_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Has been converted to the cult!</span>"
@@ -200,6 +201,7 @@
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1)
if(cult_mind in cult)
cult -= cult_mind
cult_mind.current.faction -= "cult"
cult_mind.current.verbs -= /mob/living/proc/cult_innate_comm
cult_mind.current.Paralyse(5)
cult_mind.current << "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant.</span>"
+1 -1
View File
@@ -106,7 +106,7 @@ structure_check() searches for nearby cultist structures required for the invoca
if(iscultist(L))
var/mob/living/carbon/human/H = L
if(!istype(H))
if(istype(L, /mob/living/simple_animal/construct))
if(istype(L, /mob/living/simple_animal/hostile/construct))
if(invocation)
L.say(invocation)
cultists_in_range++
+5 -5
View File
@@ -171,13 +171,13 @@
return
switch(construct_class)
if("Juggernaut")
makeNewConstruct(/mob/living/simple_animal/construct/armored, A, user)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, A, user, 0, T.loc)
if("Wraith")
makeNewConstruct(/mob/living/simple_animal/construct/wraith, A, user)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, A, user, 0, T.loc)
if("Artificer")
makeNewConstruct(/mob/living/simple_animal/construct/builder, A, user)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, A, user, 0, T.loc)
qdel(T)
qdel(src)
@@ -186,8 +186,8 @@
return
/proc/makeNewConstruct(mob/living/simple_animal/construct/ctype, mob/target, mob/stoner = null, cultoverride = 0, loc_override = null)
var/mob/living/simple_animal/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target)))
/proc/makeNewConstruct(mob/living/simple_animal/hostile/construct/ctype, mob/target, mob/stoner = null, cultoverride = 0, loc_override = null)
var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target)))
newstruct.faction |= "\ref[stoner]"
newstruct.key = target.key
if(stoner && iscultist(stoner) || cultoverride)
+1 -2
View File
@@ -26,8 +26,7 @@
audible_message("<span class='notice'>[src] lets out a screech, it doesn't seem to be able to handle the load.</span>")
break
use_power(500)
spawn(0)
O.throw_at(target, drive_range * power, power)
O.throw_at_fast(target, drive_range * power, power)
flick("mass_driver1", src)
+1 -2
View File
@@ -285,8 +285,7 @@
log_message("Launched a [O.name] from [name], targeting [target].")
projectiles--
proj_init(O)
spawn(0)
O.throw_at(target, missile_range, missile_speed, spin = 0)
O.throw_at_fast(target, missile_range, missile_speed, spin = 0)
return 1
//used for projectile initilisation (priming flashbang) and additional logging
+5 -6
View File
@@ -134,12 +134,11 @@
var/throw_dir = get_dir(epicenter,T)
for(var/obj/item/I in T)
spawn(0) //Simultaneously not one at a time
if(I && !I.anchored)
var/throw_range = rand(throw_dist, max_range)
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
I.throw_at(throw_at, throw_range, 2)//Throw it at 2 speed, this is purely visual anyway.
if(I && !I.anchored)
var/throw_range = rand(throw_dist, max_range)
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
I.throw_at_fast(throw_at, throw_range, 2)//Throw it at 2 speed, this is purely visual anyway.
var/took = (world.timeofday-start)/10
+3 -4
View File
@@ -467,10 +467,9 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
bloody_hands_mob = null
/obj/item/singularity_pull(S, current_size)
spawn(0) //this is needed or multiple items will be thrown sequentially and not simultaneously
if(current_size >= STAGE_FOUR)
throw_at(S,14,3, spin=0)
else ..()
if(current_size >= STAGE_FOUR)
throw_at_fast(S,14,3, spin=0)
else ..()
/obj/item/acid_act(acidpwr, acid_volume)
. = 1
@@ -116,12 +116,11 @@
add_logs(user, target, "fired at", src)
playsound(src.loc, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
for(var/obj/item/ITD in loadedItems) //Item To Discharge
spawn(0)
loadedItems.Remove(ITD)
loadedWeightClass -= ITD.w_class
ITD.throw_speed = pressureSetting * 2
ITD.loc = get_turf(src)
ITD.throw_at(target, pressureSetting * 5, pressureSetting * 2,user)
loadedItems.Remove(ITD)
loadedWeightClass -= ITD.w_class
ITD.throw_speed = pressureSetting * 2
ITD.loc = get_turf(src)
ITD.throw_at_fast(target, pressureSetting * 5, pressureSetting * 2,user)
if(pressureSetting >= 3 && user)
user.visible_message("<span class='warning'>[user] is thrown down by the force of the cannon!</span>", "<span class='userdanger'>[src] slams into your shoulder, knocking you down!")
user.Weaken(3)
@@ -30,21 +30,31 @@
slot_flags = SLOT_ID
var/obj/item/weapon/card/id/front_id = null
var/list/combined_access = list()
/obj/item/weapon/storage/wallet/remove_from_storage(obj/item/W, atom/new_location)
. = ..(W, new_location)
if(.)
if(W == front_id)
front_id = null
if(istype(W, /obj/item/weapon/card/id))
if(W == front_id)
front_id = null
refreshID()
update_icon()
/obj/item/weapon/storage/wallet/proc/refreshID()
combined_access.Cut()
for(var/obj/item/weapon/card/id/I in contents)
if(!front_id)
front_id = I
update_icon()
combined_access |= I.access
/obj/item/weapon/storage/wallet/handle_item_insertion(obj/item/W, prevent_warning = 0)
. = ..(W, prevent_warning)
if(.)
if(!front_id && istype(W, /obj/item/weapon/card/id))
front_id = W
update_icon()
if(istype(W, /obj/item/weapon/card/id))
refreshID()
/obj/item/weapon/storage/wallet/update_icon()
@@ -69,9 +79,8 @@
return front_id
/obj/item/weapon/storage/wallet/GetAccess()
var/obj/item/I = GetID()
if(I)
return I.GetAccess()
if(combined_access.len)
return combined_access
else
return ..()
@@ -89,4 +98,4 @@
if(item2_type)
new item2_type(src)
if(item3_type)
new item3_type(src)
new item3_type(src)
+4
View File
@@ -4,6 +4,10 @@
if (!key || !address || !computer_id)
log_access("Failed Login (invalid data): [key] [address]-[computer_id]")
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]'. (If you continue to get this error, please restart byond or contact byond support.)")
if (computer_id == 2147483647) //this cid causes stickybans to go haywire
log_access("Failed Login (invalid cid): [key] [address]-[computer_id]")
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)")
var/admin = 0
var/ckey = ckey(key)
if((ckey in admin_datums) || (ckey in deadmins))
+3 -3
View File
@@ -400,9 +400,9 @@
if("coffee") M.change_mob_type( /mob/living/simple_animal/crab/Coffee , null, null, delmob )
if("parrot") M.change_mob_type( /mob/living/simple_animal/parrot , null, null, delmob )
if("polyparrot") M.change_mob_type( /mob/living/simple_animal/parrot/Poly , null, null, delmob )
if("constructarmored") M.change_mob_type( /mob/living/simple_animal/construct/armored , null, null, delmob )
if("constructbuilder") M.change_mob_type( /mob/living/simple_animal/construct/builder , null, null, delmob )
if("constructwraith") M.change_mob_type( /mob/living/simple_animal/construct/wraith , null, null, delmob )
if("constructarmored") M.change_mob_type( /mob/living/simple_animal/hostile/construct/armored , null, null, delmob )
if("constructbuilder") M.change_mob_type( /mob/living/simple_animal/hostile/construct/builder , null, null, delmob )
if("constructwraith") M.change_mob_type( /mob/living/simple_animal/hostile/construct/wraith , null, null, delmob )
if("shade") M.change_mob_type( /mob/living/simple_animal/shade , null, null, delmob )
@@ -163,7 +163,7 @@ var/sc_safecode5 = "[rand(0,9)]"
desc = "Your body becomes weak and your feel your mind slipping away as you try to comprehend what you know can't be possible."
move_self = 0 //Contianed narsie does not move!
grav_pull = 0 //Contained narsie does not pull stuff in!
var/uneatable = list(/turf/space, /obj/effect/overlay, /mob/living/simple_animal/construct)
var/uneatable = list(/turf/space, /obj/effect/overlay, /mob/living/simple_animal/hostile/construct)
//Override this to prevent no adminlog runtimes and admin warnings about a singularity without containment
/obj/singularity/narsie/sc_Narsie/admin_investigate_setup()
return
@@ -207,7 +207,7 @@
var/list/nearby_turfs = orange(3, get_turf(src))
var/obj/item/meatslab = allmeat[i]
meatslab.loc = src.loc
meatslab.throw_at(pick(nearby_turfs),i,3)
meatslab.throw_at_fast(pick(nearby_turfs),i,3)
for (var/turfs=1 to meat_produced*3)
var/turf/gibturf = pick(nearby_turfs)
if (!gibturf.density && src in viewers(gibturf))
+1 -1
View File
@@ -316,7 +316,7 @@ var/global/list/datum/cachedbook/cachedbooks // List of our cached book datums
usr << browse(null, "window=library")
onclose(usr, "library")
return
if(href_list["page"] && screenstate == 4 && isnum(href_list["page"]))
if(href_list["page"] && screenstate == 4)
page = text2num(href_list["page"])
if(href_list["switchscreen"])
switch(href_list["switchscreen"])
+1 -1
View File
@@ -766,7 +766,7 @@ Sorry Giacom. Please don't be mad :(
/mob/living/narsie_act()
if(client)
makeNewConstruct(/mob/living/simple_animal/construct/harvester, src, null, 0)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, null, 0)
spawn_dust()
gib()
return
+4 -3
View File
@@ -517,15 +517,16 @@ var/list/ai_list = list()
var/ai_Zlevel = ai_current_turf.z
var/d
var/area/bot_area
d += "<A HREF=?src=\ref[src];botrefresh=\ref[Bot]>Query network status</A><br>"
d += "<A HREF=?src=\ref[src];botrefresh=1>Query network status</A><br>"
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='30%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
for (Bot in living_mob_list)
if(Bot.z == ai_Zlevel && !Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
bot_area = get_area(Bot)
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!)</span>" : ""] [Bot.name] ([Bot.model])</td>"
var/bot_mode = Bot.get_mode()
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!)</span>" : ""] [Bot.name]</A> ([Bot.model])</td>"
//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 += "<td width='30%'>[Bot.on ? "[Bot.mode ? "<span class='average'>[ Bot.get_mode() ]</span>": "<span class='good'>Idle</span>"]" : "<span class='bad'>Inactive</span>"]</td>"
d += "<td width='30%'>[bot_mode]</td>"
d += "<td width='30%'>[bot_area.name]</td>"
d += "<td width='10%'><A HREF=?src=\ref[src];interface=\ref[Bot]>Interface</A></td>"
d += "<td width='10%'><A HREF=?src=\ref[src];callbot=\ref[Bot]>Call</A></td>"
@@ -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 "<b>Sentient</b>"
else if(!on)
return "<span class='bad'>Inactive</span>"
else if(!mode)
return "<span class='good'>Idle</span>"
else
return mode_name[mode]
return "<span class='average'>[mode_name[mode]]</span>"
/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 << "<span class='warning'>[src]'s interface is not responding!</span>"
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()
. = ..()
@@ -231,7 +231,8 @@ text("<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>"))
return dat
/mob/living/simple_animal/bot/cleanbot/Topic(href, href_list)
..()
if(..())
return 1
switch(href_list["operation"])
if("blood")
blood =!blood
@@ -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)
@@ -118,7 +118,9 @@
user << "<span class='danger'>[src] buzzes and beeps.</span>"
/mob/living/simple_animal/bot/floorbot/Topic(href, href_list)
..()
if(..())
return 1
switch(href_list["operation"])
if("replace")
replacetiles = !replacetiles
@@ -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"])
@@ -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)
..()
@@ -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 = "<b>You are a generic construct! Your job is to not exist.</b>"
var/playstyle_string = "<b>You are a generic construct! Your job is to not exist, and you should probably adminhelp this.</b>"
/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("<span class='danger'>[src] collapses in a shattered heap.</span>")
@@ -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 = "<span cass='info'>*---------*\nThis is \icon[src] \a <b>[src]</b>!\n"
if (src.health < src.maxHealth)
msg += "<span class='warning'>"
@@ -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("<span class='danger'>[M] repairs some of \the <b>[src]'s</b> dents.</span>", \
"<span class='cult'>You repair some of <b>[src]'s</b> dents, leaving <b>[src]</b> at [health]/[maxHealth] health.</span>")
"<span class='cult'>You repair some of <b>[src]'s</b> dents, leaving <b>[src]</b> at <b>[health]/[maxHealth]</b> health.</span>")
else
M.visible_message("<span class='danger'>[M] repairs some of its own dents.</span>", \
"<span class='cult'>You repair some of your own dents, leaving you at [M.health]/[M.maxHealth] health.</span>")
"<span class='cult'>You repair some of your own dents, leaving you at <b>[M.health]/[M.maxHealth]</b> health.</span>")
else
if(src != M)
M << "<span class='cult'>You cannot repair <b>[src]'s</b> dents, as it has none!</span>"
@@ -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 = "<b>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.</b>"
/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 = "<b>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</b>"
/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 @@
<i>and, most important of all,</i> create new constructs by producing soulstones to capture souls, \
and shells to place those soulstones into.</b>"
/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 = "<B>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.</B>"
/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
@@ -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)
@@ -37,11 +37,11 @@
var/morph_time = 0
var/playstyle_string = "<b><font size=3 color='red'>You are a morph,</font> 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.</b>"
Finally, you can restore yourself to your original form while morphed by shift-clicking yourself.</b>"
/mob/living/simple_animal/hostile/morph/examine(mob/user)
if(morphed)
@@ -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.
+1 -1
View File
@@ -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!
+4
View File
@@ -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)
+1 -1
View File
@@ -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)
@@ -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
+1 -3
View File
@@ -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)
+7 -10
View File
@@ -457,10 +457,9 @@
visible_message("<span class='danger'>[src]'s crusher goes way too many levels too high, crushing right through space-time!</span>")
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("<span class='danger'>[src]'s crusher goes one level too high, crushing right into space-time!</span>")
@@ -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++)
+19
View File
@@ -55,6 +55,25 @@
-->
<div class="commit sansserif">
<h2 class="date">07 December 2015</h2>
<h3 class="author">octareenroon91 updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Wallets now use the access of all IDs stored inside them.</li>
<li class="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.</li>
<li class="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.</li>
</ul>
<h2 class="date">06 December 2015</h2>
<h3 class="author">Gun Hog updated:</h3>
<ul class="changes bgimages16">
<li class="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!</li>
<li class="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.</li>
</ul>
<h3 class="author">neersighted updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Cryo now properly checks it is on before healing...</li>
</ul>
<h2 class="date">05 December 2015</h2>
<h3 class="author">Joan updated:</h3>
<ul class="changes bgimages16">
+19
View File
@@ -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.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

+1
View File
@@ -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"