This commit is contained in:
LetterJay
2017-10-19 09:01:55 -05:00
71 changed files with 595 additions and 309 deletions
+11
View File
@@ -240,6 +240,17 @@ This prevents nesting levels from getting deeper then they need to be.
* Queries must never specify the database, be it in code, or in text files in the repo.
### Mapping Standards
* TGM Format & Map Merge
* All new maps submitted to the repo through a pull request must be in TGM format (unless there is a valid reason present to have it in the default BYOND format.) This is done using the [Map Merge](https://github.com/tgstation/tgstation/wiki/Map-Merger) utility included in the repo to convert the file to TGM format.
* Likewise, you MUST run `Map Merge - TGM.bat` prior to opening your PR when updating existing maps to minimize the change differences (even when using third party mapping programs such as FastDMM.)
* Failure to run Map Merge on a map after using third party mapping programs (such as FastDMM) greatly increases the risk of the map's key dictionary becoming corrupted by future edits after running map merge. Resolving the corruption issue involves rebuilding the map's key dictionary; id est rewriting all the keys contained within the map by reconverting it from BYOND to TGM format - which creates very large differences that ultimately delay the PR process and is extremely likely to cause merge conflicts with other pull requests.
* Variable Editing (Var-edits)
* While var-editing an item within the editor is perfectly fine, it is preferred that when you are changing the base behavior of an item (how it functions) that you make a new subtype of that item within the code, especially if you plan to use the item in multiple locations on the same map, or across multiple maps. This makes it easier to make corrections as needed to all instances of the item at one time as opposed to having to find each instance of it and change them all individually.
* Subtypes only intended to be used on away mission or ruin maps should be contained within an .dm file with a name corresponding to that map within `code\modules\awaymissions` or `code\modules\ruins` respectively. This is so in the event that the map is removed, that subtype will be removed at the same time as well to minimize leftover/unused data within the repo.
* Please attempt to clean out any dirty variables that may be contained within items you alter through var-editing. For example, due to how DM functions, changing the `pixel_x` variable from 23 to 0 will leave a dirty record in the map's code of `pixel_x = 0`. Likewise this can happen when changing an item's icon to something else and then back. This can lead to some issues where an item's icon has changed within the code, but becomes broken on the map due to it still attempting to use the old entry.
* Areas should not be var-edited on a map to change it's name or attributes. All areas of a single type and it's altered instances are considered the same area within the code, and editing their variables on a map can lead to issues with powernets and event subsystems which are difficult to debug.
### Other Notes
@@ -40811,6 +40811,7 @@
network = list("MiniSat","tcomm");
pixel_y = -29
},
/obj/structure/bed/dogbed/renault,
/mob/living/simple_animal/pet/fox/Renault,
/turf/open/floor/carpet,
/area/crew_quarters/heads/captain/private)
+119 -95
View File
@@ -46290,11 +46290,6 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"car" = (
/obj/structure/cable/yellow{
icon_state = "1-4";
d1 = 1;
d2 = 4
},
/obj/structure/cable/yellow{
d1 = 1;
d2 = 8;
@@ -47261,16 +47256,6 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"ccV" = (
/obj/structure/cable/yellow{
d1 = 4;
d2 = 8;
icon_state = "4-8"
},
/obj/structure/cable/yellow{
d1 = 2;
d2 = 4;
icon_state = "2-4"
},
/obj/effect/turf_decal/stripes/line{
dir = 4
},
@@ -47282,22 +47267,12 @@
id = "Singularity";
name = "radiation shutters"
},
/obj/structure/cable/yellow{
d1 = 4;
d2 = 8;
icon_state = "4-8"
},
/obj/effect/turf_decal/bot{
dir = 2
},
/turf/open/floor/plasteel/black,
/area/engine/engineering)
"ccX" = (
/obj/structure/cable/yellow{
d1 = 4;
d2 = 8;
icon_state = "4-8"
},
/obj/structure/cable/yellow{
d1 = 2;
d2 = 4;
@@ -47326,11 +47301,6 @@
/turf/open/floor/plating,
/area/engine/engineering)
"cda" = (
/obj/structure/cable/yellow{
d1 = 1;
d2 = 4;
icon_state = "1-4"
},
/obj/effect/landmark/event_spawn,
/turf/open/floor/plating,
/area/engine/engineering)
@@ -47346,16 +47316,6 @@
/turf/open/floor/plating,
/area/engine/engineering)
"cdc" = (
/obj/structure/cable/yellow{
d1 = 2;
d2 = 8;
icon_state = "2-8"
},
/obj/structure/cable/yellow{
d1 = 4;
d2 = 8;
icon_state = "4-8"
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
@@ -47599,19 +47559,9 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"cdQ" = (
/obj/structure/cable/yellow{
d1 = 1;
d2 = 2;
icon_state = "1-2"
},
/turf/open/floor/plasteel/yellow/side,
/area/engine/engineering)
"cdR" = (
/obj/structure/cable/yellow{
d1 = 1;
d2 = 2;
icon_state = "1-2"
},
/obj/machinery/button/door{
id = "Singularity";
name = "Shutters Control";
@@ -47666,11 +47616,6 @@
/turf/open/floor/plating,
/area/engine/engineering)
"cdX" = (
/obj/structure/cable/yellow{
d1 = 1;
d2 = 2;
icon_state = "1-2"
},
/obj/machinery/button/door{
id = "Singularity";
name = "Shutters Control";
@@ -47850,14 +47795,10 @@
id = "Singularity";
name = "radiation shutters"
},
/obj/structure/cable/yellow{
d1 = 1;
d2 = 2;
icon_state = "1-2"
},
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/engine/engineering)
"ceu" = (
@@ -48053,9 +47994,6 @@
/turf/open/floor/plating,
/area/engine/engineering)
"ceY" = (
/obj/machinery/power/rad_collector/anchored,
/obj/item/tank/internals/plasma,
/obj/structure/cable/yellow,
/obj/effect/turf_decal/stripes/line{
dir = 1
},
@@ -48872,6 +48810,9 @@
icon_state = "0-8"
},
/obj/machinery/power/tesla_coil,
/obj/structure/window/plasma/reinforced{
dir = 4
},
/turf/open/floor/plating/airless,
/area/engine/engineering)
"chy" = (
@@ -48884,6 +48825,9 @@
d2 = 4
},
/obj/machinery/power/tesla_coil,
/obj/structure/window/plasma/reinforced{
dir = 8
},
/turf/open/floor/plating/airless,
/area/engine/engineering)
"chA" = (
@@ -49000,7 +48944,15 @@
/turf/open/floor/plating/airless,
/area/engine/engineering)
"chQ" = (
/turf/open/space/basic,
/obj/structure/window/plasma/reinforced{
dir = 4
},
/obj/machinery/power/rad_collector/anchored,
/obj/structure/cable/yellow{
d2 = 8;
icon_state = "0-8"
},
/turf/open/floor/plating/airless,
/area/engine/engineering)
"chR" = (
/obj/structure/cable{
@@ -54066,6 +54018,78 @@
/obj/machinery/smoke_machine,
/turf/open/floor/plasteel/white,
/area/medical/chemistry)
"YXI" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/poddoor/shutters/preopen{
id = "Singularity";
name = "radiation shutters"
},
/obj/effect/turf_decal/bot{
dir = 2
},
/turf/open/floor/plasteel/black,
/area/engine/engineering)
"YXJ" = (
/obj/machinery/power/rad_collector/anchored,
/turf/open/floor/plating,
/area/engine/engineering)
"YXK" = (
/obj/machinery/power/rad_collector/anchored,
/turf/open/floor/plating,
/area/engine/engineering)
"YXL" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/turf/open/floor/plating,
/area/engine/engineering)
"YXM" = (
/obj/structure/cable/yellow{
d1 = 1;
d2 = 2;
icon_state = "1-2"
},
/obj/structure/cable/yellow{
icon_state = "1-4";
d1 = 1;
d2 = 4
},
/obj/item/tank/internals/plasma,
/turf/open/floor/plating/airless,
/area/engine/engineering)
"YXN" = (
/obj/structure/window/plasma/reinforced{
dir = 8
},
/obj/machinery/power/rad_collector/anchored,
/obj/structure/cable/yellow{
icon_state = "0-4";
d2 = 4
},
/turf/open/floor/plating/airless,
/area/engine/engineering)
"YXO" = (
/obj/structure/window/plasma/reinforced{
dir = 8
},
/obj/machinery/power/rad_collector/anchored,
/obj/structure/cable/yellow{
icon_state = "0-4";
d2 = 4
},
/turf/open/floor/plating/airless,
/area/engine/engineering)
"YXP" = (
/obj/structure/window/plasma/reinforced{
dir = 8
},
/obj/machinery/power/rad_collector/anchored,
/obj/structure/cable/yellow{
icon_state = "0-4";
d2 = 4
},
/turf/open/floor/plating/airless,
/area/engine/engineering)
(1,1,1) = {"
aaa
@@ -81734,7 +81758,7 @@ bOG
bva
bDi
bXk
cbX
YXJ
cbX
cdK
bXk
@@ -81991,7 +82015,7 @@ bOG
bTE
cae
bXk
cbX
YXK
cbX
cdK
bXk
@@ -83791,20 +83815,20 @@ bZC
cal
cbh
cam
ccT
cam
cdQ
cet
ceY
cfa
cbX
cfU
cgu
cgU
chw
cgU
YXM
chw
chw
chw
cgU
chw
cgU
cjs
cfV
cfV
@@ -84048,18 +84072,18 @@ bZA
cam
cam
cam
ccU
cam
cdQ
cet
ceZ
cfa
ceY
cbX
cfV
cgv
cfV
chx
chQ
chx
cfV
chQ
chx
chQ
chx
@@ -84308,8 +84332,8 @@ ccc
ccV
cdR
cet
ceZ
cfa
ceY
cbX
cfU
cgv
cgV
@@ -85587,9 +85611,9 @@ bXo
bYi
bYV
bZA
cas
cbk
cce
cdN
YXI
YXL
cda
cdV
cex
@@ -85847,7 +85871,7 @@ bZF
cat
bXk
ccg
cdb
cey
cdW
cey
cey
@@ -86364,8 +86388,8 @@ cch
cdc
cdX
cet
ceZ
cfa
ceY
cbX
cfU
cgv
cgV
@@ -86618,20 +86642,20 @@ bZA
cam
cam
cam
cdd
cam
cdQ
cet
ceZ
cfa
ceY
cbX
cfV
cgv
cfV
chz
chQ
YXN
chz
cfV
YXO
chz
chQ
YXP
chz
cfV
cfV
@@ -86875,20 +86899,20 @@ bZC
cal
cbm
cci
cde
cam
cdQ
cet
ceZ
cfa
ceY
cbX
cfU
cgx
cgU
chA
cgU
chA
cgU
chA
cgU
chA
chA
chA
cjt
cfV
cfV
+1
View File
@@ -93,6 +93,7 @@
//Mob AI Status
//Hostile simple animals
//If you add a new status, be sure to add a list for it to the simple_animals global in _globalvars/lists/mobs.dm
#define AI_ON 1
#define AI_IDLE 2
#define AI_OFF 3
+9 -6
View File
@@ -18,13 +18,16 @@ Ask ninjanomnom if they're around
#define RAD_TOX_COEFFICIENT 0.05 // Toxin damage per tick coefficient
#define RAD_MOB_SAFE 300 // How much stored radiation in a mob with no ill effects
#define RAD_MOB_KNOCKDOWN 1500 // How much stored radiation to start stunning
// If (mutate*2<knockdown) then monkeys will sometimes turn into gorillas before being knocked down
// otherwise they only turn into gorillas *after* being knocked down
#define RAD_MOB_MUTATE 800 // How much stored radiation to check for mutation
#define RAD_MOB_HAIRLOSS 500 // How much stored radiation to check for hair loss
#define RAD_KNOCKDOWN_TIME 200 // How much knockdown to apply
#define RAD_MOB_KNOCKDOWN 2000 // How much stored radiation to check for stunning
#define RAD_MOB_KNOCKDOWN_PROB 1 // Chance of knockdown per tick when over threshold
#define RAD_MOB_KNOCKDOWN_AMOUNT 3 // Amount of knockdown when it occurs
#define RAD_MOB_VOMIT 1500 // The amount of radiation to check for vomitting
#define RAD_MOB_VOMIT_PROB 1 // Chance per tick of vomitting
#define RAD_MOB_MUTATE 1000 // How much stored radiation to check for mutation
#define RAD_MOB_HAIRLOSS 500 // How much stored radiation to check for hair loss
#define RAD_NO_INSULATION 1.0 // For things that shouldn't become irradiated for whatever reason
#define RAD_VERY_LIGHT_INSULATION 0.9 // What girders have
+1 -1
View File
@@ -19,7 +19,7 @@ GLOBAL_LIST_EMPTY(silicon_mobs) //all silicon mobs
GLOBAL_LIST_EMPTY(ai_list)
GLOBAL_LIST_EMPTY(pai_list)
GLOBAL_LIST_EMPTY(available_ai_shells)
GLOBAL_LIST_EMPTY(simple_animals)
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
GLOBAL_LIST_EMPTY(language_datum_instances)
+11 -16
View File
@@ -22,7 +22,6 @@
else
A.move_camera_by_click()
/mob/living/silicon/ai/ClickOn(var/atom/A, params)
if(world.time <= next_click)
return
@@ -36,20 +35,16 @@
return
var/turf/pixel_turf = get_turf_pixel(A)
var/turf_visible
if(pixel_turf)
turf_visible = GLOB.cameranet.checkTurfVis(pixel_turf)
if(!turf_visible)
if(istype(loc, /obj/item/device/aicard) && (pixel_turf in view(client.view, loc)))
turf_visible = TRUE
else
if (pixel_turf.obscured)
log_admin("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)])")
message_admins("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))")
if(REALTIMEOFDAY >= chnotify + 9000)
chnotify = REALTIMEOFDAY
send2irc_adminless_only("NOCHEAT", "[key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))")
return
if(isnull(pixel_turf))
return
if(!can_see(A))
message_admins("[key_name_admin(src)] might be running a modified client! (failed can_see on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))")
var/message = "[key_name(src)] might be running a modified client! (failed can_see on AI click of [A]([COORD(pixel_turf)]))"
log_admin(message)
if(REALTIMEOFDAY >= chnotify + 9000)
chnotify = REALTIMEOFDAY
send2irc_adminless_only("NOCHEAT", message)
return
var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["ctrl"])
@@ -74,7 +69,7 @@
if(world.time <= next_move)
return
if(aicamera.in_camera_mode && pixel_turf && turf_visible)
if(aicamera.in_camera_mode)
aicamera.camera_mode_off()
aicamera.captureimage(pixel_turf, usr)
return
+3 -3
View File
@@ -243,7 +243,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
/obj/screen/alert/fire/Click()
var/mob/living/L = usr
if(!L.can_resist())
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if(L.canmove)
@@ -559,7 +559,7 @@ so as to remain in compliance with the most up-to-date laws."
/obj/screen/alert/restrained/Click()
var/mob/living/L = usr
if(!L.can_resist())
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if((L.canmove) && (L.last_special <= world.time))
@@ -567,7 +567,7 @@ so as to remain in compliance with the most up-to-date laws."
/obj/screen/alert/restrained/buckled/Click()
var/mob/living/L = usr
if(!L.can_resist())
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if(L.last_special <= world.time)
+34
View File
@@ -0,0 +1,34 @@
SUBSYSTEM_DEF(idlenpcpool)
name = "Idling NPC Pool"
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
priority = 10
wait = 60
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun = list()
/datum/controller/subsystem/idlenpcpool/stat_entry()
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
..("IdleNPCS:[idlelist.len]")
/datum/controller/subsystem/idlenpcpool/fire(resumed = FALSE)
if (!resumed)
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
src.currentrun = idlelist.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
--currentrun.len
if(!SA.ckey)
if(SA.stat != DEAD)
SA.handle_automated_movement()
if(SA.stat != DEAD)
SA.consider_wakeup()
if (MC_TICK_CHECK)
return
+2 -1
View File
@@ -37,7 +37,8 @@ SUBSYSTEM_DEF(npcpool)
// 5. Do all assignments: goes through the delegated/coordianted bots and assigns the right variables/tasks to them.
if (!resumed)
src.currentrun = GLOB.simple_animals.Copy()
var/list/activelist = GLOB.simple_animals[AI_ON]
src.currentrun = activelist.Copy()
stage = PROCESSING_SIMPLES
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
@@ -0,0 +1,89 @@
/*
list/atom/output_atoms
mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end.
mid_length (num) The length to wait between playing mid_sounds
start_sound (soundfile) Played before starting the mid_sounds loop
start_length (num) How long to wait before starting the main loop after playing start_sound
end_sound (soundfile) The sound played after the main loop has concluded
chance (num) Chance per loop to play a mid_sound
volume (num) Sound output volume
muted (bool) Private. Used to stop the sound loop.
max_loops (num) The max amount of loops to run for.
*/
/datum/looping_sound
var/list/atom/output_atoms
var/mid_sounds
var/mid_length
var/start_sound
var/start_length
var/end_sound
var/chance
var/volume
var/muted = TRUE
var/max_loops
/datum/looping_sound/New(list/_output_atoms, start_immediately=FALSE)
if(!mid_sounds)
WARNING("A looping sound datum was created without sounds to play.")
return
if(_output_atoms)
output_atoms = _output_atoms
else
output_atoms = list()
if(start_immediately)
start()
/datum/looping_sound/Destroy()
stop()
output_atoms = null
return ..()
/datum/looping_sound/proc/start()
if(!muted)
return
muted = FALSE
on_start()
/datum/looping_sound/proc/stop()
if(muted)
return
muted = TRUE
/datum/looping_sound/proc/sound_loop(looped=0)
if(muted || (max_loops && looped > max_loops))
on_stop(looped)
return
if(!chance || prob(chance))
play(get_sound(looped))
addtimer(CALLBACK(src, .proc/sound_loop, ++looped), mid_length)
/datum/looping_sound/proc/play(soundfile)
var/list/atoms_cache = output_atoms
for(var/i in 1 to atoms_cache.len)
var/atom/thing = atoms_cache[i]
playsound(thing, soundfile, volume)
/datum/looping_sound/proc/get_sound(looped, _mid_sounds)
if(!_mid_sounds)
. = mid_sounds
else
. = _mid_sounds
while(!isfile(.) && !isnull(.))
. = pickweight(.)
/datum/looping_sound/proc/on_start()
var/start_wait = 0
if(start_sound)
play(start_sound)
start_wait = start_length
addtimer(CALLBACK(src, .proc/sound_loop), start_wait)
/datum/looping_sound/proc/on_stop(looped)
if(end_sound)
play(end_sound)
@@ -0,0 +1,9 @@
/datum/looping_sound/showering
start_sound = 'sound/machines/shower/shower_start.ogg'
start_length = 2
mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1)
mid_length = 10
end_sound = 'sound/machines/shower/shower_end.ogg'
volume = 25
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -89,7 +89,7 @@
continue
thing.rad_act(strength)
var/static/list/blacklisted = typecacheof(list(/turf, /obj/structure/cable, /obj/machinery/atmospherics))
var/static/list/blacklisted = typecacheof(list(/turf, /mob, /obj/structure/cable, /obj/machinery/atmospherics))
if(!can_contaminate || blacklisted[thing.type])
continue
if(prob((strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1/(steps*range_modifier), 1))) // Only stronk rads get to have little baby rads
@@ -38,7 +38,7 @@
beckon(AM)
/obj/effect/clockwork/city_of_cogs_rift/proc/beckon(atom/movable/AM)
AM.visible_message("<span class='danger'>[AM] passes through [src]!</span>", ignore_mob = AM)
AM.visible_message("<span class='danger'>[AM] passes through [src]!</span>", ignored_mob = AM)
AM.forceMove(pick(!is_servant_of_ratvar(AM) ? GLOB.city_of_cogs_spawns : GLOB.servant_spawns))
AM.visible_message("<span class='danger'>[AM] materializes from the air!</span>", \
"<span class='boldannounce'>You pass through [src] and appear [is_servant_of_ratvar(AM) ? "back at the City of Cogs" : "somewhere unfamiliar. Looks like it was a one-way trip.."].</span>")
+5 -1
View File
@@ -45,7 +45,11 @@
/datum/game_mode/wizard/check_finished()
for(var/datum/mind/wizard in wizards)
if(isliving(wizard.current) && wizard.current.stat!=DEAD)
return ..()
return FALSE
for(var/obj/item/phylactery/P in GLOB.poi_list) //TODO : IsProperlyDead()
if(P.mind && P.mind.has_antag_datum(/datum/antagonist/wizard))
return FALSE
if(SSevents.wizardmode) //If summon events was active, turn it off
SSevents.toggleWizardmode()
+1 -1
View File
@@ -9,7 +9,7 @@
#define RADIATION_DURATION_MAX 30
#define RADIATION_ACCURACY_MULTIPLIER 3 //larger is less accurate
#define RADIATION_IRRADIATION_MULTIPLIER 10 //multiplier for how much radiation a test subject recieves
#define RADIATION_IRRADIATION_MULTIPLIER 1 //multiplier for how much radiation a test subject recieves
#define SCANNER_ACTION_SE 1
#define SCANNER_ACTION_UI 2
+1 -1
View File
@@ -798,7 +798,7 @@
// Otherwise it will runtime with this kind of error: null.Topic()
if(!nowindow)
..()
if(usr.incapacitated() && !IsAdminGhost(usr))
if(!usr.canUseTopic(src) && !IsAdminGhost(usr))
return
add_fingerprint(usr)
if(href_list["close"])
+1 -1
View File
@@ -617,7 +617,7 @@ GLOBAL_LIST_EMPTY(PDAs)
P.show_recieved_message(msg,src)
if(!multiple)
show_to_ghosts(user,msg)
log_talk(user,"[key_name(user)] (PDA: [initial(name)]) sent \"[message]\" to [key_name(P,null,TRUE)]",LOGPDA)
log_talk(user,"[key_name(user)] (PDA: [initial(name)]) sent \"[message]\" to [P.name]",LOGPDA)
else
if(!multiple)
to_chat(user, "<span class='notice'>ERROR: Server isn't responding.</span>")
+2 -9
View File
@@ -124,6 +124,8 @@ GLOBAL_LIST_EMPTY(GPS_list)
a = copytext(sanitize(a), 1, 20)
gpstag = a
. = TRUE
name = "global positioning system ([gpstag])"
if("power")
toggletracking(usr)
. = TRUE
@@ -134,15 +136,6 @@ GLOBAL_LIST_EMPTY(GPS_list)
global_mode = !global_mode
. = TRUE
/obj/item/device/gps/Topic(href, href_list)
..()
if(href_list["tag"] )
var/a = input("Please enter desired tag.", name, gpstag) as text
a = uppertext(copytext(sanitize(a), 1, 5))
if(in_range(src, usr))
gpstag = a
name = "global positioning system ([gpstag])"
attack_self(usr)
/obj/item/device/gps/science
icon_state = "gps-s"
@@ -109,7 +109,6 @@
new /obj/item/clothing/gloves/krav_maga/sec(src)
new /obj/item/door_remote/head_of_security(src)
new /obj/item/gun/ballistic/shotgun/automatic/combat/compact(src)
new /obj/item/pinpointer/crew(src)
/obj/structure/closet/secure_closet/security
name = "security officer's locker"
@@ -68,14 +68,15 @@
START_PROCESSING(SSfastprocess, src)
/obj/machinery/manned_turret/process()
if(!LAZYLEN(buckled_mobs))
if (!update_positioning())
return PROCESS_KILL
update_positioning()
/obj/machinery/manned_turret/proc/update_positioning()
if (!LAZYLEN(buckled_mobs))
return FALSE
var/mob/living/controller = buckled_mobs[1]
if(!istype(controller))
return
return FALSE
var/client/C = controller.client
if(C)
var/atom/A = C.mouseObject
@@ -143,7 +144,7 @@
addtimer(CALLBACK(src, /obj/machinery/manned_turret/.proc/fire_helper, user), i*rate_of_fire)
/obj/machinery/manned_turret/proc/fire_helper(mob/user)
if(user.incapacitated())
if(user.incapacitated() || !(user in buckled_mobs))
return
update_positioning() //REFRESH MOUSE TRACKING!!
var/turf/targets_from = get_turf(src)
@@ -199,7 +199,15 @@
var/obj/effect/mist/mymist = null
var/ismist = 0 //needs a var so we can make it linger~
var/watertemp = "normal" //freezing, normal, or boiling
var/datum/looping_sound/showering/soundloop
/obj/machinery/shower/Initialize()
. = ..()
soundloop = new(list(src), FALSE)
/obj/machinery/shower/Destroy()
QDEL_NULL(soundloop)
return ..()
/obj/effect/mist
name = "mist"
@@ -215,6 +223,7 @@
update_icon()
add_fingerprint(M)
if(on)
soundloop.start()
wash_turf()
for(var/atom/movable/G in loc)
if(isliving(G))
@@ -223,6 +232,7 @@
else if(isobj(G)) // Skip the light objects
wash_obj(G)
else
soundloop.stop()
if(isopenturf(loc))
var/turf/open/tile = loc
tile.MakeSlippery(min_wet_time = 5, wet_time_to_add = 1)
@@ -368,6 +378,15 @@
else
L.clean_blood()
/obj/machinery/shower/proc/contamination_cleanse(atom/movable/thing)
var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
if(!healthy_green_glow || QDELETED(healthy_green_glow))
return
var/strength = healthy_green_glow.strength
if(strength <= RAD_BACKGROUND_RADIATION)
qdel(healthy_green_glow)
return
healthy_green_glow.strength = max(strength-1, 0)
/obj/machinery/shower/process()
if(on)
@@ -377,6 +396,7 @@
wash_mob(AM)
else if(isobj(AM))
wash_obj(AM)
contamination_cleanse(AM)
/obj/machinery/shower/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 3)
@@ -27,7 +27,7 @@
var/datum/excited_group/excited_group
var/excited = 0
var/recently_active = 0
var/datum/gas_mixture/air
var/datum/gas_mixture/turf/air
var/obj/effect/hotspot/active_hotspot
var/atmos_cooldown = 0
@@ -65,22 +65,17 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//PV = nRT
/datum/gas_mixture/proc/heat_capacity() //joules per kelvin
/datum/gas_mixture/proc/heat_capacity(data = MOLES) //joules per kelvin
var/list/cached_gases = gases
. = 0
for(var/id in cached_gases)
var/gas_data = cached_gases[id]
. += gas_data[MOLES] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
if(!. && temperature) //if temp isn't defined, this mixture isn't a vacuum like space is. it hasn't been filled with *anything* so we want it to take on the properties of whatever gas enters it
. += HEAT_CAPACITY_VACUUM //however, if temp is defined but HC is still 0, then we want the mixture to behave like space does, as a heat sink
. += gas_data[data] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
/datum/gas_mixture/proc/heat_capacity_archived() //joules per kelvin
var/list/cached_gases = gases
. = 0
for(var/id in cached_gases)
var/gas_data = cached_gases[id]
. += gas_data[ARCHIVE] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
/datum/gas_mixture/turf/heat_capacity()
. = ..()
if(!.)
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
//prefer this in performance critical areas
#define TOTAL_MOLES(cached_gases, out_var)\
@@ -195,7 +190,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
var/datum/gas_mixture/removed = new
var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
removed.temperature = temperature
@@ -213,7 +208,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
ratio = min(ratio, 1)
var/list/cached_gases = gases
var/datum/gas_mixture/removed = new
var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
removed.temperature = temperature
@@ -228,7 +223,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
/datum/gas_mixture/copy()
var/list/cached_gases = gases
var/datum/gas_mixture/copy = new
var/datum/gas_mixture/copy = new type
var/list/copy_gases = copy.gases
copy.temperature = temperature
@@ -364,8 +359,8 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
sharer_temperature = sharer.temperature_archived
var/temperature_delta = temperature_archived - sharer_temperature
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity_archived()
sharer_heat_capacity = sharer_heat_capacity || sharer.heat_capacity_archived()
var/self_heat_capacity = heat_capacity(ARCHIVE)
sharer_heat_capacity = sharer_heat_capacity || sharer.heat_capacity(ARCHIVE)
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
var/heat = conduction_coefficient*temperature_delta* \
@@ -19,9 +19,6 @@
/datum/gas_mixture/immutable/merge()
return 0 //we're immutable.
/datum/gas_mixture/immutable/heat_capacity_archived()
return heat_capacity()
/datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
. = ..(sharer, 0)
garbage_collect()
@@ -24,7 +24,7 @@
if(!isnull(new_piping_layer))
target_layer = new_piping_layer
SSair.atmos_machinery += src
if(mapload && !target)
if(!target)
reattach_to_layer()
return ..()
@@ -49,7 +49,7 @@
//Make sure are close enough for a valid connection
if(new_port.loc != get_turf(src))
return TRUE
return FALSE
//Perform the connection
connected_port = new_port
+68 -62
View File
@@ -1,45 +1,48 @@
//Engineering Mesons
#define MODE_NONE ""
#define MODE_MESON "meson"
#define MODE_TRAY "t-ray"
#define MODE_RAD "radiation"
/obj/item/clothing/glasses/meson/engine
name = "engineering scanner goggles"
desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes."
icon_state = "trayson-meson"
desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, the T-ray Scanner mode lets you see underfloor objects such as cables and pipes, and the Radiation Scanner mode let's you see objects contaminated by radiation."
icon_state = "trayson"
actions_types = list(/datum/action/item_action/toggle_mode)
origin_tech = "materials=3;magnets=3;engineering=3;plasmatech=3"
var/mesons_on = TRUE //if set to FALSE, these goggles work as t-ray scanners.
vision_flags = NONE
darkness_view = 2
invis_view = SEE_INVISIBLE_LIVING
var/list/modes = list(MODE_NONE = MODE_MESON, MODE_MESON = MODE_TRAY, MODE_TRAY = MODE_RAD, MODE_RAD = MODE_NONE)
var/mode = MODE_NONE
var/range = 1
/obj/item/clothing/glasses/meson/engine/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
update_icon()
/obj/item/clothing/glasses/meson/engine/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/clothing/glasses/meson/engine/proc/toggle_mode(mob/user, voluntary)
mesons_on = !mesons_on
mode = modes[mode]
to_chat(user, "<span class='[voluntary ? "notice":"warning"]'>[voluntary ? "You turn the goggles":"The goggles turn"] [mode ? "to [mode] mode":"off"][voluntary ? ".":"!"]</span>")
if(!mesons_on)
vision_flags = 0
darkness_view = 2
invis_view = SEE_INVISIBLE_LIVING
lighting_alpha = null
if(voluntary)
to_chat(user, "<span class='notice'>You toggle the goggles' scanning mode to \[T-Ray].</span>")
else
to_chat(user, "<span class='warning'>The goggles abruptly toggle to \[T-Ray] mode!</span>")
else
vision_flags = SEE_TURFS
darkness_view = 1
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
if(voluntary)
to_chat(user, "<span class='notice'>You toggle the goggles' scanning mode to \[Meson].</span>")
else
to_chat(user, "<span class='warning'>The goggles abruptly toggle to \[Meson] mode!</span>")
switch(mode)
if(MODE_MESON)
vision_flags = SEE_TURFS
darkness_view = 1
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
if(MODE_TRAY) //undoes the last mode, meson
vision_flags = NONE
darkness_view = 2
lighting_alpha = null
if(ishuman(user))
var/mob/living/carbon/human/H = user
@@ -55,7 +58,7 @@
toggle_mode(user, TRUE)
/obj/item/clothing/glasses/meson/engine/process()
if(mesons_on)
if(mode == MODE_MESON)
var/turf/T = get_turf(src)
if(T && T.z == ZLEVEL_MINING)
toggle_mode(loc)
@@ -63,11 +66,13 @@
if(!ishuman(loc))
return
var/mob/living/carbon/human/user = loc
if(user.glasses != src)
if(user.glasses != src || !user.client)
return
scan()
if(mode == MODE_TRAY)
scan()
else if(mode == MODE_RAD)
show_rads()
/obj/item/clothing/glasses/meson/engine/proc/scan()
for(var/turf/T in range(range, loc))
@@ -79,17 +84,40 @@
flick_sonar(O)
/obj/item/clothing/glasses/meson/engine/proc/flick_sonar(obj/pipe)
if(ismob(loc))
var/mob/M = loc
var/image/I = new(loc = get_turf(pipe))
var/mutable_appearance/MA = new(pipe)
var/mob/M = loc
var/image/I = new(loc = get_turf(pipe))
var/mutable_appearance/MA = new(pipe)
MA.alpha = 128
I.appearance = MA
flick_overlay(I, list(M.client), 8)
/obj/item/clothing/glasses/meson/engine/proc/show_rads()
var/mob/living/carbon/human/user = loc
var/list/rad_places = list()
for(var/datum/component/radioactive/thing in SSradiation.processing)
var/atom/owner = thing.parent
var/turf/place = get_turf(owner)
if(rad_places[place])
rad_places[place] += thing.strength
else
rad_places[place] = thing.strength
for(var/i in rad_places)
var/turf/place = i
if(get_dist(user, place) >= range*2) //Rads are easier to see than wires under the floor
continue
var/strength = round(rad_places[i] / 1000, 0.1)
var/image/pic = new(loc = place)
var/mutable_appearance/MA = new()
MA.alpha = 128
I.appearance = MA
if(M.client)
flick_overlay(I, list(M.client), 8)
MA.maptext = "[strength]k"
MA.color = "#64C864"
MA.layer = AREA_LAYER
pic.appearance = MA
flick_overlay(pic, list(user.client), 8)
/obj/item/clothing/glasses/meson/engine/update_icon()
icon_state = mesons_on ? "trayson-meson" : "trayson-tray"
icon_state = "[initial(icon_state)]-[mode]"
if(istype(loc, /mob/living/carbon/human/))
var/mob/living/carbon/human/user = loc
if(user.glasses == src)
@@ -98,35 +126,13 @@
/obj/item/clothing/glasses/meson/engine/tray //atmos techs have lived far too long without tray goggles while those damned engineers get their dual-purpose gogles all to themselves
name = "optical t-ray scanner"
desc = "Used by engineering staff to see underfloor objects such as cables and pipes."
icon_state = "trayson-tray_off"
origin_tech = "materials=3;magnets=2;engineering=2"
mesons_on = FALSE
var/on = FALSE
vision_flags = 0
darkness_view = 2
invis_view = SEE_INVISIBLE_LIVING
range = 2
modes = list(MODE_NONE = MODE_TRAY, MODE_TRAY = MODE_NONE)
/obj/item/clothing/glasses/meson/engine/tray/process()
if(!on)
return
..()
/obj/item/clothing/glasses/meson/engine/tray/update_icon()
icon_state = "trayson-tray[on ? "" : "_off"]"
if(istype(loc, /mob/living/carbon/human/))
var/mob/living/carbon/human/user = loc
if(user.glasses == src)
user.update_inv_glasses()
/obj/item/clothing/glasses/meson/engine/tray/toggle_mode(mob/user, voluntary)
on = !on
to_chat(user, "<span class='[voluntary ? "notice":"warning"]'>[voluntary ? "You turn the goggles":"The goggles turn"] [on ? "on":"off"][voluntary ? ".":"!"]</span>")
update_icon()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
#undef MODE_NONE
#undef MODE_MESON
#undef MODE_TRAY
#undef MODE_RAD
+2 -2
View File
@@ -119,7 +119,7 @@
L.anchored = TRUE
if(ishostile(L))
var/mob/living/simple_animal/hostile/H = L
H.AIStatus = AI_OFF
H.toggle_ai(AI_OFF)
H.LoseTarget()
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mob(mob/living/L)
@@ -128,4 +128,4 @@
frozen_mobs -= L
if(ishostile(L))
var/mob/living/simple_animal/hostile/H = L
H.AIStatus = initial(H.AIStatus)
H.toggle_ai(initial(H.AIStatus))
+1 -1
View File
@@ -59,7 +59,7 @@
SetCollectBehavior()
/mob/living/simple_animal/hostile/mining_drone/sentience_act()
AIStatus = AI_OFF
..()
check_friendly_fire = 0
/mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I, mob/user, params)
@@ -1144,11 +1144,14 @@
radiation = 0
return TRUE
if(radiation > RAD_MOB_KNOCKDOWN)
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
if(!H.IsKnockdown())
H.emote("collapse")
H.Knockdown(RAD_KNOCKDOWN_TIME)
H.Knockdown(RAD_MOB_KNOCKDOWN_AMOUNT)
to_chat(H, "<span class='danger'>You feel weak.</span>")
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
H.vomit(10, TRUE)
if(radiation > RAD_MOB_MUTATE)
if(prob(1))
@@ -1158,10 +1161,9 @@
H.domutcheck()
if(radiation > RAD_MOB_HAIRLOSS)
if(prob(15))
if(!( H.hair_style == "Shaved") || !(H.hair_style == "Bald") || (HAIR in species_traits))
to_chat(H, "<span class='danger'>Your hair starts to fall out in clumps...</span>")
addtimer(CALLBACK(src, .proc/go_bald, H), 50)
if(prob(15) && !(H.hair_style == "Bald") && (HAIR in species_traits))
to_chat(H, "<span class='danger'>Your hair starts to fall out in clumps...</span>")
addtimer(CALLBACK(src, .proc/go_bald, H), 50)
/datum/species/proc/go_bald(mob/living/carbon/human/H)
if(QDELETED(H)) //may be called from a timer
@@ -63,7 +63,7 @@ There are several things that need to be remembered:
..()
/mob/living/carbon/human/update_fire()
..("Standing")
..((fire_stacks > 3) ? "Standing" : "Generic_mob_burning")
/* --------------------------------------- */
@@ -24,10 +24,10 @@
/mob/living/carbon/monkey/handle_mutations_and_radiation()
if(radiation)
if(radiation > RAD_MOB_KNOCKDOWN)
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
if(!IsKnockdown())
emote("collapse")
Knockdown(200)
Knockdown(RAD_MOB_KNOCKDOWN_AMOUNT)
to_chat(src, "<span class='danger'>You feel weak.</span>")
if(radiation > RAD_MOB_MUTATE)
if(prob(1))
@@ -39,6 +39,8 @@
if(radiation > RAD_MOB_MUTATE * 2 && prob(50))
gorillize()
return
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
vomit(10, TRUE)
return ..()
/mob/living/carbon/monkey/handle_breath_temperature(datum/gas_mixture/breath)
+15 -26
View File
@@ -41,39 +41,28 @@
clear_fullscreen("eye_damage")
/mob/living/carbon/adjust_drugginess(amount)
var/old_druggy = druggy
if(amount>0)
druggy += amount
if(!old_druggy)
overlay_fullscreen("high", /obj/screen/fullscreen/high)
throw_alert("high", /obj/screen/alert/high)
else if(old_druggy)
druggy = max(druggy+amount, 0)
if(!druggy)
clear_fullscreen("high")
clear_alert("high")
druggy = max(druggy+amount, 0)
if(druggy)
overlay_fullscreen("high", /obj/screen/fullscreen/high)
throw_alert("high", /obj/screen/alert/high)
else
clear_fullscreen("high")
clear_alert("high")
/mob/living/carbon/set_drugginess(amount)
var/old_druggy = druggy
druggy = amount
if(amount>0)
if(!old_druggy)
overlay_fullscreen("high", /obj/screen/fullscreen/high)
throw_alert("high", /obj/screen/alert/high)
else if(old_druggy)
druggy = max(amount, 0)
if(druggy)
overlay_fullscreen("high", /obj/screen/fullscreen/high)
throw_alert("high", /obj/screen/alert/high)
else
clear_fullscreen("high")
clear_alert("high")
/mob/living/carbon/adjust_disgust(amount)
var/old_disgust = disgust
if(amount>0)
disgust = min(disgust+amount, DISGUST_LEVEL_MAXEDOUT)
else if(old_disgust)
disgust = max(disgust+amount, 0)
disgust = Clamp(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT)
/mob/living/carbon/set_disgust(amount)
if(amount >= 0)
disgust = amount
disgust = Clamp(amount, 0, DISGUST_LEVEL_MAXEDOUT)
/mob/living/carbon/cure_blind()
if(disabilities & BLIND)
+1 -1
View File
@@ -586,7 +586,7 @@
if(!force_moving)
..(pressure_difference, direction, pressure_resistance_prob_delta)
/mob/living/proc/can_resist()
/mob/living/can_resist()
return !((next_move > world.time) || incapacitated(ignore_restraints = TRUE))
/mob/living/verb/resist()
+10 -6
View File
@@ -813,12 +813,16 @@
return FALSE
if(be_close && !in_range(M, src))
return FALSE
//stop AIs from leaving windows open and using then after they lose vision
//apc_override is needed here because AIs use their own APC when powerless
//get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
if(M && GLOB.cameranet && !GLOB.cameranet.checkTurfVis(get_turf_pixel(M)) && !apc_override)
return FALSE
return TRUE
return can_see(M) //stop AIs from leaving windows open and using then after they lose vision
/mob/living/silicon/ai/proc/can_see(atom/A)
if(isturf(loc)) //AI in core, check if on cameras
//get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
//apc_override is needed here because AIs use their own APC when depowered
return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(get_turf_pixel(A))) || apc_override
//AI is carded/shunted
//view(src) returns nothing for carded/shunted AIs and they have x-ray vision so just use get_dist
return get_dist(src, A) <= client.view
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
raw_message = lang_treat(speaker, message_language, raw_message, spans, message_mode)
@@ -305,6 +305,7 @@
/obj/item/device/multitool/cyborg,
/obj/item/device/t_scanner,
/obj/item/device/analyzer,
/obj/item/device/geiger_counter,
/obj/item/device/assembly/signaler/cyborg,
/obj/item/areaeditor/blueprints/cyborg,
/obj/item/device/electroadaptive_pseudocircuit,
@@ -348,7 +348,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
mode = BOT_HUNT
/mob/living/simple_animal/bot/honkbot/Crossed(atom/movable/AM)
if(ismob(AM))
if(ismob(AM) && (on)) //only if its online
if(prob(30)) //you're far more likely to trip on a honkbot
var/mob/living/carbon/C = AM
if(!istype(C) || !C || in_range(src, target))
@@ -362,7 +362,8 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
"[C] leaps out of [src]'s way!")]</span>")
C.Knockdown(10)
playsound(loc, 'sound/misc/sadtrombone.ogg', 50, 1, -1)
speak("Honk!")
if(!client)
speak("Honk!")
sensor_blink()
return
..()
@@ -49,6 +49,8 @@
var/idle = 0
var/isqueen = FALSE
var/icon_base = "bee"
var/static/beehometypecache = typecacheof(/obj/structure/beebox)
var/static/hydroponicstypecache = typecacheof(/obj/machinery/hydroponics)
/mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(movement_dir = 0)
@@ -118,7 +120,7 @@
if(istype(A, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = A
if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit)
wanted_objects |= typecacheof(/obj/machinery/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
wanted_objects |= hydroponicstypecache //so we only hunt them while they're alive/seeded/not visisted
return TRUE
return FALSE
@@ -132,8 +134,9 @@
if(target == beehome)
var/obj/structure/beebox/BB = target
forceMove(BB)
toggle_ai(AI_IDLE)
target = null
wanted_objects -= typecacheof(/obj/structure/beebox) //so we don't attack beeboxes when not going home
wanted_objects -= beehometypecache //so we don't attack beeboxes when not going home
return //no don't attack the goddamm box
else
. = ..()
@@ -157,7 +160,7 @@
return
target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
wanted_objects -= typecacheof(/obj/machinery/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
wanted_objects -= hydroponicstypecache //so we only hunt them while they're alive/seeded/not visisted
Hydro.recent_bee_visit = TRUE
spawn(BEE_TRAY_RECENT_VISIT)
if(Hydro)
@@ -187,12 +190,13 @@
if(loc == beehome)
idle = min(100, ++idle)
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
toggle_ai(AI_ON)
forceMove(beehome.drop_location())
else
idle = max(0, --idle)
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
if(!FindTarget())
wanted_objects |= typecacheof(/obj/structure/beebox) //so we don't attack beeboxes when not going home
wanted_objects |= beehometypecache //so we don't attack beeboxes when not going home
target = beehome
if(!beehome) //add outselves to a beebox (of the same reagent) if we have no home
for(var/obj/structure/beebox/BB in view(vision_range, src))
@@ -285,3 +289,11 @@
QDEL_NULL(queen)
return ..()
/mob/living/simple_animal/hostile/poison/bees/consider_wakeup()
if (beehome && loc == beehome) // If bees are chilling in their nest, they're not actively looking for targets
idle = min(100, ++idle)
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
toggle_ai(AI_ON)
forceMove(beehome.drop_location())
else
..()
@@ -49,7 +49,6 @@
var/stat_attack = CONSCIOUS //Mobs with stat_attack to UNCONSCIOUS will attempt to attack things that are unconscious, Mobs with stat_attack set to DEAD will attempt to attack the dead.
var/stat_exclusive = FALSE //Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack DEAD means they will only attack corpses
var/attack_same = 0 //Set us to 1 to allow us to attack our own faction
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such
var/attack_all_objects = FALSE //if true, equivalent to having a wanted_objects list containing ALL objects.
@@ -88,7 +87,7 @@
DestroySurroundings()
if(!MoveToTarget(possible_targets)) //if we lose our target
if(AIShouldSleep(possible_targets)) // we try to acquire a new one
AIStatus = AI_IDLE // otherwise we go idle
toggle_ai(AI_IDLE) // otherwise we go idle
return 1
/mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user)
@@ -289,7 +288,7 @@
target = null
LoseSearchObjects()
if(AIStatus == AI_IDLE)
AIStatus = AI_ON
toggle_ai(AI_ON)
FindTarget()
else if(target != null && prob(40))//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
FindTarget()
@@ -424,7 +423,7 @@
if(AI_IDLE)
if(FindTarget(possible_targets, 1))
. = 1
AIStatus = AI_ON //Wake up for more than one Life() cycle.
toggle_ai(AI_ON) //Wake up for more than one Life() cycle.
else
. = 0
@@ -455,3 +454,9 @@
if(!value)
value = initial(search_objects)
search_objects = value
/mob/living/simple_animal/hostile/consider_wakeup()
..()
if(AIStatus == AI_IDLE && FindTarget(ListTargets(), 1))
toggle_ai(AI_ON)
@@ -82,6 +82,10 @@
var/dextrous_hud_type = /datum/hud/dextrous
var/datum/personal_crafting/handcrafting
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check.
//domestication
var/tame = 0
@@ -89,7 +93,7 @@
/mob/living/simple_animal/Initialize()
. = ..()
GLOB.simple_animals += src
GLOB.simple_animals[AIStatus] += src
handcrafting = new()
if(gender == PLURAL)
gender = pick(MALE,FEMALE)
@@ -102,7 +106,7 @@
verbs |= /mob/living/proc/animal_nom
/mob/living/simple_animal/Destroy()
GLOB.simple_animals -= src
GLOB.simple_animals[AIStatus] -= src
return ..()
/mob/living/simple_animal/updatehealth()
@@ -422,7 +426,7 @@
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
return
toggle_ai(AI_OFF) // To prevent any weirdness.
/mob/living/simple_animal/update_sight()
if(!client)
@@ -545,3 +549,23 @@
/mob/living/simple_animal/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1)
. = ..()
riding_datum = new/datum/riding/animal
/mob/living/simple_animal/proc/toggle_ai(togglestatus)
if (AIStatus != togglestatus)
if (togglestatus > 0 && togglestatus < 4)
GLOB.simple_animals[AIStatus] -= src
GLOB.simple_animals[togglestatus] += src
AIStatus = togglestatus
else
stack_trace("Something attempted to set simple animals AI to an invalid state: [togglestatus]")
/mob/living/simple_animal/proc/consider_wakeup()
if (pulledby || shouldwakeup)
toggle_ai(AI_ON)
/mob/living/simple_animal/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
. = ..()
if(!ckey && !stat)//Not unconscious
if(AIStatus == AI_IDLE)
toggle_ai(AI_ON)
@@ -30,7 +30,7 @@
spawned_mobs = null
return ..()
/mob/living/simple_animal/hostile/spawner/handle_automated_action()
/mob/living/simple_animal/hostile/spawner/Life()
. = ..()
spawn_mob()
+3
View File
@@ -356,6 +356,9 @@
else
M.LAssailant = usr
/mob/proc/can_resist()
return FALSE //overridden in living.dm
/mob/proc/spin(spintime, speed)
set waitfor = 0
var/D = dir
+1 -1
View File
@@ -278,7 +278,7 @@
//dist_check - set to only shock mobs within 1 of source (vendors, airlocks, etc.)
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/M, power_source, obj/source, siemens_coeff = 1, dist_check = FALSE)
if(ismecha(M.loc))
if(!M || ismecha(M.loc))
return 0 //feckin mechs are dumb
if(dist_check)
if(!in_range(source,M))
+5 -14
View File
@@ -21,7 +21,7 @@
var/move_self = 1 //Do we move on our own?
var/grav_pull = 4 //How many tiles out do we pull?
var/consume_range = 0 //How many tiles out do we eat
var/event_chance = 15 //Prob for event each tick
var/event_chance = 10 //Prob for event each tick
var/target = null //its target. moves towards the target if it has one
var/last_failed_movement = 0//Will not move in the same dir if it couldnt before, will help with the getting stuck on fields thing
var/last_warning
@@ -114,7 +114,7 @@
/obj/singularity/process()
if(current_size >= STAGE_TWO)
move()
radiation_pulse(src, energy, 0.5)
radiation_pulse(src, min(5000, (energy*3)+1000), RAD_DISTANCE_COEFFICIENT*0.5)
if(prob(event_chance))//Chance for it to run a special event TODO:Come up with one or two more that fit
event()
eat()
@@ -367,15 +367,13 @@
/obj/singularity/proc/event()
var/numb = pick(1,2,3,4,5,6)
var/numb = rand(1,4)
switch(numb)
if(1)//EMP
emp_area()
if(2,3)//tox damage all carbon mobs in area
toxmob()
if(4)//Stun mobs who lack optic scanners
if(2)//Stun mobs who lack optic scanners
mezzer()
if(5,6) //Sets all nearby mobs on fire
if(3,4) //Sets all nearby mobs on fire
if(current_size < STAGE_SIX)
return 0
combust_mobs()
@@ -384,13 +382,6 @@
return 1
/obj/singularity/proc/toxmob()
var/radiation = 15
if (energy>200)
radiation += round((energy-150)/10,1)
radiation_pulse(src, radiation)
/obj/singularity/proc/combust_mobs()
for(var/mob/living/carbon/C in urange(20, src, 1))
C.visible_message("<span class='warning'>[C]'s skin bursts into flame!</span>", \
@@ -78,7 +78,7 @@
/datum/reagent/blob/networked_fibers
name = "Networked Fibers"
id = "networked_fibers"
description = "will do high brute and burn damage but non-manual expansion will only generate resources."
description = "will do high brute and burn damage and will generate resources quicker, but can only expand manually."
shortdesc = "will do high brute and burn damage."
effectdesc = "will move your core when manually expanding near it."
analyzerdescdamage = "Does high brute and burn damage."
@@ -466,7 +466,7 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/medicine/pen_acid/on_mob_life(mob/living/M)
M.radiation -= min(M.radiation, log(M.radiation)*10)
M.radiation -= min(M.radiation-RAD_MOB_SAFE, 0)/100
M.adjustToxLoss(-2*REM, 0)
for(var/datum/reagent/R in M.reagents.reagent_list)
if(R != src)
@@ -16,7 +16,7 @@
new /obj/item/device/assembly/signaler/anomaly (get_step(loc, pick(GLOB.alldirs)))
return ..()
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/handle_automated_action()
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/Life()
consume()
return ..()
+2 -2
View File
@@ -42,8 +42,8 @@ GLOBAL_DATUM_INIT(default_state, /datum/ui_state/default, new)
if(. < UI_INTERACTIVE)
return
// The AI can interact with anything it can see nearby, or with cameras.
if((get_dist(src, src_object) <= client.view) || GLOB.cameranet.checkTurfVis(get_turf_pixel(src_object)))
// The AI can interact with anything it can see nearby, or with cameras while wireless control is enabled.
if(!control_disabled && can_see(src_object))
return UI_INTERACTIVE
return UI_CLOSE
@@ -0,0 +1,4 @@
author: "Gun Hog"
delete-after: True
changes:
- bugfix: "The GPS item now correctly changes its name when the GPS tag is changed."
@@ -0,0 +1,4 @@
author: "ShizCalev"
delete-after: True
changes:
- tweak: "Engineering cyborgs now have access to geiger counters."
+10
View File
@@ -0,0 +1,10 @@
author: "ninjanomnom"
delete-after: True
changes:
- rscadd: "You can vomit blood at high enough radiation."
- balance: "Radiation knockdown is far far shorter."
- balance: "Genetics modification is less harmful but still, upgrade your machines."
- balance: "Pentetic acid is useless for low amounts of radiation but indispensable for high amounts now."
- balance: "Singularity radiation has been normalized and Pubby engine has been remapped."
- bugfix: "No more hair loss spam"
- bugfix: "Mob rad contamination has been disabled for now. Regular contamination is still a thing."
@@ -0,0 +1,4 @@
author: "More Robust Than You"
delete-after: True
changes:
- tweak: "People that are burning slightly less will appear to be burning... slightly less."
@@ -0,0 +1,4 @@
author: "ShizCalev"
delete-after: True
changes:
- bugfix: "Renault now has a comfy new bed on Metastation!"
@@ -0,0 +1,4 @@
author: "ninjanomnom"
delete-after: True
changes:
- rscadd: "Engineering scanner goggles have a radiation mode now"
@@ -0,0 +1,5 @@
author: "ninjanomnom"
delete-after: True
changes:
- rscadd: "Objects placed under showers are cleansed of radioactive contamination over a short time."
- soundadd: "Showers make sound now."
@@ -0,0 +1,5 @@
author: "CitadelStationBot"
delete-after: True
changes:
- tweak: "You will no longer trip on inactive honkbots."
- bugfix: "Sentient Honkbots are no longer forced to speak when somebody trip on them."
@@ -0,0 +1,4 @@
author: "deathride58"
delete-after: True
changes:
- tweak: "You can now press Ctrl+H to stop pulling, or simply H to stop pulling if you're in hotkey mode."
@@ -0,0 +1,4 @@
author: "Naksu"
delete-after: True
changes:
- bugfix: "Manned turrets stop firing when there's no-one in the turret shooting."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

+6 -4
View File
@@ -116,6 +116,7 @@ Hotkey-Mode: (hotkey-mode must be on)
\tt = say
\to = OOC
\tb = resist
\t<B></B>h = stop pulling
\tx = swap-hand
\tz = activate held object (or y)
\tf = cycle-intents-left
@@ -138,6 +139,7 @@ Any-Mode: (hotkey doesn't need to be on)
\tCtrl+e = equip
\tCtrl+r = throw
\tCtrl+b = resist
\tCtrl+h = stop pulling
\tCtrl+o = OOC
\tCtrl+x = swap-hand
\tCtrl+z = activate held object (or Ctrl+y)
@@ -149,7 +151,7 @@ Any-Mode: (hotkey doesn't need to be on)
\tCtrl+4 = harm-intent
\tCtrl+'+/-' OR
\tShift+Mousewheel = Ghost zoom in/out
\tDEL = pull
\tDEL = stop pulling
\tINS = cycle-intents-right
\tHOME = drop
\tPGUP = swap-hand
@@ -171,9 +173,9 @@ Hotkey-Mode: (hotkey-mode must be on)
\td = right
\tw = up
\tq = unequip active module
\t<B></B>h = stop pulling
\tm = me
\tt = say
\t<B></B>h = talk-wheel
\to = OOC
\tx = cycle active modules
\tb = resist
@@ -195,7 +197,7 @@ Any-Mode: (hotkey doesn't need to be on)
\tCtrl+q = unequip active module
\tCtrl+x = cycle active modules
\tCtrl+b = resist
\tCtrl+h = talk-wheel
\tCtrl+h = stop pulling
\tCtrl+o = OOC
\tCtrl+z = activate held object (or Ctrl+y)
\tCtrl+f = cycle-intents-left
@@ -204,7 +206,7 @@ Any-Mode: (hotkey doesn't need to be on)
\tCtrl+2 = activate module 2
\tCtrl+3 = activate module 3
\tCtrl+4 = toggle intents
\tDEL = pull
\tDEL = stop pulling
\tINS = toggle intents
\tPGUP = cycle active modules
\tPGDN = activate held object
+16
View File
@@ -63,6 +63,10 @@ macro "default"
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
elem
name = "CTRL+H"
command = "delete-key-pressed"
is-disabled = false
elem
name = "CTRL+1"
command = "a-intent help"
@@ -285,6 +289,10 @@ macro "hotkeys"
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
elem
name = "H"
command = "delete-key-pressed"
is-disabled = false
elem
name = "1"
command = "a-intent help"
@@ -583,6 +591,10 @@ macro "robot-default"
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
elem
name = "CTRL+H"
command = "delete-key-pressed"
is-disabled = false
elem
name = "CTRL+1"
command = "toggle-module 1"
@@ -777,6 +789,10 @@ macro "robot-hotkeys"
name = "DELETE"
command = "delete-key-pressed"
is-disabled = false
elem
name = "H"
command = "delete-key-pressed"
is-disabled = false
elem
name = "1"
command = "toggle-module 1"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -226,6 +226,7 @@
#include "code\controllers\subsystem\fire_burning.dm"
#include "code\controllers\subsystem\garbage.dm"
#include "code\controllers\subsystem\icon_smooth.dm"
#include "code\controllers\subsystem\idlenpcpool.dm"
#include "code\controllers\subsystem\inbounds.dm"
#include "code\controllers\subsystem\ipintel.dm"
#include "code\controllers\subsystem\job.dm"
@@ -376,6 +377,8 @@
#include "code\datums\helper_datums\icon_snapshot.dm"
#include "code\datums\helper_datums\teleport.dm"
#include "code\datums\helper_datums\topic_input.dm"
#include "code\datums\looping_sounds\looping_sound.dm"
#include "code\datums\looping_sounds\machinery_sounds.dm"
#include "code\datums\martial\boxing.dm"
#include "code\datums\martial\cqc.dm"
#include "code\datums\martial\krav_maga.dm"