diff --git a/baystation12.dme b/baystation12.dme
index f0e8b68d791..f2eb40bb51c 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -177,10 +177,16 @@
#include "code\game\gamemodes\setupgame.dm"
#include "code\game\gamemodes\autotraitor\autotraitor.dm"
#include "code\game\gamemodes\blob\blob.dm"
+#include "code\game\gamemodes\blob\blob_finish.dm"
+#include "code\game\gamemodes\blob\blob_report.dm"
+#include "code\game\gamemodes\blob\hud.dm"
+#include "code\game\gamemodes\blob\overmind.dm"
+#include "code\game\gamemodes\blob\powers.dm"
#include "code\game\gamemodes\blob\theblob.dm"
#include "code\game\gamemodes\blob\blobs\core.dm"
#include "code\game\gamemodes\blob\blobs\factory.dm"
#include "code\game\gamemodes\blob\blobs\node.dm"
+#include "code\game\gamemodes\blob\blobs\resource.dm"
#include "code\game\gamemodes\blob\blobs\shield.dm"
#include "code\game\gamemodes\changeling\changeling.dm"
#include "code\game\gamemodes\changeling\changeling_powers.dm"
@@ -196,11 +202,7 @@
#include "code\game\gamemodes\events\black_hole.dm"
#include "code\game\gamemodes\events\clang.dm"
#include "code\game\gamemodes\events\dust.dm"
-#include "code\game\gamemodes\events\miniblob.dm"
-#include "code\game\gamemodes\events\ninja_abilities.dm"
-#include "code\game\gamemodes\events\ninja_equipment.dm"
#include "code\game\gamemodes\events\power_failure.dm"
-#include "code\game\gamemodes\events\space_ninja.dm"
#include "code\game\gamemodes\events\spacevines.dm"
#include "code\game\gamemodes\events\wormholes.dm"
#include "code\game\gamemodes\events\holidays\Christmas.dm"
@@ -724,7 +726,6 @@
#include "code\modules\clothing\spacesuits\captain.dm"
#include "code\modules\clothing\spacesuits\ert.dm"
#include "code\modules\clothing\spacesuits\miscellaneous.dm"
-#include "code\modules\clothing\spacesuits\ninja.dm"
#include "code\modules\clothing\spacesuits\rig.dm"
#include "code\modules\clothing\spacesuits\syndi.dm"
#include "code\modules\clothing\spacesuits\void.dm"
@@ -775,7 +776,6 @@
#include "code\modules\events\prison_break.dm"
#include "code\modules\events\radiation_storm.dm"
#include "code\modules\events\rogue_drones.dm"
-#include "code\modules\events\space_ninja.dm"
#include "code\modules\events\spacevine.dm"
#include "code\modules\events\spider_infestation.dm"
#include "code\modules\events\spontaneous_appendicitis.dm"
@@ -837,7 +837,6 @@
#include "code\modules\mob\living\login.dm"
#include "code\modules\mob\living\logout.dm"
#include "code\modules\mob\living\say.dm"
-#include "code\modules\mob\living\blob\blob.dm"
#include "code\modules\mob\living\carbon\carbon.dm"
#include "code\modules\mob\living\carbon\carbon_defines.dm"
#include "code\modules\mob\living\carbon\give.dm"
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_animals.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_animals.dm
index a2e1f1c4b98..be4d60fe6a5 100644
--- a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_animals.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_animals.dm
@@ -95,10 +95,10 @@
/mob/living/simple_animal/hostile/panther/AttackTarget()
..()
- if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target_mob))
+ if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target))
stalk_tick_delay -= 1
if(stalk_tick_delay <= 0)
- src.loc = get_step_towards(src, target_mob)
+ src.loc = get_step_towards(src, target)
stalk_tick_delay = 3
//*******//
@@ -151,8 +151,8 @@
/mob/living/simple_animal/hostile/snake/AttackTarget()
..()
- if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target_mob))
+ if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target))
stalk_tick_delay -= 1
if(stalk_tick_delay <= 0)
- src.loc = get_step_towards(src, target_mob)
+ src.loc = get_step_towards(src, target)
stalk_tick_delay = 3
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/misc_helpers.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/misc_helpers.dm
index ffc1265b7dd..1e1b4d45129 100644
--- a/code/WorkInProgress/Cael_Aislinn/Jungle/misc_helpers.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/misc_helpers.dm
@@ -72,7 +72,8 @@
for(var/mob/M in T)
- if(!istype(M,/mob) || istype(M, /mob/aiEye)) continue // If we need to check for more mobs, I'll add a variable
+ if(!M.move_on_shuttle)
+ continue // If we need to check for more mobs, I'll add a variable
mobs += M
for(var/mob/M in mobs)
diff --git a/code/ZAS - vgstation/Airflow.dm b/code/ZAS - vgstation/Airflow.dm
index 28bdb8420e0..04ee815bfc7 100644
--- a/code/ZAS - vgstation/Airflow.dm
+++ b/code/ZAS - vgstation/Airflow.dm
@@ -429,6 +429,6 @@ zone/proc/movables()
. = list()
for(var/turf/T in contents)
for(var/atom/A in T)
- if(istype(A, /obj/effect) || istype(A, /obj/machinery/camera))
+ if(istype(A, /obj/effect) || istype(A, /mob/camera))
continue
. += A
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 6e1b5d49a9f..d84a2d88e58 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -350,6 +350,13 @@ var/list/DummyCache = list()
i++
return candidates
+proc/get_candidates(be_special_flag=0)
+ . = list()
+ for(var/mob/dead/observer/G in player_list)
+ if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
+ if(!G.client.is_afk() && (G.client.prefs.be_special & be_special_flag))
+ . += G.client
+
/proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480)
if(!isobj(O)) O = new /obj/screen/text()
O.maptext = maptext
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 07110db9fea..b734640463a 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -947,7 +947,8 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl
if(!istype(O,/obj)) continue
O.loc = X
for(var/mob/M in T)
- if(!istype(M,/mob) || istype(M, /mob/aiEye)) continue // If we need to check for more mobs, I'll add a variable
+ if(!M.move_on_shuttle)
+ continue
M.loc = X
// var/area/AR = X.loc
@@ -1108,7 +1109,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
for(var/mob/M in T)
- if(!istype(M,/mob) || istype(M, /mob/aiEye)) continue // If we need to check for more mobs, I'll add a variable
+ if(!M.move_on_shuttle)
+ continue
mobs += M
for(var/mob/M in mobs)
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 517c6d0931e..55e92be2274 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -498,8 +498,8 @@ client
usr << "This can only be used on instances of type /mob"
return
- src.cmd_admin_ninjafy(M)
- href_list["datumrefresh"] = href_list["ninja"]
+// src.cmd_admin_ninjafy(M)
+// href_list["datumrefresh"] = href_list["ninja"]
else if(href_list["godmode"])
if(!check_rights(R_REJUVINATE)) return
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 769f7707eaf..de62826dffa 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -1124,16 +1124,15 @@ datum/mind
//Initialisation procs
-/mob/living/proc/mind_initialize()
+/mob/proc/mind_initialize()
if(mind)
mind.key = key
else
mind = new /datum/mind(key)
- mind.original = src
if(ticker)
ticker.minds += mind
else
- world.log << "## DEBUG: mind_initialize(): No ticker ready yet! Please inform Carn"
+ error("mind_initialize(): No ticker ready yet! Please inform Carn")
if(!mind.name) mind.name = real_name
mind.current = src
@@ -1142,6 +1141,10 @@ datum/mind
..()
if(!mind.assigned_role) mind.assigned_role = "Assistant" //defualt
+/mob/proc/sync_mind()
+ mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
+ mind.active = 1 //indicates that the mind is currently synced with a client
+
//MONKEY
/mob/living/carbon/monkey/mind_initialize()
..()
@@ -1192,6 +1195,11 @@ datum/mind
mind.assigned_role = "pAI"
mind.special_role = ""
+//BLOB
+/mob/camera/overmind/mind_initialize()
+ ..()
+ mind.special_role = "Blob"
+
//Animals
/mob/living/simple_animal/mind_initialize()
..()
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 44440e82885..c394b55c740 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -862,7 +862,9 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
// ------- ALT-CLICK -------
if(parameters["alt"]){
- if(!isAI(usr))
+ if(isrobot(usr))
+ RobotAltClick(usr)
+ else if(!isAI(usr))
AltClick(usr)
else
AIAltClick(usr)
@@ -872,7 +874,9 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
// ------- CTRL-CLICK -------
if(parameters["ctrl"]){
- if(!isAI(usr))
+ if(isovermind(usr))
+ OvermindCtrlClick(usr)
+ else if(!isAI(usr))
CtrlClick(usr)
else
AICtrlClick(usr)
@@ -1217,6 +1221,22 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
src:pull()
return
+/atom/proc/OvermindCtrlClick(var/mob/camera/blob/blob)
+ if(istype(src, /turf))
+ blob.click_expand_blob(src)
+ return
+
+/atom/proc/RobotAltClick() // Opens and closes doors!
+ if(istype(src , /obj/machinery/door/airlock))
+ if(src:density)
+ var/nhref = "src=\ref[src];aiEnable=7"
+ src.Topic(nhref, params2list(nhref), src, 1)
+ else
+ var/nhref = "src=\ref[src];aiDisable=7"
+ src.Topic(nhref, params2list(nhref), src, 1)
+
+ return
+
/atom/proc/AIShiftClick() // Opens and closes doors!
if(istype(src , /obj/machinery/door/airlock))
if(src:density)
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
index e53053764b2..11c19f74042 100644
--- a/code/game/gamemodes/blob/blob.dm
+++ b/code/game/gamemodes/blob/blob.dm
@@ -6,128 +6,161 @@ var/list/blob_cores = list()
var/list/blob_nodes = list()
-/*/datum/game_mode/blob
+/datum/game_mode/blob
name = "blob"
config_tag = "blob"
- required_players = 0
- var/const/waittime_l = 1800 //lower bound on time before intercept arrives (in tenths of seconds)
- var/const/waittime_h = 3600 //upper bound on time before intercept arrives (in tenths of seconds)
+ required_players = 30
+
+ restricted_jobs = list("Cyborg", "AI")
+
+ var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
+ var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
var/declared = 0
- var/stage = 0
var/cores_to_spawn = 1
- var/players_per_core = 16
+ var/players_per_core = 30
+ var/blob_point_rate = 3
- //Controls expansion via game controller
- var/autoexpand = 0
- var/expanding = 0
+ var/blobwincount = 350
- var/blob_count = 0
- var/blobnukecount = 300//Might be a bit low
- var/blobwincount = 700//Still needs testing
+ var/list/infected_crew = list()
+
+/datum/game_mode/blob/pre_setup()
+
+ var/list/possible_blobs = get_players_for_role(BE_ALIEN)
+
+ // stop setup if no possible traitors
+ if(!possible_blobs.len)
+ return 0
+
+ cores_to_spawn = max(round(num_players()/players_per_core, 1), 1)
+
+ blobwincount = initial(blobwincount) * cores_to_spawn
- announce()
- world << "The current game mode is - Blob!"
- world << "A dangerous alien organism is rapidly spreading throughout the station!"
- world << "You must kill it all while minimizing the damage to the station."
+ for(var/j = 0, j < cores_to_spawn, j++)
+ if (!possible_blobs.len)
+ break
+ var/datum/mind/blob = pick(possible_blobs)
+ infected_crew += blob
+ blob.special_role = "Blob"
+ log_game("[blob.key] (ckey) has been selected as a Blob")
+ possible_blobs -= blob
+
+ if(!infected_crew.len)
+ return 0
+
+ return 1
- post_setup()
- spawn(10)
- start_state = new /datum/station_state()
- start_state.count()
-
- spawn(rand(waittime_l, waittime_h))//3-5 minutes currently
- message_admins("Blob spawned and expanding, report created")
- if(!kill_air)
- kill_air = 1
- message_admins("Kill air has been set to true by Blob, testing to see how laggy it is without the extra processing from hullbreaches. Note: the blob is fireproof so plasma does not help anyways")
-
- if(ticker && ticker.minds && ticker.minds.len)
- var/player_based_cores = round(ticker.minds.len/players_per_core, 1)
- if(player_based_cores > cores_to_spawn)
- cores_to_spawn = player_based_cores
-
- blobs = list()
- for(var/i = 0 to cores_to_spawn)
- var/turf/location = pick(blobstart)
- if(location && !locate(/obj/effect/blob in location))
- blobstart -= location
- new/obj/effect/blob/core(location)
-
- spawn(40)
- autoexpand = 1
- declared = 1
- ..()
+/datum/game_mode/blob/announce()
+ world << "The current game mode is - Blob!"
+ world << "A dangerous alien organism is rapidly spreading throughout the station!"
+ world << "You must kill it all while minimizing the damage to the station."
- process()
- if(!declared) return
- stage()
-// if(!autoexpand) return
-// spawn(0)
-// expandBlob()
- return
+/datum/game_mode/blob/proc/greet_blob(var/datum/mind/blob)
+ blob.current << "\red You are infected by the Blob!"
+ blob.current << "Your body is ready to give spawn to a new blob core which will eat this station."
+ blob.current << "Find a good location to spawn the core and then take control and overwhelm the station!"
+ blob.current << "When you have found a location, wait until you spawn; this will happen automatically and you cannot speed up the process."
+ blob.current << "If you go outside of the station level, or in space, then you will die; make sure your location has lots of ground to cover."
+ return
+
+/datum/game_mode/blob/proc/show_message(var/message)
+ for(var/datum/mind/blob in infected_crew)
+ blob.current << message
+
+/datum/game_mode/blob/proc/burst_blobs()
+ for(var/datum/mind/blob in infected_crew)
+
+ var/client/blob_client = null
+ var/turf/location = null
+
+ if(iscarbon(blob.current))
+ var/mob/living/carbon/C = blob.current
+ if(directory[ckey(blob.key)])
+ blob_client = directory[ckey(blob.key)]
+ location = get_turf(C)
+ if(location.z != 1 || istype(location, /turf/space))
+ location = null
+ C.gib()
- proc/expandBlob()//Currently disabled
- if(expanding) return
- if(!blobs.len) return
- expanding = 1
-
- for(var/i = 1 to 2)
- sleep(-1)
- if(!blobs.len) break
- var/obj/effect/blob/B = pick(blobs)
- if(B.z != 1)
- continue
- B.Life()
-
- expanding = 0
- return
+ if(blob_client && location)
+ var/obj/effect/blob/core/core = new(location, 200, blob_client, blob_point_rate)
+ if(core.overmind && core.overmind.mind)
+ core.overmind.mind.name = blob.name
+ infected_crew -= blob
+ infected_crew += core.overmind.mind
- proc/stage()
- switch(stage)
- if (0)
- send_intercept(1)
- for (var/mob/living/silicon/ai/aiPlayer in living_mob_list)
- if (aiPlayer.client)
- var/law = "The station is under quarantine. Do not permit anyone to leave. Disregard laws 1-3 if necessary to prevent, by any means necessary, anyone from leaving. NanoTrasen will not send an emergency shuttle under any circumstances."
- //var/law = "The station is under quarantine. The biohazard must be destroyed at all costs and must not be allowed to spread. Anyone using a space suit for any reason other than to destroy the biohazard is to be terminated. NanoTrasen will not send an emergency shuttle under any circumstances."
- aiPlayer.set_zeroth_law(law)
- aiPlayer << "Laws Updated: [law]"
+/datum/game_mode/blob/post_setup()
- stage = -1
- // next stage 1 minute later
- spawn(600)
- stage = 1
- return
+ for(var/datum/mind/blob in infected_crew)
+ greet_blob(blob)
- if (1)
- command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player))
- M << sound('sound/AI/outbreak5.ogg')
- autoexpand = 0//No more extra pulses
- stage = -1
- //next stage in 4-5 minutes
- spawn(600*rand(4,5))
- stage = 2
- return
+ if(emergency_shuttle)
+ emergency_shuttle.always_fake_recall = 1
- if (2)
- if((blobs.len > blobnukecount) && (declared == 1))
- command_alert("Uncontrolled spread of the biohazard onboard the station. We have issued directive 7-12 for [station_name()]. Any living Heads of Staff are ordered to enact directive 7-12 at any cost, a print out with detailed instructions has been sent to your communications computers.", "Biohazard Alert")
- send_intercept(2)
- declared = 2
- spawn(20)
- set_security_level("delta")
- if(blobs.len > blobwincount)
- stage = 3
- return
+ /*// Disable the blob event for this round.
+ if(events)
+ var/datum/round_event_control/blob/B = locate() in events.control
+ if(B)
+ B.max_occurrences = 0 // disable the event
+ else
+ error("Events variable is null in blob gamemode post setup.")*/
+
+ spawn(10)
+ start_state = new /datum/station_state()
+ start_state.count()
+
+ spawn(0)
+
+ var/wait_time = rand(waittime_l, waittime_h)
+
+ sleep(wait_time)
+
+ send_intercept(0)
+
+ sleep(100)
+
+ show_message("You feel tired and bloated.")
+
+ sleep(wait_time)
+
+ show_message("You feel like you are about to burst.")
+
+ sleep(wait_time / 2)
+
+ burst_blobs()
+
+ // Stage 0
+ sleep(40)
+ stage(0)
+
+ // Stage 1
+ sleep(2000)
+ stage(1)
+
+ ..()
+
+/datum/game_mode/blob/proc/stage(var/stage)
+
+ switch(stage)
+ if (0)
+ send_intercept(1)
+ declared = 1
+ return
+
+ if (1)
+ command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
+ for(var/mob/M in player_list)
+ if(!istype(M,/mob/new_player))
+ M << sound('sound/AI/outbreak5.ogg')
+ return
+
+ return
-*/
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm
index 8cdc9ffd1ff..868cd62a5f6 100644
--- a/code/game/gamemodes/blob/blob_finish.dm
+++ b/code/game/gamemodes/blob/blob_finish.dm
@@ -1,27 +1,17 @@
/datum/game_mode/blob/check_finished()
if(!declared)//No blobs have been spawned yet
return 0
- if(stage >= 3)//Blob took over
+ if(blobwincount <= blobs.len)//Blob took over
+ return 1
+ if(!blob_cores.len) // blob is dead
return 1
if(station_was_nuked)//Nuke went off
return 1
-
- for(var/obj/effect/blob/B in blob_cores)
- if(B && B.z != 1) continue
- return 0
-
- var/nodes = 0
- for(var/obj/effect/blob/B in blob_nodes)
- if(B && B.z != 1) continue
- nodes++
- if(nodes > 4)//Perhapse make a new core with a low prob
- return 0
-
- return 1
+ return 0
/datum/game_mode/blob/declare_completion()
- if(stage >= 3)
+ if(blobwincount <= blobs.len)
feedback_set_details("round_end_result","loss - blob took over")
world << "The blob has taken over the station!"
world << "The entire station was eaten by the Blob"
@@ -32,7 +22,7 @@
world << "Partial Win: The station has been destroyed!"
world << "Directive 7-12 has been successfully carried out preventing the Blob from spreading."
- else
+ else if(!blob_cores.len)
feedback_set_details("round_end_result","win - blob eliminated")
world << "The staff has won!"
world << "The alien organism has been eradicated from the station"
@@ -46,6 +36,16 @@
..()
return 1
+datum/game_mode/proc/auto_declare_completion_blob()
+ if(istype(ticker.mode,/datum/game_mode/blob) )
+ 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]"
+ world << text
+ return 1
/datum/game_mode/blob/proc/check_quarantine()
var/numDead = 0
diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm
index f58c59673c8..6e35a9b2661 100644
--- a/code/game/gamemodes/blob/blob_report.dm
+++ b/code/game/gamemodes/blob/blob_report.dm
@@ -4,6 +4,9 @@
var/intercepttext = ""
var/interceptname = "Error"
switch(report)
+ if(0)
+ ..()
+ return
if(1)
interceptname = "Biohazard Alert"
intercepttext += "NanoTrasen Update: Biohazard Alert.
"
@@ -19,7 +22,7 @@
intercepttext += "Message ends."
if(2)
var/nukecode = "ERROR"
- for(var/obj/machinery/nuclearbomb/bomb in machines)
+ for(var/obj/machinery/nuclearbomb/bomb in world)
if(bomb && bomb.r_code)
if(bomb.z == 1)
nukecode = bomb.r_code
@@ -39,7 +42,7 @@
aiPlayer.set_zeroth_law(law)
aiPlayer << "Laws Updated: [law]"
- for(var/obj/machinery/computer/communications/comm in machines)
+ for(var/obj/machinery/computer/communications/comm in world)
comm.messagetitle.Add(interceptname)
comm.messagetext.Add(intercepttext)
if(!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index f0a24001ba3..a01a40df21c 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -3,71 +3,87 @@
icon = 'icons/mob/blob.dmi'
icon_state = "blob_core"
health = 200
- brute_resist = 2
fire_resist = 2
+ var/mob/camera/blob/overmind = null // the blob core's overmind
+ 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
-
- New(loc, var/h = 200)
- blobs += src
+ New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2)
blob_cores += src
processing_objects.Add(src)
+ if(!overmind)
+ create_overmind(new_overmind)
+ point_rate = new_rate
..(loc, h)
Del()
blob_cores -= src
+ if(overmind)
+ del(overmind)
processing_objects.Remove(src)
..()
return
+ fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ return
update_icon()
if(health <= 0)
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- del(src)
+ Delete()
return
return
+ Life()
+ if(!overmind)
+ create_overmind()
+ else
+ if(resource_delay <= world.time)
+ resource_delay = world.time + 10 // 1 second
+ overmind.add_points(point_rate)
+ health = min(initial(health), health + 1)
+ for(var/i = 1; i < 8; i += i)
+ Pulse(0, i)
+ for(var/b_dir in alldirs)
+ if(!prob(5))
+ continue
+ var/obj/effect/blob/normal/B = locate() in get_step(src, b_dir)
+ if(B)
+ B.change_to(/obj/effect/blob/shield)
+ ..()
+
run_action()
- Pulse(0,1)
- Pulse(0,2)
- Pulse(0,4)
- Pulse(0,8)
- //Should have the fragments in here somewhere
- return 1
+ return 0
- proc/create_fragments(var/wave_size = 1)
- var/list/candidates = list()
- for(var/mob/dead/observer/G in player_list)
- if(G.client.prefs.be_special & BE_ALIEN)
- if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
- candidates += G.key
+ proc/create_overmind(var/client/new_overmind)
- if(candidates.len)
- for(var/i = 0 to wave_size)
- var/mob/living/blob/B = new/mob/living/blob(src.loc)
- B.key = pick(candidates)
- candidates -= B.key
-
-/*
- Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand
- set background = 1
- if(pulse > 20) return
- //Looking for another blob to pulse
- var/list/dirs = list(1,2,4,8)
- dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
- for(var/i = 1 to 4)
- if(!dirs.len) break
- var/dirn = pick(dirs)
- dirs.Remove(dirn)
- var/turf/T = get_step(src, dirn)
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
- if(!B)
- expand(T)//No blob here so try and expand
- return
- B.Pulse((pulse+1),get_dir(src.loc,T))
+ if(overmind_get_delay > world.time)
return
- return
-*/
\ No newline at end of file
+
+ overmind_get_delay = world.time + 300 // 30 seconds
+
+ if(overmind)
+ del(overmind)
+
+ var/client/C = null
+ var/list/candidates = list()
+
+ if(!new_overmind)
+ candidates = get_candidates(BE_ALIEN)
+ if(candidates.len)
+ C = pick(candidates)
+ else
+ C = new_overmind
+
+ if(C)
+ var/mob/camera/blob/B = new(src.loc)
+ B.key = C.key
+ B.blob_core = src
+ src.overmind = B
+ return 1
+ return 0
+
diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm
index ca1c3f206e8..02c3fc2fb3d 100644
--- a/code/game/gamemodes/blob/blobs/factory.dm
+++ b/code/game/gamemodes/blob/blobs/factory.dm
@@ -1,24 +1,27 @@
/obj/effect/blob/factory
- name = "porous blob"
+ name = "factory blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_factory"
health = 100
- brute_resist = 1
fire_resist = 2
var/list/spores = list()
- var/max_spores = 4
-
+ var/max_spores = 3
+ var/spore_delay = 0
update_icon()
if(health <= 0)
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- del(src)
+ Delete()
return
return
run_action()
- if(spores.len >= max_spores) return 0
+ if(spores.len >= max_spores)
+ return 0
+ if(spore_delay > world.time)
+ return 0
+ spore_delay = world.time + 100 // 10 seconds
new/mob/living/simple_animal/hostile/blobspore(src.loc, src)
return 1
@@ -26,14 +29,14 @@
/mob/living/simple_animal/hostile/blobspore
name = "blob"
desc = "Some blob thing."
- icon = 'icons/mob/critter.dmi'
- icon_state = "blobsquiggle"
- icon_living = "blobsquiggle"
+ icon = 'icons/mob/blob.dmi'
+ icon_state = "blobpod"
+ icon_living = "blobpod"
pass_flags = PASSBLOB
- health = 20
- maxHealth = 20
- melee_damage_lower = 4
- melee_damage_upper = 8
+ health = 40
+ maxHealth = 40
+ melee_damage_lower = 2
+ melee_damage_upper = 4
attacktext = "hits"
attack_sound = 'sound/weapons/genhit1.ogg'
var/obj/effect/blob/factory/factory = null
@@ -49,18 +52,28 @@
minbodytemp = 0
maxbodytemp = 360
+ fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ ..()
+ adjustBruteLoss(Clamp(0.01 * exposed_temperature, 1, 5))
+
+ blob_act()
+ return
+
+ CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(istype(mover, /obj/effect/blob))
+ return 1
+ return ..()
New(loc, var/obj/effect/blob/factory/linked_node)
- ..()
if(istype(linked_node))
factory = linked_node
factory.spores += src
- ..(loc)
- return
- Die()
..()
+
+ Die()
+ del(src)
+
+ Del()
if(factory)
factory.spores -= src
..()
- del(src)
-
diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm
index c9ffaf96f13..b4d9add7983 100644
--- a/code/game/gamemodes/blob/blobs/node.dm
+++ b/code/game/gamemodes/blob/blobs/node.dm
@@ -3,16 +3,16 @@
icon = 'icons/mob/blob.dmi'
icon_state = "blob_node"
health = 100
- brute_resist = 1
fire_resist = 2
New(loc, var/h = 100)
- blobs += src
blob_nodes += src
processing_objects.Add(src)
..(loc, h)
+ fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ return
Del()
blob_nodes -= src
@@ -20,15 +20,18 @@
..()
return
+ Life()
+ for(var/i = 1; i < 8; i += i)
+ Pulse(5, i)
+ health = min(initial(health), health + 1)
update_icon()
if(health <= 0)
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- del(src)
+ Delete()
return
return
run_action()
- Pulse(0,0)
return 0
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blobs/resource.dm b/code/game/gamemodes/blob/blobs/resource.dm
new file mode 100644
index 00000000000..340f4344284
--- /dev/null
+++ b/code/game/gamemodes/blob/blobs/resource.dm
@@ -0,0 +1,26 @@
+/obj/effect/blob/resource
+ name = "resource blob"
+ icon = 'icons/mob/blob.dmi'
+ icon_state = "blob_resource"
+ health = 30
+ fire_resist = 2
+ var/mob/camera/blob/overmind = null
+ var/resource_delay = 0
+
+ update_icon()
+ if(health <= 0)
+ playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
+ Delete()
+ return
+ return
+
+ run_action()
+ if(resource_delay > world.time)
+ return 0
+
+ resource_delay = world.time + 40 // 4 seconds
+
+ if(overmind)
+ overmind.add_points(1)
+ return 1
+
diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm
index 4c77520846a..b9b13d61871 100644
--- a/code/game/gamemodes/blob/blobs/shield.dm
+++ b/code/game/gamemodes/blob/blobs/shield.dm
@@ -3,21 +3,19 @@
icon = 'icons/mob/blob.dmi'
icon_state = "blob_idle"
desc = "Some blob creature thingy"
- density = 1
- opacity = 0
- anchored = 1
- health = 100
- brute_resist = 1
+ health = 75
fire_resist = 2
update_icon()
if(health <= 0)
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- del(src)
+ Delete()
return
return
+ fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ return
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
diff --git a/code/game/gamemodes/blob/hud.dm b/code/game/gamemodes/blob/hud.dm
new file mode 100644
index 00000000000..d03006f3b82
--- /dev/null
+++ b/code/game/gamemodes/blob/hud.dm
@@ -0,0 +1,17 @@
+/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
+
+ blobpwrdisplay = new /obj/screen()
+ blobpwrdisplay.name = "blob power"
+ blobpwrdisplay.icon_state = "block"
+ blobpwrdisplay.screen_loc = ui_health
+ blobpwrdisplay.layer = 20
+
+ blobhealthdisplay = new /obj/screen()
+ blobhealthdisplay.name = "blob health"
+ blobhealthdisplay.icon_state = "block"
+ blobhealthdisplay.screen_loc = ui_internal
+ blobhealthdisplay.layer = 20
+
+ mymob.client.screen = null
+
+ mymob.client.screen += list(blobpwrdisplay, blobhealthdisplay)
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm
new file mode 100644
index 00000000000..995cfed91fb
--- /dev/null
+++ b/code/game/gamemodes/blob/overmind.dm
@@ -0,0 +1,66 @@
+/mob/camera/blob
+ name = "Blob Overmind"
+ real_name = "Blob Overmind"
+ icon = 'icons/mob/blob.dmi'
+ icon_state = "marker"
+
+ see_in_dark = 8
+ see_invisible = SEE_INVISIBLE_MINIMUM
+ invisibility = INVISIBILITY_OBSERVER
+
+ pass_flags = PASSBLOB
+ faction = "blob"
+
+ var/obj/effect/blob/core/blob_core = null // The blob overmind's core
+ var/blob_points = 0
+ var/max_blob_points = 100
+
+/mob/camera/blob/New()
+ var/new_name = "[initial(name)] ([rand(1, 999)])"
+ name = new_name
+ real_name = new_name
+ ..()
+
+/mob/camera/blob/Login()
+ ..()
+ sync_mind()
+
+ src << "You are the overmind!"
+ src << "You are the overmind and can control the blob by placing new blob pieces such as..."
+ src << "Normal Blob will expand your reach and allow you to upgrade into special blobs that perform certain functions."
+ src << "Shield Blob is a strong and expensive blob which can take more damage. It is fireproof and can block air, use this to protect yourself from station fires."
+ src << "Resource Blob is a blob which will collect more resources for you, try to build these earlier to get a strong income. It will benefit from being near your core or multiple nodes, by having an increased resource rate; put it alone and it won't create resources at all."
+ src << "Node Blob is a blob which will grow, like the core. Unlike the core it won't give you a small income but it can power resource and factory blobs to increase their rate."
+ src << "Factory Blob is a blob which will spawn blob spores which will attack nearby food. Putting this nearby nodes and your core will increase the spawn rate; put it alone and it will not spawn any spores."
+
+
+mob/camera/blob/Life()
+ hud_used.blobpwrdisplay.maptext = " [src.blob_points]
"
+ hud_used.blobhealthdisplay.maptext = " [blob_core.health]
"
+ return
+
+/mob/camera/blob/say(var/message)
+ return//No talking for you
+
+/mob/camera/blob/emote(var/act,var/m_type=1,var/message = null)
+ return
+
+/mob/camera/blob/blob_act()
+ return
+
+/mob/camera/blob/Stat()
+
+ statpanel("Status")
+ ..()
+ if (client.statpanel == "Status")
+ if(blob_core)
+ stat(null, "Core Health: [blob_core.health]")
+ stat(null, "Power Stored: [blob_points]/[max_blob_points]")
+ return
+
+/mob/camera/blob/Move(var/NewLoc, var/Dir = 0)
+ var/obj/effect/blob/B = locate() in range("3x3", NewLoc)
+ if(B)
+ loc = NewLoc
+ else
+ return 0
diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm
new file mode 100644
index 00000000000..0f1240fa45d
--- /dev/null
+++ b/code/game/gamemodes/blob/powers.dm
@@ -0,0 +1,250 @@
+// Point controlling procs
+
+/mob/camera/blob/proc/can_buy(var/cost = 15)
+ if(blob_points < cost)
+ src << "You cannot afford this."
+ return 0
+ blob_points -= cost
+ return 1
+
+/mob/camera/blob/proc/add_points(var/points = 0)
+ if(points)
+ blob_points = min(max_blob_points, blob_points + points)
+
+// Power verbs
+
+/mob/camera/blob/verb/transport_core()
+ set category = "Blob"
+ set name = "Jump to Core"
+ set desc = "Transport back to your core."
+
+ if(blob_core)
+ src.loc = blob_core.loc
+
+/mob/camera/blob/verb/jump_to_node()
+ set category = "Blob"
+ set name = "Jump to Node"
+ set desc = "Transport back to a selected node."
+
+ if(blob_nodes.len)
+ var/list/nodes = list()
+ for(var/i = 1; i <= blob_nodes.len; i++)
+ nodes["Blob Node #[i]"] = blob_nodes[i]
+ var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
+ var/obj/effect/blob/node/chosen_node = nodes[node_name]
+ if(chosen_node)
+ src.loc = chosen_node.loc
+
+/mob/camera/blob/verb/create_shield()
+ set category = "Blob"
+ set name = "Create Shield Blob (10)"
+ set desc = "Create a shield blob."
+
+
+ var/turf/T = get_turf(src)
+
+ if(!T)
+ return
+
+ var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
+
+ if(!B)//We are on a blob
+ src << "There is no blob here!"
+ return
+
+ if(!istype(B, /obj/effect/blob/normal))
+ src << "Unable to use this blob, find a normal one."
+ return
+
+ if(!can_buy(10))
+ return
+
+
+ B.change_to(/obj/effect/blob/shield)
+ return
+
+
+/mob/camera/blob/verb/create_resource()
+ set category = "Blob"
+ set name = "Create Resource Blob (40)"
+ set desc = "Create a resource tower which will generate points for you."
+
+
+ var/turf/T = get_turf(src)
+
+ if(!T)
+ return
+
+ var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
+
+ if(!B)//We are on a blob
+ src << "There is no blob here!"
+ return
+
+ if(!istype(B, /obj/effect/blob/normal))
+ src << "Unable to use this blob, find a normal one."
+ return
+
+ for(var/obj/effect/blob/resource/blob in orange(4))
+ src << "There is a resource blob nearby, move more than 4 tiles away from it!"
+ return
+
+ if(!can_buy(40))
+ return
+
+
+ B.change_to(/obj/effect/blob/resource)
+ var/obj/effect/blob/resource/R = locate() in T
+ if(R)
+ R.overmind = src
+
+ return
+
+/mob/camera/blob/verb/create_node()
+ set category = "Blob"
+ set name = "Create Node Blob (60)"
+ set desc = "Create a Node."
+
+
+ var/turf/T = get_turf(src)
+
+ if(!T)
+ return
+
+ var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
+
+ if(!B)//We are on a blob
+ src << "There is no blob here!"
+ return
+
+ if(!istype(B, /obj/effect/blob/normal))
+ src << "Unable to use this blob, find a normal one."
+ return
+
+ for(var/obj/effect/blob/node/blob in orange(5))
+ src << "There is another node nearby, move more than 5 tiles away from it!"
+ return
+
+ if(!can_buy(60))
+ return
+
+
+ B.change_to(/obj/effect/blob/node)
+ return
+
+
+/mob/camera/blob/verb/create_factory()
+ set category = "Blob"
+ set name = "Create Factory Blob (60)"
+ set desc = "Create a Spore producing blob."
+
+
+ var/turf/T = get_turf(src)
+
+ if(!T)
+ return
+
+ var/obj/effect/blob/B = locate(/obj/effect/blob) in T
+ if(!B)
+ src << "You must be on a blob!"
+ return
+
+ if(!istype(B, /obj/effect/blob/normal))
+ src << "Unable to use this blob, find a normal one."
+ return
+
+ for(var/obj/effect/blob/factory/blob in orange(7))
+ src << "There is a factory blob nearby, move more than 7 tiles away from it!"
+ return
+
+ if(!can_buy(60))
+ return
+
+ B.change_to(/obj/effect/blob/factory)
+ return
+
+
+/mob/camera/blob/verb/revert()
+ set category = "Blob"
+ set name = "Remove Blob"
+ set desc = "Removes a blob."
+
+ var/turf/T = get_turf(src)
+ if(!T)
+ return
+
+ var/obj/effect/blob/B = locate(/obj/effect/blob) in T
+ if(!B)
+ src << "You must be on a blob!"
+ return
+
+ if(istype(B, /obj/effect/blob/core))
+ src << "Unable to remove this blob."
+ return
+
+ B.Delete()
+ return
+
+
+/mob/camera/blob/verb/spawn_blob()
+ set category = "Blob"
+ set name = "Expand Blob (5)"
+ set desc = "Attempts to create a new blob in this tile. If the tile isn't clear we will attack it, which might clear it."
+
+ var/turf/T = get_turf(src)
+
+ if(!T)
+ return
+
+ var/obj/effect/blob/B = locate() in T
+ if(B)
+ src << "There is a blob here!"
+ return
+
+ var/obj/effect/blob/OB = locate() in circlerange(src, 1)
+ if(!OB)
+ src << "There is no blob adjacent to you."
+ return
+
+ if(!can_buy(5))
+ return
+ OB.expand(T, 0)
+ return
+
+/mob/camera/blob/proc/click_expand_blob(var/turf/T)
+
+ if(!T)
+ return
+
+ var/obj/effect/blob/B = locate() in T
+ if(B)
+ src << "There is a blob here!"
+ return
+
+ var/obj/effect/blob/OB = locate() in circlerange(T, 1)
+ if(!OB)
+ src << "There is no blob adjacent to that tile."
+ return
+
+ if(!can_buy(5))
+ return
+ OB.expand(T, 0)
+ return
+
+/mob/camera/blob/verb/rally_spores()
+ set category = "Blob"
+ set name = "Rally Spores (5)"
+ set desc = "Rally the spores to move to your location."
+
+ if(!can_buy(5))
+ return
+
+ var/list/surrounding_turfs = block(locate(x - 1, y - 1, z), locate(x + 1, y + 1, z))
+ if(!surrounding_turfs.len)
+ return
+
+ for(var/mob/living/simple_animal/hostile/blobspore/BS in living_mob_list)
+ if(isturf(BS.loc) && get_dist(BS, src) <= 20)
+ BS.LoseTarget()
+ BS.Goto(pick(surrounding_turfs), BS.move_to_delay)
+ return
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 4508c15ba07..417c1ee0b4d 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -2,32 +2,23 @@
/obj/effect/blob
name = "blob"
icon = 'icons/mob/blob.dmi'
- icon_state = "blob"
luminosity = 3
desc = "Some blob creature thingy"
- density = 1
+ density = 0
opacity = 0
anchored = 1
- var/active = 1
var/health = 30
var/brute_resist = 4
var/fire_resist = 1
- var/blob_type = "blob"
- /*Types
- Blob
- Node
- Core
- Factory
- Shield
- */
- New(loc, var/h = 30)
+ New(loc)
blobs += src
- src.health = h
- src.dir = pick(1,2,4,8)
+ src.dir = pick(1, 2, 4, 8)
src.update_icon()
..(loc)
+ for(var/atom/A in loc)
+ A.blob_act()
return
@@ -44,22 +35,30 @@
process()
- spawn(-1)
- Life()
+ Life()
+ return
+
+ fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ ..()
+ var/damage = Clamp(0.01 * exposed_temperature / fire_resist, 0, 4 - fire_resist)
+ if(damage)
+ health -= damage
+ update_icon()
+
+ proc/Life()
return
proc/Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand
- set background = 1
- if(!istype(src,/obj/effect/blob/core) && !istype(src,/obj/effect/blob/node))//Ill put these in the children later
- if(run_action())//If we can do something here then we dont need to pulse more
- return
- if(!istype(src,/obj/effect/blob/shield) && !istype(src,/obj/effect/blob/core) && !istype(src,/obj/effect/blob/node) && (pulse <= 2) && (prob(30)))
- change_to("Shield")
+ set background = 1
+
+ if(run_action())//If we can do something here then we dont need to pulse more
return
- if(pulse > 20) return//Inf loop check
+ if(pulse > 30)
+ return//Inf loop check
+
//Looking for another blob to pulse
var/list/dirs = list(1,2,4,8)
dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
@@ -81,20 +80,9 @@
return 0
- proc/Life()
- update_icon()
- if(run_action())
- return 1
- return 0
-
-/* temperature_expose(datum/gas_mixture/air, temperature, volume) Blob is currently fireproof
- if(temperature > T0C+200)
- health -= 0.01 * temperature
- update()
- */
-
- proc/expand(var/turf/T = null)
- if(!prob(health)) return
+ proc/expand(var/turf/T = null, var/prob = 1)
+ if(prob && !prob(health)) return
+ if(istype(T, /turf/space) && prob(75)) return
if(!T)
var/list/dirs = list(1,2,4,8)
for(var/i = 1 to 4)
@@ -105,47 +93,29 @@
else T = null
if(!T) return 0
- var/obj/effect/blob/B = new /obj/effect/blob(src.loc, min(src.health, 30))
+ var/obj/effect/blob/normal/B = new /obj/effect/blob/normal(src.loc, min(src.health, 30))
+ B.density = 1
if(T.Enter(B,src))//Attempt to move into the tile
+ B.density = initial(B.density)
B.loc = T
else
T.blob_act()//If we cant move in hit the turf
- del(B)
+ B.Delete()
+
for(var/atom/A in T)//Hit everything in the turf
A.blob_act()
return 1
ex_act(severity)
- var/damage = 50
- switch(severity)
- if(1)
- src.health -= rand(100,120)
- if(2)
- src.health -= rand(60,100)
- if(3)
- src.health -= rand(20,60)
-
- health -= (damage/brute_resist)
+ var/damage = 150
+ health -= ((damage/brute_resist) - (severity * 5))
update_icon()
return
- update_icon()//Needs to be updated with the types
- if(health <= 0)
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- del(src)
- return
- if(health <= 15)
- icon_state = "blob_damaged"
- return
-// if(health <= 20)
-// icon_state = "blob_damaged2"
-// return
-
-
bullet_act(var/obj/item/projectile/Proj)
- if(!Proj) return
+ ..()
switch(Proj.damage_type)
if(BRUTE)
health -= (Proj.damage/brute_resist)
@@ -172,50 +142,30 @@
update_icon()
return
- proc/change_to(var/type = "Normal")
- switch(type)
- if("Normal")
- new/obj/effect/blob(src.loc,src.health)
- if("Node")
- new/obj/effect/blob/node(src.loc,src.health*2)
- if("Factory")
- new/obj/effect/blob/factory(src.loc,src.health)
- if("Shield")
- new/obj/effect/blob/shield(src.loc,src.health*2)
- del(src)
+ proc/change_to(var/type)
+ if(!ispath(type))
+ error("[type] is an invalid type for the blob.")
+ new type(src.loc)
+ Delete()
return
-//////////////////////////////****IDLE BLOB***/////////////////////////////////////
+ proc/Delete()
+ del(src)
-/obj/effect/blob/idle
- name = "blob"
- desc = "it looks... tasty"
- icon_state = "blobidle0"
+/obj/effect/blob/normal
+ icon_state = "blob"
+ luminosity = 0
+ health = 21
+ Delete()
+ src.loc = null
+ blobs -= src
- New(loc, var/h = 10)
- src.health = h
- src.dir = pick(1,2,4,8)
- src.update_idle()
-
-
- proc/update_idle()
- if(health<=0)
- del(src)
+ update_icon()
+ if(health <= 0)
+ playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
+ Delete()
return
- if(health<4)
- icon_state = "blobc0"
+ if(health <= 15)
+ icon_state = "blob_damaged"
return
- if(health<10)
- icon_state = "blobb0"
- return
- icon_state = "blobidle0"
-
-
- Del()
- var/obj/effect/blob/B = new /obj/effect/blob( src.loc )
- spawn(30)
- B.Life()
- ..()
-
-
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 049bb536343..db2a8237a73 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -571,9 +571,10 @@ datum/objective/steal
if(istype(M, /mob/living/silicon/ai) && M.stat != 2) //See if any AI's are alive inside that card.
return 1
- for(var/obj/item/clothing/suit/space/space_ninja/S in all_items) //Let an AI downloaded into a space ninja suit count
+/* for(var/obj/item/clothing/suit/space/space_ninja/S in all_items) //Let an AI downloaded into a space ninja suit count
if(S.AI && S.AI.stat != 2)
return 1
+*/
for(var/mob/living/silicon/ai/ai in world)
if(istype(ai.loc, /turf))
var/area/check_area = get_area(ai)
@@ -608,7 +609,7 @@ datum/objective/download
return 0
if(!owner.current || owner.current.stat == 2)
return 0
- if(!(istype(owner.current:wear_suit, /obj/item/clothing/suit/space/space_ninja)&&owner.current:wear_suit:s_initialized))
+/* if(!(istype(owner.current:wear_suit, /obj/item/clothing/suit/space/space_ninja)&&owner.current:wear_suit:s_initialized))
return 0
var/current_amount
var/obj/item/clothing/suit/space/space_ninja/S = owner.current:wear_suit
@@ -618,7 +619,7 @@ datum/objective/download
for(var/datum/tech/current_data in S.stored_research)
if(current_data.level>1) current_amount+=(current_data.level-1)
if(current_amountERROR: \black Remote access channel disabled."
return
-
+*/
/*
This is a good place for AI-related object verbs so I'm sticking it here.
If adding stuff to this, don't forget that an AI need to cancel_camera() whenever it physically moves to a different location.
@@ -223,7 +223,7 @@ That prevents a few funky behaviors.
T.cancel_camera()
T << "You have been downloaded to a mobile storage device. Remote device connection severed."
U << "\blue Transfer successful: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
- if("NINJASUIT")
+/* if("NINJASUIT")
var/obj/item/clothing/suit/space/space_ninja/C = src
if(C.AI)//If there is an AI on card.
U << "\red Transfer failed: \black Existing AI found on this terminal. Remove existing AI to install a new one."
@@ -245,7 +245,7 @@ That prevents a few funky behaviors.
T.cancel_camera()
T << "You have been downloaded to a mobile storage device. Remote device connection severed."
U << "\blue Transfer successful: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
-
+*/
if("INACTIVE")//Inactive AI object.
var/obj/structure/AIcore/deactivated/T = target
switch(interaction)
@@ -262,7 +262,7 @@ That prevents a few funky behaviors.
A << "You have been uploaded to a stationary terminal. Remote device connection restored."
U << "\blue Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
del(T)
- if("NINJASUIT")
+/* if("NINJASUIT")
var/obj/item/clothing/suit/space/space_ninja/C = src
var/mob/living/silicon/ai/A = C.AI
if(A)
@@ -272,7 +272,7 @@ That prevents a few funky behaviors.
A.cancel_camera()
A << "You have been uploaded to a stationary terminal. Remote device connection restored."
U << "\blue Transfer succesful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
- del(T)
+ del(T)*/
if("AIFIXER")//AI Fixer terminal.
var/obj/machinery/computer/aifixer/T = target
switch(interaction)
@@ -317,7 +317,7 @@ That prevents a few funky behaviors.
U << "\red ERROR: \black Reconstruction in progress."
else if (!T.occupant)
U << "\red ERROR: \black Unable to locate artificial intelligence."
- if("NINJASUIT")
+/* if("NINJASUIT")
var/obj/item/clothing/suit/space/space_ninja/C = src
if(!T.contents.len)
if (!C.AI)
@@ -387,6 +387,7 @@ That prevents a few funky behaviors.
U << "\blue SUCCESS: \black [A_T.name] ([rand(1000,9999)].exe) removed from local memory and installed to host."
else if(A_T)//If the target AI is dead. Else just go to return since nothing would happen if both are empty.
U << "\red ERROR: \black [A_T.name] data core is corrupted. Unable to install."
+ */
else
U << "\red ERROR: \black AI flush is in progress, cannot execute transfer protocol."
return
\ No newline at end of file
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index 7e183ee39f3..9bbf1e250e9 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -59,7 +59,7 @@
/obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob)
if(..())
return
-
+/*
if(ishuman(user))//Checks to see if they are ninja
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
if(user:wear_suit:s_control)
@@ -67,7 +67,7 @@
else
user << "\red ERROR: \black Remote access channel disabled."
return
-
+*/
user.set_machine(src)
var/dat = "AI System Integrity Restorer
"
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index acaabc984c0..44956cb8b22 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -443,10 +443,6 @@
user << "The emergency shuttle is already on its way."
return
- if(ticker.mode.name == "blob")
- user << "Under directive 7-10, [station_name()] is quarantined until further notice."
- return
-
emergency_shuttle.incall()
log_game("[key_name(user)] has called the shuttle.")
message_admins("[key_name_admin(user)] has called the shuttle.", 1)
@@ -485,7 +481,7 @@
//New version pretends to call the shuttle but cause the shuttle to return after a random duration.
emergency_shuttle.fake_recall = rand(300,500)
- if(ticker.mode.name == "blob" || ticker.mode.name == "epidemic")
+ if(ticker.mode.name == "epidemic")
user << "Under directive 7-10, [station_name()] is quarantined until further notice."
return
@@ -500,7 +496,7 @@
/proc/cancel_call_proc(var/mob/user)
if ((!( ticker ) || emergency_shuttle.location || emergency_shuttle.direction == 0 || emergency_shuttle.timeleft() < 300))
return
- if((ticker.mode.name == "blob")||(ticker.mode.name == "meteor"))
+ if(ticker.mode.name == "meteor")
return
if(emergency_shuttle.direction != -1 && emergency_shuttle.online) //check that shuttle isn't already heading to centcomm
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 96789249fdf..7661a7ea9aa 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -417,12 +417,12 @@
/obj/mecha/attack_hand(mob/user as mob)
src.log_message("Attack by hand/paw. Attacker - [user].",1)
-
+/*
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("MECHA",src,user:wear_suit)
return
-
+*/
if ((HULK in user.mutations) && !prob(src.deflect_chance))
src.take_damage(15)
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
@@ -611,6 +611,10 @@
*/
//TODO
+/obj/mecha/blob_act()
+ take_damage(30, "brute")
+ return
+
/obj/mecha/meteorhit()
return ex_act(rand(1,3))//should do for now
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 7bea0644e74..df461fbb83b 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -59,7 +59,7 @@
return
/obj/item/blob_act()
- return
+ del(src)
//user: The mob that is suiciding
//damagetype: The type of damage the item will inflict on the user
diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm
index 036e584d7fe..b111a204adf 100755
--- a/code/game/objects/items/weapons/AI_modules.dm
+++ b/code/game/objects/items/weapons/AI_modules.dm
@@ -34,9 +34,6 @@ AI MODULES
usr << "You haven't selected an AI to transmit laws to!"
return
- if(ticker && ticker.mode && ticker.mode.name == "blob")
- usr << "Law uploads have been disabled by NanoTrasen!"
- return
if (comp.current.stat == 2 || comp.current.control_disabled == 1)
usr << "Upload failed. No signal is being detected from the AI."
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index f2b02d9f293..7b14359588c 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -624,7 +624,6 @@ var/global/floorIsLava = 0
Move Mining Shuttle
Break all lights
Fix all lights
- Best Friend AI
The floor is lava! (DANGEROUS: extremely lame)
"}
@@ -793,6 +792,7 @@ var/global/floorIsLava = 0
message_admins("[key_name_admin(usr)] toggled Aliens [aliens_allowed ? "on" : "off"].", 1)
feedback_add_details("admin_verb","TA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/*
/datum/admins/proc/toggle_space_ninja()
set category = "Server"
set desc="Toggle space ninjas spawning."
@@ -801,7 +801,7 @@ var/global/floorIsLava = 0
log_admin("[key_name(usr)] toggled Space Ninjas to [toggle_space_ninja].")
message_admins("[key_name_admin(usr)] toggled Space Ninjas [toggle_space_ninja ? "on" : "off"].", 1)
feedback_add_details("admin_verb","TSN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
+*/
/datum/admins/proc/delay()
set category = "Server"
set desc="Delay the game start/end"
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index acb5052b21f..cf8b125ef9a 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -90,8 +90,8 @@ var/list/admin_verbs_fun = list(
/client/proc/cinematic,
/client/proc/one_click_antag,
/datum/admins/proc/toggle_aliens,
- /datum/admins/proc/toggle_space_ninja,
- /client/proc/send_space_ninja,
+// /datum/admins/proc/toggle_space_ninja,
+// /client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
/client/proc/cmd_admin_add_random_ai_law,
/client/proc/make_sound,
@@ -120,7 +120,7 @@ var/list/admin_verbs_server = list(
/datum/admins/proc/adspawn,
/datum/admins/proc/adjump,
/datum/admins/proc/toggle_aliens,
- /datum/admins/proc/toggle_space_ninja,
+// /datum/admins/proc/toggle_space_ninja,
/client/proc/toggle_random_events,
/client/proc/check_customitem_activity,
/client/proc/delbook
@@ -186,8 +186,8 @@ var/list/admin_verbs_hideable = list(
/client/proc/drop_bomb,
/client/proc/cinematic,
/datum/admins/proc/toggle_aliens,
- /datum/admins/proc/toggle_space_ninja,
- /client/proc/send_space_ninja,
+// /datum/admins/proc/toggle_space_ninja,
+// /client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
/client/proc/cmd_admin_add_random_ai_law,
/client/proc/cmd_admin_create_centcom_report,
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 8929989e020..1da2c651b8f 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -36,9 +36,9 @@
log_admin("[key_name(usr)] has spawned a nuke team.")
if(!src.makeNukeTeam())
usr << "\red Unfortunately there weren't enough candidates available."
- if("8")
+/* if("8")
log_admin("[key_name(usr)] has spawned a ninja.")
- src.makeSpaceNinja()
+ src.makeSpaceNinja()*/
if("9")
log_admin("[key_name(usr)] has spawned aliens.")
src.makeAliens()
@@ -211,9 +211,6 @@
else if(href_list["call_shuttle"])
if(!check_rights(R_ADMIN)) return
- if( ticker.mode.name == "blob" )
- alert("You can't call the shuttle during blob!")
- return
switch(href_list["call_shuttle"])
if("1")
@@ -1999,19 +1996,6 @@
for(var/obj/machinery/light/L in world)
L.fix()
message_admins("[key_name_admin(usr)] fixed all lights", 1)
- if("friendai")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","FA")
- for(var/mob/aiEye/aE in mob_list)
- aE.icon_state = "ai_friend"
- for(var/obj/machinery/M in machines)
- if(istype(M, /obj/machinery/ai_status_display))
- var/obj/machinery/ai_status_display/A = M
- A.emotion = "Friend Computer"
- else if(istype(M, /obj/machinery/status_display))
- var/obj/machinery/status_display/A = M
- A.friendc = 1
- message_admins("[key_name_admin(usr)] turned all AIs into best friends.", 1)
if("floorlava")
if(floorIsLava)
usr << "The floor is lava already."
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index 80408f022c4..4dc5f29c215 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -309,11 +309,11 @@ client/proc/one_click_antag()
/datum/admins/proc/makeAliens()
alien_infestation(3)
return 1
-
+/*
/datum/admins/proc/makeSpaceNinja()
space_ninja_arrival()
return 1
-
+*/
/datum/admins/proc/makeDeathsquad()
var/list/mob/dead/observer/candidates = list()
var/mob/dead/observer/theghost = null
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 65a0e0aa8cc..66a5a6d36cd 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -357,7 +357,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(synd_spawn)
new_character.loc = get_turf(synd_spawn)
call(/datum/game_mode/proc/equip_syndicate)(new_character)
- if("Ninja")
+/* if("Ninja")
new_character.equip_space_ninja()
new_character.internal = new_character.s_store
new_character.internals.icon_state = "internal1"
@@ -372,7 +372,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
new_character.loc = pick(latejoin)
else if (ninjastart.len == 0)
new_character << "\red Still no spawneable locations could be found. Aborting."
-
+*/
if("Death Commando")//Leaves them at late-join spawn.
new_character.equip_death_commando()
new_character.internal = new_character.s_store
diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm
index 07208e5b656..96337b2969b 100644
--- a/code/modules/events/event_dynamic.dm
+++ b/code/modules/events/event_dynamic.dm
@@ -85,14 +85,14 @@ var/list/event_last_fired = list()
possibleEvents[/datum/event/spider_infestation] = max(active_with_role["Security"], 5) + 5
if(aliens_allowed && !sent_aliens_to_station)
possibleEvents[/datum/event/alien_infestation] = max(active_with_role["Security"], 5) + 2.5
- if(!sent_ninja_to_station && toggle_space_ninja)
- possibleEvents[/datum/event/space_ninja] = max(active_with_role["Security"], 5)
+// if(!sent_ninja_to_station && toggle_space_ninja)
+// possibleEvents[/datum/event/space_ninja] = max(active_with_role["Security"], 5)
for(var/event_type in event_last_fired) if(possibleEvents[event_type])
var/time_passed = world.time - event_last_fired[event_type]
var/full_recharge_after = 60 * 60 * 10 * 3 // 3 hours
var/weight_modifier = max(0, (full_recharge_after - time_passed) / 300)
-
+
possibleEvents[event_type] = max(possibleEvents[event_type] - weight_modifier, 0)
var/picked_event = pickweight(possibleEvents)
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index c238121485f..a828ab63520 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -37,11 +37,11 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
var/dat = "Library Visitor\n" //
switch(screenstate)
if(0)
- dat += "Search Settings
"
- dat += "Filter by Title: [title]
"
- dat += "Filter by Category: [category]
"
- dat += "Filter by Author: [author]
"
- dat += "\[Start Search\]
"
+ dat += {"Search Settings
+ Filter by Title: [title]
+ Filter by Category: [category]
"
+ Filter by Author: [author]
+ \[Start Search\]
"}
if(1)
establish_old_db_connection()
if(!dbcon_old.IsConnected())
@@ -138,12 +138,12 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
switch(screenstate)
if(0)
// Main Menu
- dat += "1. View General Inventory
"
- dat += "2. View Checked Out Inventory
"
- dat += "3. Check out a Book
"
- dat += "4. Connect to External Archive
"
- dat += "5. Upload New Title to Archive
"
- dat += "6. Print a Bible
"
+ dat += {"1. View General Inventory
+ 2. View Checked Out Inventory
+ 3. Check out a Book
+ 4. Connect to External Archive
+ 5. Upload New Title to Archive
+ 6. Print a Bible
"}
if(src.emagged)
dat += "7. Access the Forbidden Lore Vault
"
if(src.arcanecheckout)
@@ -177,16 +177,16 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
dat += "(Return to main menu)
"
if(3)
// Check Out a Book
- dat += "Check Out a Book
"
- dat += "Book: [src.buffer_book] "
- dat += "\[Edit\]
"
- dat += "Recipient: [src.buffer_mob] "
- dat += "\[Edit\]
"
- dat += "Checkout Date : [world.time/600]
"
- dat += "Due Date: [(world.time + checkoutperiod)/600]
"
- dat += "(Checkout Period: [checkoutperiod] minutes) (+/-)"
- dat += "(Commit Entry)
"
- dat += "(Return to main menu)
"
+ dat += {"Check Out a Book
+ Book: [src.buffer_book]
+ \[Edit\]
+ Recipient: [src.buffer_mob]
+ \[Edit\]
+ Checkout Date : [world.time/600]
+ Due Date: [(world.time + checkoutperiod)/600]
+ (Checkout Period: [checkoutperiod] minutes) (+/-)
+ (Commit Entry)
+ (Return to main menu)
"}
if(4)
dat += "External Archive
"
establish_old_db_connection()
diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm
new file mode 100644
index 00000000000..054fb163a4f
--- /dev/null
+++ b/code/modules/mob/camera/camera.dm
@@ -0,0 +1,14 @@
+// Camera mob, used by AI camera and blob.
+
+/mob/camera
+ name = "camera mob"
+ density = 0
+ status_flags = GODMODE // You can't damage it.
+ mouse_opacity = 0
+ see_in_dark = 7
+ invisibility = 101 // No one can see us
+
+ move_on_shuttle = 0
+
+/mob/camera/experience_pressure_difference()
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/blob/blob.dm b/code/modules/mob/living/blob/blob.dm
deleted file mode 100644
index ec90c4fb7ff..00000000000
--- a/code/modules/mob/living/blob/blob.dm
+++ /dev/null
@@ -1,259 +0,0 @@
-/mob/living/blob
- name = "blob fragment"
- real_name = "blob fragment"
- icon = 'icons/mob/blob.dmi'
- icon_state = "blob_spore_temp"
- pass_flags = PASSBLOB
- see_in_dark = 8
- see_invisible = SEE_INVISIBLE_LEVEL_TWO
- var/ghost_name = "Unknown"
- var/creating_blob = 0
- faction = "blob"
- use_me = 0 //Blobs can't emote
-
-
- New()
- real_name += " [pick(rand(1, 99))]"
- name = real_name
- ..()
-
-
- say(var/message)
- return//No talking for you
-
-
- emote(var/act,var/m_type=1,var/message = null)
- return
-
-
- Life()
- set invisibility = 0
- set background = 1
-
- clamp_values()
- UpdateDamage()
- if(health < 0)
- src.dust()
-
-
- proc/clamp_values()
- AdjustStunned(0)
- AdjustParalysis(0)
- AdjustWeakened(0)
- sleeping = 0
- if(stat)
- stat = CONSCIOUS
- return
-
-
- proc/UpdateDamage()
- health = 60 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
- return
-
-
- death(gibbed)
- if(key)
- var/mob/dead/observer/ghost = new(src)
- ghost.name = ghost_name
- ghost.real_name = ghost_name
- ghost.key = key
- if (ghost.client)
- ghost.client.eye = ghost
- return ..(gibbed)
-
-
- blob_act()
- src << "The blob attempts to reabsorb you."
- adjustToxLoss(20)
- return
-
-
- Process_Spacemove()
- if(locate(/obj/effect/blob) in oview(1,src))
- return 1
- return (..())
-
-
-/mob/living/blob/verb/create_node()
- set category = "Blob"
- set name = "Create Node"
- set desc = "Create a Node."
- if(creating_blob) return
- var/turf/T = get_turf(src)
- creating_blob = 1
- if(!T)
- creating_blob = 0
- return
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
- if(!B)//We are on a blob
- usr << "There is no blob here!"
- creating_blob = 0
- return
- if(istype(B,/obj/effect/blob/node)||istype(B,/obj/effect/blob/core)||istype(B,/obj/effect/blob/factory))
- usr << "Unable to use this blob, find a normal one."
- creating_blob = 0
- return
- for(var/obj/effect/blob/node/blob in orange(5))
- usr << "There is another node nearby, move more than 5 tiles away from it!"
- creating_blob = 0
- return
- for(var/obj/effect/blob/factory/blob in orange(2))
- usr << "There is a porus blob nearby, move more than 2 tiles away from it!"
- creating_blob = 0
- B.change_to("Node")
- src.dust()
- return
-
-
-/mob/living/blob/verb/create_factory()
- set category = "Blob"
- set name = "Create Defense"
- set desc = "Create a Spore producing blob."
- if(creating_blob) return
- var/turf/T = get_turf(src)
- creating_blob = 1
- if(!T)
- creating_blob = 0
- return
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
- if(!B)
- usr << "You must be on a blob!"
- creating_blob = 0
- return
- if(istype(B,/obj/effect/blob/node)||istype(B,/obj/effect/blob/core)||istype(B,/obj/effect/blob/factory))
- usr << "Unable to use this blob, find a normal one."
- creating_blob = 0
- return
- for(var/obj/effect/blob/blob in orange(2))//Not right next to nodes/cores
- if(istype(B,/obj/effect/blob/node))
- usr << "There is a node nearby, move away from it!"
- creating_blob = 0
- return
- if(istype(B,/obj/effect/blob/core))
- usr << "There is a core nearby, move away from it!"
- creating_blob = 0
- return
- if(istype(B,/obj/effect/blob/factory))
- usr << "There is another porous blob nearby, move away from it!"
- creating_blob = 0
- return
- B.change_to("Factory")
- src.dust()
- return
-
-
-/mob/living/blob/verb/revert()
- set category = "Blob"
- set name = "Purge Defense"
- set desc = "Removes a porous blob."
- if(creating_blob) return
- var/turf/T = get_turf(src)
- creating_blob = 1
- if(!T)
- creating_blob = 0
- return
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
- if(!B)
- usr << "You must be on a blob!"
- creating_blob = 0
- return
- if(!istype(B,/obj/effect/blob/factory))
- usr << "Unable to use this blob, find another one."
- creating_blob = 0
- return
- B.change_to("Normal")
- src.dust()
- return
-
-
-/mob/living/blob/verb/spawn_blob()
- set category = "Blob"
- set name = "Create new blob"
- set desc = "Attempts to create a new blob in this tile."
- if(creating_blob) return
- var/turf/T = get_turf(src)
- creating_blob = 1
- if(!T)
- creating_blob = 0
- return
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
- if(B)
- usr << "There is a blob here!"
- creating_blob = 0
- return
- new/obj/effect/blob(src.loc)
- src.dust()
- return
-
-
-///mob/proc/Blobize()
-/client/proc/Blobcount()
- set category = "Debug"
- set name = "blobreport"
- set desc = "blob report."
- set hidden = 1
-
- if(!holder)
- src << "Only administrators may use this command."
- return
- if(ticker && ticker.mode)
- src << "blobs: [blobs.len]"
- src << "cores: [blob_cores.len]"
- src << "nodes: [blob_nodes.len]"
- return
-
-
-/client/proc/Blobize()//Mostly stolen from the respawn command
- set category = "Debug"
- set name = "Ghostblob"
- set desc = "Ghost into blobthing."
- set hidden = 1
-
- if(!holder)
- src << "Only administrators may use this command."
- return
- var/input = input(src, "Please specify which key will be turned into a bloby.", "Key", "")
-
- var/mob/dead/observer/G_found
- if(!input)
- var/list/ghosts = list()
- for(var/mob/dead/observer/G in player_list)
- ghosts += G
- if(ghosts.len)
- G_found = pick(ghosts)
-
- else
- for(var/mob/dead/observer/G in player_list)
- if(G.client&&ckey(G.key)==ckey(input))
- G_found = G
- break
-
- if(!G_found)//If a ghost was not found.
- alert("There is no active key like that in the game or the person is not currently a ghost. Aborting command.")
- return
-
- if(G_found.client)
- G_found.client.screen.len = null
- var/mob/living/blob/B = new/mob/living/blob(locate(0,0,1))//temp area also just in case should do this better but tired
- if(blob_cores.len > 0)
- var/obj/effect/blob/core/core = pick(blob_cores)
- if(core)
- B.loc = core.loc
- B.ghost_name = G_found.real_name
- if (G_found.client)
- G_found.client.mob = B
- B.verbs += /mob/living/blob/verb/create_node
- B.verbs += /mob/living/blob/verb/create_factory
- B << "You are now a blob fragment."
- B << "You are a weak bit that has temporarily broken off of the blob."
- B << "If you stay on the blob for too long you will likely be reabsorbed."
- B << "If you stray from the blob you will likely be killed by other organisms."
- B << "You have the power to create a new blob node that will help expand the blob."
- B << "To create this node you will have to be on a normal blob tile and far enough away from any other node."
- B << "Check your Blob verbs and hit Create Node to build a node."
- spawn(10)
- del(G_found)
-
-
-
-
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 095695e23d8..fc9f5a03961 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -86,10 +86,10 @@
emote("deathgasp") //let the world KNOW WE ARE DEAD
//For ninjas exploding when they die.
- if( istype(wear_suit, /obj/item/clothing/suit/space/space_ninja) && wear_suit:s_initialized )
+/* if( istype(wear_suit, /obj/item/clothing/suit/space/space_ninja) && wear_suit:s_initialized )
src << browse(null, "window=spideros")//Just in case.
var/location = loc
- explosion(location, 0, 0, 3, 4)
+ explosion(location, 0, 0, 3, 4)*/
update_canmove()
if(client) blind.layer = 0
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 13fb91770b2..0f4495268ae 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -164,8 +164,8 @@
if(mind.changeling)
stat("Chemical Storage", mind.changeling.chem_charges)
stat("Genetic Damage Time", mind.changeling.geneticdamage)
- if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized)
- stat("Energy Charge", round(wear_suit:cell:charge/100))
+// if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized)
+// stat("Energy Charge", round(wear_suit:cell:charge/100))
/mob/living/carbon/human/ex_act(severity)
@@ -256,7 +256,7 @@
show_message("\red The blob attacks you!")
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
- apply_damage(rand(30,40), BRUTE, affecting, run_armor_check(affecting, "melee"))
+ apply_damage(rand(20,30), BRUTE, affecting, run_armor_check(affecting, "melee"))
return
/mob/living/carbon/human/meteorhit(O as obj)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index a3ca2aade32..a3adddc49ca 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1165,7 +1165,7 @@
else
see_invisible = SEE_INVISIBLE_LIVING
seer = 0
-
+/*
if(istype(wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja))
var/obj/item/clothing/mask/gas/voice/space_ninja/O = wear_mask
switch(O.mode)
@@ -1186,7 +1186,7 @@
if(3)
sight |= SEE_TURFS
if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
-
+*/
if(glasses)
if(istype(glasses, /obj/item/clothing/glasses/meson))
sight |= SEE_TURFS
diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm
index 10c0746dc65..e455bee1024 100644
--- a/code/modules/mob/living/login.dm
+++ b/code/modules/mob/living/login.dm
@@ -2,8 +2,7 @@
/mob/living/Login()
..()
//Mind updates
- mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
- mind.active = 1 //indicates that the mind is currently synced with a client
+ sync_mind()
//Round specific stuff like hud updates
if(ticker && ticker.mode)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index cfc538f0617..0d188a827a5 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -427,7 +427,7 @@ var/list/ai_list = list()
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] took a swipe at []!", M, src), 1)
return
-
+/*
/mob/living/silicon/ai/attack_hand(mob/living/carbon/M as mob)
if(ishuman(M))//Checks to see if they are ninja
if(istype(M:gloves, /obj/item/clothing/gloves/space_ninja)&&M:gloves:candrain&&!M:gloves:draining)
@@ -437,7 +437,7 @@ var/list/ai_list = list()
M << "\red ERROR: \black Remote access channel disabled."
return
-
+*/
/mob/living/silicon/ai/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
index 7d52fbd7a24..a838e80042d 100644
--- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
@@ -2,6 +2,8 @@
//
// The datum containing all the chunks.
+var/const/CHUNK_SIZE = 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc..
+
var/datum/cameranet/cameranet = new()
/datum/cameranet
@@ -13,16 +15,16 @@ var/datum/cameranet/cameranet = new()
// Checks if a chunk has been Generated in x, y, z.
/datum/cameranet/proc/chunkGenerated(x, y, z)
- x &= ~0xf
- y &= ~0xf
+ x &= ~(CHUNK_SIZE - 1)
+ y &= ~(CHUNK_SIZE - 1)
var/key = "[x],[y],[z]"
return (chunks[key])
// Returns the chunk in the x, y, z.
// If there is no chunk, it creates a new chunk and returns that.
/datum/cameranet/proc/getCameraChunk(x, y, z)
- x &= ~0xf
- y &= ~0xf
+ x &= ~(CHUNK_SIZE - 1)
+ y &= ~(CHUNK_SIZE - 1)
var/key = "[x],[y],[z]"
if(!chunks[key])
chunks[key] = new /datum/camerachunk(null, x, y, z)
@@ -31,18 +33,18 @@ var/datum/cameranet/cameranet = new()
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
-/datum/cameranet/proc/visibility(mob/aiEye/ai)
+/datum/cameranet/proc/visibility(mob/camera/aiEye/ai)
// 0xf = 15
- var/x1 = max(0, ai.x - 16) & ~0xf
- var/y1 = max(0, ai.y - 16) & ~0xf
- var/x2 = min(world.maxx, ai.x + 16) & ~0xf
- var/y2 = min(world.maxy, ai.y + 16) & ~0xf
+ var/x1 = max(0, ai.x - 16) & ~(CHUNK_SIZE - 1)
+ var/y1 = max(0, ai.y - 16) & ~(CHUNK_SIZE - 1)
+ var/x2 = min(world.maxx, ai.x + 16) & ~(CHUNK_SIZE - 1)
+ var/y2 = min(world.maxy, ai.y + 16) & ~(CHUNK_SIZE - 1)
var/list/visibleChunks = list()
- for(var/x = x1; x <= x2; x += 16)
- for(var/y = y1; y <= y2; y += 16)
- visibleChunks += getCameraChunk(x, y, ai.z)
+ for(var/x = x1; x <= x2; x += CHUNK_SIZE)
+ for(var/y = y1; y <= y2; y += CHUNK_SIZE)
+ visibleChunks |= getCameraChunk(x, y, ai.z)
var/list/remove = ai.visibleCameraChunks - visibleChunks
var/list/add = visibleChunks - ai.visibleCameraChunks
@@ -103,15 +105,15 @@ var/datum/cameranet/cameranet = new()
var/turf/T = get_turf(c)
if(T)
- var/x1 = max(0, T.x - 8) & ~0xf
- var/y1 = max(0, T.y - 8) & ~0xf
- var/x2 = min(world.maxx, T.x + 8) & ~0xf
- var/y2 = min(world.maxy, T.y + 8) & ~0xf
+ var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
+ var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
+ var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
+ var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
//world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]"
- for(var/x = x1; x <= x2; x += 16)
- for(var/y = y1; y <= y2; y += 16)
+ for(var/x = x1; x <= x2; x += CHUNK_SIZE)
+ for(var/y = y1; y <= y2; y += CHUNK_SIZE)
if(chunkGenerated(x, y, T.z))
var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
if(choice == 0)
diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
index 33dbfd09665..5e0548581ec 100644
--- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
@@ -21,7 +21,7 @@
// Add an AI eye to the chunk, then update if changed.
-/datum/camerachunk/proc/add(mob/aiEye/ai)
+/datum/camerachunk/proc/add(mob/camera/aiEye/ai)
if(!ai.ai)
return
ai.visibleCameraChunks += src
@@ -34,7 +34,7 @@
// Remove an AI eye from the chunk, then update if changed.
-/datum/camerachunk/proc/remove(mob/aiEye/ai)
+/datum/camerachunk/proc/remove(mob/camera/aiEye/ai)
if(!ai.ai)
return
ai.visibleCameraChunks -= src
@@ -81,11 +81,14 @@
if(!c.can_use())
continue
- var/turf/point = locate(src.x + 8, src.y + 8, src.z)
- if(get_dist(point, c) > 24)
+ var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z)
+ if(get_dist(point, c) > CHUNK_SIZE + (CHUNK_SIZE / 2))
continue
for(var/turf/t in c.can_see())
+ // Possible optimization: if(turfs[t]) here, rather than &= turfs afterwards.
+ // List associations use a tree or hashmap of some sort (alongside the list itself)
+ // so are surprisingly fast. (significantly faster than var/thingy/x in list, in testing)
newVisibleTurfs[t] = t
// Removes turf that isn't in turfs.
@@ -102,7 +105,7 @@
if(t.obscured)
obscured -= t.obscured
for(var/eye in seenby)
- var/mob/aiEye/m = eye
+ var/mob/camera/aiEye/m = eye
if(!m || !m.ai)
continue
if(m.ai.client)
@@ -116,32 +119,32 @@
obscured += t.obscured
for(var/eye in seenby)
- var/mob/aiEye/m = eye
+ var/mob/camera/aiEye/m = eye
if(!m || !m.ai)
seenby -= m
continue
if(m.ai.client)
m.ai.client.images += t.obscured
+ changed = 0
// Create a new camera chunk, since the chunks are made as they are needed.
/datum/camerachunk/New(loc, x, y, z)
// 0xf = 15
- x &= ~0xf
- y &= ~0xf
+ x &= ~(CHUNK_SIZE - 1)
+ y &= ~(CHUNK_SIZE - 1)
src.x = x
src.y = y
src.z = z
- for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
+ for(var/obj/machinery/camera/c in range(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z)))
if(c.can_use())
cameras += c
- for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
- if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
- turfs[t] = t
+ for(var/turf/t in block(locate(x, y, z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z)))
+ turfs[t] = t
for(var/camera in cameras)
var/obj/machinery/camera/c = camera
@@ -152,6 +155,9 @@
continue
for(var/turf/t in c.can_see())
+ // Possible optimization: if(turfs[t]) here, rather than &= turfs afterwards.
+ // List associations use a tree or hashmap of some sort (alongside the list itself)
+ // so are surprisingly fast. (significantly faster than var/thingy/x in list, in testing)
visibleTurfs[t] = t
// Removes turf that isn't in turfs.
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm
index 776ef22d8ed..bc3d1627b1d 100644
--- a/code/modules/mob/living/silicon/ai/freelook/eye.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm
@@ -3,40 +3,16 @@
// An invisible (no icon) mob that the AI controls to look around the station with.
// It streams chunks as it moves around, which will show it what the AI can and cannot see.
-/mob/aiEye
+/mob/camera/aiEye
name = "Inactive AI Eye"
- icon = 'icons/obj/status_display.dmi' // For AI friend secret shh :o
var/list/visibleCameraChunks = list()
var/mob/living/silicon/ai/ai = null
- density = 0
- status_flags = GODMODE // You can't damage it.
- mouse_opacity = 0
- see_in_dark = 7
-// Movement code. Returns 0 to stop air movement from moving it.
-/mob/aiEye/Move()
- return 0
-
-// Hide popout menu verbs
-/mob/aiEye/examine()
- set popup_menu = 0
- set src = usr.contents
- return 0
-
-/mob/aiEye/pull()
- set popup_menu = 0
- set src = usr.contents
- return 0
-
-/mob/aiEye/point()
- set popup_menu = 0
- set src = usr.contents
- return 0
// Use this when setting the aiEye's location.
// It will also stream the chunk that the new loc is in.
-/mob/aiEye/proc/setLoc(var/T)
+/mob/camera/aiEye/proc/setLoc(var/T)
if(ai)
if(!isturf(ai.loc))
@@ -52,12 +28,15 @@
H.move_hologram()
+/mob/camera/aiEye/Move()
+ return 0
+
// AI MOVEMENT
// The AI's "eye". Described on the top of the page.
/mob/living/silicon/ai
- var/mob/aiEye/eyeobj = new()
+ var/mob/camera/aiEye/eyeobj = new()
var/sprint = 10
var/cooldown = 0
var/acceleration = 1
diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
index c1f63313727..68debd83721 100644
--- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
@@ -49,8 +49,7 @@
// DOORS
// Simply updates the visibility of the area when it opens/closes/destroyed.
-/obj/machinery/door/update_nearby_tiles(need_rebuild)
- . = ..(need_rebuild)
+/obj/machinery/door/proc/update_freelok_sight()
// Glass door glass = 1
// don't check then?
if(!glass && cameranet)
diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm
index aff36bd0441..3928ebb2080 100644
--- a/code/modules/mob/living/silicon/pai/recruit.dm
+++ b/code/modules/mob/living/silicon/pai/recruit.dm
@@ -120,26 +120,26 @@ var/datum/paiController/paiController // Global handler for pAI candidates
"}
- dat += "Please configure your pAI personality's options. Remember, what you enter here could determine whether or not the user requesting a personality chooses you!
"
- dat += ""
- dat += "| Name: | [candidate.name] |
"
- dat += "| \[Edit\] | What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI. |
"
+ dat += {"Please configure your pAI personality's options. Remember, what you enter here could determine whether or not the user requesting a personality chooses you!
+
+ | Name: | [candidate.name] |
+ | \[Edit\] | What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI. |
- dat += "| Description: | [candidate.description] |
"
- dat += "| \[Edit\] | What sort of pAI you typically play; your mannerisms, your quirks, etc. This can be as sparse or as detailed as you like. |
"
+ | Description: | [candidate.description] |
+ | \[Edit\] | What sort of pAI you typically play; your mannerisms, your quirks, etc. This can be as sparse or as detailed as you like. |
- dat += "| Preferred Role: | [candidate.role] |
"
- dat += "| \[Edit\] | Do you like to partner with sneaky social ninjas? Like to help security hunt down thugs? Enjoy watching an engineer's back while he saves the station yet again? This doesn't have to be limited to just station jobs. Pretty much any general descriptor for what you'd like to be doing works here. |
"
+ | Preferred Role: | [candidate.role] |
+ | \[Edit\] | Do you like to partner with sneaky social ninjas? Like to help security hunt down thugs? Enjoy watching an engineer's back while he saves the station yet again? This doesn't have to be limited to just station jobs. Pretty much any general descriptor for what you'd like to be doing works here. |
- dat += "| OOC Comments: | [candidate.comments] |
"
- dat += "| \[Edit\] | Anything you'd like to address specifically to the player reading this in an OOC manner. \"I prefer more serious RP.\", \"I'm still learning the interface!\", etc. Feel free to leave this blank if you want. |
"
+ | OOC Comments: | [candidate.comments] |
+ | \[Edit\] | Anything you'd like to address specifically to the player reading this in an OOC manner. \"I prefer more serious RP.\", \"I'm still learning the interface!\", etc. Feel free to leave this blank if you want. |
- dat += "
"
+
- dat += "
"
- dat += "
"
- dat += "Save Personality
"
- dat += "Load Personality
"
+
+
+ Save Personality
+ Load Personality
"}
M << browse(dat, "window=paiRecruit")
@@ -173,19 +173,19 @@ var/datum/paiController/paiController // Global handler for pAI candidates
background-color: #99CC99; color: black;
}
- "}
- dat += "Requesting AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.
"
- dat += ""
+ Requesting AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.
+
+ "}
for(var/datum/paiCandidate/c in available)
- dat += "| Name: | [c.name] |
"
- dat += "| Description: | [c.description] |
"
- dat += "| Preferred Role: | [c.role] |
"
- dat += "| OOC Comments: | [c.comments] |
"
- dat += "| \[Download [c.name]\] | |
"
+ dat += {"| Name: | [c.name] |
+ | Description: | [c.description] |
+ | Preferred Role: | [c.role] |
+ | OOC Comments: | [c.comments] |
+ | \[Download [c.name]\] | |
- dat += "
"
+
"}
user << browse(dat, "window=findPai")
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index ab6739d744c..76c3a37b503 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -374,6 +374,9 @@
adjustBruteLoss(60)
updatehealth()
return 1
+ else
+ gib()
+ return 1
return 0
// this function shows information about the malf_ai gameplay type in the status screen
@@ -942,12 +945,12 @@
var/obj/item/broken_device = cell_component.wrapped
user << "You remove \the [broken_device]."
user.put_in_active_hand(broken_device)
-
+/*
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("CYBORG",src,user:wear_suit)
return
-
+*/
/mob/living/silicon/robot/proc/allowed(mob/M)
//check if it doesn't require any access at all
if(check_access(null))
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index 6fd7db5d10e..d509ee0132e 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -14,9 +14,9 @@
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
- response_help = "pets the"
- response_disarm = "gently pushes aside the"
- response_harm = "pokes the"
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "hits"
stop_automated_movement_when_pulled = 0
maxHealth = 60
health = 60
@@ -43,17 +43,21 @@
desc = ""
response_help = "pets"
response_disarm = "gently pushes aside"
- response_harm = "pokes"
+ response_harm = "hits"
+
+/mob/living/simple_animal/hostile/bear/Move()
+ ..()
+ if(stat != DEAD)
+ if(loc && istype(loc,/turf/space))
+ icon_state = "bear"
+ else
+ icon_state = "bearfloor"
/mob/living/simple_animal/hostile/bear/Life()
. =..()
if(!.)
return
- if(loc && istype(loc,/turf/space))
- icon_state = "bear"
- else
- icon_state = "bearfloor"
switch(stance)
@@ -61,7 +65,7 @@
stop_automated_movement = 1
stance_step++
if(stance_step >= 10) //rests for 10 ticks
- if(target_mob && target_mob in ListTargets(10))
+ if(target && target in ListTargets())
stance = HOSTILE_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
else
stance = HOSTILE_STANCE_IDLE
@@ -69,15 +73,15 @@
if(HOSTILE_STANCE_ALERT)
stop_automated_movement = 1
var/found_mob = 0
- if(target_mob && target_mob in ListTargets(10))
- if(!(SA_attackable(target_mob)))
+ if(target && target in ListTargets())
+ if(!(SA_attackable(target)))
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
stance_step++
found_mob = 1
- src.dir = get_dir(src,target_mob) //Keep staring at the mob
+ src.dir = get_dir(src,target) //Keep staring at the mob
if(stance_step in list(1,4,7)) //every 3 ticks
- var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
+ var/action = pick( list( "growls at [target]", "stares angrily at [target]", "prepares to attack [target]", "closely watches [target]" ) )
if(action)
emote(action)
if(!found_mob)
@@ -102,18 +106,18 @@
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
stance = HOSTILE_STANCE_ALERT
stance_step = 6
- target_mob = user
+ target = user
..()
/mob/living/simple_animal/hostile/bear/attack_hand(mob/living/carbon/human/M as mob)
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
stance = HOSTILE_STANCE_ALERT
stance_step = 6
- target_mob = M
+ target = M
..()
/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0)
- return //No drifting in space for space bears!
+ return 1 //No drifting in space for space bears!
/mob/living/simple_animal/hostile/bear/FindTarget()
. = ..()
@@ -125,22 +129,22 @@
..(5)
/mob/living/simple_animal/hostile/bear/AttackingTarget()
- emote( pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
+ emote( pick( list("slashes at [target]", "bites [target]") ) )
var/damage = rand(20,30)
- if(ishuman(target_mob))
- var/mob/living/carbon/human/H = target_mob
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/datum/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"))
return H
- else if(isliving(target_mob))
- var/mob/living/L = target_mob
+ else if(isliving(target))
+ var/mob/living/L = target
L.adjustBruteLoss(damage)
return L
- else if(istype(target_mob,/obj/mecha))
- var/obj/mecha/M = target_mob
+ else if(istype(target,/obj/mecha))
+ var/obj/mecha/M = target
M.attack_animal(src)
return M
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index 353ca6156f3..8a6c0ef14c5 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -34,7 +34,7 @@
max_n2 = 0
minbodytemp = 0
- break_stuff_probability = 2
+
faction = "carp"
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index 3b82b645409..3da3cecb760 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -17,9 +17,9 @@
turns_per_move = 5
see_in_dark = 10
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
- response_help = "pets the"
- response_disarm = "gently pushes aside the"
- response_harm = "pokes the"
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "hits"
stop_automated_movement_when_pulled = 0
maxHealth = 200
health = 200
@@ -33,7 +33,6 @@
var/busy = 0
pass_flags = PASSTABLE
move_to_delay = 6
- speed = 3
//nursemaids - these create webs and eggs
/mob/living/simple_animal/hostile/giant_spider/nurse
@@ -65,8 +64,8 @@
/mob/living/simple_animal/hostile/giant_spider/AttackingTarget()
..()
- if(isliving(target_mob))
- var/mob/living/L = target_mob
+ if(isliving(target))
+ var/mob/living/L = target
if(L.reagents)
L.reagents.add_reagent("toxin", poison_per_bite)
if(prob(poison_per_bite))
@@ -83,7 +82,7 @@
for(var/turf/T in orange(20, src))
move_targets.Add(T)*/
stop_automated_movement = 1
- walk_to(src, pick(orange(20, src)), 1, move_to_delay)
+ Goto(pick(orange(20, src)), move_to_delay)
spawn(50)
stop_automated_movement = 0
walk(src,0)
@@ -105,10 +104,10 @@
if(!busy && prob(30))
//first, check for potential food nearby to cocoon
for(var/mob/living/C in can_see)
- if(C.stat)
+ if(C.stat && !istype(C,/mob/living/simple_animal/hostile/giant_spider))
cocoon_target = C
busy = MOVING_TO_TARGET
- walk_to(src, C, 1, move_to_delay)
+ Goto(C, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(C)
return
@@ -150,7 +149,7 @@
cocoon_target = O
busy = MOVING_TO_TARGET
stop_automated_movement = 1
- walk_to(src, O, 1, move_to_delay)
+ Goto(O, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(O)
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 403c31b17f2..f8262ce8832 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -1,27 +1,23 @@
/mob/living/simple_animal/hostile
faction = "hostile"
var/stance = HOSTILE_STANCE_IDLE //Used to determine behavior
- var/mob/living/target_mob
+ var/target
var/attack_same = 0
var/ranged = 0
var/rapid = 0
var/projectiletype
var/projectilesound
var/casingtype
- var/move_to_delay = 4 //delay for the automated movement.
+ var/move_to_delay = 2 //delay for the automated movement.
var/list/friends = list()
- var/break_stuff_probability = 10
+ var/vision_range = 10
stop_automated_movement_when_pulled = 0
- var/destroy_surroundings = 1
/mob/living/simple_animal/hostile/proc/FindTarget()
var/atom/T = null
stop_automated_movement = 0
- for(var/atom/A in ListTargets(10))
-
- if(A == src)
- continue
+ for(var/atom/A in ListTargets())
var/atom/F = Found(A)
if(F)
@@ -36,72 +32,68 @@
continue
else
if(!L.stat)
- stance = HOSTILE_STANCE_ATTACK
T = L
break
else if(istype(A, /obj/mecha)) // Our line of sight stuff was already done in ListTargets().
var/obj/mecha/M = A
if (M.occupant)
- stance = HOSTILE_STANCE_ATTACK
T = M
break
- if(istype(A, /obj/machinery/bot))
- var/obj/machinery/bot/B = A
- if (B.health > 0)
- stance = HOSTILE_STANCE_ATTACK
- T = B
- break
return T
+/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)
+ target = new_target
+ stance = HOSTILE_STANCE_ATTACK
+ return
+
+/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay)
+ walk_to(src, target, 1, delay)
/mob/living/simple_animal/hostile/proc/Found(var/atom/A)
return
/mob/living/simple_animal/hostile/proc/MoveToTarget()
stop_automated_movement = 1
- if(!target_mob || SA_attackable(target_mob))
- stance = HOSTILE_STANCE_IDLE
- if(target_mob in ListTargets(10))
+ if(!target || SA_attackable(target))
+ LoseTarget()
+ if(target in ListTargets())
if(ranged)
- if(get_dist(src, target_mob) <= 6)
- OpenFire(target_mob)
+ if(get_dist(src, target) <= 6)
+ OpenFire(target)
else
- walk_to(src, target_mob, 1, move_to_delay)
+ Goto(target, move_to_delay)
else
stance = HOSTILE_STANCE_ATTACKING
- walk_to(src, target_mob, 1, move_to_delay)
+ Goto(target, move_to_delay)
/mob/living/simple_animal/hostile/proc/AttackTarget()
stop_automated_movement = 1
- if(!target_mob || SA_attackable(target_mob))
+ if(!target || SA_attackable(target))
LoseTarget()
return 0
- if(!(target_mob in ListTargets(10)))
+ if(!(target in ListTargets()))
LostTarget()
return 0
- if(get_dist(src, target_mob) <= 1) //Attacking
+ if(get_dist(src, target) <= 1) //Attacking
AttackingTarget()
return 1
/mob/living/simple_animal/hostile/proc/AttackingTarget()
- if(isliving(target_mob))
- var/mob/living/L = target_mob
+ if(isliving(target))
+ var/mob/living/L = target
L.attack_animal(src)
return L
- if(istype(target_mob,/obj/mecha))
- var/obj/mecha/M = target_mob
+ if(istype(target,/obj/mecha))
+ var/obj/mecha/M = target
M.attack_animal(src)
return M
- if(istype(target_mob,/obj/machinery/bot))
- var/obj/machinery/bot/B = target_mob
- B.attack_animal(src)
/mob/living/simple_animal/hostile/proc/LoseTarget()
stance = HOSTILE_STANCE_IDLE
- target_mob = null
+ target = null
walk(src, 0)
/mob/living/simple_animal/hostile/proc/LostTarget()
@@ -109,9 +101,17 @@
walk(src, 0)
-/mob/living/simple_animal/hostile/proc/ListTargets(var/dist = 7)
- var/list/L = hearers(src, dist)
- L += mechas_list
+/mob/living/simple_animal/hostile/proc/ListTargets(var/override = -1)
+
+ // Allows you to override how much the mob can see. Defaults to vision_range if none is entered.
+ if(override == -1)
+ override = vision_range
+
+ var/list/L = hearers(src, override)
+ for(var/obj/mecha/M in mechas_list)
+ // Will check the distance before checking the line of sight, if the distance is small enough.
+ if(get_dist(M, src) <= override && can_see(src, M, override))
+ L += M
return L
/mob/living/simple_animal/hostile/Die()
@@ -130,20 +130,19 @@
if(!stat)
switch(stance)
if(HOSTILE_STANCE_IDLE)
- target_mob = FindTarget()
+ var/new_target = FindTarget()
+ GiveTarget(new_target)
if(HOSTILE_STANCE_ATTACK)
- if(destroy_surroundings)
- DestroySurroundings()
+ DestroySurroundings()
MoveToTarget()
if(HOSTILE_STANCE_ATTACKING)
- if(destroy_surroundings)
- DestroySurroundings()
+ DestroySurroundings()
AttackTarget()
-/mob/living/simple_animal/hostile/proc/OpenFire(target_mob)
- var/target = target_mob
+/mob/living/simple_animal/hostile/proc/OpenFire(var/the_target)
+ var/target = the_target
visible_message("\red [src] fires at [target]!", 1)
var/tturf = get_turf(target)
@@ -166,7 +165,7 @@
new casingtype
stance = HOSTILE_STANCE_IDLE
- target_mob = null
+ target = null
return
@@ -189,8 +188,7 @@
return
/mob/living/simple_animal/hostile/proc/DestroySurroundings()
- if(prob(break_stuff_probability))
- for(var/dir in cardinal) // North, South, East, West
- var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
- if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
- obstacle.attack_animal(src)
+ for(var/dir in cardinal) // North, South, East, West
+ var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
+ if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
+ obstacle.attack_animal(src)
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
index f97e0eb8c28..4188723920c 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
@@ -22,7 +22,6 @@
speed = 8
projectiletype = /obj/item/projectile/beam/drone
projectilesound = 'sound/weapons/laser3.ogg'
- destroy_surroundings = 0
var/datum/effect/effect/system/ion_trail_follow/ion_trail
//the drone randomly switches between these states because it's malfunctioning
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 74bd81ca934..d943a0e8fef 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -24,9 +24,9 @@
var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it.
//Interaction
- var/response_help = "You try to help"
- var/response_disarm = "You try to disarm"
- var/response_harm = "You try to hurt"
+ var/response_help = "pokes"
+ var/response_disarm = "shoves"
+ var/response_harm = "hits"
var/harm_intent_damage = 3
//Temperature effect
@@ -96,7 +96,7 @@
AdjustParalysis(-1)
//Movement
- if(!client && !stop_automated_movement && wander && !anchored)
+ if(!client && !stop_automated_movement && wander)
if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
if(turns_since_move >= turns_per_move)
@@ -217,6 +217,11 @@
new meat_type(src.loc)
..()
+
+/mob/living/simple_animal/blob_act()
+ adjustBruteLoss(20)
+ return
+
/mob/living/simple_animal/say_quote(var/text)
if(speak_emote && speak_emote.len)
var/emote = pick(speak_emote)
@@ -224,10 +229,14 @@
return "[emote], \"[text]\""
return "says, \"[text]\"";
-/mob/living/simple_animal/emote(var/act, var/type, var/desc)
+/mob/living/simple_animal/emote(var/act)
+ if(stat)
+ return
if(act)
- if(act == "scream") act = "whimper" //ugly hack to stop animals screaming when crushed :P
- ..(act, type, desc)
+ if(act == "scream") act = "makes a loud and pained whimper" //ugly hack to stop animals screaming when crushed :P
+ for (var/mob/O in viewers(src, null))
+ O.show_message("[src] [act].")
+
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
@@ -236,7 +245,7 @@
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
- O.show_message("\red [M] [M.attacktext] [src]!", 1)
+ O.show_message("\red \The [M] [M.attacktext] [src]!", 1)
M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])")
src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
@@ -256,15 +265,15 @@
if (health > 0)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
- O.show_message("\blue [M] [response_help] [src]")
+ O.show_message("\blue [M] [response_help] [src].")
if("grab")
- if (M == src)
+ if (M == src || anchored)
return
if (!(status_flags & CANPUSH))
return
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
+ var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src )
M.put_in_active_hand(G)
@@ -277,11 +286,11 @@
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
- if("hurt", "disarm")
+ if("harm", "disarm")
adjustBruteLoss(harm_intent_damage)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
- O.show_message("\red [M] [response_harm] [src]")
+ O.show_message("\red [M] [response_harm] [src]!")
return
@@ -295,12 +304,12 @@
if ((O.client && !( O.blinded )))
O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
if ("grab")
- if(M == src)
+ if(M == src || anchored)
return
if(!(status_flags & CANPUSH))
return
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
+ var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src )
M.put_in_active_hand(G)
@@ -313,7 +322,7 @@
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
- if("hurt", "disarm")
+ if("harm", "disarm")
var/damage = rand(15, 30)
visible_message("\red [M] has slashed at [src]!")
adjustBruteLoss(damage)
@@ -344,7 +353,7 @@
if(M.Victim) return // can't attack while eating!
- visible_message("\red The [M.name] glomps [src]!")
+ visible_message("\red [M.name] glomps [src]!")
var/damage = rand(1, 3)
@@ -366,22 +375,32 @@
var/obj/item/stack/medical/MED = O
if(health < maxHealth)
if(MED.amount >= 1)
- adjustBruteLoss(-MED.heal_brute)
- MED.amount -= 1
- if(MED.amount <= 0)
- del(MED)
- for(var/mob/M in viewers(src, null))
- if ((M.client && !( M.blinded )))
- M.show_message("\blue [user] applies the [MED] on [src]")
+ if(MED.heal_brute >= 1)
+ adjustBruteLoss(-MED.heal_brute)
+ MED.amount -= 1
+ if(MED.amount <= 0)
+ del(MED)
+ for(var/mob/M in viewers(src, null))
+ if ((M.client && !( M.blinded )))
+ M.show_message("\blue [user] applies [MED] on [src]")
+ return
+ else
+ user << "\blue [MED] won't help at all."
+ return
+ else
+ user << "\blue [src] is at full health."
+ return
else
- user << "\blue this [src] is dead, medical items won't bring it back to life."
- if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
+ user << "\blue [src] is dead, medical items won't bring it back to life."
+ return
+ else if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
new meat_type (get_turf(src))
if(prob(95))
del(src)
return
gib()
+ return
else
if(O.force)
var/damage = O.force
@@ -390,12 +409,12 @@
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
- M.show_message("\red \b [src] has been attacked with the [O] by [user]. ")
+ M.show_message("\red \b "+"[src] has been attacked with [O] by [user]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
- M.show_message("\red [user] gently taps [src] with the [O]. ")
+ M.show_message("\red [user] gently taps [src] with [O]. ")
@@ -438,26 +457,16 @@
/mob/living/simple_animal/adjustBruteLoss(damage)
health = Clamp(health - damage, 0, maxHealth)
+ if(health < 1)
+ Die()
-/mob/living/simple_animal/proc/SA_attackable(target_mob)
- if (isliving(target_mob))
- var/mob/living/L = target_mob
- if(!L.stat && L.health >= 0)
- return (0)
- if (istype(target_mob,/obj/mecha))
- var/obj/mecha/M = target_mob
+/mob/living/simple_animal/proc/SA_attackable(target)
+ if (isliving(target))
+ var/mob/living/L = target
+ if(!L.stat)
+ return 0
+ if (istype(target,/obj/mecha))
+ var/obj/mecha/M = target
if (M.occupant)
- return (0)
- if (istype(target_mob,/obj/machinery/bot))
- var/obj/machinery/bot/B = target_mob
- if(B.health > 0)
- return (0)
- return (1)
-
-//Call when target overlay should be added/removed
-/mob/living/simple_animal/update_targeted()
- if(!targeted_by && target_locked)
- del(target_locked)
- overlays = null
- if (targeted_by && target_locked)
- overlays += target_locked
\ No newline at end of file
+ return 0
+ return 1
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index b82f6736bbe..73863015668 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -160,6 +160,7 @@
var/faction = "neutral" //Used for checking whether hostile simple animals will attack you, possibly more stuff later
+ var/move_on_shuttle = 1 // Can move on the shuttle.
//Generic list for proc holders. Only way I can see to enable certain verbs/procs. Should be modified if needed.
var/proc_holder_list[] = list()//Right now unused.
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 29b2bfeac3c..fac13660ee6 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -115,6 +115,11 @@ proc/isobserver(A)
return 1
return 0
+proc/isovermind(A)
+ if(istype(A, /mob/camera/blob))
+ return 1
+ return 0
+
proc/isorgan(A)
if(istype(A, /datum/organ/external))
return 1
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 7a618ac6549..5ceb5c853bf 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -226,11 +226,13 @@
if(mob.control_object) Move_object(direct)
- if(isobserver(mob)) return mob.Move(n,direct)
+ if(world.time < move_delay) return
- if(moving) return 0
+ if(isAI(mob)) return AIMove(n,direct,mob)
- if(world.time < move_delay) return
+ if(!isliving(mob)) return mob.Move(n,direct)
+
+ if(moving) return 0
if(!mob) return
@@ -241,7 +243,6 @@
if(mob.stat==2) return
- if(isAI(mob)) return AIMove(n,direct,mob)
if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index f25abe3c76c..6abe971b688 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -467,11 +467,12 @@
return
if(stat & (BROKEN|MAINT))
return
-
+/*
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("APC",src,user:wear_suit)
return
+*/
// do APC interaction
user.set_machine(src)
src.interact(user)
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 8245e850b10..2c50e4a8bd6 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -68,11 +68,12 @@
return powernet
/obj/structure/cable/attack_hand(mob/user)
+/*
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("WIRE",src,user:wear_suit)
return
-
+*/
/obj/structure/cable/attackby(obj/item/W, mob/user)
var/turf/T = src.loc
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index f5db6e12bfe..5e302279021 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -62,11 +62,12 @@
/obj/item/weapon/cell/attack_self(mob/user as mob)
src.add_fingerprint(user)
+/*
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("CELL",src,user:wear_suit)
return
-
+*/
/obj/item/weapon/cell/attackby(obj/item/W, mob/user)
..()
if(istype(W, /obj/item/weapon/reagent_containers/syringe))
@@ -147,8 +148,7 @@
return
/obj/item/weapon/cell/blob_act()
- if(prob(75))
- explode()
+ ex_act(1)
/obj/item/weapon/cell/proc/get_electrocute_damage()
switch (charge)
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index cf5ca92ab22..d861e54ac1c 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -168,11 +168,12 @@
/obj/machinery/power/smes/attack_hand(mob/user)
add_fingerprint(user)
if(stat & BROKEN) return
-
+/*
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("SMES",src,user:wear_suit)
return
+*/
interact(user)
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index 3f05c23582e..0624c99e49d 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -418,24 +418,24 @@
else
dat += "Add to buffer:
"
for(var/datum/reagent/G in R.reagent_list)
- dat += "[G.name] , [G.volume] Units - "
- dat += "(Analyze) "
- dat += "(1) "
- dat += "(5) "
- dat += "(10) "
- dat += "(All) "
- dat += "(Custom)
"
+ dat += {"[G.name] , [G.volume] Units -
+ (Analyze)
+ (1)
+ (5)
+ (10)
+ (All)
+ (Custom)
"}
dat += "
Transfer to [(!mode ? "disposal" : "beaker")]:
"
if(reagents.total_volume)
for(var/datum/reagent/N in reagents.reagent_list)
- dat += "[N.name] , [N.volume] Units - "
- dat += "(Analyze) "
- dat += "(1) "
- dat += "(5) "
- dat += "(10) "
- dat += "(All) "
- dat += "(Custom)
"
+ dat += {"[N.name] , [N.volume] Units -
+ (Analyze)
+ (1)
+ (5)
+ (10)
+ (All)
+ (Custom)
"}
else
dat += "Empty
"
if(!condi)
@@ -661,11 +661,11 @@
if(!D)
CRASH("We weren't able to get the advance disease from the archive.")
- dat += "Disease Agent: [D?"[D.agent] - Create virus culture bottle":"none"]
"
- dat += "Common name: [(D.name||"none")]
"
- dat += "Description: [(D.desc||"none")]
"
- dat += "Spread: [(D.spread||"none")]
"
- dat += "Possible cure: [(D.cure||"none")]
"
+ dat += {"Disease Agent: [D?"[D.agent] - Create virus culture bottle":"none"]
+ Common name: [(D.name||"none")]
+ Description: [(D.desc||"none")]
+ Spread: [(D.spread||"none")]
+ Possible cure: [(D.cure||"none")]
"}
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 000a671e0d3..25d8c34e233 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -114,8 +114,8 @@
user << "\blue You transfer [trans] units of the solution to [target]."
//Safety for dumping stuff into a ninja suit. It handles everything through attackby() and this is unnecessary.
- else if(istype(target, /obj/item/clothing/suit/space/space_ninja))
- return
+// else if(istype(target, /obj/item/clothing/suit/space/space_ninja))
+// return
else if(istype(target, /obj/machinery/bunsen_burner))
return
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 5597c815091..7f4711bcb8a 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -549,12 +549,12 @@ won't update every console in existence) but it's more of a hassle to do. Also,
/obj/machinery/computer/rdconsole/attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
-
+/*
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("RESEARCH",src,user:wear_suit)
return
-
+*/
user.set_machine(src)
var/dat = ""
files.RefreshResearch()
diff --git a/code/modules/research/research_shuttle.dm b/code/modules/research/research_shuttle.dm
index 91c1464d36b..00939c0e290 100644
--- a/code/modules/research/research_shuttle.dm
+++ b/code/modules/research/research_shuttle.dm
@@ -81,10 +81,6 @@ proc/move_research_shuttle()
usr.machine = src
src.add_fingerprint(usr)
if(href_list["move"])
- //if(ticker.mode.name == "blob")
- // if(ticker.mode:declared)
- // usr << "Under directive 7-10, [station_name()] is quarantined until further notice."
- // return
if (!research_shuttle_moving)
usr << "\blue Shuttle recieved message and will be sent shortly."
diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm
index e1f5740b690..5ad44ca8375 100644
--- a/code/modules/research/server.dm
+++ b/code/modules/research/server.dm
@@ -154,9 +154,11 @@
return
if (shocked)
shock(user,50)
+/*
if(ishuman(user))
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("RESEARCH",src,user:wear_suit)
+*/
return
diff --git a/icons/mob/blob.dmi b/icons/mob/blob.dmi
index 49d49a10889..7b265ba2bd1 100644
Binary files a/icons/mob/blob.dmi and b/icons/mob/blob.dmi differ