diff --git a/code/__DATASTRUCTURES/linked_lists.dm b/code/__DATASTRUCTURES/linked_lists.dm
new file mode 100644
index 00000000000..eccc3c422a8
--- /dev/null
+++ b/code/__DATASTRUCTURES/linked_lists.dm
@@ -0,0 +1,191 @@
+
+//Ok so it's technically a double linked list, bite me.
+
+/datum/linked_list
+ var/datum/linked_node/head
+ var/datum/linked_node/tail
+ var/node_amt = 0
+
+
+/datum/linked_node
+ var/value = null
+ var/datum/linked_list/linked_list = null
+ var/datum/linked_node/next_node = null
+ var/datum/linked_node/previous_node = null
+
+
+/datum/linked_list/proc/IsEmpty()
+ . = (node_amt <= 0)
+
+
+//Add a linked_node (or value, creating a linked_node) at position
+//the added node BECOMES the position-th element,
+//eg: add("Test",5), the 5th node is now "Test", the previous 5th moves up to become the 6th
+/datum/linked_list/proc/Add(node, position)
+ var/datum/linked_node/adding
+ if(istype(node, /datum/linked_node))
+ adding = node
+ else
+ adding = new()
+ adding.value = node
+
+ if(!adding.linked_list || (adding.linked_list && (adding.linked_list != src)))
+ node_amt++
+
+ adding.linked_list = src
+
+ if(position && position < node_amt)
+ //Replacing head
+ if(position == 1)
+ if(head)
+ head.previous_node = adding
+ adding.next_node = head
+ head = adding
+
+ //Replacing any middle node
+ else
+ var/location = 0
+ var/datum/linked_node/at
+ while((location != position) && (location <= node_amt))
+ if(at)
+ if(at.next_node)
+ at = at.next_node
+ else
+ break
+ else
+ at = head
+ location++
+
+ //Push at up and assume it's place as the position-th element
+ if(at && at.previous_node)
+ at.previous_node.next_node = adding
+ adding.previous_node = at.previous_node
+ at.previous_node = adding
+ adding.next_node = at
+ return
+
+ //Replacing tail
+ if(tail)
+ tail.next_node = adding
+ adding.previous_node = tail
+ if(!tail.previous_node)
+ head = tail
+ tail = adding
+
+
+
+//Remove a linked_node or the linked_node of a value
+//If you specify a value the FIRST ONE is removed
+/datum/linked_list/proc/Remove(node)
+ var/datum/linked_node/removing
+ if(istype(node,/datum/linked_node))
+ removing = node
+ else
+ //optimise removing head and tail, no point looping for them, especially the tail
+ if(removing == head)
+ removing = head
+ else if(removing == tail)
+ removing = tail
+ else
+ var/location = 1
+ var/current_value = null
+ var/datum/linked_node/at = null
+ while((current_value != node) && (location <= node_amt))
+ if(at)
+ if(at.next_node)
+ at = at.next_node
+ else
+ at = head
+ location++
+ if(at)
+ current_value = at.value
+ if(current_value == node)
+ removing = at
+ break
+
+ //Adjust pointers of where removing -was- in the chain.
+ if(removing)
+ if(removing.previous_node)
+ if(removing == tail)
+ tail = removing.previous_node
+ if(removing.next_node)
+ if(removing == head)
+ head = removing.next_node
+ removing.next_node.previous_node = removing.previous_node
+ removing.previous_node.next_node = removing.next_node
+ else
+ removing.previous_node.next_node = null
+ else
+ if(removing.next_node)
+ if(removing == head)
+ head = removing.next_node
+ removing.next_node.previous_node = null
+
+ //if this is still true at this point, there's no more nodes to replace them with
+ if(removing == head)
+ head = null
+ if(removing == tail)
+ tail = null
+
+ removing.next_node = null
+ removing.previous_node = null
+ if(removing.linked_list == src)
+ node_amt--
+ removing.linked_list = null
+
+ return removing
+ return 0
+
+
+//Removes and deletes a node or value
+/datum/linked_list/proc/RemoveDelete(node)
+ var/datum/linked_node/dead = Remove(node)
+ if(dead)
+ qdel(dead)
+ return 1
+ return 0
+
+
+//Empty the linked_list, deleting all nodes
+/datum/linked_list/proc/Empty()
+ var/datum/linked_node/n = head
+ while(n)
+ var/next = n.next_node
+ Remove(n)
+ qdel(n)
+ n = next
+ node_amt = 0
+
+
+//Some debugging tools
+/datum/linked_list/proc/CheckNodeLinks()
+ var/datum/linked_node/n = head
+ while(n)
+ . = "|[n.value]|"
+ if(n.previous_node)
+ . = "[n.previous_node.value]<-" + .
+ if(n.next_node)
+ . += "->[n.next_node.value]"
+ n = n.next_node
+ . += "
"
+
+
+/datum/linked_list/proc/DrawNodeLinks()
+ . = "|<-"
+ var/datum/linked_node/n = head
+ while(n)
+ if(n.previous_node)
+ . += "<-"
+ . += "[n.value]"
+ if(n.next_node)
+ . += "->"
+ n = n.next_node
+ . += "->|"
+
+
+/datum/linked_list/proc/ToList()
+ . = list()
+ var/datum/linked_node/n = head
+ while(n)
+ . += n
+ n = n.next_node
\ No newline at end of file
diff --git a/code/__DATASTRUCTURES/priority_queue.dm b/code/__DATASTRUCTURES/priority_queue.dm
new file mode 100644
index 00000000000..2983924e0a1
--- /dev/null
+++ b/code/__DATASTRUCTURES/priority_queue.dm
@@ -0,0 +1,65 @@
+
+//////////////////////
+//PriorityQueue object
+//////////////////////
+
+//an ordered list, using the cmp proc to weight the list elements
+/PriorityQueue
+ var/list/L //the actual queue
+ var/cmp //the weight function used to order the queue
+
+/PriorityQueue/New(compare)
+ L = new()
+ cmp = compare
+
+/PriorityQueue/proc/IsEmpty()
+ return !L.len
+
+//add an element in the list,
+//immediatly ordering it to its position using Insertion sort
+/PriorityQueue/proc/Enqueue(atom/A)
+ var/i
+ L.Add(A)
+ i = L.len -1
+ while(i > 0 && call(cmp)(L[i],A) >= 0) //place the element at it's right position using the compare proc
+ L.Swap(i,i+1) //last inserted element being first in case of ties (optimization)
+ i--
+
+//removes and returns the first element in the queue
+/PriorityQueue/proc/Dequeue()
+ if(!L.len)
+ return 0
+ . = L[1]
+ Remove(.)
+ return .
+
+//removes an element
+/PriorityQueue/proc/Remove(atom/A)
+ return L.Remove(A)
+
+//returns a copy of the elements list
+/PriorityQueue/proc/List()
+ var/list/ret = L.Copy()
+ return ret
+
+//return the position of an element or 0 if not found
+/PriorityQueue/proc/Seek(atom/A)
+ return L.Find(A)
+
+//return the element at the i_th position
+/PriorityQueue/proc/Get(i)
+ if(i > L.len || i < 1)
+ return 0
+ return L[i]
+
+//replace the passed element at it's right position using the cmp proc
+/PriorityQueue/proc/ReSort(atom/A)
+ var/i = Seek(A)
+ if(i == 0)
+ return
+ while(i < L.len && call(cmp)(L[i],L[i+1]) > 0)
+ L.Swap(i,i+1)
+ i++
+ while(i > 1 && call(cmp)(L[i],L[i-1]) <= 0) //last inserted element being first in case of ties (optimization)
+ L.Swap(i,i-1)
+ i--
\ No newline at end of file
diff --git a/code/__DATASTRUCTURES/stacks.dm b/code/__DATASTRUCTURES/stacks.dm
new file mode 100644
index 00000000000..64280ec7006
--- /dev/null
+++ b/code/__DATASTRUCTURES/stacks.dm
@@ -0,0 +1,64 @@
+
+//Both count as failures, and they don't equate to each other
+//this lets us do if(Pop()) without having to specifically check for underflow
+//same for if(Push()) and overflow
+#define STACK_OVERFLOW -1
+#define STACK_UNDERFLOW -2
+
+
+/datum/stack
+ var/list/stack = list()
+ var/max_elements = 0
+
+/datum/stack/New(list/elements,max)
+ ..()
+ if(elements)
+ stack = elements.Copy()
+ if(max)
+ max_elements = max
+
+/datum/stack/proc/Pop()
+ if(is_empty())
+ return STACK_UNDERFLOW
+ . = stack[stack.len]
+ stack.Cut(stack.len,0)
+
+/datum/stack/proc/Push(element)
+ if(max_elements && (stack.len+1 > max_elements))
+ return STACK_OVERFLOW
+ stack += element
+
+/datum/stack/proc/Top()
+ if(is_empty())
+ return STACK_UNDERFLOW
+ . = stack[stack.len]
+
+/datum/stack/proc/is_empty()
+ . = (stack.len > 0)
+
+//Rotate entire stack left with the leftmost looping around to the right
+/datum/stack/proc/RotateLeft()
+ if(is_empty())
+ return 0
+ . = stack[1]
+ stack.Cut(1,2)
+ Push(.)
+
+//Rotate entire stack to the right with the rightmost looping around to the left
+/datum/stack/proc/RotateRight()
+ if(is_empty())
+ return 0
+ . = stack[stack.len]
+ stack.Cut(stack.len,0)
+ stack.Insert(1,.)
+
+
+/datum/stack/proc/Copy()
+ var/datum/stack/S=new()
+ S.stack = stack.Copy()
+ S.max_elements = max_elements
+ return S
+
+
+/datum/stack/proc/Clear()
+ stack.Cut()
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index 2d514504c81..ef414e9269c 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -40,7 +40,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/selection_type = "view" //can be "range" or "view"
var/spell_level = 0 //if a spell can be taken multiple times, this raises
var/level_max = 4 //The max possible level_max is 4
- var/cooldown_min = 0 //This defines what spell quickened four timeshas as a cooldown. Make sure to set this for every spell
+ var/cooldown_min = 0 //This defines what spell quickened four times has as a cooldown. Make sure to set this for every spell
var/overlay = 0
var/overlay_icon = 'icons/obj/wizard.dmi'
diff --git a/code/datums/spells/bloodcrawl.dm b/code/datums/spells/bloodcrawl.dm
new file mode 100644
index 00000000000..0e5db631223
--- /dev/null
+++ b/code/datums/spells/bloodcrawl.dm
@@ -0,0 +1,32 @@
+/obj/effect/proc_holder/spell/bloodcrawl
+ name = "Blood crawl"
+ desc = "Use blood to travel."
+ charge_max = 10
+ clothes_req = 0
+ selection_type = "range"
+ range = 1
+ cooldown_min = 0
+ overlay = null
+ action_icon_state = "bloodcrawl"
+ var/phased = 0
+
+/obj/effect/proc_holder/spell/bloodcrawl/choose_targets(mob/user = usr)
+ for(var/obj/effect/decal/cleanable/target in range(range, get_turf(user)))
+ if(istype(target, /obj/effect/decal/cleanable/blood) || istype(target, /obj/effect/decal/cleanable/trail_holder))
+ perform(target)
+ return
+ revert_cast()
+ user << "You need blood to blood crawl."
+
+/obj/effect/proc_holder/spell/bloodcrawl/perform(obj/effect/decal/cleanable/target, recharge = 1, mob/living/user = usr)
+ if(istype(user))
+ if(phased)
+ if(user.phasein(target))
+ phased = 0
+ else
+ user.phaseout(target)
+ phased = 1
+ start_recharge()
+ return
+ revert_cast()
+ user << "You cannot blood crawl."
\ No newline at end of file
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 0375b0e1894..fadd5898320 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -477,7 +477,7 @@ var/list/uplink_items = list()
/datum/uplink_item/stealthy_tools/camera_bug
name = "Camera Bug"
- desc = "Enables you to bug cameras to view them remotely. Adding particular items to it alters its functions."
+ desc = "Enables you to view all cameras on the network and track a target. Bugging cameras allows you to disable them remotely"
item = /obj/item/device/camera_bug
cost = 1
surplus = 90
@@ -526,7 +526,7 @@ var/list/uplink_items = list()
item = /obj/item/weapon/storage/belt/military
cost = 3
excludefrom = list(/datum/game_mode/nuclear)
-
+
/datum/uplink_item/device_tools/medkit
name = "Syndicate Combat Medic Kit"
desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical hud for quick identification of injured comrades, \
diff --git a/code/game/gamemodes/abduction/abduction.dm b/code/game/gamemodes/abduction/abduction.dm
index 8e6662109e3..0b710001f38 100644
--- a/code/game/gamemodes/abduction/abduction.dm
+++ b/code/game/gamemodes/abduction/abduction.dm
@@ -277,9 +277,9 @@
var/datum/objective/objective = team_objectives[team_number]
var/team_name = team_names[team_number]
if(console.experiment.points >= objective.target_amount)
- world << "[team_name] team fullfilled its mission!"
+ world << "[team_name] team fullfilled its mission!"
else
- world << "[team_name] team failed its mission."
+ world << "[team_name] team failed its mission."
..()
return 1
diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm
index 743196fbb2a..55f79d883b8 100644
--- a/code/game/gamemodes/blob/blob_finish.dm
+++ b/code/game/gamemodes/blob/blob_finish.dm
@@ -45,8 +45,7 @@
var/datum/game_mode/blob/blob_mode = src
if(blob_mode.infected_crew.len)
var/text = "The blob[(blob_mode.infected_crew.len > 1 ? "s were" : " was")]:"
-
for(var/datum/mind/blob in blob_mode.infected_crew)
- text += "
[blob.key] was [blob.name]"
+ text += printplayer(blob)
world << text
- return 1
+ return 1
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm
index d4d4aa5a272..17e79f569bd 100644
--- a/code/game/gamemodes/blob/blobs/blob_mobs.dm
+++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm
@@ -26,7 +26,7 @@
/mob/living/simple_animal/hostile/blob/blobspore
name = "blob"
- desc = "Some blob thing."
+ desc = "A floating, fragile spore."
icon_state = "blobpod"
icon_living = "blobpod"
health = 40
@@ -146,7 +146,7 @@
/mob/living/simple_animal/hostile/blob/blobbernaut
name = "blobbernaut"
- desc = "Some HUGE blob thing."
+ desc = "A hulking, mobile chunk of blobmass."
icon_state = "blobbernaut"
icon_living = "blobbernaut"
icon_dead = "blobbernaut_dead"
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index fbf1295f811..b3056465ffe 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -2,8 +2,10 @@
name = "blob core"
icon = 'icons/mob/blob.dmi'
icon_state = "blank_blob"
+ desc = "A huge, pulsating yellow mass."
health = 200
fire_resist = 2
+ explosion_block = 6
var/overmind_get_delay = 0 // we don't want to constantly try to find an overmind, do it every 30 seconds
var/resource_delay = 0
var/point_rate = 2
@@ -44,6 +46,9 @@
/obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
+/obj/effect/blob/core/ex_act(severity, target)
+ return
+
/obj/effect/blob/core/update_icon()
if(health <= 0)
qdel(src)
diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm
index dd4f83dd9ba..ea5c39267ea 100644
--- a/code/game/gamemodes/blob/blobs/factory.dm
+++ b/code/game/gamemodes/blob/blobs/factory.dm
@@ -2,6 +2,7 @@
name = "factory blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_factory"
+ desc = "A thick spire of tendrils."
health = 100
fire_resist = 2
var/list/spores = list()
diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm
index bf756df0315..8d2ef8caa7c 100644
--- a/code/game/gamemodes/blob/blobs/node.dm
+++ b/code/game/gamemodes/blob/blobs/node.dm
@@ -2,6 +2,7 @@
name = "blob node"
icon = 'icons/mob/blob.dmi'
icon_state = "blank_blob"
+ desc = "A large, pulsating yellow mass."
health = 100
fire_resist = 2
diff --git a/code/game/gamemodes/blob/blobs/resource.dm b/code/game/gamemodes/blob/blobs/resource.dm
index 78527b7cde0..2996265ee2c 100644
--- a/code/game/gamemodes/blob/blobs/resource.dm
+++ b/code/game/gamemodes/blob/blobs/resource.dm
@@ -2,6 +2,7 @@
name = "resource blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_resource"
+ desc = "A thin spire of slightly swaying tendrils."
health = 30
fire_resist = 2
var/resource_delay = 0
diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm
index 1c145f4404f..68e29f221ee 100644
--- a/code/game/gamemodes/blob/blobs/shield.dm
+++ b/code/game/gamemodes/blob/blobs/shield.dm
@@ -2,8 +2,9 @@
name = "strong blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_idle"
- desc = "Some blob creature thingy"
+ desc = "A solid wall of slightly twitching tendrils."
health = 75
+ explosion_block = 3
fire_resist = 2
diff --git a/code/game/gamemodes/blob/blobs/storage.dm b/code/game/gamemodes/blob/blobs/storage.dm
index 4b5089b10cc..a09e58915f3 100644
--- a/code/game/gamemodes/blob/blobs/storage.dm
+++ b/code/game/gamemodes/blob/blobs/storage.dm
@@ -2,6 +2,7 @@
name = "storage blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_resource"
+ desc = "A huge, smooth mass supported by tendrils."
health = 30
fire_resist = 2
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 0de202a456a..c0dd7fa6a8b 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -3,10 +3,11 @@
name = "blob"
icon = 'icons/mob/blob.dmi'
luminosity = 3
- desc = "Some blob creature thingy"
+ desc = "A thick wall of writhing tendrils."
density = 0
opacity = 0
anchored = 1
+ explosion_block = 1
var/health = 30
var/health_timestamp = 0
var/brute_resist = 4
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 50fac253f91..333142996be 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -313,11 +313,11 @@
if(!check_cult_victory())
feedback_set_details("round_end_result","win - cult win")
feedback_set("round_end_result",acolytes_survived)
- world << "The cult wins! It has succeeded in serving its dark masters!"
+ world << "The cult wins! It has succeeded in serving its dark masters!"
else
feedback_set_details("round_end_result","loss - staff stopped the cult")
feedback_set("round_end_result",acolytes_survived)
- world << "The staff managed to stop the cult!"
+ world << "The staff managed to stop the cult!"
var/text = ""
@@ -328,28 +328,28 @@
switch(cult_objectives[obj_count])
if("survive")
if(!check_survive())
- explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!"
+ explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!"
feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
else
- explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail."
+ explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail."
feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
if("sacrifice")
if(sacrifice_target)
if(sacrifice_target in sacrificed)
- explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!"
+ explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!"
feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
else if(sacrifice_target && sacrifice_target.current)
- explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail."
+ explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail."
feedback_add_details("cult_objective","cult_sacrifice|FAIL")
else
- explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)."
+ explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)."
feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
if("eldergod")
if(!eldergod)
- explanation = "Summon Nar-Sie. Success!"
+ explanation = "Summon Nar-Sie. Success!"
feedback_add_details("cult_objective","cult_narsie|SUCCESS")
else
- explanation = "Summon Nar-Sie. Fail."
+ explanation = "Summon Nar-Sie. Fail."
feedback_add_details("cult_objective","cult_narsie|FAIL")
text += "
Objective #[obj_count]: [explanation]"
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index f27e6522c59..b47f6b500c3 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -471,17 +471,19 @@
if(M.client && M.client.holder)
M << msg
-/datum/game_mode/proc/printplayer(datum/mind/ply)
+/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck)
var/text = "
[ply.key] was [ply.name] the [ply.assigned_role] and"
if(ply.current)
if(ply.current.stat == DEAD)
- text += " died"
+ text += " died"
else
- text += " survived"
+ text += " survived"
+ if(fleecheck && ply.current.z > ZLEVEL_STATION)
+ text += " while fleeing the station"
if(ply.current.real_name != ply.name)
text += " as [ply.current.real_name]"
else
- text += " had their body destroyed"
+ text += " had their body destroyed"
return text
/datum/game_mode/proc/printobjectives(datum/mind/ply)
@@ -489,9 +491,9 @@
var/count = 1
for(var/datum/objective/objective in ply.objectives)
if(objective.check_completion())
- text += "
Objective #[count]: [objective.explanation_text] Success!"
+ text += "
Objective #[count]: [objective.explanation_text] Success!"
else
- text += "
Objective #[count]: [objective.explanation_text] Fail."
+ text += "
Objective #[count]: [objective.explanation_text] Fail."
count++
return text
diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm
index d68df799d20..c641b5f6392 100644
--- a/code/game/gamemodes/gang/gang.dm
+++ b/code/game/gamemodes/gang/gang.dm
@@ -248,39 +248,20 @@ var/list/gang_colors_pool = list("red","orange","yellow","green","blue","purple"
/datum/game_mode/proc/auto_declare_completion_gang(datum/gang/winner)
if(gangs.len)
if(!winner)
- world << "The station was [station_was_nuked ? "destroyed!" : "evacuated before a gang could claim it! The station wins!"]
"
+ world << "The station was [station_was_nuked ? "destroyed!" : "evacuated before a gang could claim it! The station wins!"]
"
else
- world << "The [winner.name] Gang successfully performed a hostile takeover of the station!
"
+ world << "The [winner.name] Gang successfully performed a hostile takeover of the station!
"
for(var/datum/gang/G in gangs)
- world << "
The [G.name] Gang was [winner==G ? "victorious" : "defeated"] with [round((G.territory.len/start_state.num_territories)*100, 1)]% control of the station!"
- world << "
The [G.name] Gang Bosses were:"
- gang_membership_report(G.bosses)
- world << "
The [G.name] Gangsters were:"
- gang_membership_report(G.gangsters)
- world << "
"
-
-
-
-/datum/game_mode/proc/gang_membership_report(list/membership)
- var/text = ""
- for(var/datum/mind/gang_mind in membership)
- text += "
[gang_mind.key] was [gang_mind.name] ("
- if(gang_mind.current)
- if(gang_mind.current.stat == DEAD || isbrain(gang_mind.current))
- text += "died"
- else if(gang_mind.current.z > ZLEVEL_STATION)
- text += "fled the station"
- else
- text += "survived"
- if(gang_mind.current.real_name != gang_mind.name)
- text += " as [gang_mind.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
-
- world << text
-
+ var/text = "The [G.name] Gang was [winner==G ? "victorious" : "defeated"] with [round((G.territory.len/start_state.num_territories)*100, 1)]% control of the station!"
+ text += "
The [G.name] Gang Bosses were:"
+ for(var/datum/mind/boss in G.bosses)
+ text += printplayer(boss, 1)
+ text += "
The [G.name] Gangsters were:"
+ for(var/datum/mind/gangster in G.gangsters)
+ text += printplayer(gangster, 1)
+ text += "
"
+ world << text
//////////////////////////////////////////////////////////
//Handles influence, territories, and the victory checks//
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index 5a88c2e0525..6c6c06e84c5 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -286,24 +286,12 @@
if( malf_ai.len || istype(ticker.mode,/datum/game_mode/malfunction) )
var/text = "
The malfunctioning AIs were:"
var/module_text_temp = "
Purchased modules:
" //Added at the end
-
for(var/datum/mind/malf in malf_ai)
-
- text += "
[malf.key] was [malf.name] ("
+ text += printplayer(malf, 1)
if(malf.current)
- if(malf.current.stat == DEAD)
- text += "deactivated"
- else
- text += "operational"
- if(malf.current.real_name != malf.name)
- text += " as [malf.current.real_name]"
var/mob/living/silicon/ai/AI = malf.current
for(var/datum/AI_Module/mod in AI.current_modules)
module_text_temp += mod.module_name + "
"
- else
- text += "hardware destroyed"
- text += ")"
text += module_text_temp
-
world << text
return 1
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index ceb70737d79..939cce46b06 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -278,36 +278,18 @@
/datum/game_mode/proc/auto_declare_completion_nuclear()
if( syndicates.len || (ticker && istype(ticker.mode,/datum/game_mode/nuclear)) )
var/text = "
The syndicate operatives were:"
-
var/purchases = ""
var/TC_uses = 0
-
for(var/datum/mind/syndicate in syndicates)
-
- text += "
[syndicate.key] was [syndicate.name] ("
- if(syndicate.current)
- if(syndicate.current.stat == DEAD)
- text += "died"
- else
- text += "survived"
- if(syndicate.current.real_name != syndicate.name)
- text += " as [syndicate.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
-
+ text += printplayer(syndicate)
for(var/obj/item/device/uplink/H in world_uplinks)
if(H && H.uplink_owner && H.uplink_owner==syndicate.key)
TC_uses += H.used_TC
purchases += H.purchase_log
-
text += "
"
-
text += "(Syndicates used [TC_uses] TC) [purchases]"
-
if(TC_uses==0 && station_was_nuked && !are_operatives_dead())
text += ""
-
world << text
return 1
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index cd721167641..0da1f7b219b 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -321,16 +321,15 @@
/datum/game_mode/revolution/declare_completion()
if(finished == 1)
feedback_set_details("round_end_result","win - heads killed")
- world << "The heads of staff were killed or exiled! The revolutionaries win!"
+ world << "The heads of staff were killed or exiled! The revolutionaries win!"
else if(finished == 2)
feedback_set_details("round_end_result","loss - rev heads killed")
- world << "The heads of staff managed to stop the revolution!"
+ world << "The heads of staff managed to stop the revolution!"
..()
return 1
/datum/game_mode/proc/auto_declare_completion_revolution()
var/list/targets = list()
-
if(head_revolutionaries.len || istype(ticker.mode,/datum/game_mode/revolution))
var/num_revs = 0
var/num_survivors = 0
@@ -340,78 +339,28 @@
if(survivor.mind)
if((survivor.mind in head_revolutionaries) || (survivor.mind in revolutionaries))
num_revs++
-
if(num_survivors)
world << "[TAB]Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%" // % of loyal crew
-
var/text = "
The head revolutionaries were:"
-
for(var/datum/mind/headrev in head_revolutionaries)
- text += "
[headrev.key] was [headrev.name] ("
- if(headrev.current)
- if(headrev.current.stat == DEAD)
- text += "died"
- else if(headrev.current.z > ZLEVEL_STATION)
- text += "fled the station"
- else
- text += "survived the revolution"
- if(headrev.current.real_name != headrev.name)
- text += " as [headrev.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
-
- for(var/datum/objective/mutiny/objective in headrev.objectives)
- targets |= objective.target
+ text += printplayer(headrev, 1)
text += "
"
-
world << text
if(revolutionaries.len || istype(ticker.mode,/datum/game_mode/revolution))
var/text = "
The revolutionaries were:"
-
for(var/datum/mind/rev in revolutionaries)
- text += "
[rev.key] was [rev.name] ("
- if(rev.current)
- if(rev.current.stat == DEAD || isbrain(rev.current))
- text += "died"
- else if(rev.current.z > ZLEVEL_STATION)
- text += "fled the station"
- else
- text += "survived the revolution"
- if(rev.current.real_name != rev.name)
- text += " as [rev.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
+ text += printplayer(rev, 1)
text += "
"
-
world << text
-
if( head_revolutionaries.len || revolutionaries.len || istype(ticker.mode,/datum/game_mode/revolution) )
var/text = "
The heads of staff were:"
-
var/list/heads = get_all_heads()
for(var/datum/mind/head in heads)
var/target = (head in targets)
if(target)
- text += ""
- text += "
[head.key] was [head.name] ("
- if(head.current)
- if(head.current.stat == DEAD || isbrain(head.current))
- text += "died"
- else if(head.current.z > ZLEVEL_STATION)
- text += "fled the station"
- else
- text += "survived the revolution"
- if(head.current.real_name != head.name)
- text += " as [head.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
- if(target)
- text += ""
+ text += "Target"
+ text += printplayer(head, 1)
text += "
"
-
world << text
diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm
index 6409717d278..394cbd35bd8 100644
--- a/code/game/gamemodes/shadowling/shadowling.dm
+++ b/code/game/gamemodes/shadowling/shadowling.dm
@@ -195,13 +195,13 @@ Made by Xhuis
/datum/game_mode/shadowling/declare_completion()
if(check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) //Doesn't end instantly - this is hacky and I don't know of a better way ~X
- world << "The shadowlings have ascended and taken over the station!"
+ world << "The shadowlings have ascended and taken over the station!"
else if(shadowling_dead && !check_shadow_victory()) //If the shadowlings have ascended, they can not lose the round
- world << "The shadowlings have been killed by the crew!"
+ world << "The shadowlings have been killed by the crew!"
else if(!check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE)
- world << "The crew escaped the station before the shadowlings could ascend!"
+ world << "The crew escaped the station before the shadowlings could ascend!"
else
- world << "The shadowlings have failed!"
+ world << "The shadowlings have failed!"
..()
return 1
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index bdb7f9b8a48..304fe753788 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -505,9 +505,19 @@ var/global/list/multiverse = list()
return src.loc == user
/obj/item/voodoo/attack_self(mob/user)
- if(!target)
+ if(!target && possible.len)
target = input(user, "Select your victim!", "Voodoo") as null|anything in possible
return
+
+ if(user.zone_sel.selecting == "chest")
+ if(link)
+ target = null
+ link.loc = get_turf(src)
+ user << "You remove the [link] from the doll."
+ link = null
+ update_targets()
+ return
+
if(target && cooldown < world.time)
switch(user.zone_sel.selecting)
if("mouth")
@@ -542,13 +552,6 @@ var/global/list/multiverse = list()
target.Dizzy(10)
target << "You suddenly feel as if your head was hit with a hammer!"
GiveHint(target,user)
- if("chest")
- if(link)
- target = null
- link.loc = get_turf(src)
- user << "You remove the [link] from the doll."
- link = null
- update_targets()
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 6ed742e75a4..c500f390b6a 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -36,9 +36,9 @@
/datum/game_mode/wizard/post_setup()
for(var/datum/mind/wizard in wizards)
log_game("[wizard.key] (ckey) has been selected as a Wizard")
- forge_wizard_objectives(wizard)
//learn_basic_spells(wizard.current)
equip_wizard(wizard.current)
+ forge_wizard_objectives(wizard)
name_wizard(wizard.current)
greet_wizard(wizard)
if(use_huds)
diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm
index ea5613108f7..2cc3150b0ef 100644
--- a/code/game/machinery/bots/cleanbot.dm
+++ b/code/game/machinery/bots/cleanbot.dm
@@ -8,7 +8,7 @@
throwforce = 5.0
throw_speed = 2
throw_range = 5
- w_class = 3.0
+ w_class = 3.
var/created_name = "Cleanbot"
@@ -151,7 +151,7 @@ text("[on ? "On" : "Off"]"))
PoolOrNew(/obj/effect/effect/foam, loc)
else if (prob(5))
- visible_message("[src] makes an excited beeping booping sound!")
+ audible_message("[src] makes an excited beeping booping sound!")
if(!target) //Search for cleanables it can see.
target = scan(/obj/effect/decal/cleanable/)
diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm
index 75194d08fcd..1322d1c4bad 100644
--- a/code/game/machinery/bots/floorbot.dm
+++ b/code/game/machinery/bots/floorbot.dm
@@ -216,7 +216,7 @@
nag()
if(prob(5))
- visible_message("[src] makes an excited booping beeping sound!")
+ audible_message("[src] makes an excited booping beeping sound!")
//Normal scanning procedure. We have tiles loaded, are not emagged.
if(!target && emagged < 2 && amount > 0)
@@ -289,7 +289,7 @@
F.break_tile_to_plating()
else
F.ReplaceWithLattice()
- visible_message("[src] makes an excited booping sound.")
+ audible_message("[src] makes an excited booping sound.")
spawn(50)
amount ++
anchored = 0
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index f7c760893ab..c7b408ca6f3 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -426,13 +426,13 @@ obj/machinery/bot/mulebot/CanPass(atom/movable/mover, turf/target, height=1.5)
/obj/machinery/bot/mulebot/proc/buzz(type)
switch(type)
if(SIGH)
- visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
+ audible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
if(ANNOYED)
- visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
+ audible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
if(DELIGHT)
- visible_message("[src] makes a delighted ping!", "You hear a ping.")
+ audible_message("[src] makes a delighted ping!", "You hear a ping.")
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
@@ -725,7 +725,7 @@ obj/machinery/bot/mulebot/CanPass(atom/movable/mover, turf/target, height=1.5)
/obj/machinery/bot/mulebot/proc/at_target()
if(!reached_target)
radio_frequency = SUPP_FREQ //Supply channel
- visible_message("[src] makes a chiming sound!", "You hear a chime.")
+ audible_message("[src] makes a chiming sound!", "You hear a chime.")
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
reached_target = 1
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index 966e3f15688..587031fa810 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -7,7 +7,7 @@
opacity = 0
anchored = 1
density = 0
- layer = OBJ_LAYER + 0.05 //above table, below windoor/airlock/foamed metal.
+ layer = OBJ_LAYER - 0.5 //above table, below windoor/airlock/foamed metal.
mouse_opacity = 0
var/amount = 3
animate_movement = 0
@@ -91,14 +91,8 @@
/obj/effect/effect/foam/proc/spread_foam()
- for(var/direction in cardinal)
- var/turf/T = get_step(src,direction)
- if(!T)
- continue
-
- if(!T.Enter(src))
- continue
-
+ var/turf/t_loc = get_turf(src)
+ for(var/turf/T in t_loc.GetAtmosAdjacentTurfs())
var/obj/effect/effect/foam/foundfoam = locate() in T //Don't spread foam where there's already foam!
if(foundfoam)
continue
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index 682fc5293fe..6d3c4e6dce0 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -98,6 +98,9 @@
if(W.reinf && W.fulltile)
cached_exp_block[T] += W.explosion_block
+ for(var/obj/effect/blob/B in T)
+ cached_exp_block[T] += B.explosion_block
+
for(var/turf/T in affected_turfs)
var/dist = cheap_hypotenuse(T.x, T.y, x0, y0)
@@ -215,6 +218,9 @@
if(W.explosion_block && W.fulltile)
dist += W.explosion_block
+ for(var/obj/effect/blob/B in T)
+ dist += B.explosion_block
+
if(dist < dev)
T.color = "red"
T.maptext = "Dev"
diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm
index 13e3c807a58..b6b36f429e9 100644
--- a/code/game/objects/items/devices/camera_bug.dm
+++ b/code/game/objects/items/devices/camera_bug.dm
@@ -1,9 +1,3 @@
-#define VANILLA_BUG 0
-#define UNIVERSAL_BUG 1
-#define NETWORK_BUG 2
-#define SABOTAGE_BUG 3
-#define ADVANCED_BUG 4
-#define ADMIN_BUG 5
#define BUGMODE_LIST 0
#define BUGMODE_MONITOR 1
@@ -22,13 +16,9 @@
throw_range = 20
var/obj/machinery/camera/current = null
- var/obj/item/expansion = null
- var/bugtype = VANILLA_BUG
var/last_net_update = 0
- var/last_bugtype = VANILLA_BUG
var/list/bugged_cameras = list()
- var/skip_bugcheck = 0
var/track_mode = BUGMODE_LIST
var/last_tracked = 0
@@ -45,9 +35,6 @@
SSobj.processing += src
/obj/item/device/camera_bug/Destroy()
- if(expansion)
- qdel(expansion)
- expansion = null
get_cameras()
for(var/cam_tag in bugged_cameras)
var/obj/machinery/camera/camera = bugged_cameras[cam_tag]
@@ -75,7 +62,7 @@
return null
var/turf/T = get_turf(user.loc)
- if(T.z != current.z || (!skip_bugcheck && current.bug != src) || !current.can_use())
+ if(T.z != current.z || !current.can_use())
user << "[src] has lost the signal."
current = null
user.reset_view(null)
@@ -85,22 +72,13 @@
return 1
/obj/item/device/camera_bug/proc/get_cameras()
- if(bugtype != last_bugtype || ( (bugtype in list(UNIVERSAL_BUG,NETWORK_BUG,ADMIN_BUG)) && world.time > (last_net_update + 100)))
+ if( world.time > (last_net_update + 100))
bugged_cameras = list()
- last_bugtype = bugtype
for(var/obj/machinery/camera/camera in cameranet.cameras)
if(camera.stat || !camera.can_use())
continue
- switch(bugtype)
- if(VANILLA_BUG,SABOTAGE_BUG,ADVANCED_BUG)
- if(camera.bug == src)
- bugged_cameras[camera.c_tag] = camera
- if(UNIVERSAL_BUG)
- if(camera.bug)
- bugged_cameras[camera.c_tag] = camera
- if(NETWORK_BUG,ADMIN_BUG)
- if(length(list("SS13","MINE")&camera.network))
- bugged_cameras[camera.c_tag] = camera
+ if(length(list("SS13","MINE")&camera.network))
+ bugged_cameras[camera.c_tag] = camera
sortList(bugged_cameras)
return bugged_cameras
@@ -116,16 +94,10 @@
for(var/entry in cameras)
var/obj/machinery/camera/C = cameras[entry]
var/functions = ""
- switch(bugtype)
- if(SABOTAGE_BUG)
- functions = " - \[Disable\]"
- if(ADVANCED_BUG)
- functions = " - \[Monitor\]"
- if(ADMIN_BUG)
- if(C.bug == src)
- functions = " - \[Monitor\] \[Disable\]"
- else
- functions = " - \[Monitor\]"
+ if(C.bug == src)
+ functions = " - \[Monitor\] \[Disable\]"
+ else
+ functions = " - \[Monitor\]"
html += "