= 2)
+ var/n = runBases.len - 1
+ if(n > 1 && runLens[n-1] <= runLens[n] + runLens[n+1])
+ if(runLens[n-1] < runLens[n+1])
+ --n
+ mergeAt(n)
+ else if(runLens[n] <= runLens[n+1])
+ mergeAt(n)
+ else
+ break //Invariant is established
+
+
+ //Merges all runs on the stack until only one remains.
+ //Called only once, to finalise the sort
+ proc/mergeForceCollapse()
+ while(runBases.len >= 2)
+ var/n = runBases.len - 1
+ if(n > 1 && runLens[n-1] < runLens[n+1])
+ --n
+ mergeAt(n)
+
+
+ //Merges the two consecutive runs at stack indices i and i+1
+ //Run i must be the penultimate or antepenultimate run on the stack
+ //In other words, i must be equal to stackSize-2 or stackSize-3
+ proc/mergeAt(i)
+ //ASSERT(runBases.len >= 2)
+ //ASSERT(i >= 1)
+ //ASSERT(i == runBases.len - 1 || i == runBases.len - 2)
+
+ var/base1 = runBases[i]
+ var/base2 = runBases[i+1]
+ var/len1 = runLens[i]
+ var/len2 = runLens[i+1]
+
+ //ASSERT(len1 > 0 && len2 > 0)
+ //ASSERT(base1 + len1 == base2)
+
+ //Record the legth of the combined runs. If i is the 3rd last run now, also slide over the last run
+ //(which isn't involved in this merge). The current run (i+1) goes away in any case.
+ runLens[i] += runLens[i+1]
+ runLens.Cut(i+1, i+2)
+ runBases.Cut(i+1, i+2)
+
+
+ //Find where the first element of run2 goes in run1.
+ //Prior elements in run1 can be ignored (because they're already in place)
+ var/k = gallopRight(fetchElement(L,base2), base1, len1, 0)
+ //ASSERT(k >= 0)
+ base1 += k
+ len1 -= k
+ if(len1 == 0)
+ return
+
+ //Find where the last element of run1 goes in run2.
+ //Subsequent elements in run2 can be ignored (because they're already in place)
+ len2 = gallopLeft(fetchElement(L,base1 + len1 - 1), base2, len2, len2-1)
+ //ASSERT(len2 >= 0)
+ if(len2 == 0)
+ return
+
+ //Merge remaining runs, using tmp array with min(len1, len2) elements
+ if(len1 <= len2)
+ mergeLo(base1, len1, base2, len2)
+ else
+ mergeHi(base1, len1, base2, len2)
+
+
+ /*
+ Locates the position to insert key within the specified sorted range
+ If the range contains elements equal to key, this will return the index of the LEFTMOST of those elements
+
+ key the element to be inserted into the sorted range
+ base the index of the first element of the sorted range
+ len the length of the sorted range, must be greater than 0
+ hint the offset from base at which to begin the search, such that 0 <= hint < len; i.e. base <= hint < base+hint
+
+ Returns the index at which to insert element 'key'
+ */
+ proc/gallopLeft(key, base, len, hint)
+ //ASSERT(len > 0 && hint >= 0 && hint < len)
+
+ var/lastOffset = 0
+ var/offset = 1
+ if(call(cmp)(key, fetchElement(L,base+hint)) > 0)
+ var/maxOffset = len - hint
+ while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint+offset)) > 0)
+ lastOffset = offset
+ offset = (offset << 1) + 1
+
+ if(offset > maxOffset)
+ offset = maxOffset
+
+ lastOffset += hint
+ offset += hint
+
+ else
+ var/maxOffset = hint + 1
+ while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint-offset)) <= 0)
+ lastOffset = offset
+ offset = (offset << 1) + 1
+
+ if(offset > maxOffset)
+ offset = maxOffset
+
+ var/temp = lastOffset
+ lastOffset = hint - offset
+ offset = hint - temp
+
+ //ASSERT(-1 <= lastOffset && lastOffset < offset && offset <= len)
+
+ //Now L[base+lastOffset] < key <= L[base+offset], so key belongs somewhere to the right of lastOffset but no farther than
+ //offset. Do a binary search with invariant L[base+lastOffset-1] < key <= L[base+offset]
+ ++lastOffset
+ while(lastOffset < offset)
+ var/m = lastOffset + ((offset - lastOffset) >> 1)
+
+ if(call(cmp)(key, fetchElement(L,base+m)) > 0)
+ lastOffset = m + 1
+ else
+ offset = m
+
+ //ASSERT(lastOffset == offset)
+ return offset
+
+ /**
+ * Like gallopLeft, except that if the range contains an element equal to
+ * key, gallopRight returns the index after the rightmost equal element.
+ *
+ * @param key the key whose insertion point to search for
+ * @param a the array in which to search
+ * @param base the index of the first element in the range
+ * @param len the length of the range; must be > 0
+ * @param hint the index at which to begin the search, 0 <= hint < n.
+ * The closer hint is to the result, the faster this method will run.
+ * @param c the comparator used to order the range, and to search
+ * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k]
+ */
+ proc/gallopRight(key, base, len, hint)
+ //ASSERT(len > 0 && hint >= 0 && hint < len)
+
+ var/offset = 1
+ var/lastOffset = 0
+ if(call(cmp)(key, fetchElement(L,base+hint)) < 0) //key <= L[base+hint]
+ var/maxOffset = hint + 1 //therefore we want to insert somewhere in the range [base,base+hint] = [base+,base+(hint+1))
+ while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint-offset)) < 0) //we are iterating backwards
+ lastOffset = offset
+ offset = (offset << 1) + 1 //1 3 7 15
+ //if(offset <= 0) //int overflow, not an issue here since we are using floats
+ // offset = maxOffset
+
+ if(offset > maxOffset)
+ offset = maxOffset
+
+ var/temp = lastOffset
+ lastOffset = hint - offset
+ offset = hint - temp
+
+ else //key > L[base+hint]
+ var/maxOffset = len - hint //therefore we want to insert somewhere in the range (base+hint,base+len) = [base+hint+1, base+hint+(len-hint))
+ while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint+offset)) >= 0)
+ lastOffset = offset
+ offset = (offset << 1) + 1
+ //if(offset <= 0) //int overflow, not an issue here since we are using floats
+ // offset = maxOffset
+
+ if(offset > maxOffset)
+ offset = maxOffset
+
+ lastOffset += hint
+ offset += hint
+
+ //ASSERT(-1 <= lastOffset && lastOffset < offset && offset <= len)
+
+ ++lastOffset
+ while(lastOffset < offset)
+ var/m = lastOffset + ((offset - lastOffset) >> 1)
+
+ if(call(cmp)(key, fetchElement(L,base+m)) < 0) //key <= L[base+m]
+ offset = m
+ else //key > L[base+m]
+ lastOffset = m + 1
+
+ //ASSERT(lastOffset == offset)
+
+ return offset
+
+
+ //Merges two adjacent runs in-place in a stable fashion.
+ //For performance this method should only be called when len1 <= len2!
+ proc/mergeLo(base1, len1, base2, len2)
+ //ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2)
+
+ //degenerate cases
+ if(len2 == 1)
+ moveElement(L, base2, base1)
+ return
+
+ if(len1 == 1)
+ moveElement(L, base1, base2+len2-1)
+ return
+
+
+ //Move first element of second run
+ moveElement(L, base2, base1) //L[dest++] = L[cursor2++]
+ --len2
+
+ var/cursor1 = base1+1
+ var/cursor2 = base2+1
+
+ outer:
+ while(1)
+ var/count1 = 0 //# of times in a row that first run won
+ var/count2 = 0 // " " " " " " second run won
+
+ //do the straightfoward thin until one run starts winning consistently
+
+ do
+ //ASSERT(len1 > 1 && len2 > 0)
+ if(call(cmp)(fetchElement(L,cursor2), fetchElement(L,cursor1)) < 0)
+ moveElement(L, cursor2, cursor1)
+ ++cursor2
+ ++cursor1
+ --len2
+
+ ++count2
+ count1 = 0
+
+ if(len2 == 0)
+ break outer
+ else
+ ++cursor1
+
+ ++count1
+ count2 = 0
+
+ if(--len1 == 1)
+ break outer
+
+ while((count1 | count2) < minGallop)
+
+
+ //one run is winning consistently so galloping may provide huge benifits
+ //so try galloping, until such time as the run is no longer consistently winning
+ do
+ //ASSERT(len1 > 1 && len2 > 0)
+
+ count1 = gallopRight(fetchElement(L,cursor2), cursor1, len1, 0)
+ if(count1)
+ cursor1 += count1
+ len1 -= count1
+
+ if(len1 <= 1)
+ break outer
+
+ moveElement(L, cursor2, cursor1)
+ ++cursor2
+ ++cursor1
+ if(--len2 == 0)
+ break outer
+
+ count2 = gallopLeft(fetchElement(L,cursor1), cursor2, len2, 0)
+ if(count2)
+ moveRange(L, cursor2, cursor1, count2)
+
+ cursor2 += count2
+ cursor1 += count2
+ len2 -= count2
+
+ if(len2 == 0)
+ break outer
+
+ ++cursor1
+ if(--len1 == 1)
+ break outer
+
+ --minGallop
+
+ while((count1|count2) > MIN_GALLOP)
+
+ if(minGallop < 0)
+ minGallop = 0
+ minGallop += 2; // Penalize for leaving gallop mode
+
+
+ if(len1 == 1)
+ //ASSERT(len2 > 0)
+
+ moveRange(L, cursor2, cursor1, len2)
+
+ //else
+ //ASSERT(len2 == 0)
+ //ASSERT(len1 > 1)
+
+
+ proc/mergeHi(base1, len1, base2, len2)
+ //ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2)
+
+ //degenerate cases
+ if(len2 == 1)
+ moveElement(L, base2, base1)
+ return
+
+ if(len1 == 1)
+ moveElement(L, base1, base2+len2-1)
+ return
+
+ var/cursor1 = base1 + len1 - 1
+ var/cursor2 = base2 + len2 - 1
+
+ moveElement(L, cursor1, cursor2)
+ --len1
+ --cursor1
+ --cursor2
+
+ outer:
+ while(1)
+ var/count1 = 0 //# of times in a row that first run won
+ var/count2 = 0 // " " " " " " second run won
+
+ //do the straightfoward thing until one run starts winning consistently
+ do
+ //ASSERT(len1 > 0 && len2 > 1)
+ if(call(cmp)(fetchElement(L,cursor2), fetchElement(L,cursor1)) < 0)
+ moveElement(L, cursor1, cursor2)
+
+ --cursor1
+ --cursor2
+ --len1
+
+ ++count1
+ count2 = 0
+
+ if(len1 == 0)
+ break outer
+ else
+ --cursor2
+ --len2
+
+ ++count2
+ count1 = 0
+
+ if(len2 == 1)
+ break outer
+ while((count1 | count2) < minGallop)
+
+ //one run is winning consistently so galloping may provide huge benifits
+ //so try galloping, until such time as the run is no longer consistently winning
+ do
+ //ASSERT(len1 > 0 && len2 > 1)
+
+ count1 = len1 - gallopRight(fetchElement(L,cursor2), base1, len1, len1-1) //should cursor1 be base1?
+ if(count1)
+ cursor1 -= count1
+ cursor2 -= count1
+ len1 -= count1
+
+ moveRange(L, cursor1+1, cursor2+1, count1)
+
+ if(len1 == 0)
+ break outer
+
+ --cursor2
+
+ if(--len2 == 1)
+ break outer
+
+ count2 = len2 - gallopLeft(fetchElement(L,cursor1), base1+len1, len2, len2-1)
+ if(count2)
+ cursor2 -= count2
+ len2 -= count2
+
+ if(len2 <= 1)
+ break outer
+
+ moveElement(L, cursor1, cursor2)
+ --cursor1
+ --cursor2
+ --len1
+
+ if(len1 == 0)
+ break outer
+
+ --minGallop
+ while((count1|count2) > MIN_GALLOP)
+
+ if(minGallop < 0)
+ minGallop = 0
+ minGallop += 2 // Penalize for leaving gallop mode
+
+ if(len2 == 1)
+ //ASSERT(len1 > 0)
+
+ cursor1 -= len1
+ cursor2 -= len1
+ moveRange(L, cursor1+1, cursor2+1, len1)
+
+ //else
+ //ASSERT(len1 == 0)
+ //ASSERT(len2 > 0)
+
+
+ proc/mergeSort(start, end)
+ var/remaining = end - start
+
+ //If array is small, do an insertion sort
+ if(remaining < MIN_MERGE)
+ //var/initRunLen = countRunAndMakeAscending(start, end)
+ binarySort(start, end, start/*+initRunLen*/)
+ return
+
+ var/minRun = minRunLength(remaining)
+
+ do
+ var/runLen = (remaining <= minRun) ? remaining : minRun
+
+ binarySort(start, start+runLen, start)
+
+ //add data about run to queue
+ runBases.Add(start)
+ runLens.Add(runLen)
+
+ //Advance to find next run
+ start += runLen
+ remaining -= runLen
+
+ while(remaining > 0)
+
+ while(runBases.len >= 2)
+ var/n = runBases.len - 1
+ if(n > 1 && runLens[n-1] <= runLens[n] + runLens[n+1])
+ if(runLens[n-1] < runLens[n+1])
+ --n
+ mergeAt2(n)
+ else if(runLens[n] <= runLens[n+1])
+ mergeAt2(n)
+ else
+ break //Invariant is established
+
+ while(runBases.len >= 2)
+ var/n = runBases.len - 1
+ if(n > 1 && runLens[n-1] < runLens[n+1])
+ --n
+ mergeAt2(n)
+
+ return L
+
+ proc/mergeAt2(i)
+ var/cursor1 = runBases[i]
+ var/cursor2 = runBases[i+1]
+
+ var/end1 = cursor1+runLens[i]
+ var/end2 = cursor2+runLens[i+1]
+
+ var/val1 = fetchElement(L,cursor1)
+ var/val2 = fetchElement(L,cursor2)
+
+ while(1)
+ if(call(cmp)(val1,val2) < 0)
+ if(++cursor1 >= end1)
+ break
+ val1 = fetchElement(L,cursor1)
+ else
+ moveElement(L,cursor2,cursor1)
+
+ ++cursor2
+ if(++cursor2 >= end2)
+ break
+ ++end1
+ ++cursor1
+ //if(++cursor1 >= end1)
+ // break
+
+ val2 = fetchElement(L,cursor2)
+
+
+ //Record the legth of the combined runs. If i is the 3rd last run now, also slide over the last run
+ //(which isn't involved in this merge). The current run (i+1) goes away in any case.
+ runLens[i] += runLens[i+1]
+ runLens.Cut(i+1, i+2)
+ runBases.Cut(i+1, i+2)
+
+#undef MIN_GALLOP
+#undef MIN_MERGE
+
+#undef moveElement
+#undef fetchElement
\ No newline at end of file
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 24cb285cb27..7450d98fcb8 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -485,7 +485,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
//Orders mobs by type then by name
/proc/sortmobs()
var/list/moblist = list()
- var/list/sortmob = sortAtom(mob_list)
+ var/list/sortmob = sortNames(mob_list)
for(var/mob/living/silicon/ai/M in sortmob)
moblist.Add(M)
for(var/mob/camera/M in sortmob)
@@ -818,7 +818,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
//Returns: all the areas in the world, sorted.
/proc/return_sorted_areas()
- return sortAtom(return_areas())
+ return sortNames(return_areas())
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all areas of that type in the world.
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 5dbd2be86fa..a799dd0ee1c 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -12,4 +12,6 @@ var/global/list/active_diseases = list()
var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions
var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
var/global/list/surgeries_list = list() //list of all surgeries by name, associated with their path.
-var/global/list/table_recipes = list() //list of all table craft recipes
\ No newline at end of file
+var/global/list/table_recipes = list() //list of all table craft recipes
+var/global/list/med_hud_users = list() //list of all entities using a medical HUD.
+var/global/list/sec_hud_users = list() //list of all entities using a security HUD.
\ No newline at end of file
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index 932d14deeeb..faad4720b36 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -44,6 +44,7 @@
#define ui_storage1 "CENTER+1:18,SOUTH:5"
#define ui_storage2 "CENTER+2:20,SOUTH:5"
+#define ui_borg_sensor "CENTER-3:16, SOUTH:5" //borgs
#define ui_inv1 "CENTER-2:16,SOUTH:5" //borgs
#define ui_inv2 "CENTER-1 :16,SOUTH:5" //borgs
#define ui_inv3 "CENTER :16,SOUTH:5" //borgs
@@ -80,6 +81,7 @@
#define ui_alien_toxin "EAST-1:28,CENTER+5:25"
#define ui_alien_fire "EAST-1:28,CENTER+4:25"
#define ui_alien_oxygen "EAST-1:28,CENTER+3:25"
+#define ui_alien_nightvision "EAST-1:28,CENTER+2:25"
//Middle right (status indicators)
#define ui_nutrition "EAST-1:28,CENTER-3:11"
@@ -94,20 +96,21 @@
// AI
-#define ui_ai_core "SOUTH:6,WEST:16"
-#define ui_ai_camera_list "SOUTH:6,WEST+1:16"
-#define ui_ai_track_with_camera "SOUTH:6,WEST+2:16"
-#define ui_ai_camera_light "SOUTH:6,WEST+3:16"
-#define ui_ai_crew_monitor "SOUTH:6,WEST+4:16"
-#define ui_ai_crew_manifest "SOUTH:6,WEST+5:16"
-#define ui_ai_alerts "SOUTH:6,WEST+6:16"
-#define ui_ai_announcement "SOUTH:6,WEST+7:16"
-#define ui_ai_shuttle "SOUTH:6,WEST+8:16"
-#define ui_ai_state_laws "SOUTH:6,WEST+9:16"
-#define ui_ai_pda_send "SOUTH:6,WEST+10:16"
-#define ui_ai_pda_log "SOUTH:6,WEST+11:16"
-#define ui_ai_take_picture "SOUTH:6,WEST+12:16"
-#define ui_ai_view_images "SOUTH:6,WEST+13:16"
+#define ui_ai_core "SOUTH:6,WEST"
+#define ui_ai_camera_list "SOUTH:6,WEST+1"
+#define ui_ai_track_with_camera "SOUTH:6,WEST+2"
+#define ui_ai_camera_light "SOUTH:6,WEST+3"
+#define ui_ai_crew_monitor "SOUTH:6,WEST+4"
+#define ui_ai_crew_manifest "SOUTH:6,WEST+5"
+#define ui_ai_alerts "SOUTH:6,WEST+6"
+#define ui_ai_announcement "SOUTH:6,WEST+7"
+#define ui_ai_shuttle "SOUTH:6,WEST+8"
+#define ui_ai_state_laws "SOUTH:6,WEST+9"
+#define ui_ai_pda_send "SOUTH:6,WEST+10"
+#define ui_ai_pda_log "SOUTH:6,WEST+11"
+#define ui_ai_take_picture "SOUTH:6,WEST+12"
+#define ui_ai_view_images "SOUTH:6,WEST+13"
+#define ui_ai_sensor "SOUTH:6,WEST+14"
//Pop-up inventory
#define ui_shoes "WEST+1:8,SOUTH:5"
diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm
index 9f254878373..b2d288b25e1 100644
--- a/code/_onclick/hud/ai.dm
+++ b/code/_onclick/hud/ai.dm
@@ -130,6 +130,15 @@
using.layer = 20
adding += using
- mymob.client.screen += adding + other
+//Medical/Security sensors
+ using = new /obj/screen()
+ using.name = "Sensor Augmentation"
+ using.icon = 'icons/mob/screen_ai.dmi'
+ using.icon_state = "ai_sensor"
+ using.screen_loc = ui_ai_sensor
+ using.layer = 20
+ adding += using
+
+ mymob.client.screen += adding + other
return
\ No newline at end of file
diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm
index 270d848eab9..797561e37cf 100644
--- a/code/_onclick/hud/alien.dm
+++ b/code/_onclick/hud/alien.dm
@@ -142,6 +142,12 @@
mymob.healths.name = "health"
mymob.healths.screen_loc = ui_alien_health
+ nightvisionicon = new /obj/screen()
+ nightvisionicon.icon ='icons/mob/screen_alien.dmi'
+ nightvisionicon.icon_state = "nightvision1"
+ nightvisionicon.name = "nightvision"
+ nightvisionicon.screen_loc = ui_alien_nightvision
+
alien_plasma_display = new /obj/screen()
alien_plasma_display.icon = 'icons/mob/screen_gen.dmi'
alien_plasma_display.icon_state = "power_display2"
@@ -168,6 +174,6 @@
mymob.client.screen = null
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.toxin, mymob.fire, mymob.healths, alien_plasma_display, mymob.pullin, mymob.blind, mymob.flash) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach )
+ mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.toxin, mymob.fire, mymob.healths, nightvisionicon, alien_plasma_display, mymob.pullin, mymob.blind, mymob.flash) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += adding + other
diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm
index d1888d6d369..2775f546c6f 100644
--- a/code/_onclick/hud/alien_larva.dm
+++ b/code/_onclick/hud/alien_larva.dm
@@ -48,6 +48,12 @@
mymob.healths.name = "health"
mymob.healths.screen_loc = ui_alien_health
+ nightvisionicon = new /obj/screen()
+ nightvisionicon.icon ='icons/mob/screen_alien.dmi'
+ nightvisionicon.icon_state = "nightvision1"
+ nightvisionicon.name = "nightvision"
+ nightvisionicon.screen_loc = ui_alien_nightvision
+
mymob.pullin = new /obj/screen()
mymob.pullin.icon = 'icons/mob/screen_alien.dmi'
mymob.pullin.icon_state = "pull0"
@@ -74,5 +80,5 @@
mymob.client.screen = null
- mymob.client.screen += list( mymob.zone_sel, mymob.oxygen, mymob.toxin, mymob.fire, mymob.healths, mymob.pullin, mymob.blind, mymob.flash) //, mymob.rest, mymob.sleep, mymob.mach )
+ mymob.client.screen += list( mymob.zone_sel, mymob.oxygen, mymob.toxin, mymob.fire, mymob.healths, nightvisionicon, mymob.pullin, mymob.blind, mymob.flash) //, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += adding + other
\ No newline at end of file
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 103d639189d..ed7abd1d7ca 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -100,6 +100,7 @@ var/datum/global_hud/global_hud = new()
var/obj/screen/blobpwrdisplay
var/obj/screen/blobhealthdisplay
var/obj/screen/alien_plasma_display
+ var/obj/screen/nightvisionicon
var/obj/screen/r_hand_hud_object
var/obj/screen/l_hand_hud_object
var/obj/screen/action_intent
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index cdc83c0ba9f..f81d908e36a 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -63,6 +63,15 @@
using.layer = 20
adding += using
+//Sec/Med HUDs
+ using = new /obj/screen()
+ using.name = "Sensor Augmentation"
+ using.icon = 'icons/mob/screen_ai.dmi'
+ using.icon_state = "ai_sensor"
+ using.screen_loc = ui_borg_sensor
+ using.layer = 20
+ adding += using
+
//Intent
using = new /obj/screen()
using.name = "act_intent"
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index ab0073a6e5a..d6ac5bb99c2 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -386,7 +386,14 @@
else if(isrobot(usr))
var/mob/living/silicon/robot/R = usr
R.aicamera.viewpictures()
-
+ if("nightvision")
+ if(isalien(usr))
+ var/mob/living/carbon/alien/humanoid/A = usr
+ A.nightvisiontoggle()
+ if("Sensor Augmentation")
+ if(issilicon(usr))
+ var/mob/living/silicon/S = usr
+ S.sensor_mode()
else
return 0
return 1
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index b74828c83f0..63ce7c0d32a 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -23,7 +23,6 @@
var/log_emote = 0 // log emotes
var/log_attack = 0 // log attack messages
var/log_adminchat = 0 // log admin chat messages
- var/log_adminwarn = 0 // log warnings admins get about bomb construction and such
var/log_pda = 0 // log pda messages
var/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits
var/sql_enabled = 0 // for sql switching
@@ -83,8 +82,9 @@
var/traitor_objectives_amount = 2
var/protect_roles_from_antagonist = 0// If security and such can be traitor/cult/other
- var/allow_latejoin_antagonists = 0 // If late-joining players can be traitor/changeling
- var/continuous_round_rev = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke.
+ var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff
+ var/allow_latejoin_antagonists = 0 // If late-joining players can be traitor/changeling
+ var/continuous_round_rev = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke.
var/continuous_round_wiz = 0
var/continuous_round_malf = 0
var/shuttle_refuel_delay = 12000
@@ -211,8 +211,6 @@
config.log_emote = 1
if("log_adminchat")
config.log_adminchat = 1
- if("log_adminwarn")
- config.log_adminwarn = 1
if("log_pda")
config.log_pda = 1
if("log_hrefs")
@@ -377,6 +375,8 @@
if("protect_roles_from_antagonist")
config.protect_roles_from_antagonist = 1
+ if("enforce_human_authority")
+ config.enforce_human_authority = 1
if("allow_latejoin_antagonists")
config.allow_latejoin_antagonists = 1
if("allow_random_events")
diff --git a/code/controllers/garbage.dm b/code/controllers/garbage.dm
index 322bc086d89..501ea8a2d92 100644
--- a/code/controllers/garbage.dm
+++ b/code/controllers/garbage.dm
@@ -70,7 +70,8 @@ var/datum/controller/garbage_collector/garbage = new()
// This should be overridden to remove all references pointing to the object being destroyed.
// Return true if the the GC controller should allow the object to continue existing. (Useful if pooling objects.)
/datum/proc/Destroy()
- del(src)
+ //del(src)
+ return
/datum/var/gc_destroyed //Time when this object was destroyed.
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index 5f8d3c7d38c..3b54156cee6 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -236,83 +236,53 @@ var/global/pipe_processing_killed = 0
*/
/datum/controller/game_controller/proc/process_mobs()
- var/i = 1
- while(i<=mob_list.len)
- var/mob/M = mob_list[i]
- if(M && !M.gc_destroyed)
+ for(var/mob/M in mob_list)
+ if(!M.gc_destroyed)
last_thing_processed = M.type
M.Life()
- i++
continue
- mob_list.Cut(i,i+1)
+ mob_list -= M
/datum/controller/game_controller/proc/process_diseases()
- var/i = 1
- while(i<=active_diseases.len)
- var/datum/disease/Disease = active_diseases[i]
- if(Disease)
- last_thing_processed = Disease.type
- Disease.process()
- i++
- continue
- active_diseases.Cut(i,i+1)
+ for(var/datum/disease/Disease in active_diseases)
+ last_thing_processed = Disease.type
+ Disease.process()
/datum/controller/game_controller/proc/process_machines()
- var/i = 1
- while(i<=machines.len)
- var/obj/machinery/Machine = machines[i]
- if(Machine && !Machine.gc_destroyed)
+ for(var/obj/machinery/Machine in machines)
+ if(!Machine.gc_destroyed)
last_thing_processed = Machine.type
if(Machine.process() != PROCESS_KILL)
if(Machine)
if(Machine.use_power)
Machine.auto_use_power()
- i++
continue
- machines.Cut(i,i+1)
+ machines -= Machine
/datum/controller/game_controller/proc/process_objects()
- var/i = 1
- while(i<=processing_objects.len)
- var/obj/Object = processing_objects[i]
- if(Object && !Object.gc_destroyed)
+ for(var/obj/Object in processing_objects)
+ if(!Object.gc_destroyed)
last_thing_processed = Object.type
Object.process()
- i++
continue
- processing_objects.Cut(i,i+1)
+ processing_objects -= Object
/datum/controller/game_controller/proc/process_pipenets()
last_thing_processed = /datum/pipe_network
- var/i = 1
- while(i<=pipe_networks.len)
- var/datum/pipe_network/Network = pipe_networks[i]
- if(Network)
- Network.process()
- i++
- continue
- pipe_networks.Cut(i,i+1)
+ for(var/datum/pipe_network/Network in pipe_networks)
+ Network.process()
/datum/controller/game_controller/proc/process_powernets()
last_thing_processed = /datum/powernet
- var/i = 1
- while(i<=powernets.len)
- var/datum/powernet/Powernet = powernets[i]
- if(Powernet)
- Powernet.reset()
- i++
- continue
- powernets.Cut(i,i+1)
+ for(var/datum/powernet/Powernet in powernets)
+ Powernet.reset()
/datum/controller/game_controller/proc/process_nano()
- var/i = 1
- while(i<=nanomanager.processing_uis.len)
- var/datum/nanoui/ui = nanomanager.processing_uis[i]
- if(ui && ui.src_object && ui.user)
+ for(var/datum/nanoui/ui in nanomanager.processing_uis)
+ if(ui.src_object && ui.user)
ui.process()
- i++
continue
- nanomanager.processing_uis.Cut(i,i+1)
+ nanomanager.processing_uis -= ui
/datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm
index 83fbd2c883a..c8ca0d4730d 100644
--- a/code/controllers/shuttle_controller.dm
+++ b/code/controllers/shuttle_controller.dm
@@ -37,16 +37,19 @@ var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle
// call the shuttle
// if not called before, set the endtime to T+600 seconds
// otherwise if outgoing, switch to incoming
-/datum/shuttle_controller/proc/incall(coeff = 1, var/signal_origin)
+/datum/shuttle_controller/proc/incall(coeff = 1, var/signal_origin, var/emergency_reason, var/red_alert)
if(endtime)
if(direction == -1)
setdirection(1)
else
- if(signal_origin && prob(60)) //40% chance the signal tracing will fail
+ if(recall_count > 2 && signal_origin && prob(70)) //30% chance the signal tracing will fail
last_call_loc = signal_origin
else
last_call_loc = null
+
+ priority_announce("The emergency shuttle has been called. [red_alert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.[emergency_reason][emergency_shuttle.last_call_loc ? "\n\nCall signal traced. Results can be viewed on any communcations console." : "" ]", null, 'sound/AI/shuttlecalled.ogg', "Priority")
+
settimeleft(SHUTTLEARRIVETIME*coeff)
online = 1
if(always_fake_recall)
@@ -67,15 +70,15 @@ var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle
recall_count ++
- if(recall_count > 2 && signal_origin && prob(60)) //40% chance the signal tracing will fail
+ if(recall_count > 2 && signal_origin && prob(70)) //30% chance the signal tracing will fail
last_call_loc = signal_origin
else
last_call_loc = null
if(recall_count == 2)
- priority_announce("The emergency shuttle has been recalled.\n\nExcessive number of emergency shuttle calls detected. We will attempt to trace all future calls and recalls to their source. Tracing results can be viewed on any communications console.", null, 'sound/AI/shuttlerecalled.ogg')
+ priority_announce("The emergency shuttle has been recalled.\n\nExcessive number of emergency shuttle calls detected. We will attempt to trace all future calls and recalls to their source. Tracing results may be viewed on any communications console.", null, 'sound/AI/shuttlerecalled.ogg')
else
- priority_announce("The emergency shuttle has been recalled.", null, 'sound/AI/shuttlerecalled.ogg', "Priority")
+ priority_announce("The emergency shuttle has been recalled.[last_call_loc ? " Recall signal traced. Results can be viewed on any communcations console." : "" ]", null, 'sound/AI/shuttlerecalled.ogg', "Priority")
setdirection(-1)
online = 1
@@ -134,7 +137,6 @@ var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle
incall(SHUTTLEAUTOCALLTIMER) //X minutes! If they want to recall, they have X-(X-5) minutes to do so
log_game("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.", 1)
- priority_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.", null, 'sound/AI/shuttlecalled.ogg', "Priority")
/datum/shuttle_controller/proc/move_shuttles()
var/datum/shuttle_manager/s
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 2fb8c9bd852..c072fc6ae39 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -639,7 +639,7 @@ body
reagent_options[R.name] = r_id
if(reagent_options.len)
- reagent_options = sortAssoc(reagent_options)
+ sortList(reagent_options)
reagent_options.Insert(1, "CANCEL")
var/chosen = input(usr, "Choose a reagent to add.", "Choose a reagent.") in reagent_options
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 2c43d367ce0..a4897448f17 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -33,5 +33,8 @@ client/verb/showrevinfo()
src << "[revdata.revision]"
else
src << "Revision unknown"
- src << "Current Infomational Settings:
Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]
Allow Latejoin Antagonists: [config.allow_latejoin_antagonists]"
+ src << "Current Infomational Settings:"
+ src << "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]"
+ src << "Enforce Human Authority: [config.enforce_human_authority]"
+ src << "Allow Latejoin Antagonists: [config.allow_latejoin_antagonists]"
return
\ No newline at end of file
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 089c9cb2cf1..ca1608ef30a 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -760,7 +760,7 @@
ticker.mode.changelings += src
current.make_changeling()
special_role = "Changeling"
- current << "Your powers are awoken. A flash of memory returns to us...we are a changeling!"
+ current << "Your powers are awoken. A flash of memory returns to us...we are [changeling.changelingID], a changeling!"
message_admins("[key_name_admin(usr)] has changeling'ed [current].")
log_admin("[key_name(usr)] has changeling'ed [current].")
if("autoobjectives")
@@ -994,21 +994,16 @@
ticker.mode.finalize_traitor(src)
ticker.mode.greet_traitor(src)
-/datum/mind/proc/make_Nuke()
+/datum/mind/proc/make_Nuke(var/turf/spawnloc,var/nuke_code,var/leader=0)
if(!(src in ticker.mode.syndicates))
ticker.mode.syndicates += src
ticker.mode.update_synd_icons_added(src)
- if (ticker.mode.syndicates.len==1)
- ticker.mode.prepare_syndicate_leader(src)
- else
- current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
special_role = "Syndicate"
assigned_role = "MODE"
- current << "You are a [syndicate_name()] agent!"
ticker.mode.forge_syndicate_objectives(src)
ticker.mode.greet_syndicate(src)
- current.loc = get_turf(locate("landmark*Syndicate-Spawn"))
+ current.loc = spawnloc
var/mob/living/carbon/human/H = current
qdel(H.belt)
@@ -1023,6 +1018,11 @@
ticker.mode.equip_syndicate(current)
+ if (leader)
+ ticker.mode.prepare_syndicate_leader(src,nuke_code)
+ else
+ current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
+
/datum/mind/proc/make_Changling()
if(!(src in ticker.mode.changelings))
ticker.mode.changelings += src
diff --git a/code/datums/spells/mind_transfer.dm b/code/datums/spells/mind_transfer.dm
index 586fd7a2700..0c8032c9b7e 100644
--- a/code/datums/spells/mind_transfer.dm
+++ b/code/datums/spells/mind_transfer.dm
@@ -18,7 +18,7 @@ Urist: I don't feel like figuring out how you store object spells so I'm leaving
Make sure spells that are removed from spell_list are actually removed and deleted when mind transfering.
Also, you never added distance checking after target is selected. I've went ahead and did that.
*/
-/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets,mob/user = usr)
+/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets,mob/user = usr, distanceoverride)
if(!targets.len)
user << "No mind found."
return
@@ -29,7 +29,7 @@ Also, you never added distance checking after target is selected. I've went ahea
var/mob/living/target = targets[1]
- if(!(target in oview(range)))//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it.
+ if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it.
user << "They are too far away!"
return
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 48d99e1d71c..d989b75eb68 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -156,6 +156,13 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
containername = "special ops crate"
hidden = 1
+/datum/supply_packs/emergency/syndicate
+ name = "#ERROR_NULL_ENTRY"
+ contains = list(/obj/item/weapon/storage/box/syndicate)
+ cost = 140
+ containertype = /obj/structure/closet/crate
+ containername = "crate"
+ hidden = 1
//////////////////////////////////////////////////////////////////////////////
//////////////////////////// Security ////////////////////////////////////////
@@ -494,6 +501,15 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 25
containername = "particle accelerator crate"
+/datum/supply_packs/engineering/engine/spacesuit
+ name = "Space Suit crate"
+ contains = list(/obj/item/clothing/suit/space,
+ /obj/item/clothing/head/helmet/space,
+ /obj/item/clothing/mask/breath,)
+ cost = 80
+ containertype = /obj/structure/closet/crate/secure
+ containername = "space suit crate"
+ access = access_eva
//////////////////////////////////////////////////////////////////////////////
//////////////////////////// Medical /////////////////////////////////////////
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 4e1ab7ef49c..fa6d850888e 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -241,7 +241,7 @@ var/list/uplink_items = list()
desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a strong anaesthetic and a chemical that is capable of blocking the movement of the vocal chords. \
The pen holds one dose of the mixture, and cannot be refilled."
item = /obj/item/weapon/pen/sleepy
- cost = 3
+ cost = 2
excludefrom = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_weapons/soap
diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm
index 372578e6038..48691c47bff 100644
--- a/code/datums/wires/airlock.dm
+++ b/code/datums/wires/airlock.dm
@@ -36,7 +36,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
. += ..()
. += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]", (A.locked ? "The door bolts have fallen!" : "The door bolts look up."),
(A.lights ? "The door bolt lights are on." : "The door bolt lights are off!"),
- ((A.arePowerSystemsOn() && !(A.stat & NOPOWER)) ? "The test light is on." : "The test light is off!"),
+ ((A.hasPower()) ? "The test light is on." : "The test light is off!"),
((A.aiControlDisabled==0 && !A.emagged) ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."),
(A.safe==0 ? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."),
(A.normalspeed==0 ? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."),
@@ -124,7 +124,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
switch(index)
if(AIRLOCK_WIRE_IDSCAN)
//Sending a pulse through this disables emergency access and flashes the red light on the door (if the door has power).
- if((A.arePowerSystemsOn()) && (!(A.stat & NOPOWER)) && A.density)
+ if(A.hasPower() && A.density)
A.do_animate("deny")
if(A.emergency)
A.emergency = 0
@@ -140,7 +140,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
for(var/mob/M in range(1, A))
M << "You hear a click from the bottom of the door."
else
- if(A.arePowerSystemsOn()) //only can raise bolts if power's on
+ if(A.hasPower()) //only can raise bolts if power's on
A.locked = 0
for(var/mob/M in range(1, A))
M << "You hear a click from the bottom of the door."
diff --git a/code/defines/procs/priority_announce.dm b/code/defines/procs/priority_announce.dm
index c191abe3265..621a4c913a2 100644
--- a/code/defines/procs/priority_announce.dm
+++ b/code/defines/procs/priority_announce.dm
@@ -43,5 +43,5 @@
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player) && !M.ear_deaf)
- M << "[title] [message]"
+ M << "[title]
[message]
"
M << sound('sound/misc/notice2.ogg')
\ No newline at end of file
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 8ac516f431d..2291605ef6d 100644
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -833,11 +833,10 @@ proc/process_ghost_teleport_locs()
/area/engine/engine_smes
name = "\improper Engineering SMES"
icon_state = "engine_smes"
- requires_power = 0//This area only covers the batteries and they deal with their own power
/area/engine/engineering
name = "Engineering"
- icon_state = "engine_smes"
+ icon_state = "engine"
/area/engine/break_room
name = "\improper Engineering Foyer"
@@ -855,7 +854,6 @@ proc/process_ghost_teleport_locs()
name = "Gravity Generator Room"
icon_state = "blue"
-
//Solars
/area/solar
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
new file mode 100644
index 00000000000..54b628e4200
--- /dev/null
+++ b/code/game/data_huds.dm
@@ -0,0 +1,181 @@
+/* Using the HUD procs is simple. Call these procs in the life.dm of the intended mob.
+Use the regular_hud_updates() proc before process_med_hud(mob) or process_sec_hud(mob) so
+the HUD updates properly! */
+
+//Deletes the current HUD images so they can be refreshed with new ones.
+mob/proc/regular_hud_updates() //Used in the life.dm of mobs that can use HUDs.
+ if(client)
+ for(var/image/hud in client.images)
+ if(copytext(hud.icon_state,1,4) == "hud")
+ client.images -= hud
+ med_hud_users -= src
+ sec_hud_users -= src
+
+
+//Medical HUD procs
+
+proc/RoundHealth(health)
+
+ switch(health)
+ if(100 to INFINITY)
+ return "health100"
+ if(70 to 100)
+ return "health80"
+ if(50 to 70)
+ return "health60"
+ if(30 to 50)
+ return "health40"
+ if(18 to 30)
+ return "health25"
+ if(5 to 18)
+ return "health10"
+ if(1 to 5)
+ return "health1"
+ if(-99 to 0)
+ return "health0"
+ else
+ return "health-100"
+ return "0"
+
+/*Called by the Life() proc of the mob using it, usually. Items can call it as well.
+Called with this syntax: (The user mob, the type of hud in use, the advanced or basic version of the hud,eye object in the case of an AI) */
+
+proc/process_data_hud(var/mob/M, var/hud_type, var/hud_mode, var/mob/eye)
+ #define DATA_HUD_MEDICAL 1
+ #define DATA_HUD_SECURITY 2
+
+ #define DATA_HUD_BASIC 1
+ #define DATA_HUD_ADVANCED 2
+
+ if(!M)
+ return
+ if(!M.client)
+ return
+
+ var/turf/T
+ if(eye)
+ T = get_turf(eye)
+ else
+ T = get_turf(M)
+
+
+ for(var/mob/living/carbon/human/H in mob_list)
+ if(get_dist(H, T) > M.client.view) //Ignores any humans outside of the user's view distance.
+ continue
+
+ switch(hud_type)
+ if(DATA_HUD_MEDICAL)
+ med_hud_users |= M
+ process_med_hud(M,hud_mode,T,H)
+
+ if(DATA_HUD_SECURITY)
+ sec_hud_users |= M //Used for Security HUD alerts.
+ process_sec_hud(M,hud_mode,T,H)
+
+/***********************************************
+Medical HUD outputs! Advanced mode ignores suit sensors.
+************************************************/
+proc/process_med_hud(var/mob/M, var/mode, var/turf/T, var/mob/living/carbon/human/patient)
+
+ var/client/C = M.client
+
+ if(mode == DATA_HUD_BASIC && !med_hud_suit_sensors(patient)) //Used for the AI's MedHUD, only works if the patient has activated suit sensors.
+ return
+
+
+ var/foundVirus = med_hud_find_virus(patient) //Detects non-hidden diseases in a patient, returns as a binary value.
+
+ C.images += med_hud_get_health(patient) //Generates a patient's health bar.
+ C.images += med_hud_get_status(patient, foundVirus) //Determines the type of status icon to show.
+
+
+proc/med_hud_suit_sensors(var/mob/living/carbon/human/patient)
+ if(istype(patient.w_uniform, /obj/item/clothing/under))
+ var/obj/item/clothing/under/U = patient.w_uniform
+ if(U.sensor_mode > 2)
+ return 1
+ else
+ return 0
+
+proc/med_hud_find_virus(var/mob/living/carbon/human/patient)
+ for(var/datum/disease/D in patient.viruses)
+ if(!D.hidden[SCANNER])
+ return 1
+
+proc/med_hud_get_health(var/mob/living/carbon/human/patient)
+ var/image/holder = patient.hud_list[HEALTH_HUD]
+ if(patient.stat == 2)
+ holder.icon_state = "hudhealth-100"
+ else
+ holder.icon_state = "hud[RoundHealth(patient.health)]"
+ return holder
+
+proc/med_hud_get_status(var/mob/living/carbon/human/patient, var/foundVirus)
+ var/image/holder = patient.hud_list[STATUS_HUD]
+ if(patient.stat == 2)
+ holder.icon_state = "huddead"
+ else if(patient.status_flags & XENO_HOST)
+ holder.icon_state = "hudxeno"
+ else if(foundVirus)
+ holder.icon_state = "hudill"
+ else
+ holder.icon_state = "hudhealthy"
+ return holder
+
+
+/***********************************************
+ Security HUDs.
+ Pass a value for the second argument to enable implant viewing or other special features.
+************************************************/
+proc/process_sec_hud(var/mob/M, var/mode, var/turf/T, var/mob/living/carbon/human/perp)
+
+ var/client/C = M.client
+
+ sec_hud_get_ID(C, perp) //Provides the perp's job icon.
+
+ if(mode == DATA_HUD_ADVANCED) //If not set to "DATA_HUD_ADVANCED, the Sec HUD will only display the job.
+ sec_hud_get_implants(C, perp) //Returns the perp's implants, if any.
+ sec_hud_get_security_status(C, perp) //Gives the perp's arrest record, if there is one.
+
+
+proc/sec_hud_get_ID(var/client/C, var/mob/living/carbon/human/perp)
+ var/image/holder
+ holder = perp.hud_list[ID_HUD]
+ holder.icon_state = "hudno_id"
+ if(perp.wear_id)
+ holder.icon_state = "hud[ckey(perp.wear_id.GetJobName())]"
+ C.images += holder
+
+proc/sec_hud_get_implants(var/client/C, var/mob/living/carbon/human/perp)
+ var/image/holder
+ for(var/obj/item/weapon/implant/I in perp)
+ if(I.implanted)
+ if(istype(I,/obj/item/weapon/implant/tracking))
+ holder = perp.hud_list[IMPTRACK_HUD]
+ holder.icon_state = "hud_imp_tracking"
+ else if(istype(I,/obj/item/weapon/implant/loyalty))
+ holder = perp.hud_list[IMPLOYAL_HUD]
+ holder.icon_state = "hud_imp_loyal"
+ else if(istype(I,/obj/item/weapon/implant/chem))
+ holder = perp.hud_list[IMPCHEM_HUD]
+ holder.icon_state = "hud_imp_chem"
+ else
+ continue
+ C.images += holder
+ break
+
+proc/sec_hud_get_security_status(var/client/C, var/mob/living/carbon/human/perp)
+ var/image/holder
+ var/perpname = perp.get_face_name(perp.get_id_name(""))
+ if(perpname)
+ var/datum/data/record/R = find_record("name", perpname, data_core.security)
+ if(R)
+ holder = perp.hud_list[WANTED_HUD]
+ switch(R.fields["criminal"])
+ if("*Arrest*") holder.icon_state = "hudwanted"
+ if("Incarcerated") holder.icon_state = "hudincarcerated"
+ if("Parolled") holder.icon_state = "hudparolled"
+ if("Discharged") holder.icon_state = "huddischarged"
+ else
+ return
+ C.images += holder
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm
index 188161d7232..1bece2f8ccd 100644
--- a/code/game/gamemodes/blob/blob_report.dm
+++ b/code/game/gamemodes/blob/blob_report.dm
@@ -19,11 +19,12 @@
intercepttext += "
Note in the event of a quarantine breach or uncontrolled spread of the biohazard, the directive 7-10 may be upgraded to a directive 7-12.
"
intercepttext += "Message ends."
if(2)
- var/nukecode = "ERROR"
+ var/nukecode = rand(10000, 99999)
for(var/obj/machinery/nuclearbomb/bomb in world)
if(bomb && bomb.r_code)
if(bomb.z == 1)
- nukecode = bomb.r_code
+ bomb.r_code = nukecode
+
intercepttext += "NanoTrasen Update: Biohazard Alert.
"
intercepttext += "Directive 7-12 has been issued for [station_name()].
"
intercepttext += "The biohazard has grown out of control and will soon reach critical mass.
"
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 6844ffe118f..fcfa5d99dd8 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -14,8 +14,6 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
required_enemies = 1
recommended_enemies = 4
- uplink_welcome = "Syndicate Uplink Console:"
- uplink_uses = 10
var/const/prob_int_murder_target = 50 // intercept names the assassination target half the time
var/const/prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target
@@ -48,7 +46,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
var/num_changelings = 1
if(config.changeling_scaling_coeff)
- num_changelings = max(1, round((num_players())/(config.changeling_scaling_coeff)))
+ num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*2))+2, round(num_players()/config.changeling_scaling_coeff) ))
else
num_changelings = max(1, min(num_players(), changeling_amount))
@@ -79,10 +77,10 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
return
/datum/game_mode/changeling/make_antag_chance(var/mob/living/carbon/human/character) //Assigns changeling to latejoiners
- var/changelingcap = round(joined_player_list.len / config.changeling_scaling_coeff)
+ var/changelingcap = min( round(num_players()/(config.changeling_scaling_coeff*2))+2, round(num_players()/config.changeling_scaling_coeff) )
if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
return
- if(changelings.len <= (changelingcap - 2) || prob(100 / config.changeling_scaling_coeff))
+ if(changelings.len <= (changelingcap - 2) || prob(100 - (config.changeling_scaling_coeff*2)))
if(character.client.prefs.be_special & BE_CHANGELING)
if(!jobban_isbanned(character.client, "changeling") && !jobban_isbanned(character.client, "Syndicate"))
if(!(character.job in ticker.mode.restricted_jobs))
@@ -101,7 +99,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
changeling.objectives += absorb_objective
var/list/active_ais = active_ais()
- if(active_ais.len && prob(2))
+ if(active_ais.len && prob(100/joined_player_list.len))
var/datum/objective/destroy/destroy_objective = new
destroy_objective.owner = changeling
destroy_objective.find_target()
@@ -138,8 +136,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
/datum/game_mode/proc/greet_changeling(var/datum/mind/changeling, var/you_are=1)
if (you_are)
- changeling.current << "You are a changeling! You have absorbed and taken the form of a human."
- changeling.current << "Use say \":g message\" to communicate with your fellow changelings."
+ changeling.current << "You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human."
changeling.current << "You must complete the following tasks:"
if (changeling.current.mind)
@@ -180,19 +177,10 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
var/text = "
The changelings were:"
for(var/datum/mind/changeling in changelings)
var/changelingwin = 1
-
- text += "
[changeling.key] was [changeling.name] ("
- if(changeling.current)
- if(changeling.current.stat == DEAD)
- text += "died"
- else
- text += "survived"
- if(changeling.current.real_name != changeling.name)
- text += " as [changeling.current.real_name]"
- else
- text += "body destroyed"
+ if(!changeling.current)
changelingwin = 0
- text += ")"
+
+ text += printplayer(changeling)
//Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed.
text += "
Changeling ID: [changeling.changeling.changelingID]."
@@ -239,6 +227,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
var/purchasedpowers = list()
var/mimicing = ""
var/canrespec = 0
+ var/changeling_speak = 0
var/datum/dna/chosen_dna
var/obj/effect/proc_holder/changeling/sting/chosen_sting
diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm
index 3365038e721..91d7f2ee9a1 100644
--- a/code/game/gamemodes/changeling/evolution_menu.dm
+++ b/code/game/gamemodes/changeling/evolution_menu.dm
@@ -316,6 +316,10 @@ var/list/sting_paths
user << "We have already evolved this ability!"
return
+ if(thepower.dna_cost < 0)
+ user << "We cannot evolve this ability."
+ return
+
if(geneticpoints < thepower.dna_cost)
user << "We have reached our capacity for abilities."
return
diff --git a/code/game/gamemodes/changeling/powers/hivemind.dm b/code/game/gamemodes/changeling/powers/hivemind.dm
index 3f9aa14b702..8823560ab66 100644
--- a/code/game/gamemodes/changeling/powers/hivemind.dm
+++ b/code/game/gamemodes/changeling/powers/hivemind.dm
@@ -1,11 +1,32 @@
+//HIVEMIND COMMUNICATION (:g)
+/obj/effect/proc_holder/changeling/hivemind_comms
+ name = "Hivemind Communication"
+ desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings."
+ helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
+ dna_cost = 1
+ chemical_cost = -1
+
+/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(var/mob/user)
+ ..()
+ var/datum/changeling/changeling=user.mind.changeling
+ changeling.changeling_speak = 1
+ user << "Use say \":g message\" to communicate with the other changelings."
+ var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
+ if(!changeling.has_sting(S1))
+ changeling.purchasedpowers+=S1
+ var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new
+ if(!changeling.has_sting(S2))
+ changeling.purchasedpowers+=S2
+ return
+
// HIVE MIND UPLOAD/DOWNLOAD DNA
var/list/datum/dna/hivemind_bank = list()
/obj/effect/proc_holder/changeling/hivemind_upload
- name = "Hive Channel"
+ name = "Hive Channel DNA"
desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it."
chemical_cost = 10
- dna_cost = 0
+ dna_cost = -1
/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
var/datum/changeling/changeling = user.mind.changeling
@@ -32,10 +53,10 @@ var/list/datum/dna/hivemind_bank = list()
return 1
/obj/effect/proc_holder/changeling/hivemind_download
- name = "Hive Absorb"
+ name = "Hive Absorb DNA"
desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives."
chemical_cost = 20
- dna_cost = 0
+ dna_cost = -1
/obj/effect/proc_holder/changeling/hivemind_download/can_sting(var/mob/living/carbon/user)
if(!..())
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index 7bb219b5e00..e6246f686e2 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -156,7 +156,7 @@
if(!A.requiresID() || A.allowed(user)) //This is to prevent stupid shit like hitting a door with an arm blade, the door opening because you have acces and still getting a "the airlocks motors resist our efforts to force it" message.
return
- if(A.arePowerSystemsOn() && !(A.stat & NOPOWER))
+ if(A.hasPower())
user << "The airlock's motors resist our efforts to force it."
return
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index 2b0b30948b5..615cf29383c 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -31,9 +31,9 @@
var/num_changelings = 1
if(config.changeling_scaling_coeff)
- num_changelings = max(1, round((num_players())/(config.changeling_scaling_coeff*2)))
+ num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*4))+2, round(num_players()/(config.changeling_scaling_coeff*2)) ))
else
- num_changelings = max(1, min(num_players(), changeling_amount))
+ num_changelings = max(1, min(num_players(), changeling_amount/2))
for(var/datum/mind/player in possible_changelings)
for(var/job in restricted_jobs)//Removing robots from the list
@@ -61,11 +61,11 @@
return
/datum/game_mode/traitor/changeling/make_antag_chance(var/mob/living/carbon/human/character) //Assigns changeling to latejoiners
- var/changelingcap = round(joined_player_list.len / (config.changeling_scaling_coeff * 2))
+ var/changelingcap = min( round(num_players()/(config.changeling_scaling_coeff*4))+2, round(num_players()/(config.changeling_scaling_coeff*2)) )
if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
..()
return
- if(changelings.len <= (changelingcap - 2) || prob(100 / (config.changeling_scaling_coeff * 2)))
+ if(changelings.len <= (changelingcap - 2) || prob(100 / (config.changeling_scaling_coeff * 4)))
if(character.client.prefs.be_special & BE_CHANGELING)
if(!jobban_isbanned(character.client, "changeling") && !jobban_isbanned(character.client, "Syndicate"))
if(!(character.job in ticker.mode.restricted_jobs))
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index e0615b75826..8ab4e6dde35 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -30,8 +30,6 @@
required_enemies = 6
recommended_enemies = 6
- uplink_welcome = "Nar-Sie Uplink Console:"
- uplink_uses = 10
var/finished = 0
@@ -375,18 +373,8 @@
if( cult.len || (ticker && istype(ticker.mode,/datum/game_mode/cult)) )
var/text = "
The cultists were:"
for(var/datum/mind/cultist in cult)
+ text += printplayer(cultist)
- text += "
[cultist.key] was [cultist.name] ("
- if(cultist.current)
- if(cultist.current.stat == DEAD)
- text += "died"
- else
- text += "survived"
- if(cultist.current.real_name != cultist.name)
- text += " as [cultist.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
text += "
"
world << text
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 36317ec9ca7..262c90379c3 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -187,7 +187,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
user << "You are unable to speak the words of the rune."
return
if(!word1 || !word2 || !word3 || prob(user.getBrainLoss()))
- return fizzle()
+ return fizzle(user)
if(word1 == wordtravel && word2 == wordself)
return teleport(src.word3)
if(word1 == wordsee && word2 == wordblood && word3 == wordhell)
@@ -241,16 +241,18 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
else
user.take_overall_damage(30, 0)
user << "You feel the life draining from you, as if Lord Nar-Sie is displeased with you."
- return fizzle()
+ return fizzle(user)
-/obj/effect/rune/proc/fizzle()
- if(istype(src,/obj/effect/rune))
- usr.say(pick("B'ADMINES SP'WNIN SH'T","IC'IN O'OC","RO'SHA'M I'SA GRI'FF'N ME'AI","TOX'IN'S O'NM FI'RAH","IA BL'AME TOX'IN'S","FIR'A NON'AN RE'SONA","A'OI I'RS ROUA'GE","LE'OAN JU'STA SP'A'C Z'EE SH'EF","IA PT'WOBEA'RD, IA A'DMI'NEH'LP"))
- else
- usr.whisper(pick("B'ADMINES SP'WNIN SH'T","IC'IN O'OC","RO'SHA'M I'SA GRI'FF'N ME'AI","TOX'IN'S O'NM FI'RAH","IA BL'AME TOX'IN'S","FIR'A NON'AN RE'SONA","A'OI I'RS ROUA'GE","LE'OAN JU'STA SP'A'C Z'EE SH'EF","IA PT'WOBEA'RD, IA A'DMI'NEH'LP"))
- for (var/mob/V in viewers(src))
- V.show_message("The markings pulse with a small burst of light, then fall dark.", 3, "You hear a faint fizzle.", 2)
+/obj/effect/rune/proc/fizzle(var/mob/living/cultist = null)
+ var/gibberish = pick("B'ADMINES SP'WNIN SH'T","IC'IN O'OC","RO'SHA'M I'SA GRI'FF'N ME'AI","TOX'IN'S O'NM FI'RAH","IA BL'AME TOX'IN'S","FIR'A NON'AN RE'SONA","A'OI I'RS ROUA'GE","LE'OAN JU'STA SP'A'C Z'EE SH'EF","IA PT'WOBEA'RD, IA A'DMI'NEH'LP")
+
+ if(cultist)
+ if(istype(src,/obj/effect/rune))
+ cultist.say(gibberish)
+ else
+ cultist.whisper(gibberish)
+ visible_message("The markings pulse with a small burst of light, then fall dark.", 3, "You hear a faint fizzle.", 2)
return
/obj/effect/rune/proc/check_icon()
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 9209b4f3df2..e899e1a7be2 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -31,7 +31,7 @@ var/list/sacrificed = list()
user.loc = allrunesloc[rand(1,index)]
return
if(istype(src,/obj/effect/rune))
- return fizzle() //Use friggin manuals, Dorf, your list was of zero length.
+ return fizzle(user) //Use friggin manuals, Dorf, your list was of zero length.
else
call(/obj/effect/rune/proc/fizzle)()
return
@@ -53,7 +53,7 @@ var/list/sacrificed = list()
IP = R
runecount++
if(runecount >= 2)
- user << "You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric"
+ user << "You feel pain, as the rune disappears in reality shift caused by too much wear of space-time fabric"
if (istype(user, /mob/living))
user.take_overall_damage(5, 0)
qdel(src)
@@ -61,7 +61,7 @@ var/list/sacrificed = list()
if(iscultist(C) && !C.stat)
culcount++
if(user.loc==src.loc)
- return fizzle()
+ return fizzle(user)
if(culcount>=1)
user.say("Sas[pick("'","`")]so c'arta forbici tarem!")
user.visible_message("You feel air moving from the rune - like as it was swapped with somewhere else.", \
@@ -74,7 +74,7 @@ var/list/sacrificed = list()
M.loc = IP.loc
return
- return fizzle()
+ return fizzle(user)
/////////////////////////////////////////SECOND RUNE
@@ -152,9 +152,10 @@ var/list/sacrificed = list()
/obj/effect/rune/proc/tearreality()
var/list/mob/living/carbon/human/cultist_count = list()
+ var/mob/living/user = usr
+ user.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!")
for(var/mob/M in range(1,src))
if(iscultist(M) && !M.stat)
- M.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!")
cultist_count += M
if(cultist_count.len >= 9)
if(ticker.mode.name == "cult")
@@ -374,7 +375,7 @@ var/list/sacrificed = list()
return
if(istype(src,/obj/effect/rune))
- return fizzle()
+ return fizzle()
else
call(/obj/effect/rune/proc/fizzle)()
return
@@ -769,7 +770,7 @@ var/list/sacrificed = list()
return
return
if(istype(W,/obj/effect/rune))
- return fizzle()
+ return fizzle()
if(istype(W,/obj/item/weapon/paper/talisman))
call(/obj/effect/rune/proc/fizzle)()
return
@@ -802,7 +803,7 @@ var/list/sacrificed = list()
if(users.len>=1)
var/mob/living/carbon/cultist = input("Choose the one who you want to free", "Followers of Geometer") as null|anything in (cultists - users)
if(!cultist)
- return fizzle()
+ return fizzle(user)
if (cultist == user) //just to be sure.
return
if(!(cultist.buckled || \
@@ -835,7 +836,7 @@ var/list/sacrificed = list()
user.take_overall_damage(15, 0)
C.say("Khari[pick("'","`")]d! Gual'te nikka!")
qdel(src)
- return fizzle()
+ return fizzle(user)
/////////////////////////////////////////NINETEENTH RUNE
@@ -852,12 +853,12 @@ var/list/sacrificed = list()
if(users.len>=3)
var/mob/living/carbon/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - user)
if(!cultist)
- return fizzle()
+ return fizzle(user)
if(cultist == user) //just to be sure.
return
if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet)))
user << "You cannot summon the [cultist], for his shackles of blood are strong"
- return fizzle()
+ return fizzle(user)
cultist.loc = src.loc
cultist.Weaken(5)
cultist.regenerate_icons()
@@ -869,7 +870,7 @@ var/list/sacrificed = list()
"You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a body.", \
"You hear a pop and smell ozone.")
qdel(src)
- return fizzle()
+ return fizzle(user)
/////////////////////////////////////////TWENTIETH RUNES
diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm
index 04dc0d29685..77e754ee36f 100644
--- a/code/game/gamemodes/extended/extended.dm
+++ b/code/game/gamemodes/extended/extended.dm
@@ -3,9 +3,6 @@
config_tag = "extended"
required_players = 0
- uplink_welcome = "Syndicate Uplink Console:"
- uplink_uses = 10
-
/datum/game_mode/announce()
world << "The current game mode is - Extended Role-Playing!"
world << "Just have fun and role-play!"
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index cb1fbdd641a..517ccae3a06 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -27,8 +27,6 @@
var/required_enemies = 0
var/recommended_enemies = 0
var/pre_setup_before_jobs = 0
- var/uplink_welcome = "Syndicate Uplink Console:"
- var/uplink_uses = 10
var/antag_flag = null //preferences flag such as BE_WIZARD that need to be turned on for players to be antag
var/datum/mind/sacrifice_target = null
@@ -386,4 +384,20 @@ proc/display_roundstart_logout_report()
for(var/mob/M in mob_list)
if(M.client && M.client.holder)
- M << msg
\ No newline at end of file
+ M << msg
+
+/datum/game_mode/proc/printplayer(var/datum/mind/ply)
+ var/role = "\improper[ply.assigned_role]"
+ var/text = "
[ply.name]([ply.key]) as \a [role] ("
+ if(ply.current)
+ if(ply.current.stat == DEAD)
+ text += "died"
+ else
+ text += "survived"
+ if(ply.current.real_name != ply.name)
+ text += " as [ply.current.real_name]"
+ else
+ text += "body destroyed"
+ text += ")"
+
+ return text
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 62573d6032a..fc67d9f723a 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -198,6 +198,11 @@ var/round_start_time = 0
world << sound('sound/effects/explosionfar.ogg')
flick("station_intact_fade_red",cinematic)
cinematic.icon_state = "summary_nukefail"
+ if("fake") //The round isn't over, we're just freaking people out for fun
+ flick("intro_nuke",cinematic)
+ sleep(35)
+ world << sound('sound/items/bikehorn.ogg')
+ flick("summary_selfdes",cinematic)
else
flick("intro_nuke",cinematic)
sleep(35)
@@ -335,7 +340,7 @@ var/round_start_time = 0
//Player status report
for(var/mob/Player in mob_list)
- if(Player.mind)
+ if(Player.mind && !isnewplayer(Player))
if(Player.stat != DEAD && !isbrain(Player))
num_survivors++
if(station_evacuated) //If the shuttle has already left the station
@@ -355,13 +360,14 @@ var/round_start_time = 0
end_state.count()
var/station_integrity = round( 100.0 * start_state.score(end_state), 0.1)
- world << "
[TAB]Shift Duration: [round(world.time / 36000)]:[add_zero(world.time / 600 % 60, 2)]:[world.time / 100 % 6][world.time / 100 % 10]"
+ world << "
[TAB]Shift Duration: [round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]"
world << "
[TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[station_integrity]%"]"
- world << "
[TAB]Total Population: [joined_player_list.len]"
- if(station_evacuated)
- world << "
[TAB]Evacuation Rate: [num_escapees] ([round((num_escapees/joined_player_list.len)*100, 0.1)]%)"
- else
- world << "
[TAB]Survival Rate: [num_survivors] ([round((num_survivors/joined_player_list.len)*100, 0.1)]%)"
+ if(joined_player_list.len)
+ world << "
[TAB]Total Population: [joined_player_list.len]"
+ if(station_evacuated)
+ world << "
[TAB]Evacuation Rate: [num_escapees] ([round((num_escapees/joined_player_list.len)*100, 0.1)]%)"
+ else
+ world << "
[TAB]Survival Rate: [num_survivors] ([round((num_survivors/joined_player_list.len)*100, 0.1)]%)"
world << "
"
//Silicon laws report
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index c5428a993a0..12d9fa68d5b 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -10,10 +10,6 @@
recommended_enemies = 1
pre_setup_before_jobs = 1
- uplink_welcome = "Crazy AI Uplink Console:"
- uplink_uses = 10
-
-
var/AI_win_timeleft = 1800 //started at 1800, in case I change this for testing round end.
var/malf_mode_declared = 0
diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm
index 76f3b1215f4..234f205e0d2 100644
--- a/code/game/gamemodes/meteor/meteor.dm
+++ b/code/game/gamemodes/meteor/meteor.dm
@@ -5,9 +5,6 @@
var/nometeors = 1
required_players = 0
- uplink_welcome = "EVIL METEOR Uplink Console:"
- uplink_uses = 10
-
/datum/game_mode/meteor/announce()
world << "The current game mode is - Meteor!"
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index aefcfc70c47..666fe48651a 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -11,9 +11,6 @@
pre_setup_before_jobs = 1
antag_flag = BE_OPERATIVE
- uplink_welcome = "Corporate Backed Uplink Console:"
- uplink_uses = 10
-
var/const/agents_possible = 5 //If we ever need more syndicate agents.
var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer!
@@ -100,7 +97,6 @@
for(var/obj/effect/landmark/A in landmarks_list)
if(A.name == "Syndicate-Spawn")
synd_spawn += get_turf(A)
- qdel(A)
continue
var/obj/effect/landmark/uplinklocker = locate("landmark*Syndicate-Uplink") //i will be rewriting this shortly
@@ -113,7 +109,7 @@
for(var/datum/mind/synd_mind in syndicates)
if(spawnpos > synd_spawn.len)
- spawnpos = 1
+ spawnpos = 2
synd_mind.current.loc = synd_spawn[spawnpos]
forge_syndicate_objectives(synd_mind)
@@ -145,19 +141,28 @@
spawn(1)
NukeNameAssign(nukelastname(synd_mind.current),syndicates) //allows time for the rest of the syndies to be chosen
synd_mind.current.real_name = "[syndicate_name()] [leader_title]"
+ synd_mind.current << "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors."
+ synd_mind.current << "If you feel you are not up to this task, give your ID to another operative."
+
if (nuke_code)
synd_mind.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0)
synd_mind.current << "The nuclear authorization code is: [nuke_code]"
+
+ var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/weapon/card/id)
+
+ if(foundIDs.len)
+ for(var/obj/item/weapon/card/id/ID in foundIDs)
+ ID.access += access_syndicate_leader
+ else
+ message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!")
+
var/obj/item/weapon/paper/P = new
P.info = "The nuclear authorization code is: [nuke_code]"
P.name = "nuclear bomb code"
- if (ticker.mode.config_tag=="nuclear")
- P.loc = synd_mind.current.loc
- else
- var/mob/living/carbon/human/H = synd_mind.current
- P.loc = H.loc
- H.equip_to_slot_or_del(P, slot_r_store, 0)
- H.update_icons()
+ var/mob/living/carbon/human/H = synd_mind.current
+ P.loc = H.loc
+ H.equip_to_slot_or_del(P, slot_r_store, 0)
+ H.update_icons()
else
nuke_code = "code will be provided later"
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 9b4368d960f..8a78f9b33ae 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -17,10 +17,6 @@ var/bomb_set
use_power = 0
var/previous_level = ""
-/obj/machinery/nuclearbomb/New()
- ..()
- r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn.
-
/obj/machinery/nuclearbomb/process()
if (src.timing)
bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed.
@@ -236,8 +232,8 @@ var/bomb_set
if(blobstart.len > 0)
var/obj/item/weapon/disk/nuclear/NEWDISK = new(pick(blobstart))
transfer_fingerprints_to(NEWDISK)
- message_admins("[src] has been destroyed. Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).")
- log_game("[src] has been destroyed. Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).")
+ message_admins("[src] has been destroyed in ([x], [y] ,[z] - JMP). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - JMP).")
+ log_game("[src] has been destroyed in ([x], [y] ,[z]). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).")
del(src) //Needed to clear all references to it
else
ERROR("[src] was supposed to be destroyed, but we were unable to locate a blobstart landmark to spawn a new one.")
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index c5f11b0ece4..35dff74d813 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -20,10 +20,6 @@
required_enemies = 3
recommended_enemies = 3
-
- uplink_welcome = "Revolutionary Uplink Console:"
- uplink_uses = 10
-
var/finished = 0
var/checkwin_counter = 0
var/const/max_headrevs = 3
diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm
index d2f36a2ee7e..9b3045d62a1 100644
--- a/code/game/gamemodes/sandbox/h_sandbox.dm
+++ b/code/game/gamemodes/sandbox/h_sandbox.dm
@@ -233,7 +233,7 @@ datum/hSB/Topic(href, href_list)
var/list/all_items = typesof(/obj/item/clothing) - /obj/item/clothing
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
- for(var/O in reverselist(all_items))
+ for(var/O in reverseRange(all_items))
clothinfo += "[O]
"
usr << browse(clothinfo,"window=sandbox")
@@ -247,7 +247,7 @@ datum/hSB/Topic(href, href_list)
var/list/all_items = typesof(/obj/item/weapon/reagent_containers) - /obj/item/weapon/reagent_containers
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
- for(var/O in reverselist(all_items))
+ for(var/O in reverseRange(all_items))
reaginfo += "[O]
"
usr << browse(reaginfo,"window=sandbox")
@@ -262,7 +262,7 @@ datum/hSB/Topic(href, href_list)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
- for(var/O in reverselist(all_items))
+ for(var/O in reverseRange(all_items))
objinfo += "[O]
"
usr << browse(objinfo,"window=sandbox")
diff --git a/code/game/gamemodes/sandbox/sandbox.dm b/code/game/gamemodes/sandbox/sandbox.dm
index 475c3d22aa5..8ebb488267a 100644
--- a/code/game/gamemodes/sandbox/sandbox.dm
+++ b/code/game/gamemodes/sandbox/sandbox.dm
@@ -3,9 +3,6 @@
config_tag = "sandbox"
required_players = 0
- uplink_welcome = "Syndicate Uplink Console:"
- uplink_uses = 10
-
/datum/game_mode/sandbox/announce()
world << "The current game mode is - Sandbox!"
world << "Build your own station with the sandbox-panel command!"
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 802b3c57bee..f26ebec359c 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -16,10 +16,6 @@
required_enemies = 1
recommended_enemies = 4
-
- uplink_welcome = "Syndicate Uplink Console:"
- uplink_uses = 10
-
var/traitors_possible = 4 //hard limit on traitors if scaling is turned off
var/scale_modifier = 1 // Used for gamemodes, that are a child of traitor, that need more than the usual.
@@ -37,7 +33,7 @@
var/num_traitors = 1
if(config.traitor_scaling_coeff)
- num_traitors = max(1, round((num_players())/((config.traitor_scaling_coeff * scale_modifier))))
+ num_traitors = max(1, min( round(num_players()/(config.traitor_scaling_coeff*scale_modifier*2))+2, round(num_players()/(config.traitor_scaling_coeff*scale_modifier)) ))
else
num_traitors = max(1, min(num_players(), traitors_possible))
@@ -74,10 +70,10 @@
return 1
/datum/game_mode/traitor/make_antag_chance(var/mob/living/carbon/human/character) //Assigns traitor to latejoiners
- var/traitorcap = round(joined_player_list.len / (config.traitor_scaling_coeff * scale_modifier))
+ var/traitorcap = round(joined_player_list.len / (config.traitor_scaling_coeff * scale_modifier * 2))
if(traitors.len >= traitorcap) //Upper cap for number of latejoin antagonists
return
- if(traitors.len <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * scale_modifier)))
+ if(traitors.len <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * scale_modifier * 2)))
if(character.client.prefs.be_special & BE_TRAITOR)
if(!jobban_isbanned(character.client, "traitor") && !jobban_isbanned(character.client, "Syndicate"))
if(!(character.job in ticker.mode.restricted_jobs))
@@ -121,27 +117,27 @@
objective_count += 1 //Exchange counts towards number of objectives
var/list/active_ais = active_ais()
for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
- if(active_ais.len && prob(1))
- var/datum/objective/destroy/destroy_objective = new
- destroy_objective.owner = traitor
- destroy_objective.find_target()
- traitor.objectives += destroy_objective
- else switch(rand(1,100))
- if(1 to 15)
+ if(prob(50))
+ if(active_ais.len && prob(100/joined_player_list.len))
+ var/datum/objective/destroy/destroy_objective = new
+ destroy_objective.owner = traitor
+ destroy_objective.find_target()
+ traitor.objectives += destroy_objective
+ else if(prob(30))
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = traitor
maroon_objective.find_target()
traitor.objectives += maroon_objective
- if(16 to 50)
+ else
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = traitor
kill_objective.find_target()
traitor.objectives += kill_objective
- else
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = traitor
- steal_objective.find_target()
- traitor.objectives += steal_objective
+ else
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = traitor
+ steal_objective.find_target()
+ traitor.objectives += steal_objective
if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
if (!(locate(/datum/objective/hijack) in traitor.objectives))
@@ -204,18 +200,7 @@
for(var/datum/mind/traitor in traitors)
var/traitorwin = 1
- text += "
[traitor.key] was [traitor.name] ("
- if(traitor.current)
- if(traitor.current.stat == DEAD)
- text += "died"
- else
- text += "survived"
- if(traitor.current.real_name != traitor.name)
- text += " as [traitor.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
-
+ text += printplayer(traitor)
var/TC_uses = 0
var/uplink_true = 0
diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm
index 1cc217b188f..7ac2e709cdb 100644
--- a/code/game/gamemodes/wizard/rightandwrong.dm
+++ b/code/game/gamemodes/wizard/rightandwrong.dm
@@ -1,4 +1,4 @@
-
+//In this file: Summon Magic/Summon Guns/Summon Events
/mob/proc/rightandwrong(var/summon_type) //0 = Summon Guns, 1 = Summon Magic
var/list/gunslist = list("taser","egun","laser","revolver","detective","smg","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","mateba","smg","uzi","crossbow","saw")
@@ -100,6 +100,8 @@
new /obj/item/weapon/gun/magic/wand/teleport(get_turf(H))
if("wanddoor")
new /obj/item/weapon/gun/magic/wand/door(get_turf(H))
+ if("wandfireball")
+ new /obj/item/weapon/gun/magic/wand/fireball(get_turf(H))
if("staffhealing")
new /obj/item/weapon/gun/magic/staff/healing(get_turf(H))
if("staffdoor")
@@ -129,4 +131,26 @@
new /obj/item/weapon/antag_spawner/contract(get_turf(H))
if("staffchaos")
new /obj/item/weapon/gun/magic/staff/chaos(get_turf(H))
- H << "You suddenly feel lucky."
\ No newline at end of file
+ H << "You suddenly feel lucky."
+
+/mob/proc/summonevents()
+ if(events) //if there isn't something is very wrong
+ if(!events.wizardmode) //lets get this party started
+ events.control = list() //out with the old
+ for(var/type in typesof(/datum/round_event_control/wizard) - /datum/round_event_control/wizard) //in with the new
+ var/datum/round_event_control/wizard/W = new type()
+ if(!W.typepath)
+ continue //don't want this one! leave it for the garbage collector
+ events.control += W //add it to the list of all events (controls)
+ events.frequency_lower = 600 //1 minute lower bound
+ events.frequency_upper = 3000 //5 minutes upper bound
+ events.wizardmode = 1
+ events.reschedule()
+
+ else //Speed it up
+ events.frequency_lower = round(events.frequency_lower * 0.8) //1 minute | 48 seconds | 34.8 seconds | 30.7 seconds | 24.6 seconds
+ events.frequency_upper = round(events.frequency_upper * 0.6) //5 minutes | 3 minutes | 1 minute 48 seconds | 1 minute 4.8 seconds | 38.9 seconds
+ if(events.frequency_upper < events.frequency_lower)
+ events.frequency_upper = events.frequency_lower //this can't happen unless somehow multiple spellbooks are used, but just in case
+
+ events.reschedule()
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 7b513e46cdc..7dd699d5789 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -112,6 +112,9 @@
dat += "Summon Magic (One time use, global spell)
"
dat += "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time.
"
+ dat += "Summon Events (One time use, persistent global spell)
"
+ dat += "Give Murphy's law a little push and replace all events with special wizard ones that will confound and confuse everyone. Multiple castings increase the rate of these events.
"
+
dat += "
"
dat += "Return
"
@@ -196,7 +199,7 @@
uses--
/*
*/
- var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", fleshtostone = "Flesh to Stone", summonguns = "Summon Guns", summonmagic = "Summon Magic", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", staffchaos = "Staff of Chaos", staffdoor = "Staff of Door Creation", wands = "Wand Assortment")
+ var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", fleshtostone = "Flesh to Stone", summonguns = "Summon Guns", summonmagic = "Summon Magic", summonevents = "Summon Events", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", staffchaos = "Staff of Chaos", staffdoor = "Staff of Door Creation", wands = "Wand Assortment")
var/already_knows = 0
for(var/obj/effect/proc_holder/spell/aspell in H.mind.spell_list)
if(available_spells[href_list["spell_choice"]] == initial(aspell.name))
@@ -300,6 +303,11 @@
H.rightandwrong(1)
max_uses--
temp = "You have cast summon magic."
+ if("summonevents")
+ feedback_add_details("wizard_spell_learned","SE") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
+ H.summonevents()
+ max_uses--
+ temp = "You have cast summon events."
if("staffchange")
feedback_add_details("wizard_spell_learned","ST") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/gun/magic/staff/change(get_turf(H))
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 516c63e56b5..245a827c3bf 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -10,9 +10,6 @@
recommended_enemies = 1
pre_setup_before_jobs = 1
- uplink_welcome = "Wizardly Uplink Console:"
- uplink_uses = 10
-
var/finished = 0
/datum/game_mode/wizard/announce()
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index a9ee8f00c16..77b0f22bb85 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -79,6 +79,7 @@
//The Syndicate
/var/const/access_syndicate = 150//General Syndicate Access
+/var/const/access_syndicate_leader = 151//Nuke Op Leader Access
/obj/var/list/req_access = null
/obj/var/req_access_txt = "0"
@@ -206,7 +207,7 @@
return list(access_cent_general, access_cent_thunder, access_cent_specops, access_cent_medical, access_cent_living, access_cent_storage, access_cent_teleporter, access_cent_captain)
/proc/get_all_syndicate_access()
- return list(access_syndicate)
+ return list(access_syndicate, access_syndicate)
/proc/get_region_accesses(var/code)
switch(code)
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index e4a9c21bb88..25b63f923bd 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -72,6 +72,9 @@ var/global/datum/controller/occupations/job_master
if(flag && (!player.client.prefs.be_special & flag))
Debug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
+ if(config.enforce_human_authority && (job.title in command_positions) && player.client.prefs.pref_species.id != "human")
+ Debug("FOC non-human failed, Player: [player]")
+ continue
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
Debug("FOC pass, Player: [player], Level:[level]")
candidates += player
@@ -97,6 +100,10 @@ var/global/datum/controller/occupations/job_master
Debug("GRJ player not old enough, Player: [player]")
continue
+ if(config.enforce_human_authority && (job.title in command_positions) && player.client.prefs.pref_species.id != "human")
+ Debug("GRJ non-human failed, Player: [player]")
+ continue
+
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
Debug("GRJ Random job given, Player: [player], Job: [job]")
AssignRole(player, job.title)
@@ -248,6 +255,10 @@ var/global/datum/controller/occupations/job_master
Debug("DO player not old enough, Player: [player], Job:[job.title]")
continue
+ if(config.enforce_human_authority && (job.title in command_positions) && player.client.prefs.pref_species.id != "human")
+ Debug("DO non-human failed, Player: [player], Job:[job.title]")
+ continue
+
// If the player wants that job on this level, then try give it to him.
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 52c8c84e1aa..afa65e0f8ad 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -17,8 +17,8 @@
var/min_health = 25
var/list/injection_chems = list() //list of injectable chems except inaprovaline, coz inaprovaline is always avalible
var/list/possible_chems = list(list("stoxin", "dexalin", "bicaridine", "kelotane"),
- list("stoxin", "dexalinp", "imidazoline", "dermaline", "bicaridine"),
- list("tricordrazine", "anti_toxin", "ryetalyn", "dermaline", "bicaridine", "imidazoline", "alkysine", "arithrazine"))
+ list("stoxin", "dexalinp", "bicaridine", "dermaline", "imidazoline"),
+ list("stoxin", "dexalinp", "bicaridine", "dermaline", "imidazoline", "anti_toxin", "ryetalyn", "alkysine", "arithrazine"))
/obj/machinery/sleeper/New()
..()
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 876b57e9b63..3cb05fe99f1 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -1032,7 +1032,6 @@ FIRE ALARM
qdel(src)
return
- src.alarm()
return
/obj/machinery/firealarm/process()//Note: this processing was mostly phased out due to other code, and only runs when needed
diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm
index f177f2ed1c2..c8bc47d15a1 100644
--- a/code/game/machinery/bots/ed209bot.dm
+++ b/code/game/machinery/bots/ed209bot.dm
@@ -134,7 +134,7 @@ Maintenance panel panel is [src.open ? "opened" : "closed"]
"},
if(!src.locked || issilicon(user))
if(!lasercolor)
dat += text({"
-Arrest for No ID: []
+Arrest Unidentifiable Persons: []
Arrest for Unauthorized Weapons: []
Arrest for Warrant: []
@@ -223,7 +223,7 @@ Auto Patrol: []"},
if(hasvar(W,"force") && W.force)//If force is defined and non-zero
threatlevel = user.assess_threat(src)
threatlevel += 6
- if(threatlevel > 0)
+ if(threatlevel >= 4)
src.target = user
if(lasercolor)//To make up for the fact that lasertag bots don't hunt
src.shootAt(user)
diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm
index e151bfc759b..ae8f5927db7 100644
--- a/code/game/machinery/bots/secbot.dm
+++ b/code/game/machinery/bots/secbot.dm
@@ -127,7 +127,7 @@ Maintenance panel panel is [src.open ? "opened" : "closed"]
"},
if(!src.locked || issilicon(user))
dat += text({"
-Arrest for No ID: []
+Arrest Unidentifiable Persons: []
Arrest for Unauthorized Weapons: []
Arrest for Warrant: []
@@ -142,7 +142,7 @@ Auto Patrol: []"},
"[src.declare_arrests ? "Yes" : "No"]",
"[auto_patrol ? "On" : "Off"]" )
- var/datum/browser/popup = new(user, "autosec", "Securitron v1.5 controls")
+ var/datum/browser/popup = new(user, "autosec", "Securitron v1.5.1 controls")
popup.set_content(dat)
popup.open()
return
@@ -210,7 +210,7 @@ Auto Patrol: []"},
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!src.target) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
threatlevel = user.assess_threat(src)
threatlevel += 6
- if(threatlevel > 0)
+ if(threatlevel >= 4)
src.target = user
src.mode = SECBOT_HUNT
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 927645b7402..37922f4529a 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -161,13 +161,14 @@
src.icon_state = "pod_1"
//Get the clone body ready
- H.adjustCloneLoss(CLONE_INITIAL_DAMAGE ) //Yeah, clones start with very low health, not with random, because why would they start with random health
- H.adjustBrainLoss(CLONE_INITIAL_DAMAGE )
+ H.adjustCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health
+ H.adjustBrainLoss(CLONE_INITIAL_DAMAGE)
H.Paralyse(4)
//Here let's calculate their health so the pod doesn't immediately eject them!!!
H.updatehealth()
+ H.silent = 5 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment.
clonemind.transfer_to(H)
H.ckey = ckey
H << "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?"
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index 993f8e03777..efb6bc939dd 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -51,6 +51,12 @@
if (src.occupier.laws.zeroth)
laws += "0: [src.occupier.laws.zeroth]
"
+ for (var/index = 1, index <= src.occupier.laws.ion.len, index++)
+ var/law = src.occupier.laws.ion[index]
+ if (length(law) > 0)
+ var/num = ionnum()
+ laws += "[num]: [law]
"
+
var/number = 1
for (var/index = 1, index <= src.occupier.laws.inherent.len, index++)
var/law = src.occupier.laws.inherent[index]
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index f390afd4299..6b5ad607a94 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -342,6 +342,8 @@
gameover = 0
/obj/machinery/computer/arcade/orion_trail/attack_hand(mob/user as mob)
+ if(..())
+ return
if(fuel <= 0 || food <=0 || settlers.len == 0)
gameover = 1
event = null
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index fc4c18c537f..5140790e6f8 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -289,7 +289,8 @@
if(istype(P, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = P
if(!WT.remove_fuel(0, user))
- user << "The welding tool must be on to complete this task."
+ if(!WT.isOn())
+ user << "The welding tool must be on to complete this task."
return
playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
user << "You start deconstructing the frame."
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 16ec25f1710..c0f658cb15c 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -332,7 +332,7 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
var/dat = ""
if (emergency_shuttle.online && emergency_shuttle.location==0)
var/timeleft = emergency_shuttle.timeleft()
- dat += "Emergency shuttle\n
\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]
"
+ dat += "Emergency shuttle\n
\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]"
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
@@ -354,10 +354,11 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
if (src.authenticated)
if(emergency_shuttle.recall_count > 1)
if(emergency_shuttle.last_call_loc)
- dat += "
Last emergency shuttle call/recall traced to: [format_text(emergency_shuttle.last_call_loc.name)].
"
+ dat += "
Most recent shuttle call/recall traced to: [format_text(emergency_shuttle.last_call_loc.name)]"
else
- dat += "
Last emergency shuttle call/recall trace failed.
"
- dat += "Logged in as: [auth_id]"
+ dat += "
Unable to trace most recent shuttle call/recall signal."
+ dat += "
Logged in as: [auth_id]"
+ dat += "
"
dat += "
\[ Log Out \]
"
dat += "
General Functions"
dat += "
\[ Message List \]"
@@ -593,11 +594,9 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
var/area/signal_origin = get_area(user)
var/emergency_reason = "\nNature of emergency:\n\n[call_reason]"
if (seclevel2num(get_security_level()) == SEC_LEVEL_RED) // There is a serious threat we gotta move no time to give them five minutes.
- emergency_shuttle.incall(0.6, signal_origin)
- priority_announce("The emergency shuttle has been called. Red Alert state confirmed: Dispatching priority shuttle. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.[emergency_reason]", null, 'sound/AI/shuttlecalled.ogg', "Priority")
+ emergency_shuttle.incall(0.6, signal_origin, emergency_reason, 1)
else
- emergency_shuttle.incall(1, signal_origin)
- priority_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.[emergency_reason]", null, 'sound/AI/shuttlecalled.ogg', "Priority")
+ emergency_shuttle.incall(1, signal_origin, emergency_reason, 0)
log_game("[key_name(user)] has called the shuttle.")
message_admins("[key_name_admin(user)] has called the shuttle.", 1)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 8be739d4b89..b9d29711de0 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -397,7 +397,7 @@
//Get out list of viable PDAs
var/list/obj/item/device/pda/sendPDAs = get_viewable_pdas()
if(PDAs && PDAs.len > 0)
- customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortAtom(sendPDAs)
+ customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortNames(sendPDAs)
else
customrecepient = null
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 4fc05d7ef41..c0ce0bcfc8b 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -26,6 +26,7 @@
dat += text("[inserted_id]
")
dat += text("Collected Points: [inserted_id.points]. Reset.
")
dat += text("Card goal: [inserted_id.goal]. Set
")
+ dat += text("Space Law recommends quotas of 100 points per minute they would normally serve in the brig.
")
else
dat += text("Insert Prisoner ID.
")
dat += "Prisoner Implant Management
"
@@ -105,6 +106,7 @@
if("setgoal")
var/num = round(input(usr, "Choose prisoner's goal:", "Input an Integer", null) as num|null)
if(num >= 0)
+ num = min(num,1000) //Cap the quota to the equivilent of 10 minutes.
inserted_id.goal = num
else if(href_list["inject1"])
var/obj/item/weapon/implant/I = locate(href_list["inject1"])
diff --git a/code/game/machinery/computer/syndicate_shuttle.dm b/code/game/machinery/computer/syndicate_shuttle.dm
index 6757442453e..2c2b34faf52 100644
--- a/code/game/machinery/computer/syndicate_shuttle.dm
+++ b/code/game/machinery/computer/syndicate_shuttle.dm
@@ -1,40 +1,45 @@
#define SYNDICATE_SHUTTLE_MOVE_TIME 240
#define SYNDICATE_SHUTTLE_COOLDOWN 200
+/var/area/synd_shuttle_curr_location
+/var/synd_shuttle_moving = 0
+/var/synd_shuttle_lastMove = 0
+
/obj/machinery/computer/syndicate_station
name = "syndicate shuttle terminal"
icon = 'icons/obj/computer.dmi'
icon_state = "syndishuttle"
req_access = list(access_syndicate)
- var/area/curr_location
- var/moving = 0
- var/lastMove = 0
+ var/recall_only = 0
+/obj/machinery/computer/syndicate_station/recall
+ name = "syndicate shuttle recall terminal"
+ recall_only = 1
/obj/machinery/computer/syndicate_station/New()
- curr_location= locate(/area/syndicate_station/start)
+ synd_shuttle_curr_location= locate(/area/syndicate_station/start)
/obj/machinery/computer/syndicate_station/proc/syndicate_move_to(area/destination as area)
- if(moving) return
- if(lastMove + SYNDICATE_SHUTTLE_COOLDOWN > world.time) return
+ if(synd_shuttle_moving) return
+ if(synd_shuttle_lastMove + SYNDICATE_SHUTTLE_COOLDOWN > world.time) return
var/area/dest_location = locate(destination)
- if(curr_location == dest_location) return
+ if(synd_shuttle_curr_location == dest_location) return
- moving = 1
- lastMove = world.time
+ synd_shuttle_moving = 1
+ synd_shuttle_lastMove = world.time
- if(curr_location.z != dest_location.z)
+ if(synd_shuttle_curr_location.z != dest_location.z)
var/area/transit_location = locate(/area/syndicate_station/transit)
- curr_location.move_contents_to(transit_location)
- curr_location = transit_location
- curr_location.has_gravity = 0
+ synd_shuttle_curr_location.move_contents_to(transit_location)
+ synd_shuttle_curr_location = transit_location
+ synd_shuttle_curr_location.has_gravity = 0
transit_location.has_gravity = 1
sleep(SYNDICATE_SHUTTLE_MOVE_TIME)
- curr_location.move_contents_to(dest_location)
- curr_location = dest_location
- moving = 0
+ synd_shuttle_curr_location.move_contents_to(dest_location)
+ synd_shuttle_curr_location = dest_location
+ synd_shuttle_moving = 0
return 1
/obj/machinery/computer/syndicate_station/attack_hand(mob/user as mob)
@@ -44,17 +49,18 @@
user.set_machine(src)
- var/dat = {"Location: [curr_location]
- Ready to move[max(lastMove + SYNDICATE_SHUTTLE_COOLDOWN - world.time, 0) ? " in [max(round((lastMove + SYNDICATE_SHUTTLE_COOLDOWN - world.time) * 0.1), 0)] seconds" : ": now"]
- Syndicate Space
- North West of SS13 |
- North of SS13 |
- North East of SS13
- South West of SS13 |
- South of SS13 |
- South East of SS13
- North East of the Mining Asteroid
- Close"}
+ var/dat = {"Location: [synd_shuttle_curr_location]
+ Ready to move[max(synd_shuttle_lastMove + SYNDICATE_SHUTTLE_COOLDOWN - world.time, 0) ? " in [max(round((synd_shuttle_lastMove + SYNDICATE_SHUTTLE_COOLDOWN - world.time) * 0.1), 0)] seconds" : ": now"]
+ Syndicate Space
"}
+ if(!recall_only)
+ dat += {"North West of SS13 |
+ North of SS13 |
+ North East of SS13
+ South West of SS13 |
+ South of SS13 |
+ South East of SS13
+ North East of the Mining Asteroid
+ Close"}
user << browse(dat, "window=computer;size=575x450")
onclose(user, "computer")
@@ -71,22 +77,21 @@
if(href_list["syndicate"])
syndicate_move_to(/area/syndicate_station/start)
- else if(href_list["station_nw"])
- syndicate_move_to(/area/syndicate_station/northwest)
- else if(href_list["station_n"])
- syndicate_move_to(/area/syndicate_station/north)
- else if(href_list["station_ne"])
- syndicate_move_to(/area/syndicate_station/northeast)
- else if(href_list["station_sw"])
- syndicate_move_to(/area/syndicate_station/southwest)
- else if(href_list["station_s"])
- syndicate_move_to(/area/syndicate_station/south)
- else if(href_list["station_se"])
- syndicate_move_to(/area/syndicate_station/southeast)
-// else if(href_list["commssat"])
-// syndicate_move_to(/area/syndicate_station/commssat)
- else if(href_list["mining"])
- syndicate_move_to(/area/syndicate_station/mining)
+ else if(!recall_only)
+ if(href_list["station_nw"])
+ syndicate_move_to(/area/syndicate_station/northwest)
+ else if(href_list["station_n"])
+ syndicate_move_to(/area/syndicate_station/north)
+ else if(href_list["station_ne"])
+ syndicate_move_to(/area/syndicate_station/northeast)
+ else if(href_list["station_sw"])
+ syndicate_move_to(/area/syndicate_station/southwest)
+ else if(href_list["station_s"])
+ syndicate_move_to(/area/syndicate_station/south)
+ else if(href_list["station_se"])
+ syndicate_move_to(/area/syndicate_station/southeast)
+ else if(href_list["mining"])
+ syndicate_move_to(/area/syndicate_station/mining)
updateUsrDialog()
return
\ No newline at end of file
diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm
index 9ecedc5142e..a620d80585c 100644
--- a/code/game/machinery/door_control.dm
+++ b/code/game/machinery/door_control.dm
@@ -87,7 +87,7 @@
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = !D.aiDisabledIdScanner
if(specialfunctions & BOLTS)
- if(!D.isWireCut(4) && D.arePowerSystemsOn())
+ if(!D.isWireCut(4) && D.hasPower())
D.locked = !D.locked
D.update_icon()
if(specialfunctions & SHOCK)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index efa7140e7fb..ed5e9f3f878 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -5,7 +5,7 @@
mend - mends a wire and makes any necessary state changes
canAIControl - 1 if the AI can control the airlock, 0 if not (then check canAIHack to see if it can hack in)
canAIHack - 1 if the AI can hack into the airlock to recover control, 0 if not. Also returns 0 if the AI does not *need* to hack it.
- arePowerSystemsOn - 1 if the main or backup power are functioning, 0 if not. Does not check whether the power grid is charged or an APC has equipment on or anything like that. (Check (stat & NOPOWER) for that)
+ hasPower - 1 if the main or backup power are functioning, 0 if not.
requiresIDs - 1 if the airlock is requiring IDs, 0 if not
isAllPowerCut - 1 if the main and backup power both have cut wires.
regainMainPower - handles the effect of main power coming back on.
@@ -344,8 +344,8 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/proc/canAIHack()
return ((src.aiControlDisabled==1) && (!hackProof) && (!src.isAllPowerCut()));
-/obj/machinery/door/airlock/proc/arePowerSystemsOn()
- return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0)
+/obj/machinery/door/airlock/hasPower()
+ return ((src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) && !(stat & NOPOWER))
/obj/machinery/door/airlock/requiresID()
return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner)
@@ -399,7 +399,7 @@ About the new airlock wires panel:
// returns 1 if shocked, 0 otherwise
// The preceding comment was borrowed from the grille's shock script
/obj/machinery/door/airlock/proc/shock(mob/user, prb)
- if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock
+ if(!hasPower()) // unpowered, no shock
return 0
if(hasShocked)
return 0 //Already shocked someone recently?
@@ -523,7 +523,7 @@ About the new airlock wires panel:
t1 += text("Door bolts are up. Drop them?
\n", src)
else
t1 += text("Door bolts are down.")
- if(src.arePowerSystemsOn())
+ if(src.hasPower())
t1 += text(" Raise?
\n", src)
else
t1 += text(" Cannot raise door bolts due to power failure.
\n")
@@ -785,7 +785,7 @@ About the new airlock wires panel:
else if(!src.locked)
usr << text("The door bolts are already up.
\n")
else
- if(src.arePowerSystemsOn())
+ if(src.hasPower())
src.locked = 0
update_icon()
else
@@ -889,17 +889,15 @@ About the new airlock wires panel:
if((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density))
var/obj/item/weapon/weldingtool/W = C
user << "You begin [welded ? "unwelding":"welding"] the airlock..."
- playsound(loc, 'sound/items/Welder2.ogg', 40, 1)
+ playsound(loc, 'sound/items/Welder.ogg', 40, 1)
if(do_after(user,40,5,1))
if(density && !operating)//Door must be closed to weld.
if(W.remove_fuel(0,user))
- playsound(loc, 'sound/items/welder.ogg', 50, 1)
+ playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
welded = !welded
user << "You [welded ? "welded the airlock shut":"unwelded the airlock"]"
update_icon()
user.visible_message("[src] has been [welded? "welded shut":"unwelded"] by [user.name].")
- else
- user << "You need more welding fuel to complete this task."
return
else if(istype(C, /obj/item/weapon/screwdriver))
src.p_open = !( src.p_open )
@@ -920,7 +918,7 @@ About the new airlock wires panel:
beingcrowbarred = 1 //derp, Agouri
else
beingcrowbarred = 0
- if( beingcrowbarred && (density && welded && !operating && src.p_open && (!src.arePowerSystemsOn() || stat & NOPOWER) && !src.locked) )
+ if( beingcrowbarred && (density && welded && !operating && src.p_open && (!hasPower()) && !src.locked) )
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.")
if(do_after(user,40))
@@ -984,7 +982,7 @@ About the new airlock wires panel:
qdel(src)
return
- else if(arePowerSystemsOn() && !(stat & NOPOWER))
+ else if(hasPower())
user << " The airlock's motors resist your efforts to force it."
else if(locked)
user << " The airlock's bolts prevent it from being forced."
@@ -1025,7 +1023,7 @@ About the new airlock wires panel:
if( operating || welded || locked )
return 0
if(!forced)
- if( !arePowerSystemsOn() || (stat & NOPOWER) || isWireCut(AIRLOCK_WIRE_OPEN_DOOR) )
+ if( !hasPower() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR) )
return 0
if(forced < 2)
if(emagged)
@@ -1056,7 +1054,7 @@ About the new airlock wires panel:
if(operating || welded || locked)
return
if(!forced)
- if( !arePowerSystemsOn() || (stat & NOPOWER) || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS) )
+ if( !hasPower() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS) )
return
if(safe)
if(locate(/mob/living) in get_turf(src))
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index ac6e9ab2720..8b03d1696c5 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -88,14 +88,17 @@
return !density || check_access(ID)
/obj/machinery/door/proc/bumpopen(mob/user as mob)
- if(operating) return
+ if(operating)
+ return
src.add_fingerprint(user)
if(!src.requiresID())
user = null
if(density && !emagged)
- if(allowed(user) || src.emergency == 1) open()
- else flick("door_deny", src)
+ if(allowed(user) || src.emergency == 1)
+ open()
+ else
+ flick("door_deny", src)
return
@@ -126,7 +129,7 @@
user = null
if(!src.requiresID())
user = null
- if(src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)))
+ if(src.density && hasPower() && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)))
flick("door_spark", src)
sleep(6)
open()
@@ -269,6 +272,9 @@
/obj/machinery/door/proc/requiresID()
return 1
+/obj/machinery/door/proc/hasPower()
+ return !(stat & NOPOWER)
+
/obj/machinery/door/BlockSuperconductivity()
if(opacity || heat_proof)
return 1
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 8d41384915c..ab94b08d5e7 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -254,8 +254,6 @@ Buildable meters
return 1
// no conflicts found
- var/pipefailtext = "There's nothing to connect this pipe section to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
-
switch(pipe_type)
if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT)
var/obj/machinery/atmospherics/pipe/simple/P = new( src.loc )
@@ -264,16 +262,13 @@ Buildable meters
var/turf/T = P.loc
P.level = T.intact ? 2 : 1
P.initialize()
- if (!P)
- usr << pipefailtext
- return 1
- P.build_network()
if (P.node1)
P.node1.initialize()
- P.node1.build_network()
+ P.node1.addMember(P)
if (P.node2)
P.node2.initialize()
- P.node2.build_network()
+ P.node2.addMember(P)
+ P.build_network()
if(PIPE_HE_STRAIGHT, PIPE_HE_BENT)
var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/P = new ( src.loc )
@@ -283,16 +278,13 @@ Buildable meters
//var/turf/T = P.loc
//P.level = T.intact ? 2 : 1
P.initialize()
- if (!P)
- usr << pipefailtext
- return 1
- P.build_network()
if (P.node1)
P.node1.initialize()
- P.node1.build_network()
+ P.node1.addMember(P)
if (P.node2)
P.node2.initialize()
- P.node2.build_network()
+ P.node2.addMember(P)
+ P.build_network()
if(PIPE_CONNECTOR) // connector
var/obj/machinery/atmospherics/portables_connector/C = new( src.loc )
@@ -310,26 +302,22 @@ Buildable meters
if(PIPE_MANIFOLD) //manifold
- var/obj/machinery/atmospherics/pipe/manifold/M = new( src.loc )
+ var/obj/machinery/atmospherics/pipe/manifold/M = new(loc)
M.dir = dir
M.initialize_directions = pipe_dir
- //M.New()
var/turf/T = M.loc
M.level = T.intact ? 2 : 1
M.initialize()
- if (!M)
- usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
- return 1
- M.build_network()
if (M.node1)
M.node1.initialize()
- M.node1.build_network()
+ M.node1.addMember(M)
if (M.node2)
M.node2.initialize()
- M.node2.build_network()
+ M.node2.addMember(M)
if (M.node3)
M.node3.initialize()
- M.node3.build_network()
+ M.node3.addMember(M)
+ M.build_network()
if(PIPE_JUNCTION)
var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/P = new ( src.loc )
@@ -339,16 +327,13 @@ Buildable meters
//var/turf/T = P.loc
//P.level = T.intact ? 2 : 1
P.initialize()
- if (!P)
- usr << "There's nothing to connect this junction to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
- return 1
- P.build_network()
if (P.node1)
P.node1.initialize()
- P.node1.build_network()
+ P.node1.addMember(P)
if (P.node2)
P.node2.initialize()
- P.node2.build_network()
+ P.node2.addMember(P)
+ P.build_network()
if(PIPE_UVENT) //unary vent
var/obj/machinery/atmospherics/unary/vent_pump/V = new( src.loc )
@@ -479,16 +464,13 @@ Buildable meters
var/turf/T = P.loc
P.level = T.intact ? 2 : 1
P.initialize()
- if (!P)
- usr << pipefailtext
- return 1
- P.build_network()
if (P.node1)
P.node1.initialize()
- P.node1.build_network()
+ P.node1.addMember(P)
if (P.node2)
P.node2.initialize()
- P.node2.build_network()
+ P.node2.addMember(P)
+ P.build_network()
if(PIPE_PASSIVE_GATE) //passive gate
var/obj/machinery/atmospherics/binary/passive_gate/P = new(src.loc)
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 905990105ca..a1aeefc9618 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -11,7 +11,7 @@
/obj/machinery/pipedispenser/attack_hand(user as mob)
if(..())
- return
+ return 1
var/dat = {"
Regular pipes:
Pipe
@@ -46,10 +46,10 @@
/obj/machinery/pipedispenser/Topic(href, href_list)
if(..())
- return
+ return 1
if(!anchored|| !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=pipedispenser")
- return
+ return 1
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["make"])
@@ -149,6 +149,7 @@ Nah
Bin
Outlet
Chute
+Sort Junction
"}
user << browse("[src][dat]", "window=pipedispenser")
@@ -163,9 +164,6 @@ Nah
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["dmake"])
- if(!anchored || !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
- usr << browse(null, "window=pipedispenser")
- return
if(!wait)
var/p_type = text2num(href_list["dmake"])
var/obj/structure/disposalconstruct/C = new (src.loc)
@@ -189,6 +187,8 @@ Nah
if(7)
C.ptype = 8
C.density = 1
+ if(8)
+ C.ptype = 9
C.add_fingerprint(usr)
C.update()
wait = 1
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index d6a97d6723d..cf3453400d8 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -374,10 +374,9 @@
src.add_fingerprint(user)
/obj/machinery/shieldwallgen/process()
- spawn(100)
- power()
- if(power)
- storedpower -= 50 //this way it can survive longer and survive at all
+ power()
+ if(power)
+ storedpower -= 50 //this way it can survive longer and survive at all
if(storedpower >= maxstoredpower)
storedpower = maxstoredpower
if(storedpower <= 0)
@@ -389,14 +388,10 @@
if(!anchored)
src.active = 0
return
- spawn(1)
- setup_field(1)
- spawn(2)
- setup_field(2)
- spawn(3)
- setup_field(4)
- spawn(4)
- setup_field(8)
+ setup_field(1)
+ setup_field(2)
+ setup_field(4)
+ setup_field(8)
src.active = 2
if(src.active >= 1)
if(src.power == 0)
@@ -404,14 +399,10 @@
"You hear heavy droning fade out")
icon_state = "Shield_Gen"
src.active = 0
- spawn(1)
- src.cleanup(1)
- spawn(1)
- src.cleanup(2)
- spawn(1)
- src.cleanup(4)
- spawn(1)
- src.cleanup(8)
+ src.cleanup(1)
+ src.cleanup(2)
+ src.cleanup(4)
+ src.cleanup(8)
/obj/machinery/shieldwallgen/proc/setup_field(var/NSEW = 0)
var/turf/T = src.loc
diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm
index a34d7cec517..a075cf88976 100644
--- a/code/game/machinery/turrets.dm
+++ b/code/game/machinery/turrets.dm
@@ -308,106 +308,6 @@
spawn(13)
qdel(src)
-/obj/machinery/turretid
- name = "turret deactivation control"
- icon = 'icons/obj/device.dmi'
- icon_state = "motion3"
- anchored = 1
- density = 0
- var/enabled = 1
- var/lethal = 0
- var/locked = 1
- var/control_area //can be area name, path or nothing.
- var/ailock = 0 // AI cannot use this
- req_access = list(access_ai_upload)
-
-/obj/machinery/turretid/New()
- ..()
- if(!control_area)
- var/area/CA = get_area(src)
- if(CA.master && CA.master != CA)
- control_area = CA.master
- else
- control_area = CA
- else if(istext(control_area))
- for(var/area/A in world)
- if(A.name && A.name==control_area)
- control_area = A
- break
- //don't have to check if control_area is path, since get_area_all_atoms can take path.
- return
-
-/obj/machinery/turretid/attackby(obj/item/weapon/W, mob/user)
- if(stat & BROKEN) return
- if (istype(user, /mob/living/silicon))
- return src.attack_hand(user)
-
- if (istype(W, /obj/item/weapon/card/emag) && !emagged)
- user << "You short out the turret controls' access analysis module."
- emagged = 1
- locked = 0
- if(user.machine==src)
- src.attack_hand(user)
-
- return
-
- else if( get_dist(src, user) == 0 ) // trying to unlock the interface
- if (src.allowed(usr))
- if(emagged)
- user << "The turret control is unresponsive."
- return
-
- locked = !locked
- user << "You [ locked ? "lock" : "unlock"] the panel."
- if (locked)
- if (user.machine==src)
- user.unset_machine()
- user << browse(null, "window=turretid")
- else
- if (user.machine==src)
- src.attack_hand(user)
- else
- user << "Access denied."
-
-/obj/machinery/turretid/attack_ai(mob/user as mob)
- if(!ailock)
- return attack_hand(user)
- else
- user << "There seems to be a firewall preventing you from accessing this device."
-
-/obj/machinery/turretid/attack_hand(mob/user as mob)
- if ( get_dist(src, user) > 0 )
- if ( !issilicon(user) )
- user << "You are too far away."
- user.unset_machine()
- user << browse(null, "window=turretid")
- return
-
- user.set_machine(src)
- var/loc = src.loc
- if (istype(loc, /turf))
- loc = loc:loc
- if (!istype(loc, /area))
- user << text("Turret badly positioned - loc.loc is [].", loc)
- return
- var/area/area = loc
- var/t = ""
-
- if(src.locked && (!istype(user, /mob/living/silicon)))
- t += "Swipe ID card to unlock interface
"
- else
- if (!istype(user, /mob/living/silicon))
- t += "Swipe ID card to lock interface
"
- t += text("Turrets [] - []?
\n", src.enabled?"activated":"deactivated", src, src.enabled?"Disable":"Enable")
- t += text("Currently set for [] - Change to []?
\n", src.lethal?"lethal":"stun repeatedly", src, src.lethal?"Stun repeatedly":"Lethal")
-
- //user << browse(t, "window=turretid")
- //onclose(user, "turretid")
- var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([area.name])")
- popup.set_content(t)
- popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
- popup.open()
-
/obj/machinery/turret/attack_animal(mob/living/simple_animal/M as mob)
M.changeNext_move(CLICK_CD_MELEE)
@@ -439,45 +339,9 @@
return
-
-/obj/machinery/turretid/Topic(href, href_list)
- if(..())
- return
- if (src.locked)
- if (!istype(usr, /mob/living/silicon))
- usr << "Control panel is locked!"
- return
- if (href_list["toggleOn"])
- src.enabled = !src.enabled
- src.updateTurrets()
- else if (href_list["toggleLethal"])
- src.lethal = !src.lethal
- src.updateTurrets()
- src.attack_hand(usr)
-
-/obj/machinery/turretid/proc/updateTurrets()
- if(control_area)
- for (var/obj/machinery/turret/aTurret in get_area_all_atoms(control_area))
- aTurret.setState(enabled, lethal)
- src.update_icons()
-
-/obj/machinery/turretid/proc/update_icons()
- if (src.enabled)
- if (src.lethal)
- icon_state = "motion1"
- else
- icon_state = "motion3"
- else
- icon_state = "motion0"
- //CODE FIXED BUT REMOVED
-// if(control_area) //USE: updates other controls in the area
-// for (var/obj/machinery/turretid/Turret_Control in world) //I'm not sure if this is what it was
-// if( Turret_Control.control_area != src.control_area ) continue //supposed to do. Or whether the person
-// Turret_Control.icon_state = icon_state //who coded it originally was just tired
-// Turret_Control.enabled = enabled //or something. I don't see any situation
-// Turret_Control.lethal = lethal //in which this would be used on the current map.
- //If he wants it back he can uncomment it
-
+//////////////
+//Gun Turret//
+//////////////
/obj/machinery/gun_turret //related to turrets but work way differentely because of being mounted on a moving ship.
name = "machine gun turret"
@@ -621,3 +485,147 @@
spawn(0)
A.process()
return
+
+
+////////////////////////
+//Turret Control Panel//
+////////////////////////
+
+/obj/machinery/turretid
+ name = "turret control panel"
+ desc = "Used to control a room's automated defenses."
+ icon = 'icons/obj/machines/turret_control.dmi'
+ icon_state = "control_standby"
+ anchored = 1
+ density = 0
+ var/enabled = 1
+ var/lethal = 0
+ var/locked = 1
+ var/control_area //can be area name, path or nothing.
+ var/ailock = 0 // AI cannot use this
+ req_access = list(access_ai_upload)
+
+/obj/machinery/turretid/New()
+ ..()
+ if(!control_area)
+ var/area/CA = get_area(src)
+ if(CA.master && CA.master != CA)
+ control_area = CA.master
+ else
+ control_area = CA
+ else if(istext(control_area))
+ for(var/area/A in world)
+ if(A.name && A.name==control_area)
+ control_area = A
+ break
+ power_change() //Checks power and initial settings
+ //don't have to check if control_area is path, since get_area_all_atoms can take path.
+ return
+
+/obj/machinery/turretid/attackby(obj/item/weapon/W, mob/user)
+ if(stat & BROKEN) return
+ if (istype(user, /mob/living/silicon))
+ return src.attack_hand(user)
+
+ if (istype(W, /obj/item/weapon/card/emag) && !emagged)
+ user << "You short out the turret controls' access analysis module."
+ emagged = 1
+ locked = 0
+ if(user.machine==src)
+ src.attack_hand(user)
+
+ return
+
+ else if( get_dist(src, user) == 0 ) // trying to unlock the interface
+ if (src.allowed(usr))
+ if(emagged)
+ user << "The turret control is unresponsive."
+ return
+
+ locked = !locked
+ user << "You [ locked ? "lock" : "unlock"] the panel."
+ if (locked)
+ if (user.machine==src)
+ user.unset_machine()
+ user << browse(null, "window=turretid")
+ else
+ if (user.machine==src)
+ src.attack_hand(user)
+ else
+ user << "Access denied."
+
+/obj/machinery/turretid/attack_ai(mob/user as mob)
+ if(!ailock)
+ return attack_hand(user)
+ else
+ user << "There seems to be a firewall preventing you from accessing this device."
+
+/obj/machinery/turretid/attack_hand(mob/user as mob)
+ if ( get_dist(src, user) > 0 )
+ if ( !issilicon(user) )
+ user << "You are too far away."
+ user.unset_machine()
+ user << browse(null, "window=turretid")
+ return
+
+ user.set_machine(src)
+ var/loc = src.loc
+ if (istype(loc, /turf))
+ loc = loc:loc
+ if (!istype(loc, /area))
+ user << text("Turret badly positioned - loc.loc is [].", loc)
+ return
+ var/area/area = loc
+ var/t = ""
+
+ if(src.locked && (!istype(user, /mob/living/silicon)))
+ t += "Swipe ID card to unlock interface
"
+ else
+ if (!istype(user, /mob/living/silicon))
+ t += "Swipe ID card to lock interface
"
+ t += text("Turrets [] - []?
\n", src.enabled?"activated":"deactivated", src, src.enabled?"Disable":"Enable")
+ t += text("Currently set for [] - Change to []?
\n", src.lethal?"lethal":"stun repeatedly", src, src.lethal?"Stun repeatedly":"Lethal")
+
+ //user << browse(t, "window=turretid")
+ //onclose(user, "turretid")
+ var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([area.name])")
+ popup.set_content(t)
+ popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
+ popup.open()
+
+/obj/machinery/turretid/Topic(href, href_list)
+ if(..())
+ return
+ if (src.locked)
+ if (!istype(usr, /mob/living/silicon))
+ usr << "Control panel is locked!"
+ return
+ if (href_list["toggleOn"])
+ src.enabled = !src.enabled
+ src.updateTurrets()
+ else if (href_list["toggleLethal"])
+ src.lethal = !src.lethal
+ src.updateTurrets()
+ src.attack_hand(usr)
+
+/obj/machinery/turretid/proc/updateTurrets()
+ if(control_area)
+ for (var/obj/machinery/turret/aTurret in get_area_all_atoms(control_area))
+ aTurret.setState(enabled, lethal)
+ src.update_icon()
+
+/obj/machinery/turretid/power_change()
+ ..()
+ update_icon()
+
+/obj/machinery/turretid/update_icon()
+ ..()
+ if(stat & NOPOWER)
+ icon_state = "control_off"
+ else if (enabled)
+ if (lethal)
+ icon_state = "control_kill"
+ else
+ icon_state = "control_stun"
+ else
+ icon_state = "control_standby"
\ No newline at end of file
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index 54b79470b12..70051b606d6 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -132,8 +132,8 @@
return 0
/obj/item/mecha_parts/mecha_equipment/tool/drill/proc/drill_mob(mob/living/target, mob/user, var/drill_damage=80)
- target.visible_message("[chassis] drills [target] with the [src].\
- [chassis] drills [target] with the [src].")
+ target.visible_message("[chassis] drills [target] with [src].", \
+ "[chassis] drills [target] with [src].")
add_logs(user, target, "attacked", object="[name]", addition="(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
if(ishuman(target))
var/mob/living/carbon/human/H = target
diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm
index 2f27fbfa34e..6d929530ee6 100644
--- a/code/game/mecha/mecha_wreckage.dm
+++ b/code/game/mecha/mecha_wreckage.dm
@@ -32,7 +32,6 @@
else
user << "You failed to salvage anything valuable from [src]."
else
- user << "You need more welding fuel to complete this task."
return
if(istype(I, /obj/item/weapon/wirecutters))
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index 3a12acdd6ca..ab27ad7dd58 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -16,23 +16,24 @@
*/
/obj/structure/alien/resin
name = "resin"
- desc = "Looks like some kind of slimy growth."
+ desc = "Looks like some kind of thick resin."
icon_state = "resin"
density = 1
opacity = 1
anchored = 1
var/health = 200
-
+ var/resintype = null
/obj/structure/alien/resin/New(location)
+ relativewall_neighbours()
..()
air_update_turf(1)
return
/obj/structure/alien/resin/Destroy()
- density = 0
- air_update_turf(1)
+ var/turf/T = loc
+ loc = null
+ T.relativewall_neighbours()
..()
- return
/obj/structure/alien/resin/Move()
var/turf/T = loc
@@ -44,19 +45,28 @@
/obj/structure/alien/resin/wall
name = "resin wall"
- desc = "Purple slime solidified into a wall."
+ desc = "Thick resin solidified into a wall."
icon_state = "resinwall" //same as resin, but consistency ho!
+ resintype = "wall"
+
+/obj/structure/alien/resin/wall/New()
+ relativewall_neighbours()
+ ..()
/obj/structure/alien/resin/wall/BlockSuperconductivity()
return 1
/obj/structure/alien/resin/membrane
name = "resin membrane"
- desc = "Purple slime just thin enough to let light pass through."
+ desc = "Resin just thin enough to let light pass through."
icon_state = "resinmembrane"
opacity = 0
health = 120
+ resintype = "membrane"
+/obj/structure/alien/resin/membrane/New()
+ relativewall_neighbours()
+ ..()
/obj/structure/alien/resin/proc/healthcheck()
if(health <=0)
@@ -145,11 +155,12 @@
/obj/structure/alien/weeds
gender = PLURAL
- name = "weeds"
- desc = "Weird purple weeds."
+ name = "resin floor"
+ desc = "A thick resin surface covers the floor."
icon_state = "weeds"
anchored = 1
density = 0
+ layer = 2
var/health = 15
var/obj/structure/alien/weeds/node/linked_node = null
@@ -162,11 +173,17 @@
return
if(icon_state == "weeds")
icon_state = pick("weeds", "weeds1", "weeds2")
-
+ fullUpdateWeedOverlays()
spawn(rand(150, 200))
if(src)
Life()
+/obj/structure/alien/weeds/Destroy()
+ var/turf/T = loc
+ loc = null
+ for (var/obj/structure/alien/weeds/W in range(1,T))
+ W.updateWeedOverlays()
+ ..()
/obj/structure/alien/weeds/proc/Life()
set background = BACKGROUND_ENABLED
@@ -226,12 +243,37 @@
healthcheck()
+/obj/structure/alien/weeds/proc/updateWeedOverlays()
+
+ overlays.Cut()
+ var/turf/N = get_step(src, NORTH)
+ var/turf/S = get_step(src, SOUTH)
+ var/turf/E = get_step(src, EAST)
+ var/turf/W = get_step(src, WEST)
+ if(!locate(/obj/structure/alien) in N.contents)
+ if(istype(N, /turf/simulated/floor))
+ src.overlays += image('icons/mob/alien.dmi', "weeds_side_s", layer=2.6, pixel_y = 32)
+ if(!locate(/obj/structure/alien) in S.contents)
+ if(istype(S, /turf/simulated/floor))
+ src.overlays += image('icons/mob/alien.dmi', "weeds_side_n", layer=2.6, pixel_y = -32)
+ if(!locate(/obj/structure/alien) in E.contents)
+ if(istype(E, /turf/simulated/floor))
+ src.overlays += image('icons/mob/alien.dmi', "weeds_side_w", layer=2.6, pixel_x = 32)
+ if(!locate(/obj/structure/alien) in W.contents)
+ if(istype(W, /turf/simulated/floor))
+ src.overlays += image('icons/mob/alien.dmi', "weeds_side_e", layer=2.6, pixel_x = -32)
+
+
+/obj/structure/alien/weeds/proc/fullUpdateWeedOverlays()
+ for (var/obj/structure/alien/weeds/W in range(1,src))
+ W.updateWeedOverlays()
+
//Weed nodes
/obj/structure/alien/weeds/node
- name = "purple sac"
- desc = "Weird purple octopus-like thing."
+ name = "glowing resin"
+ desc = "Blue bioluminescence shines from beneath the surface."
icon_state = "weednode"
- luminosity = NODERANGE
+ luminosity = 1
var/node_range = NODERANGE
@@ -291,6 +333,7 @@
/obj/structure/alien/egg/attack_hand(mob/user)
user << "It feels slimy."
+ user.changeNext_move(CLICK_CD_MELEE)
/obj/structure/alien/egg/proc/GetFacehugger()
@@ -342,6 +385,7 @@
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
health -= damage
+ user.changeNext_move(CLICK_CD_MELEE)
healthcheck()
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index 7aaffa5dea4..a3b1520af36 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -96,7 +96,7 @@
/obj/item/weapon/crowbar = 1,
/obj/item/weapon/crowbar/red = 1,
/obj/item/weapon/extinguisher = 11,
- /obj/item/weapon/gun/projectile/revolver/russian = 1,
+ //obj/item/weapon/gun/projectile/revolver/russian = 1, //disabled until lootdrop is a proper world proc.
/obj/item/weapon/hand_labeler = 1,
/obj/item/weapon/paper/crumpled = 1,
/obj/item/weapon/pen = 1,
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 752d894dfb4..3f239f3d591 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -37,6 +37,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
var/cart = "" //A place to stick cartridge menu information
var/detonate = 1 // Can the PDA be blown up?
var/hidden = 0 // Is the PDA hidden from the PDA list?
+ var/emped = 0
var/obj/item/weapon/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both.
var/ownjob = null //related to above
@@ -370,7 +371,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
var/count = 0
if (!toff)
- for (var/obj/item/device/pda/P in sortAtom(get_viewable_pdas()))
+ for (var/obj/item/device/pda/P in sortNames(get_viewable_pdas()))
if (P == src) continue
dat += "[P]"
if (istype(cartridge, /obj/item/weapon/cartridge/syndicate) && P.detonate)
@@ -730,6 +731,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
var/datum/signal/signal = src.telecomms_process()
+ if(emped)
+ t = Gibberish(t, 100)
+
var/useTC = 0
if(signal)
if(signal.data["done"])
@@ -1071,6 +1075,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/emp_act(severity)
for(var/atom/A in src)
A.emp_act(severity)
+ emped += 1
+ spawn(200 * severity)
+ emped -= 1
/proc/get_viewable_pdas()
. = list()
diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm
index 24edb356243..da1bcf84de8 100644
--- a/code/game/objects/items/devices/camera_bug.dm
+++ b/code/game/objects/items/devices/camera_bug.dm
@@ -103,7 +103,7 @@
if(NETWORK_BUG,ADMIN_BUG)
if(length(list("SS13","MINE")&camera.network))
bugged_cameras[camera.c_tag] = camera
- bugged_cameras = sortAssoc(bugged_cameras)
+ sortList(bugged_cameras)
return bugged_cameras
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 9ab97b5cb93..8c31edae6cb 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -245,7 +245,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
//#### Tagging the signal with all appropriate identity values ####//
// ||-- The mob's name identity --||
- var/displayname = M.name // grab the display name (name you get when you hover over someone's icon)
var/real_name = M.name // mob's real name
var/mobkey = "none" // player key associated with mob
var/voicemask = 0 // the speaker is wearing a voice mask
@@ -265,7 +264,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
var/datum/data/record/findjob = find_record("name", voice, data_core.general)
if(voice != real_name)
- displayname = voice
voicemask = 1
if(findjob)
jobname = findjob.fields["rank"]
@@ -310,7 +308,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
"mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
"realname" = real_name, // the mob's real name
- "name" = voice, // the mob's display name
+ "name" = voice, // the mob's voice name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmask" = voicemask, // 1 if the mob is using a voice gas mask
@@ -356,17 +354,17 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
/* --- Try to send a normal subspace broadcast first */
signal.data = list(
- "mob" = M, // store a reference to the mob
+ "mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
"realname" = real_name, // the mob's real name
- "name" = displayname, // the mob's display name
+ "name" = voice, // the mob's voice name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmask" = voicemask, // 1 if the mob is using a voice gas mas
- "compression" = 0, // uncompressed radio signal
- "message" = message, // the actual sent message
- "radio" = src, // stores the radio used for transmission
+ "compression" = 0, // uncompressed radio signal
+ "message" = message, // the actual sent message
+ "radio" = src, // stores the radio used for transmission
"slow" = 0,
"traffic" = 0,
"type" = 0,
@@ -388,7 +386,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
// Oh my god; the comms are down or something because the signal hasn't been broadcasted yet in our level.
// Send a mundane broadcast with limited targets:
Broadcast_Message(M, voicemask,
- src, message, displayname, jobname, real_name,
+ src, message, voice, jobname, real_name,
filter_type, signal.data["compression"], list(position.z), freq)
/obj/item/device/radio/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq)
diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm
index 770a1159de5..44913a00a4f 100644
--- a/code/game/objects/items/devices/uplinks.dm
+++ b/code/game/objects/items/devices/uplinks.dm
@@ -9,8 +9,8 @@ A list of items and costs is stored under the datum of every game mode, alongsid
var/list/world_uplinks = list()
/obj/item/device/uplink
- var/welcome // Welcoming menu message
- var/uses // Numbers of crystals
+ var/welcome = "Syndicate Uplink Console:" // Welcoming menu message
+ var/uses = 10 // Numbers of crystals
// List of items not to shove in their hands.
var/purchase_log = ""
var/show_description = null
@@ -22,8 +22,6 @@ var/list/world_uplinks = list()
/obj/item/device/uplink/New()
..()
world_uplinks+=src
- welcome = ticker.mode.uplink_welcome
- uses = ticker.mode.uplink_uses
/obj/item/device/uplink/Destroy()
world_uplinks-=src
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 98040a52653..26ad543c980 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -253,6 +253,8 @@
else
user << "The MMI must go in after everything else!"
+ if(istype(W,/obj/item/weapon/pen))
+ user << "You need to use a multitool to name [src]."
return
/obj/item/robot_parts/robot_suit/proc/Interact(mob/user)
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index fabece80e32..57d716488b1 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -323,7 +323,7 @@
if(G.amount >= G.max_amount)
continue
G.attackby(NG, user)
- user << "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s."
+ user << "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s."
qdel(src)
..()
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index 23243aef5cd..a848cb4dc3f 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -269,6 +269,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM
src.pixel_x = rand(-5.0, 5)
src.pixel_y = rand(-5.0, 5)
+/obj/item/clothing/mask/cigarette/rollie/trippy/New()
+ ..()
+ reagents.add_reagent("mushroomhallucinogen", 50)
+ light()
+ //for(var/mob/M in player_list) M << 'sound/misc/Smoke_Weed_Everyday.ogg'
+
/obj/item/weapon/cigbutt/roach
name = "roach"
diff --git a/code/game/objects/items/weapons/storage/book.dm b/code/game/objects/items/weapons/storage/book.dm
index 3becca92514..b5b488c90e0 100644
--- a/code/game/objects/items/weapons/storage/book.dm
+++ b/code/game/objects/items/weapons/storage/book.dm
@@ -127,7 +127,7 @@
user << " You purify [A]."
var/unholy2clean = A.reagents.get_reagent_amount("unholywater")
A.reagents.del_reagent("unholywater")
- A.reagents.add_reagent("cleaner",unholy2clean) //it cleans their soul, get it? I'll get my coat...
+ A.reagents.add_reagent("holywater",unholy2clean)
/obj/item/weapon/storage/book/bible/attackby(obj/item/weapon/W as obj, mob/user as mob)
playsound(src.loc, "rustle", 50, 1, -5)
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index f497312f5d7..0ff49f7cb63 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -176,7 +176,6 @@
item_heal_robotic(H, user, 30, 0)
return
else
- user << "Need more welding fuel!"
return
else
return ..()
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 1ce6e22f988..9c772d349b2 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -180,11 +180,11 @@
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
user << "You begin cutting the [src] apart..."
- playsound(loc, 'sound/items/Welder2.ogg', 40, 1)
+ playsound(loc, 'sound/items/Welder.ogg', 40, 1)
if(do_after(user,40,5,1))
if(src.opened)
if(WT.remove_fuel(0,user))
- playsound(loc, 'sound/items/welder.ogg', 50, 1)
+ playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
new /obj/item/stack/sheet/metal(src.loc)
for(var/mob/M in viewers(src))
M.show_message("\The [src] has been cut apart by [user] with \the [WT].", 3, "You hear welding.", 2)
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 898e96e7968..ab62e1ee84a 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -457,7 +457,6 @@ obj/structure/door_assembly/New()
new M(get_turf(src))
qdel(src)
else
- user << " You need more welding fuel to dissassemble the airlock assembly."
return
else if(istype(W, /obj/item/weapon/wrench) && !anchored )
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 46730d0332f..bb0dc4486f6 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -118,7 +118,7 @@
user << "You can't reach, close it first!"
if(istype(W, /obj/item/weapon/pickaxe/plasmacutter) || istype(W, /obj/item/weapon/pickaxe/diamonddrill) || istype(W, /obj/item/weapon/melee/energy/blade))
- dismantle()
+ dismantle(user)
/obj/structure/falsewall/proc/dismantle(mob/user)
user.visible_message("[user] dismantles the false wall.", "You dismantle the false wall.")
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index ea89e95dfa6..73c9e58a568 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -59,9 +59,8 @@
var/obj/item/weapon/weldingtool/WT = C
if(WT.remove_fuel(0, user))
user << "Slicing lattice joints ..."
- new /obj/item/stack/rods(src.loc)
- qdel(src)
-
+ new /obj/item/stack/rods(src.loc)
+ qdel(src)
return
/obj/structure/lattice/proc/updateOverlays()
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 657acb8b02c..e163f334470 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -249,25 +249,3 @@
for(var/i = 1, i <= oreAmount, i++)
new/obj/item/stack/sheet/mineral/wood(get_turf(src))
qdel(src)
-
-/obj/structure/mineral_door/resin
- mineralType = "resin"
- hardness = 1
- close_delay = 100
- openSound = 'sound/effects/attackblob.ogg'
- closeSound = 'sound/effects/attackblob.ogg'
-
-/obj/structure/mineral_door/resin/TryToSwitchState(atom/user)
- if(isalien(user))
- return ..()
-
-/obj/structure/mineral_door/resin/Dismantle(devastated = 0)
- qdel(src)
-
-/obj/structure/mineral_door/resin/CheckHardness()
- playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
- ..()
-
-/obj/structure/mineral_door/resin/BlockSuperconductivity()
- if(opacity)
- return 1
\ No newline at end of file
diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
index 4512e2b45cc..5428ec16cd3 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
@@ -13,6 +13,7 @@
"[user.name] pulls you free from the gelatinous resin.",\
"You hear squelching...")
buckled_mob.pixel_y = 0
+ buckled_mob.pixel_x = 0
unbuckle()
/obj/structure/stool/bed/nest/unbuckle_myself(mob/user as mob)
@@ -23,6 +24,7 @@
spawn(600)
if(user && buckled_mob && user.buckled == src)
buckled_mob.pixel_y = 0
+ buckled_mob.pixel_x = 0
unbuckle()
/obj/structure/stool/bed/nest/buckle_mob(mob/M as mob, mob/user as mob)
@@ -47,11 +49,17 @@
M.loc = src.loc
M.dir = src.dir
M.update_canmove()
- M.pixel_y = 6
+ M.pixel_y = 1
+ M.pixel_x = 2
src.buckled_mob = M
src.add_fingerprint(user)
+ src.overlays += image('icons/mob/alien.dmi', "nestoverlay", layer=6)
return
+/obj/structure/stool/bed/nest/unbuckle()
+ overlays.Cut()
+ ..()
+
/obj/structure/stool/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob)
var/aforce = W.force
health = max(0, health - aforce)
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 281594704e1..e6c0a4e2179 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -89,7 +89,6 @@ obj/structure/windoor_assembly/Destroy()
R.add_fingerprint(user)
qdel(src)
else
- user << "You need more welding fuel to dissassemble the windoor assembly."
return
//Wrenching an unsecure assembly anchors it in place. Step 4 complete
diff --git a/code/game/smoothwall.dm b/code/game/smoothwall.dm
index 29800a163e8..e98c839150a 100644
--- a/code/game/smoothwall.dm
+++ b/code/game/smoothwall.dm
@@ -81,6 +81,9 @@
for(var/obj/structure/falsewall/W in range(src,1))
W.relativewall()
W.update_icon()//Refreshes the wall to make sure the icons don't desync
+ for(var/obj/structure/alien/resin/W in range(src,1))
+ W.relativewall()
+ W.update_icon()
return
/turf/simulated/wall/New()
@@ -129,4 +132,17 @@
junction |= get_dir(src,W)
var/turf/simulated/wall/wall = src
wall.icon_state = "[wall.walltype][junction]"
+ return
+
+
+/obj/structure/alien/resin/relativewall()
+
+ var/junction = 0 //will be used to determine from which side the wall is connected to other walls
+
+ for(var/obj/structure/alien/resin/W in orange(src,1))
+ if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls
+ junction |= get_dir(src,W)
+ var/obj/structure/alien/resin/resin = src
+ resin.icon_state = "[resin.resintype][junction]"
+
return
\ No newline at end of file
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 1ccb3cb9675..4e8ae18a48c 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -588,5 +588,3 @@ turf/simulated/floor/proc/update_icon()
icon_state = icon_plating
burnt = 0
broken = 0
- else
- user << "You need more welding fuel to complete this task."
diff --git a/code/game/turfs/simulated/floor_mineral.dm b/code/game/turfs/simulated/floor_mineral.dm
index 5870aa2396e..f281fd6c471 100644
--- a/code/game/turfs/simulated/floor_mineral.dm
+++ b/code/game/turfs/simulated/floor_mineral.dm
@@ -33,6 +33,11 @@
floortype = "clown"
floor_tile = new/obj/item/stack/tile/mineral/bananium
+/turf/simulated/floor/mineral/bananium/airless
+ oxygen = 0.01
+ nitrogen = 0.01
+ temperature = TCMB
+
/turf/simulated/floor/mineral/diamond
name = "diamond floor"
icon_state = "diamond"
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 540c9d2d88f..ef645aa7963 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -228,7 +228,6 @@
user << "You remove the outer plating."
dismantle_wall()
else
- user << "You need more welding fuel to complete this task."
return
else if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) )
diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm
index 8126029fc18..ed18c29dc8c 100644
--- a/code/game/turfs/simulated/walls_reinforced.dm
+++ b/code/game/turfs/simulated/walls_reinforced.dm
@@ -102,8 +102,6 @@
src.d_state = 3
src.icon_state = "r_wall-3"
user << "You press firmly on the cover, dislodging it."
- else
- user << "You need more welding fuel to complete this task."
return
if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) )
@@ -166,8 +164,6 @@
src.icon_state = "r_wall-6"
new /obj/item/stack/rods( src )
user << "The support rods drop out as you cut them loose from the frame."
- else
- user << "You need more welding fuel to complete this task."
return
if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) )
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 76ef6c096da..3f811920e73 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -6,7 +6,6 @@ var/global/floorIsLava = 0
////////////////////////////////
/proc/message_admins(var/msg)
msg = "ADMIN LOG: [msg]"
- log_adminwarn(msg)
admins << msg
diff --git a/code/modules/admin/admin_memo.dm b/code/modules/admin/admin_memo.dm
index b3f9e451ee3..18b9b030ed1 100644
--- a/code/modules/admin/admin_memo.dm
+++ b/code/modules/admin/admin_memo.dm
@@ -21,13 +21,15 @@
if(null)
return
if("")
+ message_admins("[src.ckey] removed their own Memo")
+ log_admin("[src.ckey] removed their own Memo")
F.dir.Remove(ckey)
- src << "Memo removed"
return
if( findtext(memo,"