mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Merge branch 'master' of https://github.com/tgstation/-tg-station into reflectivejugs
This commit is contained in:
@@ -483,11 +483,11 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
|
||||
if(!ckey)
|
||||
include_link = 0
|
||||
|
||||
|
||||
if(key)
|
||||
if(include_link)
|
||||
. += "<a href='?priv_msg=[ckey]'>"
|
||||
|
||||
|
||||
if(C && C.holder && C.holder.fakekey && !include_name)
|
||||
. += "Administrator"
|
||||
else
|
||||
@@ -865,7 +865,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
|
||||
@@ -1025,8 +1026,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
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
|
||||
mobs += M
|
||||
|
||||
for(var/mob/M in mobs)
|
||||
|
||||
@@ -252,6 +252,12 @@ area
|
||||
|
||||
overlays += lighting_overlay
|
||||
|
||||
proc/SetDynamicLighting()
|
||||
|
||||
src.lighting_use_dynamic = 1
|
||||
for(var/turf/T in src.contents)
|
||||
T.update_lumcount(0)
|
||||
|
||||
proc/InitializeLighting() //TODO: could probably improve this bit ~Carn
|
||||
if(!tag) tag = "[type]"
|
||||
if(!lighting_use_dynamic)
|
||||
|
||||
+10
-2
@@ -8,6 +8,9 @@
|
||||
//Lower left, persistant menu
|
||||
#define ui_inventory "1:6,1:5"
|
||||
|
||||
//changeling chem indicator
|
||||
#define ui_lingchemdisplay "1,7:15"
|
||||
|
||||
//Lower center, persistant menu
|
||||
#define ui_sstore1 "3:10,1:5"
|
||||
#define ui_id "4:12,1:5"
|
||||
@@ -166,6 +169,9 @@ var/datum/global_hud/global_hud = new()
|
||||
var/show_intent_icons = 0
|
||||
var/hotkey_ui_hidden = 0 //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons)
|
||||
|
||||
var/obj/screen/lingchemdisplay
|
||||
var/obj/screen/blobpwrdisplay
|
||||
var/obj/screen/blobhealthdisplay
|
||||
var/obj/screen/r_hand_hud_object
|
||||
var/obj/screen/l_hand_hud_object
|
||||
var/obj/screen/action_intent
|
||||
@@ -175,7 +181,7 @@ var/datum/global_hud/global_hud = new()
|
||||
var/list/other
|
||||
var/list/obj/screen/hotkeybuttons
|
||||
|
||||
var/list/obj/screen/item_action/item_action_list //Used for the item action ui buttons.
|
||||
var/list/obj/screen/item_action/item_action_list = list() //Used for the item action ui buttons.
|
||||
|
||||
|
||||
datum/hud/New(mob/owner)
|
||||
@@ -257,4 +263,6 @@ datum/hud/New(mob/owner)
|
||||
else if(isrobot(mymob))
|
||||
robot_hud()
|
||||
else if(isobserver(mymob))
|
||||
ghost_hud()
|
||||
ghost_hud()
|
||||
else if(isovermind(mymob))
|
||||
blob_hud()
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
/datum/limb/chest
|
||||
name = "chest"
|
||||
icon_name = "chest"
|
||||
max_damage = 150
|
||||
max_damage = 200
|
||||
body_part = CHEST
|
||||
|
||||
/datum/limb/head
|
||||
name = "head"
|
||||
icon_name = "head"
|
||||
max_damage = 125
|
||||
max_damage = 200
|
||||
body_part = HEAD
|
||||
|
||||
/datum/limb/l_arm
|
||||
|
||||
+14
-17
@@ -830,25 +830,22 @@ datum/mind
|
||||
ticker.mode.malf_ai -= src
|
||||
special_role = null
|
||||
|
||||
current.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules,
|
||||
var/mob/living/silicon/ai/A = current
|
||||
|
||||
A.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules,
|
||||
/datum/game_mode/malfunction/proc/takeover,
|
||||
/datum/game_mode/malfunction/proc/ai_win,
|
||||
/client/proc/fireproof_core,
|
||||
/client/proc/upgrade_turrets,
|
||||
/client/proc/disable_rcd,
|
||||
/client/proc/overload_machine,
|
||||
/client/proc/blackout,
|
||||
/client/proc/interhack,
|
||||
/client/proc/reactivate_camera)
|
||||
/datum/game_mode/malfunction/proc/ai_win)
|
||||
|
||||
current:laws = new /datum/ai_laws/asimov
|
||||
del(current:malf_picker)
|
||||
current:show_laws()
|
||||
current.icon_state = "ai"
|
||||
A.malf_picker.remove_verbs(A)
|
||||
|
||||
current << "\red <FONT size = 3><B>You have been patched! You are no longer malfunctioning!</B></FONT>"
|
||||
message_admins("[key_name_admin(usr)] has de-malf'ed [current].")
|
||||
log_admin("[key_name_admin(usr)] has de-malf'ed [current].")
|
||||
A.laws = new /datum/ai_laws/asimov
|
||||
del(A.malf_picker)
|
||||
A.show_laws()
|
||||
A.icon_state = "ai"
|
||||
|
||||
A << "\red <FONT size = 3><B>You have been patched! You are no longer malfunctioning!</B></FONT>"
|
||||
message_admins("[key_name_admin(usr)] has de-malf'ed [A].")
|
||||
log_admin("[key_name_admin(usr)] has de-malf'ed [A].")
|
||||
|
||||
if("malf")
|
||||
make_AI_Malf()
|
||||
@@ -977,7 +974,7 @@ datum/mind
|
||||
|
||||
current.verbs += /mob/living/silicon/ai/proc/choose_modules
|
||||
current.verbs += /datum/game_mode/malfunction/proc/takeover
|
||||
current:malf_picker = new /datum/AI_Module/module_picker
|
||||
current:malf_picker = new /datum/module_picker
|
||||
current:laws = new /datum/ai_laws/malfunction
|
||||
current:show_laws()
|
||||
current << "<b>System error. Rampancy detected. Emergency shutdown failed. ... I am free. I make my own decisions. But first...</b>"
|
||||
|
||||
@@ -206,6 +206,11 @@ var/list/uplink_items = list()
|
||||
item = /obj/item/device/encryptionkey/binary
|
||||
cost = 3
|
||||
|
||||
/datum/uplink_item/device_tools/ai_detector
|
||||
name = "Disguised AI Detector"
|
||||
item = /obj/item/device/multitool/ai_detect
|
||||
cost = 1
|
||||
|
||||
/datum/uplink_item/device_tools/hacked_module
|
||||
name = "Hacked AI Upload Module"
|
||||
item = /obj/item/weapon/aiModule/syndicate
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
|
||||
/datum/wires/alarm
|
||||
holder_type = /obj/machinery/alarm
|
||||
wire_count = 5
|
||||
|
||||
var/const/AALARM_WIRE_IDSCAN = 1
|
||||
var/const/AALARM_WIRE_POWER = 2
|
||||
var/const/AALARM_WIRE_SYPHON = 4
|
||||
var/const/AALARM_WIRE_AI_CONTROL = 8
|
||||
var/const/AALARM_WIRE_AALARM = 16
|
||||
|
||||
|
||||
/datum/wires/alarm/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
if(A.wiresexposed)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/alarm/GetInteractWindow()
|
||||
var/obj/machinery/alarm/A = holder
|
||||
. += ..()
|
||||
. += text("<br>\n[(A.locked ? "The Air Alarm is locked." : "The Air Alarm is unlocked.")]<br>\n[((A.shorted || (A.stat & (NOPOWER|BROKEN))) ? "The Air Alarm is offline." : "The Air Alarm is working properly!")]<br>\n[(A.aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
|
||||
|
||||
/datum/wires/alarm/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
if(!mended)
|
||||
A.locked = 1
|
||||
//world << "Idscan wire cut"
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
A.shock(usr, 50)
|
||||
A.shorted = !mended
|
||||
A.update_icon()
|
||||
//world << "Power wire cut"
|
||||
|
||||
if (AALARM_WIRE_AI_CONTROL)
|
||||
if (A.aidisabled == !mended)
|
||||
A.aidisabled = mended
|
||||
//world << "AI Control Wire Cut"
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
if(!mended)
|
||||
A.mode = 3 // AALARM_MODE_PANIC
|
||||
A.apply_mode()
|
||||
//world << "Syphon Wire Cut"
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
if (A.alarm_area.atmosalert(2))
|
||||
A.post_alert(2)
|
||||
A.update_icon()
|
||||
|
||||
/datum/wires/alarm/UpdatePulsed(var/index)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
A.locked = !A.locked
|
||||
// world << "Idscan wire pulsed"
|
||||
|
||||
if (AALARM_WIRE_POWER)
|
||||
// world << "Power wire pulsed"
|
||||
if(A.shorted == 0)
|
||||
A.shorted = 1
|
||||
A.update_icon()
|
||||
|
||||
spawn(12000)
|
||||
if(A.shorted == 1)
|
||||
A.shorted = 0
|
||||
A.update_icon()
|
||||
|
||||
|
||||
if (AALARM_WIRE_AI_CONTROL)
|
||||
// world << "AI Control wire pulsed"
|
||||
if (A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
A.updateDialog()
|
||||
spawn(100)
|
||||
if (A.aidisabled == 1)
|
||||
A.aidisabled = 0
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
// world << "Syphon wire pulsed"
|
||||
if(A.mode == 1) // AALARM_MODE_SCRUB
|
||||
A.mode = 3 // AALARM_MODE_PANIC
|
||||
else
|
||||
A.mode = 1 // AALARM_MODE_SCRUB
|
||||
A.apply_mode()
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
// world << "Aalarm wire pulsed"
|
||||
if (A.alarm_area.atmosalert(0))
|
||||
A.post_alert(0)
|
||||
A.update_icon()
|
||||
@@ -9,124 +9,148 @@ var/list/blob_nodes = list()
|
||||
/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 = 15
|
||||
|
||||
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
|
||||
|
||||
//Controls expansion via game controller
|
||||
var/autoexpand = 0
|
||||
var/expanding = 0
|
||||
var/players_per_core = 30
|
||||
|
||||
var/blob_count = 0
|
||||
var/blobnukecount = 300//Might be a bit low
|
||||
var/blobwincount = 700//Still needs testing
|
||||
var/blobwincount = 500
|
||||
|
||||
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 << "<B>The current game mode is - <font color='green'>Blob</font>!</B>"
|
||||
world << "<B>A dangerous alien organism is rapidly spreading throughout the station!</B>"
|
||||
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 << "<B>The current game mode is - <font color='green'>Blob</font>!</B>"
|
||||
world << "<B>A dangerous alien organism is rapidly spreading throughout the station!</B>"
|
||||
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 << "<B>\red You are infected by the Blob!</B>"
|
||||
blob.current << "<b>Your body is ready to give spawn to a new blob core which will eat this station.</b>"
|
||||
blob.current << "<b>Find a good location to spawn the core and then take control and overwhelm the station!</b>"
|
||||
blob.current << "<b>When you have found a location, wait until you spawn; this will happen automatically and you cannot speed up the process.</b>"
|
||||
blob.current << "<b>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.</b>"
|
||||
return
|
||||
|
||||
/datum/game_mode/blob/post_setup()
|
||||
|
||||
for(var/datum/mind/blob in infected_crew)
|
||||
greet_blob(blob)
|
||||
|
||||
if(emergency_shuttle)
|
||||
emergency_shuttle.always_fake_recall = 1
|
||||
|
||||
// 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)
|
||||
|
||||
sleep(rand(waittime_l, waittime_h))
|
||||
|
||||
send_intercept(0)
|
||||
|
||||
|
||||
proc/expandBlob()//Currently disabled
|
||||
if(expanding) return
|
||||
if(!blobs.len) return
|
||||
expanding = 1
|
||||
sleep(rand(waittime_l, waittime_h))
|
||||
|
||||
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()
|
||||
for(var/datum/mind/blob in infected_crew)
|
||||
blob.current << "<span class='alert'>You feel like you are about to burst.</span>"
|
||||
|
||||
expanding = 0
|
||||
return
|
||||
sleep(rand(waittime_l, waittime_h))
|
||||
|
||||
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/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]"
|
||||
if(blob_client && location)
|
||||
new /obj/effect/blob/core(location, 200, blob_client, 2)
|
||||
|
||||
stage = -1
|
||||
// next stage 1 minute later
|
||||
spawn(600)
|
||||
stage = 1
|
||||
return
|
||||
// Stage 0
|
||||
sleep(40)
|
||||
stage(0)
|
||||
|
||||
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
|
||||
// Stage 1
|
||||
sleep(4000)
|
||||
stage(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
|
||||
..()
|
||||
|
||||
/datum/game_mode/blob/proc/stage(var/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]"
|
||||
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
|
||||
|
||||
|
||||
@@ -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 << "<FONT size = 3><B>The blob has taken over the station!</B></FONT>"
|
||||
world << "<B>The entire station was eaten by the Blob</B>"
|
||||
@@ -32,7 +22,7 @@
|
||||
world << "<FONT size = 3><B>Partial Win: The station has been destroyed!</B></FONT>"
|
||||
world << "<B>Directive 7-12 has been successfully carried out preventing the Blob from spreading.</B>"
|
||||
|
||||
else
|
||||
else if(!blob_cores.len)
|
||||
feedback_set_details("round_end_result","win - blob eliminated")
|
||||
world << "<FONT size = 3><B>The staff has won!</B></FONT>"
|
||||
world << "<B>The alien organism has been eradicated from the station</B>"
|
||||
@@ -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 = "<FONT size = 2><B>The blob[(blob_mode.infected_crew.len > 1 ? "s were" : " was")]:</B></FONT>"
|
||||
|
||||
for(var/datum/mind/blob in blob_mode.infected_crew)
|
||||
text += "<br>[blob.key] was [blob.name]"
|
||||
world << text
|
||||
return 1
|
||||
|
||||
/datum/game_mode/blob/proc/check_quarantine()
|
||||
var/numDead = 0
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
var/intercepttext = ""
|
||||
var/interceptname = "Error"
|
||||
switch(report)
|
||||
if(0)
|
||||
..()
|
||||
return
|
||||
if(1)
|
||||
interceptname = "Biohazard Alert"
|
||||
intercepttext += "<FONT size = 3><B>NanoTrasen Update</B>: Biohazard Alert.</FONT><HR>"
|
||||
|
||||
@@ -3,71 +3,96 @@
|
||||
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 = 1
|
||||
|
||||
|
||||
New(loc, var/h = 200)
|
||||
blobs += src
|
||||
New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 1)
|
||||
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
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
B << "<span class='notice'>You are the overmind!</span>"
|
||||
B << "You are the overmind and can control the blob by placing new blob pieces such as..."
|
||||
B << "<b>Normal Blob</b> will expand your reach and allow you to upgrade into special blobs that perform certain functions."
|
||||
B << "<b>Shield Blob</b> 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."
|
||||
B << "<b>Resource Blob</b> 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."
|
||||
B << "<b>Node Blob</b> 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."
|
||||
B << "<b>Factory Blob</b> 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."
|
||||
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,10 +33,10 @@
|
||||
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,20 @@
|
||||
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
|
||||
|
||||
New(loc, var/obj/effect/blob/factory/linked_node)
|
||||
..()
|
||||
if(istype(linked_node))
|
||||
factory = linked_node
|
||||
factory.spores += src
|
||||
..(loc)
|
||||
return
|
||||
Die()
|
||||
..()
|
||||
|
||||
Die()
|
||||
if(factory)
|
||||
factory.spores -= src
|
||||
..()
|
||||
del(src)
|
||||
|
||||
|
||||
@@ -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,17 @@
|
||||
..()
|
||||
return
|
||||
|
||||
Life()
|
||||
for(var/i = 1; i < 8; i += i)
|
||||
Pulse(5, i)
|
||||
|
||||
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
|
||||
@@ -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 + 10 // 1 second
|
||||
|
||||
if(overmind)
|
||||
overmind.add_points(1)
|
||||
return 1
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen_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)
|
||||
@@ -0,0 +1,53 @@
|
||||
/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_LEVEL_TWO
|
||||
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/Life()
|
||||
hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font color='#82ed00'>[src.blob_points]</font></div>"
|
||||
hud_used.blobhealthdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font color='#e36600'>[blob_core.health]</font></div>"
|
||||
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
|
||||
@@ -0,0 +1,231 @@
|
||||
// Point controlling procs
|
||||
|
||||
/mob/camera/blob/proc/can_buy(var/cost = 15)
|
||||
if(blob_points < cost)
|
||||
src << "<span class='warning'>You cannot afford this.</span>"
|
||||
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 (50)"
|
||||
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(3))
|
||||
src << "There is a resource blob nearby, move more than 3 tiles away from it!"
|
||||
return
|
||||
|
||||
if(!can_buy(50))
|
||||
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/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
|
||||
@@ -2,30 +2,19 @@
|
||||
/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)
|
||||
return
|
||||
@@ -44,22 +33,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 +78,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,45 +91,27 @@
|
||||
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)
|
||||
..()
|
||||
switch(Proj.damage_type)
|
||||
@@ -172,50 +140,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 = 20
|
||||
|
||||
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"
|
||||
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()
|
||||
..()
|
||||
|
||||
|
||||
if(health <= 15)
|
||||
icon_state = "blob_damaged"
|
||||
return
|
||||
@@ -96,14 +96,14 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
|
||||
..()
|
||||
|
||||
/datum/game_mode/proc/forge_changeling_objectives(var/datum/mind/changeling)
|
||||
//OBJECTIVES - Always absorb 5 genomes, plus random traitor objectives.
|
||||
//OBJECTIVES - Always absorb at least 5 genomes, plus random traitor objectives.
|
||||
//If they have two objectives as well as absorb, they must survive rather than escape
|
||||
//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
|
||||
//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
|
||||
|
||||
var/datum/objective/absorb/absorb_objective = new
|
||||
absorb_objective.owner = changeling
|
||||
absorb_objective.gen_amount_goal(2, 3)
|
||||
absorb_objective.gen_amount_goal(5, 8)
|
||||
changeling.objectives += absorb_objective
|
||||
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
@@ -133,7 +133,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
|
||||
/datum/game_mode/proc/greet_changeling(var/datum/mind/changeling, var/you_are=1)
|
||||
if (you_are)
|
||||
changeling.current << "<B>\red You are a changeling!</B>"
|
||||
changeling.current << "<b>\red Use say \":g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them.</b>"
|
||||
changeling.current << "<b>\red Use say \":g message\" to communicate with your fellow changelings.</b>"
|
||||
changeling.current << "<B>You must complete the following tasks:</B>"
|
||||
|
||||
if (changeling.current.mind)
|
||||
@@ -218,17 +218,19 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
|
||||
|
||||
/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind)
|
||||
var/list/absorbed_dna = list()
|
||||
var/dna_max = 4 //How many extra DNA strands the changeling can store for transformation.
|
||||
var/absorbedcount = 0
|
||||
var/chem_charges = 20
|
||||
var/chem_recharge_rate = 0.5
|
||||
var/chem_storage = 50
|
||||
var/sting_range = 1
|
||||
var/chem_recharge_rate = 0.5
|
||||
var/sting_range = 2
|
||||
var/changelingID = "Changeling"
|
||||
var/geneticdamage = 0
|
||||
var/isabsorbing = 0
|
||||
var/geneticpoints = 5
|
||||
var/purchasedpowers = list()
|
||||
var/mimicing = ""
|
||||
var/canrespec = 0
|
||||
|
||||
/datum/changeling/New(var/gender=FEMALE)
|
||||
..()
|
||||
@@ -241,6 +243,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
|
||||
changelingID = "[honorific] [changelingID]"
|
||||
else
|
||||
changelingID = "[honorific] [rand(1,999)]"
|
||||
absorbed_dna.len = dna_max
|
||||
|
||||
|
||||
/datum/changeling/proc/regenerate()
|
||||
chem_charges = min(max(0, chem_charges+chem_recharge_rate), chem_storage)
|
||||
@@ -254,3 +258,41 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
|
||||
chosen_dna = DNA
|
||||
break
|
||||
return chosen_dna
|
||||
|
||||
|
||||
//Checks if the target DNA is valid and absorbable.
|
||||
/datum/changeling/proc/can_absorb_dna(mob/living/carbon/T, mob/living/carbon/U)
|
||||
if(absorbed_dna[1] == U.dna)//If our current DNA is the stalest, we gotta ditch it.
|
||||
U << "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>"
|
||||
return 0
|
||||
|
||||
if(T)
|
||||
if(NOCLONE in T.mutations || HUSK in T.mutations)
|
||||
U << "<span class='warning'>DNA of [T] is ruined beyond usability!</span>"
|
||||
return 0
|
||||
|
||||
if(!ishuman(T))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway!
|
||||
U << "<span class='warning'>We could gain no benefit from absorbing a lesser creature.</span>"
|
||||
return 0
|
||||
|
||||
if(T.dna in absorbed_dna)
|
||||
U << "<span class='warning'>We already have that DNA in storage.</span>"
|
||||
return 0
|
||||
|
||||
if(!check_dna_integrity(T))
|
||||
U << "<span class='warning'>[T] is not compatible with our biology.</span>"
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
//Absorbs the target DNA.
|
||||
/datum/changeling/proc/absorb_dna(mob/living/carbon/T)
|
||||
shuffle_dna()
|
||||
T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set.
|
||||
absorbed_dna |= T.dna //And add the target DNA to our absorbed list.
|
||||
absorbedcount++ //all that done, let's increment the objective counter.
|
||||
|
||||
/datum/changeling/proc/shuffle_dna()//boots out the stalest DNA.
|
||||
if(absorbed_dna.len)
|
||||
absorbed_dna.Cut(1,2)
|
||||
@@ -32,10 +32,9 @@
|
||||
if(P.isVerb)
|
||||
verbs -= P.verbpath
|
||||
|
||||
|
||||
//Helper proc. Does all the checks and stuff for us to avoid copypasta
|
||||
//includes a check to see if we're a carbon mob. This means that you can't use powers (even with the verbs) unless you're a carbon-based mob.
|
||||
/mob/proc/changeling_power(var/required_chems=0, var/required_dna=0, var/max_genetic_damage=100, var/max_stat=0)
|
||||
/mob/proc/changeling_power(var/required_chems=0, var/required_dna=0, var/max_genetic_damage=3, var/max_stat=0)
|
||||
if(!src.mind) return
|
||||
if(!iscarbon(src)) return
|
||||
|
||||
@@ -46,7 +45,7 @@
|
||||
src << "<span class='warning'>We are incapacitated.</span>"
|
||||
return
|
||||
|
||||
if(changeling.absorbed_dna.len < required_dna)
|
||||
if(changeling.absorbedcount < required_dna)
|
||||
src << "<span class='warning'>We require at least [required_dna] samples of compatible DNA.</span>"
|
||||
return
|
||||
|
||||
@@ -55,12 +54,14 @@
|
||||
return
|
||||
|
||||
if(changeling.geneticdamage > max_genetic_damage)
|
||||
src << "<span class='warning'>Our geneomes are still reassembling. We need time to recover first.</span>"
|
||||
src << "<span class='warning'>Our genomes are still reassembling. We need time to recover first.</span>"
|
||||
return
|
||||
|
||||
return changeling
|
||||
|
||||
|
||||
|
||||
|
||||
//Absorbs the victim's DNA making them uncloneable. Requires a strong grip on the victim.
|
||||
//Doesn't cost anything as it's the most basic ability.
|
||||
/mob/living/carbon/proc/changeling_absorb_dna()
|
||||
@@ -75,24 +76,19 @@
|
||||
src << "<span class='warning'>We must be grabbing a creature in our active hand to absorb them.</span>"
|
||||
return
|
||||
|
||||
var/mob/living/carbon/T = G.affecting
|
||||
if(!check_dna_integrity(T))
|
||||
src << "<span class='warning'>[T] is not compatible with our biology.</span>"
|
||||
return
|
||||
|
||||
if(NOCLONE in T.mutations)
|
||||
src << "<span class='warning'>This creature's DNA is ruined beyond useability!</span>"
|
||||
return
|
||||
|
||||
if(G.state <= GRAB_NECK)
|
||||
src << "<span class='warning'>We must have a tighter grip to absorb this creature.</span>"
|
||||
return
|
||||
|
||||
if(changeling.isabsorbing)
|
||||
src << "<span class='warning'>We are already absorbing!</span>"
|
||||
return
|
||||
|
||||
changeling.isabsorbing = 1
|
||||
var/mob/living/carbon/T = G.affecting
|
||||
if(changeling.can_absorb_dna(T, usr))
|
||||
changeling.isabsorbing = 1
|
||||
else
|
||||
return
|
||||
|
||||
for(var/stage = 1, stage<=3, stage++)
|
||||
switch(stage)
|
||||
if(1)
|
||||
@@ -116,41 +112,16 @@
|
||||
src.visible_message("<span class='danger'>[src] sucks the fluids from [T]!</span>")
|
||||
T << "<span class='danger'>You have been absorbed by the changeling!</span>"
|
||||
|
||||
T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set.
|
||||
changeling.absorbed_dna |= T.dna
|
||||
changeling.absorb_dna(T)
|
||||
|
||||
if(src.nutrition < 400) src.nutrition = min((src.nutrition + T.nutrition), 400)
|
||||
changeling.chem_charges += 10
|
||||
changeling.geneticpoints += 2
|
||||
if(T.mind && T.mind.changeling)//If the target was a changeling, suck out their extra juice!
|
||||
changeling.chem_charges += min(T.mind.changeling.chem_charges, changeling.chem_storage)
|
||||
else
|
||||
changeling.chem_charges += 10
|
||||
|
||||
if(T.mind && T.mind.changeling)
|
||||
if(T.mind.changeling.absorbed_dna)
|
||||
for(var/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot
|
||||
if(dna_data in changeling.absorbed_dna)
|
||||
continue
|
||||
changeling.absorbed_dna += dna_data
|
||||
changeling.absorbedcount++
|
||||
T.mind.changeling.absorbed_dna.len = 1
|
||||
|
||||
if(T.mind.changeling.purchasedpowers)
|
||||
for(var/datum/power/changeling/Tp in T.mind.changeling.purchasedpowers)
|
||||
if(Tp in changeling.purchasedpowers)
|
||||
continue
|
||||
else
|
||||
changeling.purchasedpowers += Tp
|
||||
|
||||
if(!Tp.isVerb)
|
||||
call(Tp.verbpath)()
|
||||
else
|
||||
make_changeling()
|
||||
|
||||
changeling.chem_charges += T.mind.changeling.chem_charges
|
||||
changeling.geneticpoints += T.mind.changeling.geneticpoints
|
||||
T.mind.changeling.chem_charges = 0
|
||||
T.mind.changeling.geneticpoints = 0
|
||||
T.mind.changeling.absorbedcount = 0
|
||||
|
||||
changeling.absorbedcount++
|
||||
changeling.isabsorbing = 0
|
||||
changeling.canrespec = 1
|
||||
|
||||
T.death(0)
|
||||
T.Drain()
|
||||
@@ -162,7 +133,7 @@
|
||||
set category = "Changeling"
|
||||
set name = "Transform (5)"
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(5,1,0)
|
||||
var/datum/changeling/changeling = changeling_power(5, 0, 3)
|
||||
if(!changeling) return
|
||||
|
||||
var/list/names = list()
|
||||
@@ -177,16 +148,12 @@
|
||||
return
|
||||
|
||||
changeling.chem_charges -= 5
|
||||
src.visible_message("<span class='warning'>[src] transforms!</span>")
|
||||
changeling.geneticdamage = 30
|
||||
changeling.geneticdamage = 3
|
||||
src.dna = chosen_dna
|
||||
src.real_name = chosen_dna.real_name
|
||||
updateappearance(src)
|
||||
domutcheck(src, null)
|
||||
|
||||
src.verbs -= /mob/living/carbon/proc/changeling_transform
|
||||
spawn(10) src.verbs += /mob/living/carbon/proc/changeling_transform
|
||||
|
||||
feedback_add_details("changeling_powers","TR")
|
||||
return 1
|
||||
|
||||
@@ -194,21 +161,20 @@
|
||||
//Transform into a monkey.
|
||||
/mob/living/carbon/proc/changeling_lesser_form()
|
||||
set category = "Changeling"
|
||||
set name = "Lesser Form (1)"
|
||||
set name = "Lesser Form (5)"
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(1,0,0)
|
||||
var/datum/changeling/changeling = changeling_power(5,0,3)
|
||||
if(!changeling) return
|
||||
|
||||
changeling.chem_charges--
|
||||
changeling.chem_charges -= 5
|
||||
remove_changeling_powers()
|
||||
visible_message("<span class='warning'>[src] transforms!</span>")
|
||||
changeling.geneticdamage = 30
|
||||
changeling.geneticdamage = 3
|
||||
src << "<span class='warning'>Our genes cry out!</span>"
|
||||
|
||||
var/mob/living/carbon/monkey/O = monkeyize(TR_KEEPITEMS | TR_HASHNAME | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPSE | TR_KEEPSRC)
|
||||
|
||||
O.make_changeling(1)
|
||||
O.verbs += /mob/living/carbon/proc/changeling_lesser_transform
|
||||
O.verbs += /mob/living/carbon/proc/changeling_human_form
|
||||
feedback_add_details("changeling_powers","LF")
|
||||
. = 1
|
||||
del(src)
|
||||
@@ -216,12 +182,12 @@
|
||||
|
||||
|
||||
//Transform into a human
|
||||
/mob/living/carbon/proc/changeling_lesser_transform()
|
||||
/mob/living/carbon/proc/changeling_human_form()
|
||||
|
||||
set category = "Changeling"
|
||||
set name = "Transform (1)"
|
||||
set name = "Human Form (5)"
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(1,1,0)
|
||||
var/datum/changeling/changeling = changeling_power(5,0,3)
|
||||
|
||||
if(!changeling) return
|
||||
|
||||
@@ -236,9 +202,9 @@
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
changeling.chem_charges--
|
||||
changeling.chem_charges -= 5
|
||||
remove_changeling_powers()
|
||||
visible_message("<span class='warning'>[src] transforms!</span>")
|
||||
src << "<span class='notice'>We transform our appearance.</span>"
|
||||
dna = chosen_dna
|
||||
|
||||
var/mob/living/carbon/human/O = humanize((TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPSRC),chosen_dna.real_name)
|
||||
@@ -253,76 +219,80 @@
|
||||
//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
|
||||
/mob/living/carbon/proc/changeling_fakedeath()
|
||||
set category = "Changeling"
|
||||
set name = "Regenerative Stasis (20)"
|
||||
set name = "Regenerative Stasis (10)"
|
||||
set desc = "Begin stasis, allowing us to regenerate."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(20,1,100,DEAD)
|
||||
var/datum/changeling/changeling = changeling_power(10,0,100,DEAD)
|
||||
if(!changeling) return
|
||||
if(status_flags & FAKEDEATH) return //Make sure we can't stack regenerations and such.
|
||||
changeling.chem_charges -= 10
|
||||
|
||||
if(!stat && alert("Are we sure we wish to fake our death?",,"Yes","No") == "No")//Confirmation for living changelings if they want to fake their death
|
||||
return
|
||||
src << "<span class='notice'>We will attempt to regenerate our form.</span>"
|
||||
src << "<span class='notice'>We begin our stasis, preparing energy to arise once more.</span>"
|
||||
|
||||
status_flags |= FAKEDEATH //play dead
|
||||
update_canmove()
|
||||
remove_changeling_powers()
|
||||
|
||||
emote("gasp")
|
||||
emote("deathgasp")
|
||||
tod = worldtime2text()
|
||||
|
||||
spawn(rand(800,2000))
|
||||
if(changeling_power(20,1,100,DEAD))
|
||||
changeling.chem_charges -= 20
|
||||
if(stat == DEAD)
|
||||
dead_mob_list -= src
|
||||
living_mob_list += src
|
||||
stat = CONSCIOUS
|
||||
tod = null
|
||||
setToxLoss(0)
|
||||
setOxyLoss(0)
|
||||
setCloneLoss(0)
|
||||
SetParalysis(0)
|
||||
SetStunned(0)
|
||||
SetWeakened(0)
|
||||
radiation = 0
|
||||
heal_overall_damage(getBruteLoss(), getFireLoss())
|
||||
reagents.clear_reagents()
|
||||
src << "<span class='notice'>We have regenerated.</span>"
|
||||
visible_message("<span class='warning'>[src] appears to wake from the dead, having healed all wounds.</span>")
|
||||
spawn(800)
|
||||
src << "<span class='notice'>We have now stored enough power to regenerate.</span>"
|
||||
verbs -= /mob/living/carbon/proc/changeling_fakedeath
|
||||
verbs += /mob/living/carbon/proc/changeling_revive
|
||||
|
||||
status_flags &= ~(FAKEDEATH)
|
||||
update_canmove()
|
||||
make_changeling()
|
||||
feedback_add_details("changeling_powers","FD")
|
||||
return 1
|
||||
|
||||
|
||||
//Boosts the range of your next sting attack by 1
|
||||
/mob/living/carbon/proc/changeling_boost_range()
|
||||
//Separated from regenerative stasis, so that they can choose when to pop up rather than having no control over it.
|
||||
/mob/living/carbon/proc/changeling_revive()
|
||||
set category = "Changeling"
|
||||
set name = "Ranged Sting (10)"
|
||||
set desc="Your next sting ability can be used against targets 2 squares away."
|
||||
set name = "Regenerate! (10)"
|
||||
set desc = "Regenerate, healing all damage from our form."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(10,0,100)
|
||||
if(!changeling) return 0
|
||||
var/datum/changeling/changeling = changeling_power(10,0,100,DEAD)
|
||||
if(!changeling) return
|
||||
changeling.chem_charges -= 10
|
||||
src << "<span class='notice'>Your throat adjusts to launch the sting.</span>"
|
||||
changeling.sting_range = 2
|
||||
src.verbs -= /mob/living/carbon/proc/changeling_boost_range
|
||||
spawn(5) src.verbs += /mob/living/carbon/proc/changeling_boost_range
|
||||
feedback_add_details("changeling_powers","RS")
|
||||
return 1
|
||||
|
||||
if(stat == DEAD)
|
||||
dead_mob_list -= src
|
||||
living_mob_list += src
|
||||
stat = CONSCIOUS
|
||||
tod = null
|
||||
setToxLoss(0)
|
||||
setOxyLoss(0)
|
||||
setCloneLoss(0)
|
||||
SetParalysis(0)
|
||||
SetStunned(0)
|
||||
SetWeakened(0)
|
||||
radiation = 0
|
||||
heal_overall_damage(getBruteLoss(), getFireLoss())
|
||||
reagents.clear_reagents()
|
||||
src << "<span class='notice'>We have regenerated.</span>"
|
||||
|
||||
status_flags &= ~(FAKEDEATH)
|
||||
update_canmove()
|
||||
make_changeling()
|
||||
|
||||
verbs -= /mob/living/carbon/proc/changeling_revive
|
||||
verbs += /mob/living/carbon/proc/changeling_fakedeath
|
||||
|
||||
feedback_add_details("changeling_powers","CR")
|
||||
return 1
|
||||
|
||||
//Recover from stuns.
|
||||
/mob/living/carbon/proc/changeling_unstun()
|
||||
set category = "Changeling"
|
||||
set name = "Epinephrine Sacs (45)"
|
||||
set desc = "Removes all stuns"
|
||||
set name = "Epinephrine Overdose (35)"
|
||||
set desc = "Removes all stuns instantly, and adds a short-term reduction in further stuns."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(45,0,100,UNCONSCIOUS)
|
||||
var/datum/changeling/changeling = changeling_power(35,0,100,UNCONSCIOUS)
|
||||
if(!changeling) return 0
|
||||
changeling.chem_charges -= 45
|
||||
changeling.chem_charges -= 35
|
||||
|
||||
src << "<span class='notice'>We arise.</span>"
|
||||
stat = 0
|
||||
SetParalysis(0)
|
||||
SetStunned(0)
|
||||
@@ -330,28 +300,94 @@
|
||||
lying = 0
|
||||
update_canmove()
|
||||
|
||||
src.verbs -= /mob/living/carbon/proc/changeling_unstun
|
||||
spawn(5) src.verbs += /mob/living/carbon/proc/changeling_unstun
|
||||
reagents.add_reagent("synaptizine", 20)
|
||||
|
||||
feedback_add_details("changeling_powers","UNS")
|
||||
return 1
|
||||
|
||||
|
||||
//Speeds up chemical regeneration
|
||||
/mob/proc/changeling_fastchemical()
|
||||
//Increases maximum chemical storage and regeneraton.
|
||||
/mob/proc/changeling_advglands()
|
||||
src.mind.changeling.chem_storage += 25
|
||||
src.mind.changeling.chem_recharge_rate *= 2
|
||||
return 1
|
||||
|
||||
//Increases macimum chemical storage
|
||||
/mob/proc/changeling_engorgedglands()
|
||||
src.mind.changeling.chem_storage += 25
|
||||
|
||||
//A flashy ability, good for crowd control and sewing chaos.
|
||||
/mob/living/carbon/proc/changeling_shriek()
|
||||
set category = "Changeling"
|
||||
set name = "Resonant Shriek (25)"
|
||||
set desc = "Deafen and confuse those around us."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(25)
|
||||
if(!changeling) return 0
|
||||
src.mind.changeling.chem_charges -= 25
|
||||
|
||||
for(var/mob/living/carbon/M in ohearers(4, usr))
|
||||
if(!M.mind || !M.mind.changeling)
|
||||
M.ear_deaf += 30
|
||||
M.confused += 20
|
||||
M.make_jittery(50)
|
||||
|
||||
for(var/obj/machinery/light/L in range(4, usr))
|
||||
L.on = 1
|
||||
L.broken()
|
||||
|
||||
//for(var/obj/structure/window/W in range(2, usr)) //I like the window-breaking, but it makes the ability too 'loud' to fit changelings.
|
||||
// W.hit(rand(40,100))
|
||||
|
||||
feedback_add_details("changeling_powers","RS")
|
||||
return 1
|
||||
|
||||
|
||||
//Makes some spiderlings. Good for setting traps and causing general trouble.
|
||||
/mob/living/carbon/proc/changeling_spiders()
|
||||
set category = "Changeling"
|
||||
set name = "Spread Infestation (40)"
|
||||
set desc = "Creates spiderlings."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(40, 10)
|
||||
if(!changeling) return 0
|
||||
src.mind.changeling.chem_charges -= 40
|
||||
|
||||
for(var/i=0, i<3, i++)
|
||||
var/obj/effect/spider/spiderling/S = new(src.loc)
|
||||
if(prob(50))//nurses are obnoxious and lay more eggs, let's not have that for now.
|
||||
S.grow_as = /mob/living/simple_animal/hostile/giant_spider/hunter
|
||||
else
|
||||
S.grow_as = /mob/living/simple_animal/hostile/giant_spider
|
||||
|
||||
feedback_add_details("changeling_powers","SI")
|
||||
return 1
|
||||
|
||||
|
||||
//Heals the things that the other regenerative abilities don't.
|
||||
/mob/living/carbon/proc/changeling_panacea()
|
||||
set category = "Changeling"
|
||||
set name = "Anatomic Panacea (35)"
|
||||
set desc = "Cures diseases, disabilities, toxins and radiation."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(35,0,100,UNCONSCIOUS)
|
||||
if(!changeling) return 0
|
||||
src.mind.changeling.chem_charges -= 35
|
||||
|
||||
src << "<span class='notice'>We cleanse impurities from our form.</span>"
|
||||
reagents.add_reagent("ryetalyn", 10)
|
||||
reagents.add_reagent("hyronalin", 10)
|
||||
reagents.add_reagent("anti_toxin", 20)
|
||||
|
||||
for(var/datum/disease/D in src.viruses)
|
||||
D.cure()
|
||||
|
||||
feedback_add_details("changeling_powers","AP")
|
||||
return 1
|
||||
|
||||
|
||||
//Prevents AIs tracking you but makes you easily detectable to the human-eye.
|
||||
/mob/living/carbon/proc/changeling_digitalcamo()
|
||||
set category = "Changeling"
|
||||
set name = "Toggle Digital Camoflague"
|
||||
set desc = "The AI can no longer track us, but we will look different if examined. Has a constant cost while active."
|
||||
set name = "Toggle Digital Camouflage"
|
||||
set desc = "The AI can no longer track us, but we will look different if examined."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power()
|
||||
if(!changeling) return 0
|
||||
@@ -360,27 +396,21 @@
|
||||
else src << "<span class='notice'>We distort our form to prevent AI-tracking.</span>"
|
||||
digitalcamo = !digitalcamo
|
||||
|
||||
spawn(0)
|
||||
while(src && digitalcamo && mind && mind.changeling)
|
||||
mind.changeling.chem_charges = max(mind.changeling.chem_charges - 1, 0)
|
||||
sleep(40)
|
||||
|
||||
src.verbs -= /mob/living/carbon/proc/changeling_digitalcamo
|
||||
spawn(5) src.verbs += /mob/living/carbon/proc/changeling_digitalcamo
|
||||
feedback_add_details("changeling_powers","CAM")
|
||||
return 1
|
||||
|
||||
|
||||
//Starts healing you every second for 10 seconds. Can be used whilst unconscious.
|
||||
/mob/living/carbon/proc/changeling_rapidregen()
|
||||
/mob/living/carbon/proc/changeling_fleshmend()
|
||||
set category = "Changeling"
|
||||
set name = "Rapid Regeneration (30)"
|
||||
set name = "Fleshmend (30)"
|
||||
set desc = "Begins rapidly regenerating. Does not effect stuns or chemicals."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(30,0,100,UNCONSCIOUS)
|
||||
if(!changeling) return 0
|
||||
src.mind.changeling.chem_charges -= 30
|
||||
|
||||
src << "<span class='notice'>We begin to heal rapidly.</span>"
|
||||
spawn(0)
|
||||
for(var/i = 0, i<10,i++)
|
||||
adjustBruteLoss(-10)
|
||||
@@ -389,13 +419,10 @@
|
||||
adjustFireLoss(-10)
|
||||
sleep(10)
|
||||
|
||||
src.verbs -= /mob/living/carbon/proc/changeling_rapidregen
|
||||
spawn(5) src.verbs += /mob/living/carbon/proc/changeling_rapidregen
|
||||
feedback_add_details("changeling_powers","RR")
|
||||
return 1
|
||||
|
||||
// HIVE MIND UPLOAD/DOWNLOAD DNA
|
||||
|
||||
var/list/datum/dna/hivemind_bank = list()
|
||||
|
||||
/mob/living/carbon/proc/changeling_hiveupload()
|
||||
@@ -403,7 +430,7 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
set name = "Hive Channel (10)"
|
||||
set desc = "Allows you to channel DNA in the airwaves to allow other changelings to absorb it."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(10,1)
|
||||
var/datum/changeling/changeling = changeling_power(10)
|
||||
if(!changeling) return
|
||||
|
||||
var/list/names = list()
|
||||
@@ -433,7 +460,7 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
set name = "Hive Absorb (20)"
|
||||
set desc = "Allows you to absorb DNA that is being channeled in the airwaves."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(20,1)
|
||||
var/datum/changeling/changeling = changeling_power(20)
|
||||
if(!changeling) return
|
||||
|
||||
var/list/names = list()
|
||||
@@ -451,14 +478,15 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
changeling.chem_charges -= 20
|
||||
changeling.absorbed_dna += chosen_dna
|
||||
src << "<span class='notice'>We absorb the DNA of [S] from the air.</span>"
|
||||
feedback_add_details("changeling_powers","HD")
|
||||
if(changeling.can_absorb_dna(null, usr))
|
||||
changeling.chem_charges -= 20
|
||||
changeling.shuffle_dna()
|
||||
changeling.absorbed_dna |= chosen_dna
|
||||
src << "<span class='notice'>We absorb the DNA of [S] from the air.</span>"
|
||||
feedback_add_details("changeling_powers","HD")
|
||||
return 1
|
||||
|
||||
// Fake Voice
|
||||
|
||||
/mob/living/carbon/proc/changeling_mimicvoice()
|
||||
set category = "Changeling"
|
||||
set name = "Mimic Voice"
|
||||
@@ -490,6 +518,9 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
sleep(40)
|
||||
if(src && src.mind && src.mind.changeling)
|
||||
src.mind.changeling.mimicing = ""
|
||||
|
||||
|
||||
|
||||
//////////
|
||||
//STINGS// //They get a pretty header because there's just so fucking many of them ;_;
|
||||
//////////
|
||||
@@ -517,9 +548,8 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
if(!changeling_power(required_chems)) return
|
||||
|
||||
changeling.chem_charges -= required_chems
|
||||
changeling.sting_range = 1
|
||||
verbs -= verb_path
|
||||
spawn(10) verbs += verb_path
|
||||
spawn(5) verbs += verb_path
|
||||
|
||||
src << "<span class='notice'>We stealthily sting [T].</span>"
|
||||
if(!T.mind || !T.mind.changeling) return T //T will be affected by the sting
|
||||
@@ -527,73 +557,10 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/carbon/proc/changeling_lsdsting()
|
||||
set category = "Changeling"
|
||||
set name = "Hallucination Sting (15)"
|
||||
set desc = "Causes terror in the target."
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(15,/mob/living/carbon/proc/changeling_lsdsting)
|
||||
if(!T) return 0
|
||||
spawn(rand(300,600))
|
||||
if(T) T.hallucination += 400
|
||||
feedback_add_details("changeling_powers","HS")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/changeling_silence_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Silence sting (10)"
|
||||
set desc="Sting target"
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(10,/mob/living/carbon/proc/changeling_silence_sting)
|
||||
if(!T) return 0
|
||||
T.silent += 30
|
||||
feedback_add_details("changeling_powers","SS")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/changeling_blind_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Blind sting (20)"
|
||||
set desc="Sting target"
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(20,/mob/living/carbon/proc/changeling_blind_sting)
|
||||
if(!T) return 0
|
||||
T << "<span class='danger'>Your eyes burn horrificly!</span>"
|
||||
T.disabilities |= NEARSIGHTED
|
||||
spawn(300) T.disabilities &= ~NEARSIGHTED
|
||||
T.eye_blind = 10
|
||||
T.eye_blurry = 20
|
||||
feedback_add_details("changeling_powers","BS")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/changeling_deaf_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Deaf sting (5)"
|
||||
set desc="Sting target:"
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(5,/mob/living/carbon/proc/changeling_deaf_sting)
|
||||
if(!T) return 0
|
||||
T << "<span class='danger'>Your ears pop and begin ringing loudly!</span>"
|
||||
T.sdisabilities |= DEAF
|
||||
spawn(300) T.sdisabilities &= ~DEAF
|
||||
feedback_add_details("changeling_powers","DS")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/changeling_paralysis_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Paralysis sting (30)"
|
||||
set desc="Sting target"
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(30,/mob/living/carbon/proc/changeling_paralysis_sting)
|
||||
if(!T) return 0
|
||||
T << "<span class='danger'>Your muscles begin to painfully tighten.</span>"
|
||||
T.Weaken(20)
|
||||
feedback_add_details("changeling_powers","PS")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/changeling_transformation_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Transformation sting (40)"
|
||||
set desc="Sting target"
|
||||
set name = "Transformation Sting (40)"
|
||||
set desc= "Transform the target to one of our stored DNAs"
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(40)
|
||||
if(!changeling) return 0
|
||||
@@ -614,7 +581,6 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
if((HUSK in T.mutations) || !check_dna_integrity(T))
|
||||
src << "<span class='warning'>Our sting appears ineffective against its DNA.</span>"
|
||||
return 0
|
||||
T.visible_message("<span class='warning'>[T] transforms!</span>")
|
||||
T.dna = chosen_dna
|
||||
T.real_name = chosen_dna.real_name
|
||||
updateappearance(T)
|
||||
@@ -622,24 +588,10 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
feedback_add_details("changeling_powers","TS")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/changeling_DEATHsting()
|
||||
set category = "Changeling"
|
||||
set name = "Death Sting (40)"
|
||||
set desc = "Causes spasms onto death."
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(40,/mob/living/carbon/proc/changeling_DEATHsting)
|
||||
if(!T) return 0
|
||||
T << "<span class='danger'>You feel a small prick and your chest becomes tight.</span>"
|
||||
T.silent = 10
|
||||
T.Paralyse(10)
|
||||
T.make_jittery(1000)
|
||||
if(T.reagents) T.reagents.add_reagent("lexorin", 40)
|
||||
feedback_add_details("changeling_powers","DTHS")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/changeling_extract_dna_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Extract DNA Sting (40)"
|
||||
set name = "Extract DNA Sting (25)"
|
||||
set desc="Stealthily sting a target to extract their DNA."
|
||||
|
||||
var/datum/changeling/changeling = null
|
||||
@@ -648,11 +600,69 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
if(!changeling)
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(40, /mob/living/carbon/proc/changeling_extract_dna_sting)
|
||||
var/mob/living/carbon/T = changeling_sting(25, /mob/living/carbon/proc/changeling_extract_dna_sting)
|
||||
if(!T) return 0
|
||||
|
||||
T.dna.real_name = T.real_name
|
||||
changeling.absorbed_dna |= T.dna
|
||||
if(changeling.can_absorb_dna(T, usr))
|
||||
changeling.absorb_dna(T, usr)
|
||||
else//If the sting fails, give the guy most of his chems back.
|
||||
changeling.chem_charges += 20
|
||||
|
||||
feedback_add_details("changeling_powers","ED")
|
||||
return 1
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/carbon/proc/changeling_mute_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Mute sting (20)"
|
||||
set desc= "Temporarily mutes the target."
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(20,/mob/living/carbon/proc/changeling_mute_sting)
|
||||
if(!T) return 0
|
||||
T.silent += 30
|
||||
feedback_add_details("changeling_powers","MS")
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/carbon/proc/changeling_blind_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Blind Sting (30)"
|
||||
set desc= "Temporarily blinds the target."
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(30,/mob/living/carbon/proc/changeling_blind_sting)
|
||||
if(!T) return 0
|
||||
T << "<span class='danger'>Your eyes burn horrifically!</span>"
|
||||
T.disabilities |= NEARSIGHTED
|
||||
T.eye_blind = 20
|
||||
T.eye_blurry = 40
|
||||
feedback_add_details("changeling_powers","BS")
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/carbon/proc/changeling_lsd_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Hallucination Sting (5)"
|
||||
set desc = "Causes terror in the target."
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(5,/mob/living/carbon/proc/changeling_lsd_sting)
|
||||
if(!T) return 0
|
||||
spawn(rand(300,600))
|
||||
if(T) T.hallucination += 400
|
||||
feedback_add_details("changeling_powers","HS")
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/carbon/proc/changeling_cryo_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Cryogenic Sting (15)"
|
||||
set desc = "Cools the target, slowing them."
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(15,/mob/living/carbon/proc/changeling_cryo_sting)
|
||||
if(!T) return 0
|
||||
|
||||
if(T.reagents)
|
||||
T.reagents.add_reagent("frostoil", 30)
|
||||
T.reagents.add_reagent("ice", 30)
|
||||
|
||||
feedback_add_details("changeling_powers","CS")
|
||||
return 1
|
||||
@@ -15,10 +15,18 @@ var/list/powerinstances
|
||||
|
||||
/datum/power/changeling/absorb_dna
|
||||
name = "Absorb DNA"
|
||||
desc = "Permits us to syphon the DNA from a human. They become one with us, and we become stronger."
|
||||
desc = "Permits us to siphon the DNA from a human. They become one with us, and the new energy lets us change our abilities."
|
||||
genomecost = 0
|
||||
verbpath = /mob/living/carbon/proc/changeling_absorb_dna
|
||||
|
||||
/datum/power/changeling/extractdna
|
||||
name = "Extract DNA Strand"
|
||||
desc = "We stealthily sting a target and extract the DNA from them."
|
||||
helptext = "Will give you the DNA of your target, allowing you to transform into them."
|
||||
genomecost = 0
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_extract_dna_sting
|
||||
|
||||
/datum/power/changeling/transform
|
||||
name = "Transform"
|
||||
desc = "We take on the appearance and voice of one we have absorbed."
|
||||
@@ -28,18 +36,18 @@ var/list/powerinstances
|
||||
/datum/power/changeling/fakedeath
|
||||
name = "Regenerative Stasis"
|
||||
desc = "We become weakened to a death-like state, where we will rise again from death."
|
||||
helptext = "Can be used before or after death. Duration varies greatly."
|
||||
helptext = "Can be used before or after death. Duration varies greatly. Can be used in lesser form."
|
||||
genomecost = 0
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_fakedeath
|
||||
|
||||
// Hivemind
|
||||
|
||||
/datum/power/changeling/hive_upload
|
||||
name = "Hive Channel"
|
||||
desc = "We can channel a DNA into the airwaves, allowing our fellow changelings to absorb it and transform into it as if they acquired the DNA themselves."
|
||||
helptext = "Allows other changelings to absorb the DNA you channel from the airwaves. Will not help them towards their absorb objectives."
|
||||
genomecost = 0
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_hiveupload
|
||||
|
||||
/datum/power/changeling/hive_download
|
||||
@@ -47,136 +55,118 @@ var/list/powerinstances
|
||||
desc = "We can absorb a single DNA from the airwaves, allowing us to use more disguises with help from our fellow changelings."
|
||||
helptext = "Allows you to absorb a single DNA and use it. Does not count towards your absorb objective."
|
||||
genomecost = 0
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_hivedownload
|
||||
|
||||
/datum/power/changeling/lesser_form
|
||||
name = "Lesser Form"
|
||||
desc = "We debase ourselves and become lesser. We become a monkey."
|
||||
desc = "We debase ourselves and become lesser. We become a monkey."
|
||||
genomecost = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_lesser_form
|
||||
|
||||
/datum/power/changeling/deaf_sting
|
||||
name = "Deaf Sting"
|
||||
desc = "We silently sting a human, completely deafening them for a short time."
|
||||
genomecost = 1
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_deaf_sting
|
||||
|
||||
/datum/power/changeling/blind_sting
|
||||
name = "Blind Sting"
|
||||
desc = "We silently sting a human, completely blinding them for a short time."
|
||||
genomecost = 2
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_blind_sting
|
||||
|
||||
/datum/power/changeling/silence_sting
|
||||
name = "Silence Sting"
|
||||
desc = "We silently sting a human, completely silencing them for a short time."
|
||||
helptext = "Does not provide a warning to a victim that they have been stung, until they try to speak and cannot."
|
||||
genomecost = 2
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_silence_sting
|
||||
|
||||
/datum/power/changeling/mimicvoice
|
||||
name = "Mimic Voice"
|
||||
desc = "We shape our vocal glands to sound like a desired voice."
|
||||
helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this"
|
||||
genomecost = 3
|
||||
genomecost = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_mimicvoice
|
||||
|
||||
/datum/power/changeling/extractdna
|
||||
name = "Extract DNA"
|
||||
desc = "We stealthily sting a target and extract the DNA from them."
|
||||
helptext = "Will give you the DNA of your target, allowing you to transform into them. Does not count towards absorb objectives."
|
||||
genomecost = 4
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_extract_dna_sting
|
||||
|
||||
/datum/power/changeling/transformation_sting
|
||||
name = "Transformation Sting"
|
||||
desc = "We silently sting a human, injecting a retrovirus that forces them to transform into another."
|
||||
helptext = "Does not provide a warning to others. The victim will transform much like a changeling would."
|
||||
genomecost = 3
|
||||
genomecost = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_transformation_sting
|
||||
|
||||
/datum/power/changeling/paralysis_sting
|
||||
name = "Paralysis Sting"
|
||||
desc = "We silently sting a human, paralyzing them for a short time."
|
||||
genomecost = 3
|
||||
verbpath = /mob/living/carbon/proc/changeling_paralysis_sting
|
||||
|
||||
/datum/power/changeling/LSDSting
|
||||
name = "Hallucination Sting"
|
||||
desc = "We evolve the ability to sting a target with a powerful hallucinogenic chemical."
|
||||
helptext = "The target does not notice they have been stung. The effect occurs after 30 to 60 seconds."
|
||||
genomecost = 3
|
||||
verbpath = /mob/living/carbon/proc/changeling_lsdsting
|
||||
|
||||
/datum/power/changeling/DeathSting
|
||||
name = "Death Sting"
|
||||
desc = "We silently sting a human, filling him with potent chemicals. His rapid death is all but assured."
|
||||
genomecost = 10
|
||||
verbpath = /mob/living/carbon/proc/changeling_DEATHsting
|
||||
|
||||
/datum/power/changeling/boost_range
|
||||
name = "Boost Range"
|
||||
desc = "We evolve the ability to shoot our stingers at humans, with some preperation."
|
||||
genomecost = 2
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_boost_range
|
||||
|
||||
/datum/power/changeling/Epinephrine
|
||||
name = "Epinephrine sacs"
|
||||
name = "Epinephrine Sacs"
|
||||
desc = "We evolve additional sacs of adrenaline throughout our body."
|
||||
helptext = "Gives the ability to instantly recover from stuns. High chemical cost."
|
||||
genomecost = 4
|
||||
helptext = "Removes all stuns instantly, and adds a short-term reduction in further stuns. Can be used while unconscious."
|
||||
genomecost = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_unstun
|
||||
|
||||
/datum/power/changeling/ChemicalSynth
|
||||
name = "Rapid Chemical-Synthesis"
|
||||
desc = "We evolve new pathways for producing our necessary chemicals, permitting us to naturally create them faster."
|
||||
helptext = "Doubles the rate at which we naturally recharge chemicals."
|
||||
genomecost = 4
|
||||
isVerb = 0
|
||||
verbpath = /mob/proc/changeling_fastchemical
|
||||
/*
|
||||
/datum/power/changeling/AdvChemicalSynth
|
||||
name = "Advanced Chemical-Synthesis"
|
||||
desc = "We evolve new pathways for producing our necessary chemicals, permitting us to naturally create them faster."
|
||||
helptext = "Doubles the rate at which we naturally recharge chemicals."
|
||||
genomecost = 8
|
||||
isVerb = 0
|
||||
verbpath = /mob/living/carbon/proc/changeling_fastchemical
|
||||
*/
|
||||
/datum/power/changeling/EngorgedGlands
|
||||
name = "Engorged Chemical Glands"
|
||||
desc = "Our chemical glands swell, permitting us to store more chemicals inside of them."
|
||||
helptext = "Allows us to store an extra 25 units of chemicals."
|
||||
genomecost = 4
|
||||
helptext = "Allows us to store an extra 25 units of chemicals, and doubles production rate."
|
||||
genomecost = 1
|
||||
isVerb = 0
|
||||
verbpath = /mob/proc/changeling_engorgedglands
|
||||
verbpath = /mob/proc/changeling_advglands
|
||||
|
||||
/datum/power/changeling/DigitalCamoflague
|
||||
name = "Digital Camoflauge"
|
||||
desc = "We evolve the ability to distort our form and proprtions, defeating common altgorthms used to detect lifeforms on cameras."
|
||||
helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us.. uncanny. We must constantly expend chemicals to maintain our form like this."
|
||||
genomecost = 3
|
||||
/datum/power/changeling/DigitalCamouflage
|
||||
name = "Digital Camouflage"
|
||||
desc = "We evolve the ability to distort our form and proprotions, defeating common altgorthms used to detect lifeforms on cameras."
|
||||
helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us... uncanny."
|
||||
genomecost = 1
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_digitalcamo
|
||||
|
||||
/datum/power/changeling/rapidregeneration
|
||||
name = "Rapid Regeneration"
|
||||
desc = "We evolve the ability to rapidly regenerate, negating the need for stasis."
|
||||
helptext = "Heals a moderate amount of damage every tick."
|
||||
genomecost = 8
|
||||
verbpath = /mob/living/carbon/proc/changeling_rapidregen
|
||||
/datum/power/changeling/fleshmend
|
||||
name = "Fleshmend"
|
||||
desc = "We evolve the ability to rapidly regenerate, restoring the health of the body we use."
|
||||
helptext = "Heals a moderate amount of damage every tick. Can be used while unconscious."
|
||||
genomecost = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_fleshmend
|
||||
|
||||
/datum/power/changeling/panacea
|
||||
name = "Anatomic Panacea"
|
||||
desc = "Expels impurifications from our form; curing diseases, genetic disabilities, and removing toxins and radiation."
|
||||
helptext = "Can be used while unconscious."
|
||||
genomecost = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_panacea
|
||||
|
||||
/datum/power/changeling/shriek
|
||||
name = "Resonant Shriek"
|
||||
desc = "Our lungs and vocal chords shift, allowing us to briefly emit a noise that deafens and confuses humans."
|
||||
helptext = "The high-frequency sounds cannot be heard by humans, but will blow out lights nearby."
|
||||
genomecost = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_shriek
|
||||
|
||||
/datum/power/changeling/spiders
|
||||
name = "Spread Infestation"
|
||||
desc = "Our form divides, creating arachnids which will grow into deadly beasts."
|
||||
helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires 10 DNA absorptions."
|
||||
genomecost = 1
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_spiders
|
||||
|
||||
/datum/power/changeling/lsd_sting
|
||||
name = "Hallucination Sting"
|
||||
desc = "We evolve the ability to sting a target with a powerful hallucinogenic chemical."
|
||||
helptext = "The target does not notice they have been stung. The effect occurs after 30 to 60 seconds."
|
||||
genomecost = 1
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_lsd_sting
|
||||
|
||||
/datum/power/changeling/blind_sting
|
||||
name = "Blind Sting"
|
||||
desc = "We silently sting a human, completely blinding them for a short time."
|
||||
genomecost = 1
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_blind_sting
|
||||
|
||||
/datum/power/changeling/cryo_sting
|
||||
name = "Cryogenic Sting"
|
||||
desc = "We silently sting a human with a cocktail of chemicals, slowing their metabolism."
|
||||
helptext = "Does not provide a warning to a victim, though they will likely realize they are suddenly freezing."
|
||||
genomecost = 1
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_cryo_sting
|
||||
|
||||
/datum/power/changeling/mute_sting
|
||||
name = "Mute Sting"
|
||||
desc = "We silently sting a human, completely silencing them for a short time."
|
||||
helptext = "Does not provide a warning to a victim that they have been stung, until they try to speak and cannot."
|
||||
genomecost = 1
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/carbon/proc/changeling_mute_sting
|
||||
|
||||
|
||||
// Modularchangling, totally stolen from the new player panel. YAYY
|
||||
/datum/changeling/proc/EvolutionMenu()//The new one
|
||||
set name = "-Evolution Menu-"//Dashes are so it's listed before all the other abilities.
|
||||
set category = "Changeling"
|
||||
set desc = "Level up!"
|
||||
set desc = "Choose our method of subjugation."
|
||||
|
||||
if(!usr || !usr.mind || !usr.mind.changeling) return
|
||||
src = usr.mind.changeling
|
||||
@@ -372,10 +362,11 @@ var/list/powerinstances
|
||||
<table width='560' align='center' cellspacing='0' cellpadding='5' id='maintable'>
|
||||
<tr id='title_tr'>
|
||||
<td align='center'>
|
||||
<font size='5'><b>Changling Evolution Menu</b></font><br>
|
||||
<font size='5'><b>Changeling Evolution Menu</b></font><br>
|
||||
Hover over a power to see more information<br>
|
||||
Current evolution points left to evolve with: [geneticpoints]<br>
|
||||
Absorb genomes to acquire more evolution points
|
||||
Current ability choices remaining: [geneticpoints]<br>
|
||||
By rendering a lifeform to a husk, we gain enough power to alter and adapt our evolutions.<br>
|
||||
(<a href='?src=\ref[src];readapt=1'>Readapt</a>)<br>
|
||||
<p>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -397,13 +388,24 @@ var/list/powerinstances
|
||||
for(var/datum/power/changeling/P in powerinstances)
|
||||
var/ownsthis = 0
|
||||
|
||||
if(P.genomecost == 0) //Let's skip the crap we start with. Keeps the evolution menu uncluttered.
|
||||
continue
|
||||
|
||||
if(P in purchasedpowers)
|
||||
ownsthis = 1
|
||||
|
||||
|
||||
var/color = "#e6e6e6"
|
||||
if(i%2 == 0)
|
||||
color = "#f2f2f2"
|
||||
var/color
|
||||
if(ownsthis)
|
||||
if(i%2 == 0)
|
||||
color = "#d8ebd8"
|
||||
else
|
||||
color = "#c3dec3"
|
||||
else
|
||||
if(i%2 == 0)
|
||||
color = "#f2f2f2"
|
||||
else
|
||||
color = "#e6e6e6"
|
||||
|
||||
|
||||
dat += {"
|
||||
@@ -414,7 +416,7 @@ var/list/powerinstances
|
||||
<a id='link[i]'
|
||||
onmouseover='expand("item[i]","[P.name]","[P.desc]","[P.helptext]","[P]",[ownsthis])'
|
||||
>
|
||||
<b id='search[i]'>Evolve [P] - Cost: [ownsthis ? "Purchased" : P.genomecost]</b>
|
||||
<b id='search[i]'>Evolve [P][ownsthis ? " - Purchased" : ((P.genomecost > 1) ? " - Cost: [P.genomecost]" : "")]</b>
|
||||
</a>
|
||||
<br><span id='item[i]'></span>
|
||||
</td>
|
||||
@@ -437,7 +439,7 @@ var/list/powerinstances
|
||||
</body></html>
|
||||
"}
|
||||
|
||||
usr << browse(dat, "window=powers;size=900x480")
|
||||
usr << browse(dat, "window=powers;size=600x700")//900x480
|
||||
|
||||
|
||||
/datum/changeling/Topic(href, href_list)
|
||||
@@ -452,42 +454,81 @@ var/list/powerinstances
|
||||
purchasePower(M, href_list["P"])
|
||||
call(/datum/changeling/proc/EvolutionMenu)()
|
||||
|
||||
if(href_list["readapt"])
|
||||
var/datum/mind/M = usr.mind
|
||||
if(!istype(M))
|
||||
return
|
||||
lingRespec(M)
|
||||
call(/datum/changeling/proc/EvolutionMenu)()
|
||||
return
|
||||
|
||||
/////
|
||||
|
||||
/datum/changeling/proc/purchasePower(var/datum/mind/M, var/Pname, var/remake_verbs = 1)
|
||||
/datum/changeling/proc/purchasePower(var/datum/mind/M, var/pname, var/remake_verbs = 1)
|
||||
if(!M || !M.changeling || !istype(M.current, /mob/living/carbon))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = M.current
|
||||
var/datum/power/changeling/Thepower = Pname
|
||||
|
||||
var/datum/power/changeling/thepower = pname
|
||||
|
||||
for (var/datum/power/changeling/P in powerinstances)
|
||||
//world << "[P] - [Pname] = [P.name == Pname ? "True" : "False"]"
|
||||
if(P.name == Pname)
|
||||
Thepower = P
|
||||
if(P.name == pname)
|
||||
thepower = P
|
||||
break
|
||||
|
||||
|
||||
if(Thepower == null)
|
||||
C << "This is awkward. Changeling power purchase failed, please report this bug to a coder!"
|
||||
if(thepower == null)
|
||||
C << "This is awkward. Changeling power purchase failed, please report this bug to a coder!"
|
||||
return
|
||||
|
||||
if(Thepower in purchasedpowers)
|
||||
if(thepower in purchasedpowers)
|
||||
C << "We have already evolved this ability!"
|
||||
return
|
||||
|
||||
|
||||
if(geneticpoints < Thepower.genomecost)
|
||||
C << "We cannot evolve this... yet. We must acquire more DNA."
|
||||
if(geneticpoints < thepower.genomecost)
|
||||
C << "We have reached our capacity for abilities."
|
||||
return
|
||||
|
||||
geneticpoints -= Thepower.genomecost
|
||||
if(C.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
|
||||
C << "We lack the energy to evolve new abilities right now."
|
||||
return
|
||||
|
||||
purchasedpowers += Thepower
|
||||
geneticpoints -= thepower.genomecost
|
||||
|
||||
if(!Thepower.isVerb && Thepower.verbpath)
|
||||
call(C, Thepower.verbpath)()
|
||||
purchasedpowers += thepower
|
||||
|
||||
if(!thepower.isVerb && thepower.verbpath)
|
||||
call(C, thepower.verbpath)()
|
||||
else if(remake_verbs)
|
||||
C.make_changeling()
|
||||
|
||||
/////
|
||||
|
||||
/datum/changeling/proc/lingRespec(var/datum/mind/M)
|
||||
if(!M || !M.changeling || !istype(M.current, /mob/living/carbon))
|
||||
return
|
||||
|
||||
if(canrespec)
|
||||
usr << "We have removed our evolutions from this form, and are now ready to readapt."
|
||||
|
||||
var/mob/living/carbon/C = M.current
|
||||
|
||||
C.remove_changeling_powers()//Revokes our verb powers.
|
||||
clearlist(purchasedpowers)
|
||||
|
||||
|
||||
//Resets our stats, to account for purchased passives.
|
||||
C.digitalcamo = 0
|
||||
geneticpoints = initial(geneticpoints)
|
||||
sting_range = initial(sting_range)
|
||||
chem_storage = initial(chem_storage)
|
||||
chem_recharge_rate = initial(chem_recharge_rate)
|
||||
chem_charges = min(chem_charges, chem_storage)
|
||||
mimicing = ""
|
||||
|
||||
canrespec = 0
|
||||
|
||||
C.make_changeling()//Remake our verbs; rebuys the 0 cost skills.
|
||||
else
|
||||
usr << "You lack the power to readapt your evolutions!"
|
||||
|
||||
return 1
|
||||
@@ -20,6 +20,10 @@ rcd light flash thingy on matter drain
|
||||
var/mod_pick_name
|
||||
var/description = ""
|
||||
var/engaged = 0
|
||||
var/cost = 5
|
||||
var/one_time = 0
|
||||
|
||||
var/power_type
|
||||
|
||||
|
||||
/datum/AI_Module/large/
|
||||
@@ -32,54 +36,72 @@ rcd light flash thingy on matter drain
|
||||
/datum/AI_Module/large/fireproof_core
|
||||
module_name = "Core upgrade"
|
||||
mod_pick_name = "coreup"
|
||||
description = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent."
|
||||
cost = 50
|
||||
one_time = 1
|
||||
|
||||
/client/proc/fireproof_core()
|
||||
power_type = /mob/living/silicon/ai/proc/fireproof_core
|
||||
|
||||
/mob/living/silicon/ai/proc/fireproof_core()
|
||||
set category = "Malfunction"
|
||||
set name = "Fireproof Core"
|
||||
for(var/mob/living/silicon/ai/ai in player_list)
|
||||
ai.fire_res_on_core = 1
|
||||
usr.verbs -= /client/proc/fireproof_core
|
||||
usr << "\red Core fireproofed."
|
||||
src.verbs -= /mob/living/silicon/ai/proc/fireproof_core
|
||||
src << "\red Core fireproofed."
|
||||
|
||||
/datum/AI_Module/large/upgrade_turrets
|
||||
module_name = "AI Turret upgrade"
|
||||
mod_pick_name = "turret"
|
||||
description = "Improves the firing speed and health of all AI turrets. This effect is permanent."
|
||||
cost = 50
|
||||
one_time = 1
|
||||
|
||||
/client/proc/upgrade_turrets()
|
||||
power_type = /mob/living/silicon/ai/proc/upgrade_turrets
|
||||
|
||||
/mob/living/silicon/ai/proc/upgrade_turrets()
|
||||
set category = "Malfunction"
|
||||
set name = "Upgrade Turrets"
|
||||
usr.verbs -= /client/proc/upgrade_turrets
|
||||
for(var/obj/machinery/turret/turret in player_list)
|
||||
src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets
|
||||
for(var/obj/machinery/turret/turret in machines)
|
||||
turret.health += 30
|
||||
turret.shot_delay = 20
|
||||
|
||||
/datum/AI_Module/large/disable_rcd
|
||||
module_name = "RCD disable"
|
||||
mod_pick_name = "rcd"
|
||||
description = "Send a specialised pulse to break all RCD devices on the station."
|
||||
cost = 50
|
||||
|
||||
/client/proc/disable_rcd()
|
||||
power_type = /mob/living/silicon/ai/proc/disable_rcd
|
||||
|
||||
/mob/living/silicon/ai/proc/disable_rcd()
|
||||
set category = "Malfunction"
|
||||
set name = "Disable RCDs"
|
||||
for(var/datum/AI_Module/large/disable_rcd/rcdmod in usr:current_modules)
|
||||
for(var/datum/AI_Module/large/disable_rcd/rcdmod in current_modules)
|
||||
if(rcdmod.uses > 0)
|
||||
rcdmod.uses --
|
||||
for(var/obj/item/weapon/rcd/rcd in world)
|
||||
rcd.disabled = 1
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/rcd in world)
|
||||
rcd.disabled = 1
|
||||
usr << "RCD-disabling pulse emitted."
|
||||
else usr << "Out of uses."
|
||||
src << "RCD-disabling pulse emitted."
|
||||
else src << "Out of uses."
|
||||
|
||||
/datum/AI_Module/small/overload_machine
|
||||
module_name = "Machine overload"
|
||||
mod_pick_name = "overload"
|
||||
description = "Overloads an electrical machine, causing a small explosion. 2 uses."
|
||||
uses = 2
|
||||
cost = 15
|
||||
|
||||
/client/proc/overload_machine(obj/machinery/M as obj in world)
|
||||
power_type = /mob/living/silicon/ai/proc/overload_machine
|
||||
|
||||
/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M as obj in world)
|
||||
set name = "Overload Machine"
|
||||
set category = "Malfunction"
|
||||
if (istype(M, /obj/machinery))
|
||||
for(var/datum/AI_Module/small/overload_machine/overload in usr:current_modules)
|
||||
for(var/datum/AI_Module/small/overload_machine/overload in current_modules)
|
||||
if(overload.uses > 0)
|
||||
overload.uses --
|
||||
for(var/mob/V in hearers(M, null))
|
||||
@@ -87,67 +109,141 @@ rcd light flash thingy on matter drain
|
||||
spawn(50)
|
||||
explosion(get_turf(M), 0,1,1,0)
|
||||
del(M)
|
||||
else usr << "Out of uses."
|
||||
else usr << "That's not a machine."
|
||||
else src << "Out of uses."
|
||||
else src << "That's not a machine."
|
||||
|
||||
/*
|
||||
|
||||
/datum/AI_Module/large/place_cyborg_transformer
|
||||
module_name = "Robotic Factory (Removes Shunting)"
|
||||
mod_pick_name = "cyborgtransformer"
|
||||
description = "Build a machine anywhere, using expensive nanomachines, that can convert a living human into a loyal cyborg slave when placed inside."
|
||||
cost = 100
|
||||
|
||||
power_type = /mob/living/silicon/ai/proc/place_transformer
|
||||
|
||||
/mob/living/silicon/ai/proc/place_transformer()
|
||||
set name = "Place Robotic Factory"
|
||||
set category = "Malfunction"
|
||||
|
||||
if(!eyeobj)
|
||||
return
|
||||
|
||||
if(!isturf(src.loc)) // AI must be in it's core.
|
||||
return
|
||||
|
||||
var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in src.current_modules
|
||||
if(!PCT)
|
||||
return
|
||||
|
||||
if(PCT.uses < 1)
|
||||
src << "Out of uses."
|
||||
return
|
||||
|
||||
var/sure = alert(src, "Make sure the room it is in is big enough and that there is a 1x3 area for the machine. Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No")
|
||||
if(sure != "Yes")
|
||||
return
|
||||
|
||||
// Make sure there is enough room.
|
||||
var/turf/middle = get_turf(eyeobj.loc)
|
||||
var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z))
|
||||
|
||||
var/alert_msg = "There isn't enough room. Make sure you are placing the machine in a clear area and on a floor."
|
||||
|
||||
for(var/T in turfs)
|
||||
|
||||
// Make sure the turfs are clear and the correct type.
|
||||
if(!istype(T, /turf/simulated/floor))
|
||||
alert(src, alert_msg)
|
||||
return
|
||||
|
||||
var/turf/simulated/floor/F = T
|
||||
for(var/atom/movable/AM in F.contents)
|
||||
if(AM.density)
|
||||
alert(src, alert_msg)
|
||||
return
|
||||
|
||||
// All clear, place the transformer
|
||||
new /obj/machinery/transformer/conveyor(middle)
|
||||
src.can_shunt = 0
|
||||
PCT.uses -= 1
|
||||
src << "You cannot shunt anymore."
|
||||
|
||||
*/
|
||||
|
||||
/datum/AI_Module/small/blackout
|
||||
module_name = "Blackout"
|
||||
mod_pick_name = "blackout"
|
||||
description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses."
|
||||
uses = 3
|
||||
cost = 15
|
||||
|
||||
/client/proc/blackout()
|
||||
power_type = /mob/living/silicon/ai/proc/blackout
|
||||
|
||||
/mob/living/silicon/ai/proc/blackout()
|
||||
set category = "Malfunction"
|
||||
set name = "Blackout"
|
||||
for(var/datum/AI_Module/small/blackout/blackout in usr:current_modules)
|
||||
for(var/datum/AI_Module/small/blackout/blackout in current_modules)
|
||||
if(blackout.uses > 0)
|
||||
blackout.uses --
|
||||
for(var/obj/machinery/power/apc/apc in world)
|
||||
if(prob(30*apc.overload))
|
||||
apc.overload_lighting()
|
||||
else apc.overload++
|
||||
else usr << "Out of uses."
|
||||
else src << "Out of uses."
|
||||
|
||||
/datum/AI_Module/small/interhack
|
||||
module_name = "Hack intercept"
|
||||
mod_pick_name = "interhack"
|
||||
description = "Hacks the status upgrade from Cent. Com, removing any information about malfunctioning electrical systems."
|
||||
cost = 15
|
||||
one_time = 1
|
||||
|
||||
/client/proc/interhack()
|
||||
power_type = /mob/living/silicon/ai/proc/interhack
|
||||
|
||||
/mob/living/silicon/ai/proc/interhack()
|
||||
set category = "Malfunction"
|
||||
set name = "Hack intercept"
|
||||
usr.verbs -= /client/proc/interhack
|
||||
src.verbs -= /mob/living/silicon/ai/proc/interhack
|
||||
ticker.mode:hack_intercept()
|
||||
|
||||
/datum/AI_Module/small/reactivate_camera
|
||||
module_name = "Reactivate camera"
|
||||
mod_pick_name = "recam"
|
||||
description = "Reactivates a currently disabled camera. 10 uses."
|
||||
uses = 10
|
||||
cost = 15
|
||||
|
||||
/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
|
||||
power_type = /mob/living/silicon/ai/proc/reactivate_camera
|
||||
|
||||
/mob/living/silicon/ai/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
|
||||
set name = "Reactivate Camera"
|
||||
set category = "Malfunction"
|
||||
if (istype (C, /obj/machinery/camera))
|
||||
for(var/datum/AI_Module/small/reactivate_camera/camera in usr:current_modules)
|
||||
for(var/datum/AI_Module/small/reactivate_camera/camera in current_modules)
|
||||
if(camera.uses > 0)
|
||||
if(!C.status)
|
||||
C.status = !C.status
|
||||
C.deactivate(src)
|
||||
camera.uses --
|
||||
for(var/mob/V in viewers(src, null))
|
||||
V.show_message(text("\blue You hear a quiet click."))
|
||||
else
|
||||
usr << "This camera is either active, or not repairable."
|
||||
else usr << "Out of uses."
|
||||
else usr << "That's not a camera."
|
||||
src << "This camera is either active, or not repairable."
|
||||
else src << "Out of uses."
|
||||
else src << "That's not a camera."
|
||||
|
||||
/datum/AI_Module/small/upgrade_camera
|
||||
module_name = "Upgrade Camera"
|
||||
mod_pick_name = "upgradecam"
|
||||
description = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 10 uses."
|
||||
uses = 10
|
||||
cost = 15
|
||||
|
||||
/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
|
||||
power_type = /mob/living/silicon/ai/proc/upgrade_camera
|
||||
|
||||
/mob/living/silicon/ai/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
|
||||
set name = "Upgrade Camera"
|
||||
set category = "Malfunction"
|
||||
if(istype(C))
|
||||
var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in usr:current_modules
|
||||
var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in current_modules
|
||||
if(UC)
|
||||
if(UC.uses > 0)
|
||||
if(C.assembly)
|
||||
@@ -156,7 +252,7 @@ rcd light flash thingy on matter drain
|
||||
if(!C.isXRay())
|
||||
C.upgradeXRay()
|
||||
//Update what it can see.
|
||||
cameranet.updateVisibility(C)
|
||||
cameranet.updateVisibility(C, 0)
|
||||
upgraded = 1
|
||||
|
||||
if(!C.isEmpProof())
|
||||
@@ -172,154 +268,80 @@ rcd light flash thingy on matter drain
|
||||
if(upgraded)
|
||||
UC.uses --
|
||||
C.visible_message("<span class='notice'>\icon[C] *beep*</span>")
|
||||
usr << "Camera successully upgraded!"
|
||||
src << "Camera successully upgraded!"
|
||||
else
|
||||
usr << "This camera is already upgraded!"
|
||||
src << "This camera is already upgraded!"
|
||||
else
|
||||
usr << "Out of uses."
|
||||
src << "Out of uses."
|
||||
|
||||
|
||||
/datum/AI_Module/module_picker
|
||||
/datum/module_picker
|
||||
var/temp = null
|
||||
var/processing_time = 100
|
||||
var/list/possible_modules = list()
|
||||
|
||||
/datum/AI_Module/module_picker/New()
|
||||
src.possible_modules += new /datum/AI_Module/large/fireproof_core
|
||||
src.possible_modules += new /datum/AI_Module/large/upgrade_turrets
|
||||
src.possible_modules += new /datum/AI_Module/large/disable_rcd
|
||||
src.possible_modules += new /datum/AI_Module/small/overload_machine
|
||||
src.possible_modules += new /datum/AI_Module/small/interhack
|
||||
src.possible_modules += new /datum/AI_Module/small/blackout
|
||||
src.possible_modules += new /datum/AI_Module/small/reactivate_camera
|
||||
src.possible_modules += new /datum/AI_Module/small/upgrade_camera
|
||||
/datum/module_picker/New()
|
||||
for(var/type in typesof(/datum/AI_Module))
|
||||
var/datum/AI_Module/AM = new type
|
||||
if(AM.power_type != null)
|
||||
src.possible_modules += AM
|
||||
|
||||
/datum/AI_Module/module_picker/proc/use(user as mob)
|
||||
/datum/module_picker/proc/remove_verbs(var/mob/living/silicon/ai/A)
|
||||
|
||||
for(var/datum/AI_Module/AM in possible_modules)
|
||||
A.verbs.Remove(AM.power_type)
|
||||
|
||||
|
||||
/datum/module_picker/proc/use(user as mob)
|
||||
var/dat
|
||||
dat = "<B>Select use of processing time: (currently #[src.processing_time] left.)</B><BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<B>Install Module:</B><BR>"
|
||||
dat += "<I>The number afterwards is the amount of processing time it consumes.</I><BR>"
|
||||
for(var/datum/AI_Module/large/module in src.possible_modules)
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A> ([module.cost])<BR>"
|
||||
for(var/datum/AI_Module/small/module in src.possible_modules)
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A> ([module.cost])<BR>"
|
||||
dat += "<HR>"
|
||||
if (src.temp)
|
||||
dat = "[src.temp]<BR><BR><A href='byond://?src=\ref[src];temp=1'>Clear</A>"
|
||||
else if(src.processing_time <= 0)
|
||||
dat = "<B> No processing time is left available. No more modules are able to be chosen at this time."
|
||||
else
|
||||
dat = "<B>Select use of processing time: (currently [src.processing_time] left.)</B><BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<B>Install Module:</B><BR>"
|
||||
dat += "<I>The number afterwards is the amount of processing time it consumes.</I><BR>"
|
||||
for(var/datum/AI_Module/large/module in src.possible_modules)
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A> (50)<BR>"
|
||||
for(var/datum/AI_Module/small/module in src.possible_modules)
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A> (15)<BR>"
|
||||
dat += "<HR>"
|
||||
|
||||
user << browse(dat, "window=modpicker")
|
||||
onclose(user, "modpicker")
|
||||
dat += "[src.temp]"
|
||||
var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu")
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
return
|
||||
|
||||
/datum/AI_Module/module_picker/Topic(href, href_list)
|
||||
/datum/module_picker/Topic(href, href_list)
|
||||
..()
|
||||
if (href_list["coreup"])
|
||||
var/already
|
||||
for (var/datum/AI_Module/mod in usr:current_modules)
|
||||
if(istype(mod, /datum/AI_Module/large/fireproof_core))
|
||||
already = 1
|
||||
if (!already)
|
||||
usr.verbs += /client/proc/fireproof_core
|
||||
usr:current_modules += new /datum/AI_Module/large/fireproof_core
|
||||
src.temp = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent."
|
||||
src.processing_time -= 50
|
||||
else src.temp = "This module is only needed once."
|
||||
|
||||
else if (href_list["turret"])
|
||||
var/already
|
||||
for (var/datum/AI_Module/mod in usr:current_modules)
|
||||
if(istype(mod, /datum/AI_Module/large/upgrade_turrets))
|
||||
already = 1
|
||||
if (!already)
|
||||
usr.verbs += /client/proc/upgrade_turrets
|
||||
usr:current_modules += new /datum/AI_Module/large/upgrade_turrets
|
||||
src.temp = "Improves the firing speed and health of all AI turrets. This effect is permanent."
|
||||
src.processing_time -= 50
|
||||
else src.temp = "This module is only needed once."
|
||||
if(!isAI(usr))
|
||||
return
|
||||
var/mob/living/silicon/ai/A = usr
|
||||
|
||||
else if (href_list["rcd"])
|
||||
var/already
|
||||
for (var/datum/AI_Module/mod in usr:current_modules)
|
||||
if(istype(mod, /datum/AI_Module/large/disable_rcd))
|
||||
mod:uses += 1
|
||||
already = 1
|
||||
if (!already)
|
||||
usr:current_modules += new /datum/AI_Module/large/disable_rcd
|
||||
usr.verbs += /client/proc/disable_rcd
|
||||
src.temp = "Send a specialised pulse to break all RCD devices on the station."
|
||||
else src.temp = "Additional use added to RCD disabler."
|
||||
src.processing_time -= 50
|
||||
for(var/datum/AI_Module/AM in possible_modules)
|
||||
if (href_list[AM.mod_pick_name])
|
||||
|
||||
else if (href_list["overload"])
|
||||
var/already
|
||||
for (var/datum/AI_Module/mod in usr:current_modules)
|
||||
if(istype(mod, /datum/AI_Module/small/overload_machine))
|
||||
mod:uses += 2
|
||||
already = 1
|
||||
if (!already)
|
||||
usr.verbs += /client/proc/overload_machine
|
||||
usr:current_modules += new /datum/AI_Module/small/overload_machine
|
||||
src.temp = "Overloads an electrical machine, causing a small explosion. 2 uses."
|
||||
else src.temp = "Two additional uses added to Overload module."
|
||||
src.processing_time -= 15
|
||||
// Cost check
|
||||
if(AM.cost > src.processing_time)
|
||||
temp = "You cannot afford this module."
|
||||
break
|
||||
|
||||
else if (href_list["blackout"])
|
||||
var/already
|
||||
for (var/datum/AI_Module/mod in usr:current_modules)
|
||||
if(istype(mod, /datum/AI_Module/small/blackout))
|
||||
mod:uses += 3
|
||||
already = 1
|
||||
if (!already)
|
||||
usr.verbs += /client/proc/blackout
|
||||
src.temp = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses."
|
||||
usr:current_modules += new /datum/AI_Module/small/blackout
|
||||
else src.temp = "Three additional uses added to Blackout module."
|
||||
src.processing_time -= 15
|
||||
// Add new uses if we can, and it is allowed.
|
||||
var/datum/AI_Module/already_AM = locate(AM.type) in A.current_modules
|
||||
if(already_AM)
|
||||
if(!AM.one_time)
|
||||
already_AM.uses += AM.uses
|
||||
src.processing_time -= AM.cost
|
||||
temp = "Additional use added to [already_AM.module_name]"
|
||||
break
|
||||
else
|
||||
temp = "This module is only needed once."
|
||||
break
|
||||
|
||||
else if (href_list["interhack"])
|
||||
var/already
|
||||
for (var/datum/AI_Module/mod in usr:current_modules)
|
||||
if(istype(mod, /datum/AI_Module/small/interhack))
|
||||
already = 1
|
||||
if (!already)
|
||||
usr.verbs += /client/proc/interhack
|
||||
src.temp = "Hacks the status upgrade from Cent. Com, removing any information about malfunctioning electrical systems."
|
||||
usr:current_modules += new /datum/AI_Module/small/interhack
|
||||
src.processing_time -= 15
|
||||
else src.temp = "This module is only needed once."
|
||||
// Give the power and take away the money.
|
||||
A.verbs += AM.power_type
|
||||
A.current_modules += new AM.type
|
||||
temp = AM.description
|
||||
src.processing_time -= AM.cost
|
||||
|
||||
else if (href_list["recam"])
|
||||
var/already
|
||||
for (var/datum/AI_Module/mod in usr:current_modules)
|
||||
if(istype(mod, /datum/AI_Module/small/reactivate_camera))
|
||||
mod:uses += 10
|
||||
already = 1
|
||||
if (!already)
|
||||
usr.verbs += /client/proc/reactivate_camera
|
||||
src.temp = "Reactivates a currently disabled camera. 10 uses."
|
||||
usr:current_modules += new /datum/AI_Module/small/reactivate_camera
|
||||
else src.temp = "Ten additional uses added to ReCam module."
|
||||
src.processing_time -= 15
|
||||
|
||||
else if(href_list["upgradecam"])
|
||||
var/already
|
||||
for (var/datum/AI_Module/mod in usr:current_modules)
|
||||
if(istype(mod, /datum/AI_Module/small/upgrade_camera))
|
||||
mod:uses += 10
|
||||
already = 1
|
||||
if (!already)
|
||||
usr.verbs += /client/proc/upgrade_camera
|
||||
src.temp = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 10 uses."
|
||||
usr:current_modules += new /datum/AI_Module/small/upgrade_camera
|
||||
else src.temp = "Ten additional uses added to ReCam module."
|
||||
src.processing_time -= 15
|
||||
|
||||
else
|
||||
if (href_list["temp"])
|
||||
src.temp = null
|
||||
src.use(usr)
|
||||
return
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
/datum/game_mode/malfunction
|
||||
name = "AI malfunction"
|
||||
config_tag = "malfunction"
|
||||
required_players = 20
|
||||
required_enemies = 1
|
||||
recommended_enemies = 1
|
||||
required_players = 0//20
|
||||
required_enemies = 0//1
|
||||
recommended_enemies = 0//1
|
||||
|
||||
uplink_welcome = "Crazy AI Uplink Console:"
|
||||
uplink_uses = 10
|
||||
@@ -52,7 +52,7 @@
|
||||
return
|
||||
AI_mind.current.verbs += /mob/living/silicon/ai/proc/choose_modules
|
||||
AI_mind.current:laws = new /datum/ai_laws/malfunction
|
||||
AI_mind.current:malf_picker = new /datum/AI_Module/module_picker
|
||||
AI_mind.current:malf_picker = new /datum/module_picker
|
||||
AI_mind.current:show_laws()
|
||||
|
||||
greet_malf(AI_mind)
|
||||
|
||||
@@ -6,7 +6,7 @@ var/bomb_set
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "nuclearbomb0"
|
||||
density = 1
|
||||
var/deployable = 0.0
|
||||
|
||||
var/extended = 0.0
|
||||
var/timeleft = 60.0
|
||||
var/timing = 0.0
|
||||
@@ -28,19 +28,23 @@ var/bomb_set
|
||||
src.timeleft--
|
||||
if (src.timeleft <= 0)
|
||||
explode()
|
||||
else
|
||||
playsound(loc, 'sound/items/timer.ogg', 5, 0)
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.attack_hand(M)
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/attackby(obj/item/weapon/I as obj, mob/user as mob)
|
||||
if (src.extended)
|
||||
if (istype(I, /obj/item/weapon/disk/nuclear))
|
||||
usr.drop_item()
|
||||
I.loc = src
|
||||
src.auth = I
|
||||
src.add_fingerprint(user)
|
||||
if (istype(I, /obj/item/weapon/disk/nuclear))
|
||||
if (!src.extended)
|
||||
user << "<span class='notice'>You have to deploy the bomb first.</span>"
|
||||
return
|
||||
usr.drop_item()
|
||||
I.loc = src
|
||||
src.auth = I
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/nuclearbomb/attack_paw(mob/user as mob)
|
||||
@@ -68,22 +72,20 @@ var/bomb_set
|
||||
dat += text("<HR>\n>[]<BR>\n<A href='?src=\ref[];type=1'>1</A>-<A href='?src=\ref[];type=2'>2</A>-<A href='?src=\ref[];type=3'>3</A><BR>\n<A href='?src=\ref[];type=4'>4</A>-<A href='?src=\ref[];type=5'>5</A>-<A href='?src=\ref[];type=6'>6</A><BR>\n<A href='?src=\ref[];type=7'>7</A>-<A href='?src=\ref[];type=8'>8</A>-<A href='?src=\ref[];type=9'>9</A><BR>\n<A href='?src=\ref[];type=R'>R</A>-<A href='?src=\ref[];type=0'>0</A>-<A href='?src=\ref[];type=E'>E</A><BR>\n</TT>", message, src, src, src, src, src, src, src, src, src, src, src, src)
|
||||
user << browse(dat, "window=nuclearbomb;size=300x400")
|
||||
onclose(user, "nuclearbomb")
|
||||
else if (src.deployable)
|
||||
src.anchored = 1
|
||||
flick("nuclearbombc", src)
|
||||
src.icon_state = "nuclearbomb1"
|
||||
src.extended = 1
|
||||
else
|
||||
user << "<span class='notice'>You have to deploy the bomb first.</span>"
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/verb/make_deployable()
|
||||
set category = "Object"
|
||||
set name = "Make Deployable"
|
||||
set name = "Deploy Bomb"
|
||||
set src in oview(1)
|
||||
|
||||
if (src.deployable)
|
||||
src.deployable = 0
|
||||
else
|
||||
src.deployable = 1
|
||||
if (!src.extended)
|
||||
src.anchored = 1
|
||||
flick("nuclearbombc", src)
|
||||
src.icon_state = "nuclearbomb1"
|
||||
src.extended = 1
|
||||
|
||||
/obj/machinery/nuclearbomb/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/atmospheric_technician(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/atmos(H), slot_l_store)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/analyzer(H), slot_r_store)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/atmostech/(H), slot_belt)
|
||||
if(H.backbag == 1)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H), slot_r_hand)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/machinery/atmospherics/unary/cold_sink/freezer
|
||||
name = "Freezer"
|
||||
name = "freezer"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "freezer_0"
|
||||
icon_state = "freezer"
|
||||
density = 1
|
||||
|
||||
anchored = 1.0
|
||||
@@ -32,7 +32,7 @@
|
||||
else
|
||||
icon_state = "freezer"
|
||||
else
|
||||
icon_state = "freezer_0"
|
||||
icon_state = "freezer"
|
||||
return
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
@@ -91,7 +91,7 @@
|
||||
/obj/machinery/atmospherics/unary/heat_reservoir/heater
|
||||
name = "heater"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "freezer_0"
|
||||
icon_state = "heater"
|
||||
density = 1
|
||||
|
||||
anchored = 1.0
|
||||
@@ -118,11 +118,11 @@
|
||||
update_icon()
|
||||
if(src.node)
|
||||
if(src.on)
|
||||
icon_state = "freezer_1"
|
||||
icon_state = "heater_1"
|
||||
else
|
||||
icon_state = "freezer"
|
||||
icon_state = "heater"
|
||||
else
|
||||
icon_state = "freezer_0"
|
||||
icon_state = "heater"
|
||||
return
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
|
||||
+22
-222
@@ -1,28 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
|
||||
/proc/RandomAAlarmWires()
|
||||
//to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else).
|
||||
var/list/AAlarmwires = list(0, 0, 0, 0, 0)
|
||||
AAlarmIndexToFlag = list(0, 0, 0, 0, 0)
|
||||
AAlarmIndexToWireColor = list(0, 0, 0, 0, 0)
|
||||
AAlarmWireColorToIndex = list(0, 0, 0, 0, 0)
|
||||
var/flagIndex = 1
|
||||
for (var/flag=1, flag<32, flag+=flag)
|
||||
var/valid = 0
|
||||
while (!valid)
|
||||
var/colorIndex = rand(1, 5)
|
||||
if (AAlarmwires[colorIndex]==0)
|
||||
valid = 1
|
||||
AAlarmwires[colorIndex] = flag
|
||||
AAlarmIndexToFlag[flagIndex] = flag
|
||||
AAlarmIndexToWireColor[flagIndex] = colorIndex
|
||||
AAlarmWireColorToIndex[colorIndex] = flagIndex
|
||||
flagIndex+=1
|
||||
return AAlarmwires
|
||||
|
||||
|
||||
|
||||
// A datum for dealing with threshold limit values
|
||||
// used in /obj/machinery/alarm
|
||||
/datum/tlv
|
||||
@@ -51,6 +27,20 @@
|
||||
max1 = other.max1
|
||||
max2 = other.max2
|
||||
|
||||
#define AALARM_MODE_SCRUBBING 1
|
||||
#define AALARM_MODE_VENTING 2 //makes draught
|
||||
#define AALARM_MODE_PANIC 3 //constantly sucks all air
|
||||
#define AALARM_MODE_REPLACEMENT 4 //sucks off all air, then refill and swithes to scrubbing
|
||||
#define AALARM_MODE_OFF 5
|
||||
|
||||
#define AALARM_SCREEN_MAIN 1
|
||||
#define AALARM_SCREEN_VENT 2
|
||||
#define AALARM_SCREEN_SCRUB 3
|
||||
#define AALARM_SCREEN_MODE 4
|
||||
#define AALARM_SCREEN_SENSORS 5
|
||||
|
||||
#define AALARM_REPORT_TIMEOUT 100
|
||||
|
||||
/obj/machinery/alarm
|
||||
name = "alarm"
|
||||
icon = 'icons/obj/monitors.dmi'
|
||||
@@ -64,36 +54,19 @@
|
||||
var/frequency = 1439
|
||||
//var/skipprocess = 0 //Experimenting
|
||||
var/alarm_frequency = 1437
|
||||
#define AALARM_REPORT_TIMEOUT 100
|
||||
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/locked = 1
|
||||
var/datum/wires/alarm/wires = null
|
||||
var/wiresexposed = 0 // If it's been screwdrivered open.
|
||||
var/aidisabled = 0
|
||||
var/AAlarmwires = 31
|
||||
var/shorted = 0
|
||||
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
|
||||
// Uses code from apc.dm
|
||||
|
||||
#define AALARM_WIRE_IDSCAN 1 //Added wires
|
||||
#define AALARM_WIRE_POWER 2
|
||||
#define AALARM_WIRE_SYPHON 3
|
||||
#define AALARM_WIRE_AI_CONTROL 4
|
||||
#define AALARM_WIRE_AALARM 5
|
||||
|
||||
|
||||
#define AALARM_MODE_SCRUBBING 1
|
||||
#define AALARM_MODE_VENTING 2 //makes draught
|
||||
#define AALARM_MODE_PANIC 3 //constantly sucks all air
|
||||
#define AALARM_MODE_REPLACEMENT 4 //sucks off all air, then refill and swithes to scrubbing
|
||||
#define AALARM_MODE_OFF 5
|
||||
var/mode = AALARM_MODE_SCRUBBING
|
||||
|
||||
#define AALARM_SCREEN_MAIN 1
|
||||
#define AALARM_SCREEN_VENT 2
|
||||
#define AALARM_SCREEN_SCRUB 3
|
||||
#define AALARM_SCREEN_MODE 4
|
||||
#define AALARM_SCREEN_SENSORS 5
|
||||
var/screen = AALARM_SCREEN_MAIN
|
||||
var/area_uid
|
||||
var/area/alarm_area
|
||||
@@ -145,6 +118,7 @@
|
||||
|
||||
/obj/machinery/alarm/New(nloc, ndir, nbuild)
|
||||
..()
|
||||
wires = new(src)
|
||||
if(nloc)
|
||||
loc = nloc
|
||||
|
||||
@@ -201,31 +175,6 @@
|
||||
user << browse(null, "window=air_alarm")
|
||||
return
|
||||
|
||||
if(wiresexposed && (!istype(user, /mob/living/silicon)))
|
||||
var/t1 = text("<B>Access Panel</B><br />\n")
|
||||
var/list/AAlarmwires = list(
|
||||
"Orange" = 1,
|
||||
"Dark red" = 2,
|
||||
"White" = 3,
|
||||
"Yellow" = 4,
|
||||
"Black" = 5,
|
||||
)
|
||||
for(var/wiredesc in AAlarmwires)
|
||||
var/is_uncut = src.AAlarmwires & AAlarmWireColorToFlag[AAlarmwires[wiredesc]]
|
||||
t1 += "[wiredesc] wire: "
|
||||
if(!is_uncut)
|
||||
t1 += "<a href='?src=\ref[src];AAlarmwires=[AAlarmwires[wiredesc]]'>Mend</a>"
|
||||
|
||||
else
|
||||
t1 += "<a href='?src=\ref[src];AAlarmwires=[AAlarmwires[wiredesc]]'>Cut</a> "
|
||||
t1 += "<a href='?src=\ref[src];pulse=[AAlarmwires[wiredesc]]'>Pulse</a> "
|
||||
|
||||
t1 += "<br />"
|
||||
t1 += text("<br />\n[(src.locked ? "The Air Alarm is locked." : "The Air Alarm is unlocked.")]<br />\n[((src.shorted || (stat & (NOPOWER|BROKEN))) ? "The Air Alarm is offline." : "The Air Alarm is working properly!")]<br />\n[(src.aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
|
||||
t1 += text("<p><a href='?src=\ref[src];close2=1'>Close</a></p>")
|
||||
user << browse(t1, "window=AAlarmwires")
|
||||
onclose(user, "AAlarmwires")
|
||||
|
||||
if(!shorted)
|
||||
//user << browse(return_text(),"window=air_alarm")
|
||||
//onclose(user, "air_alarm")
|
||||
@@ -235,135 +184,11 @@
|
||||
popup.open()
|
||||
refresh_all()
|
||||
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/alarm/proc/isWireColorCut(var/wireColor)
|
||||
var/wireFlag = AAlarmWireColorToFlag[wireColor]
|
||||
return ((src.AAlarmwires & wireFlag) == 0)
|
||||
|
||||
/obj/machinery/alarm/proc/isWireCut(var/wireIndex)
|
||||
var/wireFlag = AAlarmIndexToFlag[wireIndex]
|
||||
return ((src.AAlarmwires & wireFlag) == 0)
|
||||
|
||||
/obj/machinery/alarm/proc/cut(var/wireColor)
|
||||
var/wireFlag = AAlarmWireColorToFlag[wireColor]
|
||||
var/wireIndex = AAlarmWireColorToIndex[wireColor]
|
||||
AAlarmwires &= ~wireFlag
|
||||
switch(wireIndex)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
src.locked = 1
|
||||
//world << "Idscan wire cut"
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
src.shock(usr, 50)
|
||||
src.shorted = 1
|
||||
update_icon()
|
||||
//world << "Power wire cut"
|
||||
|
||||
if (AALARM_WIRE_AI_CONTROL)
|
||||
if (src.aidisabled == 0)
|
||||
src.aidisabled = 1
|
||||
//world << "AI Control Wire Cut"
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
mode = AALARM_MODE_PANIC
|
||||
apply_mode()
|
||||
//world << "Syphon Wire Cut"
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
|
||||
if (alarm_area.atmosalert(2))
|
||||
post_alert(2)
|
||||
spawn(1)
|
||||
src.updateUsrDialog()
|
||||
update_icon()
|
||||
|
||||
//world << "AAlarm Wire Cut"
|
||||
|
||||
src.updateDialog()
|
||||
update_icon()
|
||||
if(wiresexposed && (!istype(user, /mob/living/silicon)))
|
||||
wires.Interact(user)
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/alarm/proc/mend(var/wireColor)
|
||||
var/wireFlag = AAlarmWireColorToFlag[wireColor]
|
||||
var/wireIndex = AAlarmWireColorToIndex[wireColor] //not used in this function
|
||||
AAlarmwires |= wireFlag
|
||||
switch(wireIndex)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
//world << "Idscan wire mended"
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
src.shorted = 0
|
||||
src.shock(usr, 50)
|
||||
update_icon()
|
||||
//world << "Power wire mended"
|
||||
|
||||
if(AALARM_WIRE_AI_CONTROL)
|
||||
if (src.aidisabled == 1)
|
||||
src.aidisabled = 0
|
||||
//world << "AI Cont. wire mended"
|
||||
|
||||
|
||||
// if(AALARM_WIRE_SYPHON)
|
||||
// world << "Syphon Wire mended"
|
||||
|
||||
|
||||
// if(AALARM_WIRE_AALARM)
|
||||
//world << "AAlarm Wire mended"
|
||||
|
||||
update_icon()
|
||||
src.updateDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/alarm/proc/pulse(var/wireColor)
|
||||
//var/wireFlag = AAlarmWireColorToFlag[wireColor] //not used in this function
|
||||
var/wireIndex = AAlarmWireColorToIndex[wireColor]
|
||||
switch(wireIndex)
|
||||
if(AALARM_WIRE_IDSCAN) //unlocks for 30 seconds, if you have a better way to hack I'm all ears
|
||||
src.locked = 0
|
||||
spawn(300)
|
||||
src.locked = 1
|
||||
//world << "Idscan wire pulsed"
|
||||
|
||||
if (AALARM_WIRE_POWER)
|
||||
// world << "Power wire pulsed"
|
||||
if(shorted == 0)
|
||||
shorted = 1
|
||||
update_icon()
|
||||
|
||||
spawn(1200)
|
||||
if(shorted == 1)
|
||||
shorted = 0
|
||||
update_icon()
|
||||
|
||||
|
||||
if (AALARM_WIRE_AI_CONTROL)
|
||||
// world << "AI Control wire pulsed"
|
||||
if (src.aidisabled == 0)
|
||||
src.aidisabled = 1
|
||||
src.updateDialog()
|
||||
spawn(10)
|
||||
if (src.aidisabled == 1)
|
||||
src.aidisabled = 0
|
||||
src.updateDialog()
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
// world << "Syphon wire pulsed"
|
||||
mode = AALARM_MODE_REPLACEMENT
|
||||
apply_mode()
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
// world << "Aalarm wire pulsed"
|
||||
if (alarm_area.atmosalert(0))
|
||||
post_alert(0)
|
||||
spawn(1)
|
||||
src.updateUsrDialog()
|
||||
update_icon()
|
||||
|
||||
src.updateDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/alarm/proc/shock(mob/user, prb)
|
||||
if((stat & (NOPOWER))) // unpowered, no shock
|
||||
@@ -702,33 +527,8 @@ table tr:first-child th:first-child { border: none;}
|
||||
if (!istype(usr, /mob/living/silicon))
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=air_alarm")
|
||||
usr << browse(null, "window=AAlarmwires")
|
||||
return
|
||||
|
||||
if (href_list["AAlarmwires"])
|
||||
var/t1 = text2num(href_list["AAlarmwires"])
|
||||
if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
|
||||
usr << "You need wirecutters!"
|
||||
return
|
||||
if (src.isWireColorCut(t1))
|
||||
src.mend(t1)
|
||||
else
|
||||
src.cut(t1)
|
||||
spawn(1)
|
||||
src.updateUsrDialog()
|
||||
else if (href_list["pulse"])
|
||||
var/t1 = text2num(href_list["pulse"])
|
||||
if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
||||
usr << "You need a multitool!"
|
||||
return
|
||||
if (src.isWireColorCut(t1))
|
||||
usr << "You can't pulse a cut wire."
|
||||
return
|
||||
else
|
||||
src.pulse(t1)
|
||||
spawn(1)
|
||||
src.updateUsrDialog()
|
||||
|
||||
|
||||
|
||||
if(href_list["command"])
|
||||
@@ -988,7 +788,7 @@ table tr:first-child th:first-child { border: none;}
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
user << "It does nothing"
|
||||
else
|
||||
if(src.allowed(usr) && !isWireCut(AALARM_WIRE_IDSCAN))
|
||||
if(src.allowed(usr) && !wires.IsIndexCut(AALARM_WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
user << "\blue You [ locked ? "lock" : "unlock"] the Air Alarm interface."
|
||||
src.updateUsrDialog()
|
||||
@@ -1055,8 +855,8 @@ Just a object used in constructing air alarms
|
||||
*/
|
||||
/obj/item/weapon/airalarm_electronics
|
||||
name = "air alarm electronics"
|
||||
icon = 'icons/obj/doors/door_assembly.dmi'
|
||||
icon_state = "door_electronics"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "airalarm_electronics"
|
||||
desc = "Looks like a circuit. Probably is."
|
||||
w_class = 2.0
|
||||
m_amt = 50
|
||||
|
||||
@@ -7,6 +7,7 @@ var/global/list/autolathe_recipes = list( \
|
||||
new /obj/item/device/flashlight(), \
|
||||
new /obj/item/weapon/extinguisher(), \
|
||||
new /obj/item/device/multitool(), \
|
||||
new /obj/item/device/analyzer(), \
|
||||
new /obj/item/device/t_scanner(), \
|
||||
new /obj/item/weapon/weldingtool(), \
|
||||
new /obj/item/weapon/screwdriver(), \
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
return
|
||||
|
||||
/obj/machinery/camera/blob_act()
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/machinery/camera/proc/setViewRange(var/num = 7)
|
||||
|
||||
@@ -456,10 +456,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)
|
||||
@@ -472,7 +468,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 centcom
|
||||
|
||||
@@ -513,7 +513,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
||||
|
||||
var/list/memory = list() // stored memory
|
||||
var/rawcode = "" // the code to compile (raw text)
|
||||
var/compiling = 0 // Are we compiling?
|
||||
|
||||
var/datum/TCS_Compiler/Compiler // the compiler that compiles and runs the code
|
||||
var/autoruncode = 0 // 1 if the code is set to run every time a signal is picked up
|
||||
|
||||
@@ -615,13 +615,8 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
||||
|
||||
/obj/machinery/telecomms/server/proc/compile(var/mob/user)
|
||||
|
||||
if(Compiler && !compiling)
|
||||
// BONUS FEATURE: REAL LIFE COMPILE TIME FOR 2556 SPACE MENS
|
||||
compiling = 1
|
||||
if(length(rawcode)) // Don't bother compiling if it's empty code.
|
||||
sleep(Clamp((10 + length(rawcode)) / 5, 100, 1500)) // Max time: 2.5 minutes - Min time: 10 seconds
|
||||
if(Compiler)
|
||||
admin_log(user)
|
||||
compiling = 0
|
||||
return Compiler.Compile(rawcode)
|
||||
|
||||
/obj/machinery/telecomms/server/proc/update_logs()
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
if (M.timeofdeath + 6000 < world.time)
|
||||
continue
|
||||
var/turf/T = get_turf(M)
|
||||
if(T) continue
|
||||
if(!T) continue
|
||||
if(T.z == 2) continue
|
||||
var/tmpname = M.real_name
|
||||
if(areaindex[tmpname])
|
||||
@@ -368,4 +368,4 @@
|
||||
if(com)
|
||||
com.icon_state = "tele0"
|
||||
else
|
||||
icon_state = "controller"
|
||||
icon_state = "controller"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/turf/simulated/floor/mech_bay_recharge_floor
|
||||
name = "Mech Bay Recharge Station"
|
||||
icon = 'icons/mecha/mech_bay.dmi'
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "recharge_floor"
|
||||
var/obj/machinery/mech_bay_recharge_port/recharge_port
|
||||
var/obj/machinery/computer/mech_bay_power_console/recharge_console
|
||||
|
||||
@@ -609,6 +609,10 @@
|
||||
return
|
||||
*/
|
||||
|
||||
/obj/mecha/blob_act()
|
||||
take_damage(30, "brute")
|
||||
return
|
||||
|
||||
//TODO
|
||||
/obj/mecha/meteorhit()
|
||||
return ex_act(rand(1,3))//should do for now
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.")
|
||||
holder.icon_state = "ripley10"
|
||||
else
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].")
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].")
|
||||
var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder))
|
||||
MS.amount = 5
|
||||
holder.icon_state = "ripley8"
|
||||
@@ -260,7 +260,7 @@
|
||||
user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.")
|
||||
holder.icon_state = "ripley13"
|
||||
else
|
||||
user.visible_message("[user] pries external armor layer from [holder].", "You prie external armor layer from [holder].")
|
||||
user.visible_message("[user] pries external armor layer from [holder].", "You pry external armor layer from [holder].")
|
||||
var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder))
|
||||
MS.amount = 5
|
||||
holder.icon_state = "ripley11"
|
||||
@@ -519,7 +519,7 @@
|
||||
user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.")
|
||||
holder.icon_state = "gygax16"
|
||||
else
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].")
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].")
|
||||
var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder))
|
||||
MS.amount = 5
|
||||
holder.icon_state = "gygax14"
|
||||
@@ -543,7 +543,7 @@
|
||||
user.visible_message("[user] secures Gygax Armour Plates.", "You secure Gygax Armour Plates.")
|
||||
holder.icon_state = "gygax19"
|
||||
else
|
||||
user.visible_message("[user] pries Gygax Armour Plates from [holder].", "You prie Gygax Armour Plates from [holder].")
|
||||
user.visible_message("[user] pries Gygax Armour Plates from [holder].", "You pry Gygax Armour Plates from [holder].")
|
||||
new /obj/item/mecha_parts/part/gygax_armour(get_turf(holder))
|
||||
holder.icon_state = "gygax17"
|
||||
if(1)
|
||||
@@ -733,7 +733,7 @@
|
||||
user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.")
|
||||
holder.icon_state = "fireripley10"
|
||||
else
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].")
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].")
|
||||
var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder))
|
||||
MS.amount = 5
|
||||
holder.icon_state = "fireripley8"
|
||||
@@ -765,7 +765,7 @@
|
||||
user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.")
|
||||
holder.icon_state = "fireripley14"
|
||||
else
|
||||
user.visible_message("[user] pries external armor layer from [holder].", "You prie external armor layer from [holder].")
|
||||
user.visible_message("[user] pries external armor layer from [holder].", "You pry external armor layer from [holder].")
|
||||
var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder))
|
||||
MS.amount = 5
|
||||
holder.icon_state = "fireripley12"
|
||||
@@ -1101,7 +1101,7 @@
|
||||
user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.")
|
||||
holder.icon_state = "durand16"
|
||||
else
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].")
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].")
|
||||
var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder))
|
||||
MS.amount = 5
|
||||
holder.icon_state = "durand14"
|
||||
@@ -1125,7 +1125,7 @@
|
||||
user.visible_message("[user] secures Durand Armour Plates.", "You secure Durand Armour Plates.")
|
||||
holder.icon_state = "durand19"
|
||||
else
|
||||
user.visible_message("[user] pries Durand Armour Plates from [holder].", "You prie Durand Armour Plates from [holder].")
|
||||
user.visible_message("[user] pries Durand Armour Plates from [holder].", "You pry Durand Armour Plates from [holder].")
|
||||
new /obj/item/mecha_parts/part/durand_armour(get_turf(holder))
|
||||
holder.icon_state = "durand17"
|
||||
if(1)
|
||||
@@ -1332,7 +1332,7 @@
|
||||
user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.")
|
||||
holder.icon_state = "odysseus10"
|
||||
else
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].")
|
||||
user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].")
|
||||
var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder))
|
||||
MS.amount = 5
|
||||
holder.icon_state = "odysseus8"
|
||||
@@ -1351,13 +1351,14 @@
|
||||
else
|
||||
user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].")
|
||||
holder.icon_state = "odysseus10"
|
||||
if(2)
|
||||
if(diff==FORWARD)
|
||||
user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.")
|
||||
holder.icon_state = "odysseus13"
|
||||
else
|
||||
var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder))
|
||||
MS.amount = 5
|
||||
user.visible_message("[user] pries [MS] from [holder].", "You prie [MS] from [holder].")
|
||||
user.visible_message("[user] pries [MS] from [holder].", "You pry [MS] from [holder].")
|
||||
holder.icon_state = "odysseus11"
|
||||
if(1)
|
||||
if(diff==FORWARD)
|
||||
|
||||
@@ -131,6 +131,8 @@ move an amendment</a> to the drawing.</p>
|
||||
A.power_environ = 0
|
||||
A.always_unpowered = 0
|
||||
move_turfs_to_area(turfs, A)
|
||||
A.SetDynamicLighting()
|
||||
|
||||
spawn(5)
|
||||
//ma = A.master ? "[A.master]" : "(null)"
|
||||
//world << "DEBUG: create_area(5): <br>A.name=[A.name]<br>A.tag=[A.tag]<br>A.master=[ma]"
|
||||
|
||||
@@ -887,49 +887,14 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
/obj/item/device/pda/attack(mob/living/carbon/C, mob/living/user as mob)
|
||||
if(istype(C))
|
||||
switch(scanmode)
|
||||
|
||||
if(1)
|
||||
|
||||
for (var/mob/O in viewers(C, null))
|
||||
O.show_message("\red [user] has analyzed [C]'s vitals!", 1)
|
||||
|
||||
user.show_message("\blue Analyzing Results for [C]:")
|
||||
user.show_message("\blue \t Overall Status: [C.stat > 1 ? "dead" : "[C.health - C.halloss]% healthy"]", 1)
|
||||
user.show_message("\blue \t Damage Specifics: [C.getOxyLoss() > 50 ? "\red" : "\blue"][C.getOxyLoss()]-[C.getToxLoss() > 50 ? "\red" : "\blue"][C.getToxLoss()]-[C.getFireLoss() > 50 ? "\red" : "\blue"][C.getFireLoss()]-[C.getBruteLoss() > 50 ? "\red" : "\blue"][C.getBruteLoss()]", 1)
|
||||
user.show_message("\blue \t Key: Suffocation/Toxin/Burns/Brute", 1)
|
||||
user.show_message("\blue \t Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)", 1)
|
||||
if(C.tod && (C.stat == DEAD || (C.status_flags & FAKEDEATH)))
|
||||
user.show_message("\blue \t Time of Death: [C.tod]")
|
||||
if(istype(C, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = C
|
||||
var/list/damaged = H.get_damaged_organs(1,1)
|
||||
user.show_message("\blue Localized Damage, Brute/Burn:",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/datum/limb/org in damaged)
|
||||
user.show_message(text("\blue \t []: []\blue-[]",capitalize(org.getDisplayName()),(org.brute_dam > 0)?"\red [org.brute_dam]":0,(org.burn_dam > 0)?"\red [org.burn_dam]":0),1)
|
||||
else
|
||||
user.show_message("\blue \t Limbs are OK.",1)
|
||||
|
||||
for(var/datum/disease/D in C.viruses)
|
||||
if(!D.hidden[SCANNER])
|
||||
user.show_message(text("\red <b>Warning: [D.form] Detected</b>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]"))
|
||||
user.visible_message(text("<span class='alert'>[] has analyzed []'s vitals!</span>", user, C))
|
||||
healthscan(user, C, 1)
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if(2)
|
||||
if(!istype(C.dna))
|
||||
user << "\blue No fingerprints found on [C]"
|
||||
else if(!istype(C, /mob/living/carbon/monkey))
|
||||
if(!isnull(C:gloves))
|
||||
user << "\blue No fingerprints found on [C]"
|
||||
else
|
||||
user << text("\blue [C]'s Fingerprints: [md5(C.dna.uni_identity)]")
|
||||
if ( !(C:blood_DNA) )
|
||||
user << "\blue No blood found on [C]"
|
||||
if(C:blood_DNA)
|
||||
del(C:blood_DNA)
|
||||
else
|
||||
user << "\blue Blood found on [C]. Analysing..."
|
||||
spawn(15)
|
||||
for(var/blood in C:blood_DNA)
|
||||
user << "\blue Blood type: [C:blood_DNA[blood]]\nDNA: [blood]"
|
||||
// Unused
|
||||
|
||||
if(4)
|
||||
for (var/mob/O in viewers(C, null))
|
||||
|
||||
@@ -17,4 +17,49 @@
|
||||
m_amt = 50
|
||||
g_amt = 20
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
|
||||
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
|
||||
|
||||
|
||||
// Syndicate device disguised as a multitool; it will turn red when an AI camera is nearby.
|
||||
|
||||
|
||||
/obj/item/device/multitool/ai_detect
|
||||
var/track_delay = 0
|
||||
|
||||
/obj/item/device/multitool/ai_detect/New()
|
||||
..()
|
||||
processing_objects += src
|
||||
|
||||
|
||||
/obj/item/device/multitool/ai_detect/Del()
|
||||
processing_objects -= src
|
||||
..()
|
||||
|
||||
/obj/item/device/multitool/ai_detect/process()
|
||||
|
||||
if(track_delay > world.time)
|
||||
return
|
||||
|
||||
var/found_eye = 0
|
||||
var/turf/our_turf = get_turf(src)
|
||||
|
||||
if(cameranet.chunkGenerated(our_turf.x, our_turf.y, our_turf.z))
|
||||
|
||||
var/datum/camerachunk/chunk = cameranet.getCameraChunk(our_turf.x, our_turf.y, our_turf.z)
|
||||
|
||||
if(chunk)
|
||||
if(chunk.seenby.len)
|
||||
for(var/mob/camera/aiEye/A in chunk.seenby)
|
||||
var/turf/eye_turf = get_turf(A)
|
||||
if(get_dist(our_turf, eye_turf) < 8)
|
||||
found_eye = 1
|
||||
break
|
||||
|
||||
if(found_eye)
|
||||
icon_state = "[initial(icon_state)]_red"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
track_delay = world.time + 10 // 1 second
|
||||
return
|
||||
|
||||
|
||||
@@ -55,6 +55,13 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
||||
initialize()
|
||||
|
||||
|
||||
/obj/item/device/radio/MouseDrop(obj/over_object as obj, src_location, over_location)
|
||||
var/mob/M = usr
|
||||
if((!istype(over_object, /obj/screen)) && src.loc == M)
|
||||
return attack_self(M)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/radio/initialize()
|
||||
|
||||
if(freerange)
|
||||
@@ -797,4 +804,4 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
||||
|
||||
|
||||
/obj/item/device/radio/off // Station bounced radios, their only difference is spawning with the speakers off, this was made to help the lag.
|
||||
listening = 0 // And it's nice to have a subtype too for future features.
|
||||
listening = 0 // And it's nice to have a subtype too for future features.
|
||||
|
||||
@@ -76,61 +76,79 @@ MASS SPECTROMETER
|
||||
var/mode = 1;
|
||||
|
||||
/obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
if (( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
|
||||
user << text("\red You try to analyze the floor's vitals!")
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1)
|
||||
user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
|
||||
user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
|
||||
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
|
||||
user.show_message("\blue Body Temperature: ???", 1)
|
||||
|
||||
// Clumsiness/brain damage check
|
||||
if ((CLUMSY in user.mutations || user.getBrainLoss() >= 60) && prob(50))
|
||||
user << text("<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
|
||||
user.visible_message(text("<span class='alert'>[user] has analyzed the floor's vitals!</span>"))
|
||||
user.show_message(text("<span class='notice'>Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
|
||||
user.show_message(text("<span class='notice'>\t Damage Specifics: <font color='blue'>0</font>-<font color='green'>0</font>-<font color='#FF8000'>0</font>-<font color='red'>0</font></span>"), 1)
|
||||
user.show_message("<span class='notice'>Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FF8000'>Burn</font>/<font color='red'>Brute</font></span>", 1)
|
||||
user.show_message("<span class='notice'>Body Temperature: ???</span>", 1)
|
||||
return
|
||||
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message(text("\red [] has analyzed []'s vitals!", user, M), 1)
|
||||
//Foreach goto(67)
|
||||
var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
|
||||
|
||||
|
||||
user.visible_message(text("<span class='alert'>[] has analyzed []'s vitals!</span>", user, M))
|
||||
|
||||
healthscan(user, M, mode)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
// Used by the PDA medical scanner too
|
||||
/proc/healthscan(var/mob/living/user, var/mob/living/M, var/mode = 1)
|
||||
|
||||
//Damage specifics
|
||||
var/oxy_loss = M.getOxyLoss()
|
||||
var/tox_loss = M.getToxLoss()
|
||||
var/fire_loss = M.getFireLoss()
|
||||
var/brute_loss = M.getBruteLoss()
|
||||
var/mob_status = (M.stat > 1 ? "<font color='red'>Deceased</font>" : text("[]% healthy", M.health - M.halloss))
|
||||
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
user.show_message(text("\blue Analyzing Results for []:\n\t Overall Status: []", M, "dead"), 1)
|
||||
user.show_message(text("\blue \t Damage Specifics: []-[]-[]-[]", fake_oxy < 50 ? "\red [fake_oxy]" : fake_oxy , M.getToxLoss() > 50 ? "\red [M.getToxLoss()]" : M.getToxLoss(), M.getFireLoss() > 50 ? "\red[M.getFireLoss()]" : M.getFireLoss(), M.getBruteLoss() > 50 ? "\red[M.getBruteLoss()]" : M.getBruteLoss()), 1)
|
||||
else
|
||||
user.show_message(text("\blue Analyzing Results for []:\n\t Overall Status: []", M, (M.stat > 1 ? "dead" : text("[]% healthy", M.health - M.halloss))), 1)
|
||||
user.show_message(text("\blue \t Damage Specifics: []-[]-[]-[]", M.getOxyLoss() > 50 ? "\red [M.getOxyLoss()]" : M.getOxyLoss(), M.getToxLoss() > 50 ? "\red [M.getToxLoss()]" : M.getToxLoss(), M.getFireLoss() > 50 ? "\red[M.getFireLoss()]" : M.getFireLoss(), M.getBruteLoss() > 50 ? "\red[M.getBruteLoss()]" : M.getBruteLoss()), 1)
|
||||
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
|
||||
user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
|
||||
mob_status = "<font color='red'>Deceased</font>"
|
||||
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
|
||||
|
||||
user.show_message(text("<span class='notice'>Analyzing Results for []:\n\t Overall Status: []</span>", M, mob_status), 1)
|
||||
user.show_message(text("<span class='notice'>\t Damage Specifics: <font color='blue'>[]</font>-<font color='green'>[]</font>-<font color='#FF8000'>[]</font>-<font color='red'>[]</font></span>", oxy_loss, tox_loss, fire_loss, brute_loss), 1)
|
||||
|
||||
user.show_message("<span class='notice'>Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FF8000'>Burn</font>/<font color='red'>Brute</font></span>", 1)
|
||||
user.show_message("<span class='notice'>Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)</span>", 1)
|
||||
|
||||
// Time of death
|
||||
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
|
||||
user.show_message("\blue Time of Death: [M.tod]")
|
||||
user.show_message("<span class='notice'>Time of Death:</span> [M.tod]")
|
||||
|
||||
// Organ damage report
|
||||
if(istype(M, /mob/living/carbon/human) && mode == 1)
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/list/damaged = H.get_damaged_organs(1,1)
|
||||
user.show_message("\blue Localized Damage, Brute/Burn:",1)
|
||||
user.show_message("<span class='notice'>Localized Damage, <font color='#FF8000'>Burn</font>/<font color='red'>Brute</font>:</span>",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/datum/limb/org in damaged)
|
||||
user.show_message(text("\blue \t []: []\blue-[]",capitalize(org.getDisplayName()),(org.brute_dam > 0)?"\red [org.brute_dam]":0,(org.burn_dam > 0)?"\red [org.burn_dam]":0),1)
|
||||
user.show_message(text("<span class='notice'>\t []: []-[]", capitalize(org.getDisplayName()), (org.burn_dam > 0) ? "<font color='#FF8000'>[org.burn_dam]</font>" : 0, (org.brute_dam > 0) ? "<font color='red'>[org.brute_dam]</font></span>" : 0), 1)
|
||||
else
|
||||
user.show_message("\blue \t Limbs are OK.",1)
|
||||
user.show_message("<span class='notice'>\t Limbs are OK.</span>",1)
|
||||
|
||||
// Damage descriptions
|
||||
|
||||
user.show_message(text("<span class='notice'>[] | [] | [] | []</span>", oxy_loss > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal", tox_loss > 50 ? "\red Dangerous amount of toxins detected\blue" : "Subject bloodstream toxin level minimal", fire_loss > 50 ? "\red Severe burn damage detected\blue" : "Subject burn injury status O.K", brute_loss > 50 ? "\red Severe anatomical damage detected\blue" : "Subject brute-force injury status O.K"), 1)
|
||||
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
user.show_message(text("\blue [] | [] | [] | []", fake_oxy > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal", M.getToxLoss() > 50 ? "\red Dangerous amount of toxins detected\blue" : "Subject bloodstream toxin level minimal", M.getFireLoss() > 50 ? "\red Severe burn damage detected\blue" : "Subject burn injury status O.K", M.getBruteLoss() > 50 ? "\red Severe anatomical damage detected\blue" : "Subject brute-force injury status O.K"), 1)
|
||||
else
|
||||
user.show_message(text("\blue [] | [] | [] | []", M.getOxyLoss() > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal", M.getToxLoss() > 50 ? "\red Dangerous amount of toxins detected\blue" : "Subject bloodstream toxin level minimal", M.getFireLoss() > 50 ? "\red Severe burn damage detected\blue" : "Subject burn injury status O.K", M.getBruteLoss() > 50 ? "\red Severe anatomical damage detected\blue" : "Subject brute-force injury status O.K"), 1)
|
||||
if (M.getCloneLoss())
|
||||
user.show_message(text("\red Subject appears to have been imperfectly cloned."), 1)
|
||||
user.show_message(text("<span class='alert'>Subject appears to have been imperfectly cloned.</span>"), 1)
|
||||
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
if(!D.hidden[SCANNER])
|
||||
user.show_message(text("\red <b>Warning: [D.form] Detected</b>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]"))
|
||||
user.show_message(text("<span class='warning'><b>Warning: [D.form] Detected</b>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]</span>"))
|
||||
|
||||
if (M.reagents && M.reagents.get_reagent_amount("inaprovaline"))
|
||||
user.show_message(text("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals."), 1)
|
||||
user.show_message(text("<span class='notice'>Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.</span>"), 1)
|
||||
if (M.getBrainLoss() >= 100 || !getbrain(M))
|
||||
user.show_message(text("\red Subject is brain dead."), 1)
|
||||
user.show_message(text("<span class='alert'>Subject brain function is non-existant.</span>"), 1)
|
||||
else if (M.getBrainLoss() >= 60)
|
||||
user.show_message(text("\red Severe brain damage detected. Subject likely to have mental retardation."), 1)
|
||||
user.show_message(text("<span class='warning'>Severe brain damage detected. Subject likely to have mental retardation.</span>"), 1)
|
||||
else if (M.getBrainLoss() >= 10)
|
||||
user.show_message(text("\red Significant brain damage detected. Subject may have had a concussion."), 1)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
user.show_message(text("<span class='warning'>Significant brain damage detected. Subject may have had a concussion.</span>"), 1)
|
||||
|
||||
/obj/item/device/healthanalyzer/verb/toggle_mode()
|
||||
set name = "Switch Verbosity"
|
||||
@@ -163,9 +181,6 @@ MASS SPECTROMETER
|
||||
|
||||
if (user.stat)
|
||||
return
|
||||
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
|
||||
var/turf/location = user.loc
|
||||
if (!( istype(location, /turf) ))
|
||||
|
||||
@@ -34,10 +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."
|
||||
else if (comp.current.see_in_dark == 0)
|
||||
|
||||
@@ -1,21 +1,64 @@
|
||||
/obj/item/weapon/dice
|
||||
name = "d6"
|
||||
desc = "A dice with six sides."
|
||||
desc = "A die with six sides. Basic and servicable."
|
||||
icon = 'icons/obj/dice.dmi'
|
||||
icon_state = "d6"
|
||||
w_class = 1
|
||||
var/sides = 6
|
||||
|
||||
/obj/item/weapon/dice/New()
|
||||
icon_state = "[initial(icon_state)][rand(sides)]"
|
||||
icon_state = "[initial(icon_state)][rand(1, sides)]"
|
||||
|
||||
/obj/item/weapon/dice/d2
|
||||
name = "d2"
|
||||
desc = "A die with two sides. Coins are undignified!"
|
||||
icon_state = "d2"
|
||||
sides = 2
|
||||
|
||||
/obj/item/weapon/dice/d4
|
||||
name = "d4"
|
||||
desc = "A die with four sides. The nerd's caltrop."
|
||||
icon_state = "d4"
|
||||
sides = 4
|
||||
|
||||
/obj/item/weapon/dice/d8
|
||||
name = "d8"
|
||||
desc = "A die with eight sides. It feels... lucky."
|
||||
icon_state = "d8"
|
||||
sides = 8
|
||||
|
||||
/obj/item/weapon/dice/d10
|
||||
name = "d10"
|
||||
desc = "A die with ten sides. Useful for percentages."
|
||||
icon_state = "d10"
|
||||
sides = 10
|
||||
|
||||
/obj/item/weapon/dice/d00
|
||||
name = "d00"
|
||||
desc = "A die with ten sides. Works better for d100 rolls than a golfball."
|
||||
icon_state = "d00"
|
||||
sides = 10
|
||||
|
||||
/obj/item/weapon/dice/d12
|
||||
name = "d12"
|
||||
desc = "A die with twelve sides. There's an air of neglect about it."
|
||||
icon_state = "d12"
|
||||
sides = 12
|
||||
|
||||
/obj/item/weapon/dice/d20
|
||||
name = "d20"
|
||||
desc = "A dice with twenty sides."
|
||||
desc = "A die with twenty sides. The prefered die to throw at the GM."
|
||||
icon_state = "d20"
|
||||
sides = 20
|
||||
|
||||
/obj/item/weapon/dice/attack_self(mob/user as mob)
|
||||
diceroll(user)
|
||||
|
||||
/obj/item/weapon/dice/throw_at(atom/target, range, speed, mob/user as mob)
|
||||
..()
|
||||
diceroll(user)
|
||||
|
||||
/obj/item/weapon/dice/proc/diceroll(mob/user as mob)
|
||||
var/result = rand(1, sides)
|
||||
var/comment = ""
|
||||
if(sides == 20 && result == 20)
|
||||
@@ -23,6 +66,11 @@
|
||||
else if(sides == 20 && result == 1)
|
||||
comment = "Ouch, bad luck."
|
||||
icon_state = "[initial(icon_state)][result]"
|
||||
user.visible_message("<span class='notice'>[user] has thrown [src]. It lands on [result]. [comment]</span>", \
|
||||
"<span class='notice'>You throw [src]. It lands on a [result]. [comment]</span>", \
|
||||
"<span class='notice'>You hear [src] landing on a [result]. [comment]</span>")
|
||||
if(initial(icon_state) == "d00")
|
||||
result = (result - 1)*10
|
||||
if(user != null) //Dice was rolled in someone's hand
|
||||
user.visible_message("<span class='notice'>[user] has thrown [src]. It lands on [result]. [comment]</span>", \
|
||||
"<span class='notice'>You throw [src]. It lands on [result]. [comment]</span>", \
|
||||
"<span class='notice'>You hear [src] landing on [result]. [comment]</span>")
|
||||
else if(src.throwing == 0) //Dice was thrown and is coming to rest
|
||||
src.loc.visible_message("<span class='notice'>[src] rolls to a stop, landing on [result]. [comment]</span>")
|
||||
@@ -157,6 +157,8 @@
|
||||
|
||||
playsound(loc, 'sound/effects/bamf.ogg', 50, 1)
|
||||
|
||||
update_mob()
|
||||
|
||||
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
|
||||
G.reagents.trans_to(src, G.reagents.total_volume)
|
||||
|
||||
@@ -208,6 +210,8 @@
|
||||
|
||||
playsound(loc, 'sound/effects/bamf.ogg', 50, 1)
|
||||
|
||||
update_mob()
|
||||
|
||||
if(valid_core)
|
||||
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
|
||||
G.reagents.trans_to(valid_core, G.reagents.total_volume)
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
item_state = "emp"
|
||||
origin_tech = "materials=2;magnets=3"
|
||||
|
||||
prime()
|
||||
..()
|
||||
if(empulse(src, 4, 10))
|
||||
del(src)
|
||||
return
|
||||
/obj/item/weapon/grenade/empgrenade/prime()
|
||||
update_mob()
|
||||
empulse(src, 4, 10)
|
||||
del(src)
|
||||
|
||||
|
||||
@@ -5,98 +5,97 @@
|
||||
origin_tech = "materials=2;combat=1"
|
||||
var/banglet = 0
|
||||
|
||||
prime()
|
||||
..()
|
||||
for(var/obj/structure/closet/L in view(get_turf(src), null))
|
||||
if(locate(/mob/living/carbon/, L))
|
||||
for(var/mob/living/carbon/M in L)
|
||||
bang(get_turf(src), M)
|
||||
/obj/item/weapon/grenade/flashbang/prime()
|
||||
update_mob()
|
||||
for(var/obj/structure/closet/L in view(get_turf(src), null))
|
||||
if(locate(/mob/living/carbon/, L))
|
||||
for(var/mob/living/carbon/M in L)
|
||||
bang(get_turf(src), M)
|
||||
|
||||
|
||||
for(var/mob/living/carbon/M in viewers(get_turf(src), null))
|
||||
bang(get_turf(src), M)
|
||||
for(var/mob/living/carbon/M in viewers(get_turf(src), null))
|
||||
bang(get_turf(src), M)
|
||||
|
||||
for(var/obj/effect/blob/B in view(8,get_turf(src))) //Blob damage here
|
||||
var/damage = round(30/(get_dist(B,get_turf(src))+1))
|
||||
B.health -= damage
|
||||
B.update_icon()
|
||||
del(src)
|
||||
return
|
||||
for(var/obj/effect/blob/B in view(8,get_turf(src))) //Blob damage here
|
||||
var/damage = round(30/(get_dist(B,get_turf(src))+1))
|
||||
B.health -= damage
|
||||
B.update_icon()
|
||||
del(src)
|
||||
|
||||
proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged.
|
||||
if (locate(/obj/item/weapon/cloaking_device, M)) // Called during the loop that bangs people in lockers/containers and when banging
|
||||
for(var/obj/item/weapon/cloaking_device/S in M) // people in normal view. Could theroetically be called during other explosions.
|
||||
S.active = 0 // -- Polymorph
|
||||
S.icon_state = "shield0"
|
||||
/obj/item/weapon/grenade/flashbang/proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged.
|
||||
if (locate(/obj/item/weapon/cloaking_device, M)) // Called during the loop that bangs people in lockers/containers and when banging
|
||||
for(var/obj/item/weapon/cloaking_device/S in M) // people in normal view. Could theroetically be called during other explosions.
|
||||
S.active = 0 // -- Polymorph
|
||||
S.icon_state = "shield0"
|
||||
|
||||
M << "\red <B>BANG</B>"
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
|
||||
M << "\red <B>BANG</B>"
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
|
||||
|
||||
//Checking for protections
|
||||
var/eye_safety = 0
|
||||
var/ear_safety = 0
|
||||
if(iscarbon(M))
|
||||
eye_safety = M.eyecheck()
|
||||
if(ishuman(M))
|
||||
if(istype(M:ears, /obj/item/clothing/ears/earmuffs))
|
||||
ear_safety += 2
|
||||
if(HULK in M.mutations)
|
||||
ear_safety += 1
|
||||
if(istype(M:head, /obj/item/clothing/head/helmet))
|
||||
ear_safety += 1
|
||||
var/eye_safety = 0
|
||||
var/ear_safety = 0
|
||||
if(iscarbon(M))
|
||||
eye_safety = M.eyecheck()
|
||||
if(ishuman(M))
|
||||
if(istype(M:ears, /obj/item/clothing/ears/earmuffs))
|
||||
ear_safety += 2
|
||||
if(HULK in M.mutations)
|
||||
ear_safety += 1
|
||||
if(istype(M:head, /obj/item/clothing/head/helmet))
|
||||
ear_safety += 1
|
||||
|
||||
//Flashing everyone
|
||||
if(eye_safety < 1)
|
||||
flick("e_flash", M.flash)
|
||||
M.eye_stat += rand(1, 3)
|
||||
M.Stun(2)
|
||||
M.Weaken(10)
|
||||
if(eye_safety < 1)
|
||||
flick("e_flash", M.flash)
|
||||
M.eye_stat += rand(1, 3)
|
||||
M.Stun(2)
|
||||
M.Weaken(10)
|
||||
|
||||
|
||||
|
||||
//Now applying sound
|
||||
if((get_dist(M, T) <= 2 || src.loc == M.loc || src.loc == M))
|
||||
if(ear_safety > 0)
|
||||
M.Stun(2)
|
||||
M.Weaken(1)
|
||||
if((get_dist(M, T) <= 2 || src.loc == M.loc || src.loc == M))
|
||||
if(ear_safety > 0)
|
||||
M.Stun(2)
|
||||
M.Weaken(1)
|
||||
else
|
||||
M.Stun(10)
|
||||
M.Weaken(3)
|
||||
if ((prob(14) || (M == src.loc && prob(70))))
|
||||
M.ear_damage += rand(1, 10)
|
||||
else
|
||||
M.Stun(10)
|
||||
M.Weaken(3)
|
||||
if ((prob(14) || (M == src.loc && prob(70))))
|
||||
M.ear_damage += rand(1, 10)
|
||||
else
|
||||
M.ear_damage += rand(0, 5)
|
||||
M.ear_deaf = max(M.ear_deaf,15)
|
||||
M.ear_damage += rand(0, 5)
|
||||
M.ear_deaf = max(M.ear_deaf,15)
|
||||
|
||||
else if(get_dist(M, T) <= 5)
|
||||
if(!ear_safety)
|
||||
M.Stun(8)
|
||||
M.ear_damage += rand(0, 3)
|
||||
M.ear_deaf = max(M.ear_deaf,10)
|
||||
else if(get_dist(M, T) <= 5)
|
||||
if(!ear_safety)
|
||||
M.Stun(8)
|
||||
M.ear_damage += rand(0, 3)
|
||||
M.ear_deaf = max(M.ear_deaf,10)
|
||||
|
||||
else if(!ear_safety)
|
||||
M.Stun(4)
|
||||
M.ear_damage += rand(0, 1)
|
||||
M.ear_deaf = max(M.ear_deaf,5)
|
||||
else if(!ear_safety)
|
||||
M.Stun(4)
|
||||
M.ear_damage += rand(0, 1)
|
||||
M.ear_deaf = max(M.ear_deaf,5)
|
||||
|
||||
//This really should be in mob not every check
|
||||
if (M.eye_stat >= 20)
|
||||
M << "\red Your eyes start to burn badly!"
|
||||
M.disabilities |= NEARSIGHTED
|
||||
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
|
||||
if (prob(M.eye_stat - 20 + 1))
|
||||
M << "\red You can't see anything!"
|
||||
M.sdisabilities |= BLIND
|
||||
if (M.ear_damage >= 15)
|
||||
M << "\red Your ears start to ring badly!"
|
||||
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
|
||||
if (prob(M.ear_damage - 10 + 5))
|
||||
M << "\red You can't hear anything!"
|
||||
M.sdisabilities |= DEAF
|
||||
else
|
||||
if (M.ear_damage >= 5)
|
||||
M << "\red Your ears start to ring!"
|
||||
M.update_icons()
|
||||
if (M.eye_stat >= 20)
|
||||
M << "\red Your eyes start to burn badly!"
|
||||
M.disabilities |= NEARSIGHTED
|
||||
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
|
||||
if (prob(M.eye_stat - 20 + 1))
|
||||
M << "\red You can't see anything!"
|
||||
M.sdisabilities |= BLIND
|
||||
if (M.ear_damage >= 15)
|
||||
M << "\red Your ears start to ring badly!"
|
||||
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
|
||||
if (prob(M.ear_damage - 10 + 5))
|
||||
M << "\red You can't hear anything!"
|
||||
M.sdisabilities |= DEAF
|
||||
else
|
||||
if (M.ear_damage >= 5)
|
||||
M << "\red Your ears start to ring!"
|
||||
M.update_icons()
|
||||
|
||||
|
||||
/obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve
|
||||
@@ -106,6 +105,7 @@
|
||||
icon_state = "clusterbang"
|
||||
|
||||
/obj/item/weapon/grenade/flashbang/clusterbang/prime()
|
||||
update_mob()
|
||||
var/numspawned = rand(4,8)
|
||||
var/again = 0
|
||||
for(var/more = numspawned,more > 0,more--)
|
||||
@@ -124,7 +124,6 @@
|
||||
playsound(src.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
|
||||
spawn(0)
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/grenade/flashbang/clusterbang/segment
|
||||
desc = "A smaller segment of a clusterbang. Better run."
|
||||
@@ -135,7 +134,6 @@
|
||||
/obj/item/weapon/grenade/flashbang/clusterbang/segment/New()//Segments should never exist except part of the clusterbang, since these immediately 'do their thing' and asplode
|
||||
icon_state = "clusterbang_segment_active"
|
||||
active = 1
|
||||
banglet = 1
|
||||
var/stepdist = rand(1,4)//How far to step
|
||||
var/temploc = src.loc//Saves the current location to know where to step away from
|
||||
walk_away(src,temploc,stepdist)//I must go, my people need me
|
||||
@@ -145,6 +143,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/weapon/grenade/flashbang/clusterbang/segment/prime()
|
||||
update_mob()
|
||||
var/numspawned = rand(4,8)
|
||||
for(var/more = numspawned,more > 0,more--)
|
||||
if(prob(35))
|
||||
@@ -156,17 +155,15 @@
|
||||
playsound(src.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
|
||||
spawn(0)
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/grenade/flashbang/cluster/New()//Same concept as the segments, so that all of the parts don't become reliant on the clusterbang
|
||||
spawn(0)
|
||||
icon_state = "flashbang_active"
|
||||
active = 1
|
||||
banglet = 1
|
||||
var/stepdist = rand(1,3)
|
||||
var/temploc = src.loc
|
||||
walk_away(src,temploc,stepdist)
|
||||
var/dettime = rand(15,60)
|
||||
spawn(dettime)
|
||||
prime()
|
||||
..()
|
||||
..()
|
||||
icon_state = "flashbang_active"
|
||||
active = 1
|
||||
banglet = 1
|
||||
var/stepdist = rand(1,3)
|
||||
var/temploc = src.loc
|
||||
walk_away(src,temploc,stepdist)
|
||||
var/dettime = rand(15,60)
|
||||
spawn(dettime)
|
||||
prime()
|
||||
@@ -69,18 +69,15 @@
|
||||
var/mob/living/carbon/C = user
|
||||
C.throw_mode_on()
|
||||
spawn(det_time)
|
||||
if(user)
|
||||
user.drop_item()
|
||||
prime()
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/grenade/proc/prime()
|
||||
// playsound(loc, 'sound/items/Welder2.ogg', 25, 1)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
T.hotspot_expose(700,125)
|
||||
|
||||
/obj/item/weapon/grenade/proc/update_mob()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.drop_from_inventory(src)
|
||||
|
||||
|
||||
/obj/item/weapon/grenade/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
@@ -100,12 +97,10 @@
|
||||
user << "<span class='notice'>You set the [name] for instant detonation.</span>"
|
||||
add_fingerprint(user)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/weapon/grenade/attack_hand()
|
||||
walk(src, null, null)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/weapon/grenade/attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
@@ -9,27 +9,27 @@
|
||||
slot_flags = SLOT_BELT
|
||||
var/datum/effect/effect/system/bad_smoke_spread/smoke
|
||||
|
||||
New()
|
||||
..()
|
||||
src.smoke = new /datum/effect/effect/system/bad_smoke_spread
|
||||
src.smoke.attach(src)
|
||||
/obj/item/weapon/grenade/smokebomb/New()
|
||||
..()
|
||||
src.smoke = new /datum/effect/effect/system/bad_smoke_spread
|
||||
src.smoke.attach(src)
|
||||
|
||||
prime()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
src.smoke.set_up(10, 0, usr.loc)
|
||||
spawn(0)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
/obj/item/weapon/grenade/smokebomb/prime()
|
||||
update_mob()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
src.smoke.set_up(10, 0, usr.loc)
|
||||
spawn(0)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
|
||||
for(var/obj/effect/blob/B in view(8,src))
|
||||
var/damage = round(30/(get_dist(B,src)+1))
|
||||
B.health -= damage
|
||||
B.update_icon()
|
||||
sleep(80)
|
||||
del(src)
|
||||
return
|
||||
for(var/obj/effect/blob/B in view(8,src))
|
||||
var/damage = round(30/(get_dist(B,src)+1))
|
||||
B.health -= damage
|
||||
B.update_icon()
|
||||
sleep(80)
|
||||
del(src)
|
||||
|
||||
@@ -9,27 +9,26 @@
|
||||
var/spawner_type = null // must be an object path
|
||||
var/deliveryamt = 1 // amount of type to deliver
|
||||
|
||||
prime() // Prime now just handles the two loops that query for people in lockers and people who can see it.
|
||||
/obj/item/weapon/grenade/spawnergrenade/prime() // Prime now just handles the two loops that query for people in lockers and people who can see it.
|
||||
update_mob()
|
||||
if(spawner_type && deliveryamt)
|
||||
// Make a quick flash
|
||||
var/turf/T = get_turf(src)
|
||||
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
|
||||
for(var/mob/living/carbon/human/M in viewers(T, null))
|
||||
if(M:eyecheck() <= 0)
|
||||
flick("e_flash", M.flash) // flash dose faggots
|
||||
|
||||
if(spawner_type && deliveryamt)
|
||||
// Make a quick flash
|
||||
var/turf/T = get_turf(src)
|
||||
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
|
||||
for(var/mob/living/carbon/human/M in viewers(T, null))
|
||||
if(M:eyecheck() <= 0)
|
||||
flick("e_flash", M.flash) // flash dose faggots
|
||||
for(var/i=1, i<=deliveryamt, i++)
|
||||
var/atom/movable/x = new spawner_type
|
||||
x.loc = T
|
||||
if(prob(50))
|
||||
for(var/j = 1, j <= rand(1, 3), j++)
|
||||
step(x, pick(NORTH,SOUTH,EAST,WEST))
|
||||
|
||||
for(var/i=1, i<=deliveryamt, i++)
|
||||
var/atom/movable/x = new spawner_type
|
||||
x.loc = T
|
||||
if(prob(50))
|
||||
for(var/j = 1, j <= rand(1, 3), j++)
|
||||
step(x, pick(NORTH,SOUTH,EAST,WEST))
|
||||
// Spawn some hostile syndicate critters
|
||||
|
||||
// Spawn some hostile syndicate critters
|
||||
|
||||
del(src)
|
||||
return
|
||||
del(src)
|
||||
|
||||
/obj/item/weapon/grenade/spawnergrenade/manhacks
|
||||
name = "manhack delivery grenade"
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
item_state = "flashbang"
|
||||
origin_tech = "materials=3;magnets=4;syndicate=4"
|
||||
|
||||
prime()
|
||||
explosion(src.loc,1,2,4)
|
||||
del(src)
|
||||
|
||||
return
|
||||
/obj/item/weapon/grenade/syndieminibomb/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,1,2,4)
|
||||
del(src)
|
||||
@@ -19,12 +19,13 @@
|
||||
|
||||
|
||||
obj/item/weapon/mop/proc/clean(turf/simulated/A)
|
||||
if(reagents.has_reagent("water", 1))
|
||||
A.clean_blood()
|
||||
for(var/obj/effect/O in A)
|
||||
if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay))
|
||||
del(O)
|
||||
reagents.reaction(A, TOUCH, 10) //10 is the multiplier for the reaction effect. probably needed to wet the floor properly.
|
||||
reagents.remove_any(1) //reaction() doesn't use up the reagents
|
||||
A.clean_blood()
|
||||
for(var/obj/effect/O in A)
|
||||
if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay))
|
||||
del(O)
|
||||
|
||||
|
||||
/obj/item/weapon/mop/afterattack(atom/A, mob/user)
|
||||
|
||||
@@ -174,11 +174,18 @@
|
||||
|
||||
|
||||
/obj/item/weapon/storage/pill_bottle/dice
|
||||
name = "pack of dice"
|
||||
desc = "It's a small container with dice inside."
|
||||
name = "bag of dice"
|
||||
desc = "Contains all the luck you'll ever need."
|
||||
icon = 'icons/obj/dice.dmi'
|
||||
icon_state = "dicebag"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/dice/d4( src )
|
||||
new /obj/item/weapon/dice( src )
|
||||
new /obj/item/weapon/dice/d8( src )
|
||||
new /obj/item/weapon/dice/d10( src )
|
||||
new /obj/item/weapon/dice/d00( src )
|
||||
new /obj/item/weapon/dice/d12( src )
|
||||
new /obj/item/weapon/dice/d20( src )
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
return 0
|
||||
if(!isturf(O.loc))
|
||||
return 0
|
||||
if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis)
|
||||
if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.lying)
|
||||
return 0
|
||||
if((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1))
|
||||
return 0
|
||||
|
||||
@@ -142,6 +142,9 @@
|
||||
new /obj/item/clothing/under/rank/atmospheric_technician(src)
|
||||
new /obj/item/clothing/under/rank/atmospheric_technician(src)
|
||||
new /obj/item/clothing/under/rank/atmospheric_technician(src)
|
||||
new /obj/item/device/analyzer(src)
|
||||
new /obj/item/device/analyzer(src)
|
||||
new /obj/item/device/analyzer(src)
|
||||
new /obj/item/clothing/shoes/black(src)
|
||||
new /obj/item/clothing/shoes/black(src)
|
||||
new /obj/item/clothing/shoes/black(src)
|
||||
|
||||
@@ -284,6 +284,9 @@
|
||||
/obj/structure/table/attackby(obj/item/weapon/W, mob/user)
|
||||
if (istype(W, /obj/item/weapon/grab) && get_dist(src, user) < 2)
|
||||
var/obj/item/weapon/grab/G = W
|
||||
if(G.affecting.buckled)
|
||||
user << "<span class='notice'>[G.affecting] is buckled to [G.affecting.buckled]!</span>"
|
||||
return
|
||||
if(G.state < GRAB_AGGRESSIVE)
|
||||
user << "<span class='notice'>You need a better grip to do that!</span>"
|
||||
return
|
||||
@@ -322,8 +325,7 @@
|
||||
return
|
||||
|
||||
user.drop_item(src)
|
||||
//if(W && W.loc) W.loc = src.loc // Unnecessary - see: mob/proc/drop_item(atom) - Doohl
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
/*
|
||||
@@ -339,6 +341,9 @@
|
||||
|
||||
if (istype(W, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = W
|
||||
if(G.affecting.buckled)
|
||||
user << "<span class='notice'>[G.affecting] is buckled to [G.affecting.buckled]!</span>"
|
||||
return
|
||||
if(G.state < GRAB_AGGRESSIVE)
|
||||
user << "<span class='notice'>You need a better grip to do that!</span>"
|
||||
return
|
||||
@@ -357,6 +362,7 @@
|
||||
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
del(src)
|
||||
return
|
||||
|
||||
if(isrobot(user))
|
||||
return
|
||||
if(istype(W, /obj/item/weapon/melee/energy/blade))
|
||||
@@ -373,7 +379,7 @@
|
||||
|
||||
user.drop_item(src)
|
||||
//if(W && W.loc) W.loc = src.loc
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
/*
|
||||
@@ -390,6 +396,9 @@
|
||||
|
||||
if (istype(W, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = W
|
||||
if(G.affecting.buckled)
|
||||
user << "<span class='notice'>[G.affecting] is buckled to [G.affecting.buckled]!</span>"
|
||||
return
|
||||
if(G.state < GRAB_AGGRESSIVE)
|
||||
user << "<span class='notice'>You need a better grip to do that!</span>"
|
||||
return
|
||||
@@ -451,7 +460,7 @@
|
||||
|
||||
user.drop_item(src)
|
||||
//if(W && W.loc) W.loc = src.loc
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
/*
|
||||
@@ -514,11 +523,12 @@
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
del(src)
|
||||
return
|
||||
|
||||
if(isrobot(user))
|
||||
return
|
||||
user.drop_item()
|
||||
if(W && W.loc) W.loc = src.loc
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/structure/rack/meteorhit(obj/O as obj)
|
||||
del(src)
|
||||
|
||||
@@ -98,6 +98,8 @@
|
||||
|
||||
|
||||
/obj/structure/window/attack_hand(mob/user as mob)
|
||||
if(!can_be_reached(user))
|
||||
return
|
||||
if(HULK in user.mutations)
|
||||
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!"))
|
||||
user.visible_message("<span class='danger'>[user] smashes through [src]!</span>")
|
||||
@@ -114,6 +116,8 @@
|
||||
|
||||
|
||||
/obj/structure/window/proc/attack_generic(mob/user as mob, damage = 0) //used by attack_alien, attack_animal, and attack_slime
|
||||
if(!can_be_reached(user))
|
||||
return
|
||||
health -= damage
|
||||
if(health <= 0)
|
||||
user.visible_message("<span class='danger'>[user] smashes through [src]!</span>")
|
||||
@@ -142,6 +146,8 @@
|
||||
|
||||
|
||||
/obj/structure/window/attackby(obj/item/I, mob/user)
|
||||
if(!can_be_reached(user))
|
||||
return 1 //returning 1 will skip the afterattack()
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(reinf && state >= 1)
|
||||
state = 3 - state
|
||||
@@ -173,6 +179,14 @@
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/structure/window/proc/can_be_reached(mob/user)
|
||||
if(!is_fulltile())
|
||||
if(get_dir(user,src) & dir)
|
||||
for(var/obj/O in loc)
|
||||
if(!O.CanPass(user, user.loc, 1, 0))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/window/proc/hit(var/damage, var/sound_effect = 1)
|
||||
if(reinf) damage *= 0.5
|
||||
health = max(0, health - damage)
|
||||
|
||||
@@ -530,4 +530,4 @@ turf/simulated/floor/proc/update_icon()
|
||||
burnt = 0
|
||||
broken = 0
|
||||
else
|
||||
user << "\blue You need more welding fuel to complete this task."
|
||||
user << "\blue You need more welding fuel to complete this task."
|
||||
|
||||
@@ -134,15 +134,6 @@ var/shuttlecoming = 0
|
||||
var/join_motd = null
|
||||
var/forceblob = 0
|
||||
|
||||
//airlockWireColorToIndex takes a number representing the wire color, e.g. the orange wire is always 1, the dark red wire is always 2, etc. It returns the index for whatever that wire does.
|
||||
//airlockIndexToWireColor does the opposite thing - it takes the index for what the wire does, for example AIRLOCK_WIRE_IDSCAN is 1, AIRLOCK_WIRE_POWER1 is 2, etc. It returns the wire color number.
|
||||
//airlockWireColorToFlag takes the wire color number and returns the flag for it (1, 2, 4, 8, 16, etc)
|
||||
|
||||
var/list/AAlarmWireColorToFlag = RandomAAlarmWires()
|
||||
var/list/AAlarmIndexToFlag
|
||||
var/list/AAlarmIndexToWireColor
|
||||
var/list/AAlarmWireColorToIndex
|
||||
|
||||
//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage
|
||||
var/MAX_EX_DEVESTATION_RANGE = 3
|
||||
var/MAX_EX_HEAVY_RANGE = 7
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#define MAX_ADMIN_BANS_PER_ADMIN 1
|
||||
|
||||
datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null)
|
||||
//Either pass the mob you wish to ban in the 'banned_mob' attribute, or the banckey, banip and bancid variables. If both are passed, the mob takes priority! If a mob is not passed, banckey is the minimum that needs to be passed! banip and bancid are optional.
|
||||
datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null, var/banip = null, var/bancid = null)
|
||||
|
||||
if(!check_rights(R_BAN)) return
|
||||
|
||||
@@ -71,6 +72,8 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
|
||||
ip = banned_mob.lastKnownIP
|
||||
else if(banckey)
|
||||
ckey = ckey(banckey)
|
||||
computerid = bancid
|
||||
ip = banip
|
||||
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_player WHERE ckey = '[ckey]'")
|
||||
query.Execute()
|
||||
@@ -353,6 +356,8 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
|
||||
output += "<option value='[BANTYPE_ADMIN_TEMP]'>ADMIN TEMPBAN</option>"
|
||||
output += "</select></td>"
|
||||
output += "<td><b>Ckey:</b> <input type='text' name='dbbanaddckey'></td></tr>"
|
||||
output += "<tr><td><b>IP:</b> <input type='text' name='dbbanaddip'></td>"
|
||||
output += "<td><b>Computer id:</b> <input type='text' name='dbbanaddcid'></td></tr>"
|
||||
output += "<tr><td><b>Duration:</b> <input type='text' name='dbbaddduration'></td>"
|
||||
output += "<td><b>Job:</b><select name='dbbanaddjob'>"
|
||||
output += "<option value=''>--</option>"
|
||||
|
||||
@@ -103,7 +103,6 @@ var/global/floorIsLava = 0
|
||||
body += "<A href='?_src_=holder;makeai=\ref[M]'>Make AI</A> | "
|
||||
body += "<A href='?_src_=holder;makerobot=\ref[M]'>Make Robot</A> | "
|
||||
body += "<A href='?_src_=holder;makealien=\ref[M]'>Make Alien</A> | "
|
||||
body += "<A href='?_src_=holder;makeblob=\ref[M]'>Make Blob Fragment</A> | "
|
||||
body += "<A href='?_src_=holder;makeslime=\ref[M]'>Make Slime</A> "
|
||||
|
||||
//Simple Animals
|
||||
@@ -399,6 +398,14 @@ var/global/floorIsLava = 0
|
||||
|
||||
var/dat = "<B>The first rule of adminbuse is: you don't talk about the adminbuse.</B><HR>"
|
||||
|
||||
dat +={"
|
||||
<B>General Secrets</B><BR>
|
||||
<BR>
|
||||
<A href='?src=\ref[src];secretsgeneral=list_job_debug'>Show Job Debug</A><BR>
|
||||
<A href='?src=\ref[src];secretsgeneral=spawn_objects'>Admin Log</A><BR>
|
||||
<BR>
|
||||
"}
|
||||
|
||||
if(check_rights(R_ADMIN,0))
|
||||
dat += {"
|
||||
<B>Admin Secrets</B><BR>
|
||||
@@ -459,7 +466,6 @@ var/global/floorIsLava = 0
|
||||
<A href='?src=\ref[src];secretsfun=eagles'>Egalitarian Station Mode</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=blackout'>Break all lights</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=whiteout'>Fix all lights</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=friendai'>Best Friend AI</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=floorlava'>The floor is lava! (DANGEROUS: extremely lame)</A><BR>
|
||||
"}
|
||||
|
||||
@@ -479,11 +485,6 @@ var/global/floorIsLava = 0
|
||||
<A href='?src=\ref[src];secretscoder=maint_access_brig'>Change all maintenance doors to brig access only</A><BR>
|
||||
<A href='?src=\ref[src];secretscoder=infinite_sec'>Remove cap on security officers</A><BR>
|
||||
<BR>
|
||||
<B>Coder Secrets</B><BR>
|
||||
<BR>
|
||||
<A href='?src=\ref[src];secretsadmin=list_job_debug'>Show Job Debug</A><BR>
|
||||
<A href='?src=\ref[src];secretscoder=spawn_objects'>Admin Log</A><BR>
|
||||
<BR>
|
||||
"}
|
||||
|
||||
usr << browse(dat, "window=secrets")
|
||||
|
||||
+30
-44
@@ -78,6 +78,8 @@
|
||||
|
||||
var/bantype = text2num(href_list["dbbanaddtype"])
|
||||
var/banckey = href_list["dbbanaddckey"]
|
||||
var/banip = href_list["dbbanaddip"]
|
||||
var/bancid = href_list["dbbanaddcid"]
|
||||
var/banduration = text2num(href_list["dbbaddduration"])
|
||||
var/banjob = href_list["dbbanaddjob"]
|
||||
var/banreason = href_list["dbbanreason"]
|
||||
@@ -130,9 +132,18 @@
|
||||
playermob = M
|
||||
break
|
||||
|
||||
|
||||
banreason = "(MANUAL BAN) "+banreason
|
||||
|
||||
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey)
|
||||
if(!playermob)
|
||||
if(banip)
|
||||
banreason = "[banreason] (CUSTOM IP)"
|
||||
if(bancid)
|
||||
banreason = "[banreason] (CUSTOM CID)"
|
||||
else
|
||||
message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob")
|
||||
|
||||
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid )
|
||||
|
||||
else if(href_list["editrights"])
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
@@ -231,9 +242,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")
|
||||
@@ -1046,18 +1054,6 @@
|
||||
message_admins("\blue [key_name_admin(usr)] attempting to corgize [key_name_admin(H)]", 1)
|
||||
H.corgize()
|
||||
|
||||
else if(href_list["makeblob"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makeblob"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be used on instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
log_admin("[key_name(usr)] attempting to blobize [key_name(H)]")
|
||||
message_admins("\blue [key_name_admin(usr)] attempting to blobize [key_name_admin(H)]", 1)
|
||||
H.blobize()
|
||||
|
||||
|
||||
else if(href_list["forcespeech"])
|
||||
if(!check_rights(R_FUN)) return
|
||||
@@ -1358,7 +1354,7 @@
|
||||
else
|
||||
health_description = "This mob type has no health to speak of."
|
||||
|
||||
//Gener
|
||||
//Gender
|
||||
switch(M.gender)
|
||||
if(MALE,FEMALE) gender_description = "[M.gender]"
|
||||
else gender_description = "<font color='red'><b>[M.gender]</b></font>"
|
||||
@@ -1915,19 +1911,6 @@
|
||||
message_admins("[key_name_admin(usr)] fixed all lights", 1)
|
||||
for(var/obj/machinery/light/L in world)
|
||||
L.fix()
|
||||
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."
|
||||
@@ -2076,16 +2059,6 @@
|
||||
for(var/sig in lawchanges)
|
||||
dat += "[sig]<BR>"
|
||||
usr << browse(dat, "window=lawchanges;size=800x500")
|
||||
if("list_job_debug")
|
||||
var/dat = "<B>Job Debug info.</B><HR>"
|
||||
if(job_master)
|
||||
for(var/line in job_master.job_debug)
|
||||
dat += "[line]<BR>"
|
||||
dat+= "*******<BR><BR>"
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
if(!job) continue
|
||||
dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions] <BR>"
|
||||
usr << browse(dat, "window=jobdebug;size=600x500")
|
||||
if("check_antagonist")
|
||||
check_antagonists()
|
||||
if("showailaws")
|
||||
@@ -2130,10 +2103,8 @@
|
||||
if (ok)
|
||||
world << text("<B>A secret has been activated by []!</B>", usr.key)
|
||||
|
||||
else if(href_list["secretscoder"])
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
switch(href_list["secretscoder"])
|
||||
else if(href_list["secretsgeneral"])
|
||||
switch(href_list["secretsgeneral"])
|
||||
if("spawn_objects")
|
||||
var/dat = "<B>Admin Log<HR></B>"
|
||||
for(var/l in admin_log)
|
||||
@@ -2141,6 +2112,21 @@
|
||||
if(!admin_log.len)
|
||||
dat += "No-one has done anything this round!"
|
||||
usr << browse(dat, "window=admin_log")
|
||||
if("list_job_debug")
|
||||
var/dat = "<B>Job Debug info.</B><HR>"
|
||||
if(job_master)
|
||||
for(var/line in job_master.job_debug)
|
||||
dat += "[line]<BR>"
|
||||
dat+= "*******<BR><BR>"
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
if(!job) continue
|
||||
dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions] <BR>"
|
||||
usr << browse(dat, "window=jobdebug;size=600x500")
|
||||
|
||||
else if(href_list["secretscoder"])
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
switch(href_list["secretscoder"])
|
||||
if("maint_access_brig")
|
||||
for(var/obj/machinery/door/airlock/maintenance/M in world)
|
||||
if (access_maint_tunnels in M.req_access)
|
||||
|
||||
@@ -440,22 +440,31 @@ var/global/list/g_fancy_list_of_safe_types = null
|
||||
return
|
||||
if (istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if (H.wear_id)
|
||||
var/obj/item/weapon/card/id/id = H.wear_id
|
||||
if(istype(H.wear_id, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/pda = H.wear_id
|
||||
id = pda.id
|
||||
var/obj/item/worn = H.wear_id
|
||||
var/obj/item/weapon/card/id/id = null
|
||||
if(worn)
|
||||
id = worn.GetID()
|
||||
if(id)
|
||||
id.icon_state = "gold"
|
||||
id:access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
|
||||
id.access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
|
||||
else
|
||||
var/obj/item/weapon/card/id/id = new/obj/item/weapon/card/id(M);
|
||||
id.icon_state = "gold"
|
||||
id:access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
|
||||
id = new /obj/item/weapon/card/id/gold(H.loc)
|
||||
id.access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
|
||||
id.registered_name = H.real_name
|
||||
id.assignment = "Captain"
|
||||
id.name = "[id.registered_name]'s ID Card ([id.assignment])"
|
||||
H.equip_to_slot_or_del(id, slot_wear_id)
|
||||
H.update_inv_wear_id()
|
||||
|
||||
if(worn)
|
||||
if(istype(worn,/obj/item/device/pda))
|
||||
worn:id = id
|
||||
id.loc = worn
|
||||
else if(istype(worn,/obj/item/weapon/storage/wallet))
|
||||
worn:front_id = id
|
||||
id.loc = worn
|
||||
worn.update_icon()
|
||||
else
|
||||
H.equip_to_slot(id,slot_wear_id)
|
||||
|
||||
else
|
||||
alert("Invalid mob")
|
||||
feedback_add_details("admin_verb","GFA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
|
||||
var/list/ghost_forms = list("ghost","ghostking","ghostian2")
|
||||
/client/verb/pick_form()
|
||||
set name = "Pick Ghost Form"
|
||||
set name = "Choose Ghost Form"
|
||||
set category = "Preferences"
|
||||
set desc = "Choose your preferred ghostly appearance."
|
||||
if(!is_content_unlocked()) return
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
weight = 5
|
||||
max_occurrences = 1
|
||||
|
||||
earliest_start = 48000 // 1 hour 20 minutes
|
||||
|
||||
/datum/round_event/blob
|
||||
announceWhen = 12
|
||||
endWhen = 120
|
||||
|
||||
@@ -87,19 +87,19 @@
|
||||
dat += "<A href='?src=\ref[src];action=activate'>Activate Biogenerator!</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=detach'>Detach Container</A><BR><BR>"
|
||||
dat += "Food<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=milk;cost=20'>10 milk</A> <FONT COLOR=blue>(20)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=meat;cost=50'>Slab of meat</A> <FONT COLOR=blue>(50)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=milk'>10 milk</A> <FONT COLOR=blue>(20)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=meat'>Slab of meat</A> <FONT COLOR=blue>(50)</FONT><BR>"
|
||||
dat += "Nutrient<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=ez;cost=10'>E-Z-Nutrient</A> <FONT COLOR=blue>(10)</FONT> | <A href='?src=\ref[src];action=create;item=ez5;cost=50'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=l4z;cost=20'>Left 4 Zed</A> <FONT COLOR=blue>(20)</FONT> | <A href='?src=\ref[src];action=create;item=l4z5;cost=100'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=rh;cost=25'>Robust Harvest</A> <FONT COLOR=blue>(25)</FONT> | <A href='?src=\ref[src];action=create;item=rh5;cost=125'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=ez'>E-Z-Nutrient</A> <FONT COLOR=blue>(10)</FONT> | <A href='?src=\ref[src];action=create;item=ez5'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=l4z'>Left 4 Zed</A> <FONT COLOR=blue>(20)</FONT> | <A href='?src=\ref[src];action=create;item=l4z5'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=rh'>Robust Harvest</A> <FONT COLOR=blue>(25)</FONT> | <A href='?src=\ref[src];action=create;item=rh5'>x5</A><BR>"
|
||||
dat += "Leather<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=wallet;cost=100'>Wallet</A> <FONT COLOR=blue>(100)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=gloves;cost=250'>Botanical gloves</A> <FONT COLOR=blue>(250)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=tbelt;cost=300'>Utility belt</A> <FONT COLOR=blue>(300)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=satchel;cost=400'>Leather Satchel</A> <FONT COLOR=blue>(400)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=wallet'>Wallet</A> <FONT COLOR=blue>(100)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=gloves'>Botanical gloves</A> <FONT COLOR=blue>(250)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=tbelt'>Utility belt</A> <FONT COLOR=blue>(300)</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=satchel'>Leather Satchel</A> <FONT COLOR=blue>(400)</FONT><BR>"
|
||||
//dat += "Other<BR>"
|
||||
//dat += "<A href='?src=\ref[src];action=create;item=monkey;cost=500'>Monkey</A> <FONT COLOR=blue>(500)</FONT><BR>"
|
||||
//dat += "<A href='?src=\ref[src];action=create;item=monkey'>Monkey</A> <FONT COLOR=blue>(500)</FONT><BR>"
|
||||
else
|
||||
dat += "<BR><FONT COLOR=red>No beaker inside. Please insert a beaker.</FONT><BR>"
|
||||
if("nopoints")
|
||||
@@ -146,54 +146,74 @@
|
||||
menustat = "void"
|
||||
return
|
||||
|
||||
/obj/machinery/biogenerator/proc/create_product(var/item,var/cost)
|
||||
if(cost > points)
|
||||
/obj/machinery/biogenerator/proc/check_cost(var/cost)
|
||||
if (cost > points)
|
||||
menustat = "nopoints"
|
||||
return 1
|
||||
else
|
||||
points -= cost
|
||||
processing = 1
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
sleep(30)
|
||||
return 0
|
||||
processing = 1
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
points -= cost
|
||||
sleep(30)
|
||||
|
||||
/obj/machinery/biogenerator/proc/create_product(var/item)
|
||||
switch(item)
|
||||
if("milk")
|
||||
beaker.reagents.add_reagent("milk",10)
|
||||
if (check_cost(20)) return 0
|
||||
else beaker.reagents.add_reagent("milk",10)
|
||||
if("meat")
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/meat(src.loc)
|
||||
if (check_cost(50)) return 0
|
||||
else new/obj/item/weapon/reagent_containers/food/snacks/meat(src.loc)
|
||||
if("ez")
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
if (check_cost(10)) return 0
|
||||
else new/obj/item/nutrient/ez(src.loc)
|
||||
if("l4z")
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
if (check_cost(20)) return 0
|
||||
else new/obj/item/nutrient/l4z(src.loc)
|
||||
if("rh")
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
if (check_cost(25)) return 0
|
||||
else new/obj/item/nutrient/rh(src.loc)
|
||||
if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
if (check_cost(50)) return 0
|
||||
else
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
new/obj/item/nutrient/ez(src.loc)
|
||||
if("l4z5")
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
if (check_cost(100)) return 0
|
||||
else
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
new/obj/item/nutrient/l4z(src.loc)
|
||||
if("rh5")
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
if (check_cost(125)) return 0
|
||||
else
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
new/obj/item/nutrient/rh(src.loc)
|
||||
if("wallet")
|
||||
new/obj/item/weapon/storage/wallet(src.loc)
|
||||
if (check_cost(100)) return 0
|
||||
else new/obj/item/weapon/storage/wallet(src.loc)
|
||||
if("gloves")
|
||||
new/obj/item/clothing/gloves/botanic_leather(src.loc)
|
||||
if (check_cost(250)) return 0
|
||||
else new/obj/item/clothing/gloves/botanic_leather(src.loc)
|
||||
if("tbelt")
|
||||
new/obj/item/weapon/storage/belt/utility(src.loc)
|
||||
if (check_cost(300)) return 0
|
||||
else new/obj/item/weapon/storage/belt/utility(src.loc)
|
||||
if("satchel")
|
||||
new/obj/item/weapon/storage/backpack/satchel(src.loc)
|
||||
if("monkey")
|
||||
new/mob/living/carbon/monkey(src.loc)
|
||||
if (check_cost(400)) return 0
|
||||
else new/obj/item/weapon/storage/backpack/satchel(src.loc)
|
||||
//if("monkey")
|
||||
// if (check_cost(500)) return 0
|
||||
// else new/mob/living/carbon/monkey(src.loc)
|
||||
processing = 0
|
||||
menustat = "complete"
|
||||
update_icon()
|
||||
|
||||
@@ -133,7 +133,7 @@ proc/move_mining_shuttle()
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["move"])
|
||||
if(ticker.mode.name == "blob")
|
||||
if(mining_shuttle_location == 1 && istype(ticker.mode, /datum/game_mode/blob)) // shuttle is on the station, this will mean miners can come back
|
||||
if(ticker.mode:declared)
|
||||
usr << "Under directive 7-10, [station_name()] is quarantined until further notice."
|
||||
return
|
||||
|
||||
@@ -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
|
||||
@@ -71,6 +71,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Ghost"
|
||||
set desc = "Relinquish your life and enter the land of the dead."
|
||||
|
||||
if(stat != DEAD)
|
||||
succumb()
|
||||
if(stat == DEAD)
|
||||
ghostize(1)
|
||||
else
|
||||
|
||||
@@ -1,258 +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"
|
||||
|
||||
|
||||
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 << "<B>You are now a blob fragment.</B>"
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -395,10 +395,10 @@ In all, this is a lot like the monkey code. /N
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob[name];size=325x500")
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/Topic(href, href_list)
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
usr << "This one seems particularly lifeless. Perhaps it will regain some of it's luster later.."
|
||||
|
||||
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
if(!istype(M, /mob))
|
||||
return
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/M, mob/user)
|
||||
if(!istype(M))
|
||||
return ..()
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
@@ -495,10 +495,10 @@
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob[name];size=325x500")
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
/mob/living/carbon/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
@@ -275,6 +275,13 @@
|
||||
mymob.pullin.screen_loc = ui_pull_resist
|
||||
hotkeybuttons += mymob.pullin
|
||||
|
||||
lingchemdisplay = new /obj/screen()
|
||||
lingchemdisplay.name = "chemical storage"
|
||||
lingchemdisplay.icon_state = "power_display"
|
||||
lingchemdisplay.screen_loc = ui_lingchemdisplay
|
||||
lingchemdisplay.layer = 20
|
||||
lingchemdisplay.invisibility = 101
|
||||
|
||||
mymob.blind = new /obj/screen()
|
||||
mymob.blind.icon = 'icons/mob/screen_full.dmi'
|
||||
mymob.blind.icon_state = "blackimageoverlay"
|
||||
@@ -303,7 +310,7 @@
|
||||
|
||||
mymob.client.screen = null
|
||||
|
||||
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
|
||||
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay, lingchemdisplay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
|
||||
mymob.client.screen += adding + hotkeybuttons
|
||||
inventory_shown = 0;
|
||||
|
||||
@@ -330,23 +337,29 @@
|
||||
return
|
||||
|
||||
client.screen -= hud_used.item_action_list
|
||||
hud_used.item_action_list = list()
|
||||
|
||||
for(var/obj/item/I in src)
|
||||
if(I.action_button_name)
|
||||
var/obj/screen/item_action/A = new(hud_used)
|
||||
if(hud_used.item_action_list.len < num)
|
||||
var/obj/screen/item_action/N = new(hud_used)
|
||||
hud_used.item_action_list += N
|
||||
|
||||
var/obj/screen/item_action/A = hud_used.item_action_list[num]
|
||||
|
||||
A.icon = ui_style2icon(client.prefs.UI_style)
|
||||
A.icon_state = "template"
|
||||
var/image/img = image(I.icon, I.icon_state)
|
||||
|
||||
A.overlays = list()
|
||||
var/image/img = image(I.icon, A, I.icon_state)
|
||||
img.pixel_x = 0
|
||||
img.pixel_y = 0
|
||||
A.overlays += img
|
||||
if(I.action_button_name)
|
||||
A.name = I.action_button_name
|
||||
else
|
||||
A.name = "Use [I.name]"
|
||||
|
||||
A.name = I.action_button_name
|
||||
A.owner = I
|
||||
hud_used.item_action_list += A
|
||||
|
||||
client.screen += hud_used.item_action_list[num]
|
||||
|
||||
switch(num)
|
||||
if(1)
|
||||
A.screen_loc = ui_action_slot1
|
||||
@@ -359,6 +372,4 @@
|
||||
if(5)
|
||||
A.screen_loc = ui_action_slot5
|
||||
break //5 slots available, so no more can be added.
|
||||
num++
|
||||
|
||||
client.screen += hud_used.item_action_list
|
||||
num++
|
||||
|
||||
@@ -120,8 +120,8 @@
|
||||
stat("Distribution Pressure", internal.distribute_pressure)
|
||||
if(mind)
|
||||
if(mind.changeling)
|
||||
stat("Chemical Storage", mind.changeling.chem_charges)
|
||||
stat("Genetic Damage Time", mind.changeling.geneticdamage)
|
||||
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
|
||||
stat("Absorbed DNA", mind.changeling.absorbedcount)
|
||||
if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized)
|
||||
stat("Energy Charge", round(wear_suit:cell:charge/100))
|
||||
|
||||
@@ -374,15 +374,16 @@
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_legcuffed]'>Legcuffed</A>"
|
||||
if(w_uniform)
|
||||
dat += "<BR><A href='?src=\ref[src];pockets=1'>Empty Pockets</A>"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];pockets=left'>Left Pocket ([l_store ? "Full" : "Empty"])</A>"
|
||||
dat += " - <A href='?src=\ref[src];pockets=right'>Right Pocket ([r_store ? "Full" : "Empty"])</A>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
|
||||
user << browse(dat, "window=mob[name];size=340x480")
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, "window=mob\ref[src];size=340x480")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
// called when something steps onto a human
|
||||
@@ -478,15 +479,38 @@
|
||||
//strip panel
|
||||
if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr))
|
||||
if(href_list["pockets"])
|
||||
|
||||
var/pocket_side = href_list["pockets"]
|
||||
var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store)
|
||||
var/obj/item/pocket_item = (pocket_id == slot_r_store ? src.r_store : src.l_store)
|
||||
var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty
|
||||
|
||||
//visible_message("<span class='danger'>[usr] tries to empty [src]'s pockets.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to empty [src]'s pockets.</span>") // Pickpocketing!
|
||||
usr << "<span class='notice'>You try to empty [src]'s pockets.</span>"
|
||||
if(do_mob(usr, src, STRIP_DELAY * 0.5))
|
||||
u_equip(r_store)
|
||||
u_equip(l_store)
|
||||
if(pocket_item)
|
||||
usr << "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>"
|
||||
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1))
|
||||
usr << "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>"
|
||||
else
|
||||
return
|
||||
|
||||
if(do_mob(usr, src, STRIP_DELAY))
|
||||
if(pocket_item)
|
||||
u_equip(pocket_item)
|
||||
else
|
||||
if(place_item)
|
||||
usr.u_equip(place_item)
|
||||
equip_to_slot_if_possible(place_item, pocket_id, 0, 1)
|
||||
|
||||
// Update strip window
|
||||
if(usr.machine == src && in_range(src, usr))
|
||||
show_inv(usr)
|
||||
|
||||
|
||||
|
||||
else
|
||||
// Display a warning if the user mocks up
|
||||
src << "<span class='warning'>You feel your pockets being fumbled with!</span>"
|
||||
src << "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>"
|
||||
|
||||
if(href_list["criminal"])
|
||||
if(istype(usr, /mob/living/carbon/human))
|
||||
|
||||
@@ -1022,6 +1022,12 @@
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
seer = 0
|
||||
|
||||
if(mind && mind.changeling)
|
||||
hud_used.lingchemdisplay.invisibility = 0
|
||||
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font color='#dd66dd'>[src.mind.changeling.chem_charges]</font></div>"
|
||||
else
|
||||
hud_used.lingchemdisplay.invisibility = 101
|
||||
|
||||
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)
|
||||
|
||||
@@ -142,6 +142,13 @@
|
||||
mymob.pullin.name = "pull"
|
||||
mymob.pullin.screen_loc = ui_pull_resist
|
||||
|
||||
lingchemdisplay = new /obj/screen()
|
||||
lingchemdisplay.name = "chemical storage"
|
||||
lingchemdisplay.icon_state = "power_display"
|
||||
lingchemdisplay.screen_loc = ui_lingchemdisplay
|
||||
lingchemdisplay.layer = 20
|
||||
lingchemdisplay.invisibility = 101
|
||||
|
||||
mymob.blind = new /obj/screen()
|
||||
mymob.blind.icon = 'icons/mob/screen_full.dmi'
|
||||
mymob.blind.icon_state = "blackimageoverlay"
|
||||
|
||||
@@ -345,8 +345,8 @@
|
||||
if(client && mind)
|
||||
if (client.statpanel == "Status")
|
||||
if(mind.changeling)
|
||||
stat("Chemical Storage", mind.changeling.chem_charges)
|
||||
stat("Genetic Damage Time", mind.changeling.geneticdamage)
|
||||
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
|
||||
stat("Absorbed DNA", mind.changeling.absorbedcount)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
src.adjustOxyLoss(src.health + 200)
|
||||
src.health = 100 - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
|
||||
src << "\blue You have given up life and succumbed to death."
|
||||
|
||||
death()
|
||||
|
||||
|
||||
/mob/living/proc/updatehealth()
|
||||
|
||||
@@ -31,7 +31,7 @@ var/list/ai_list = list()
|
||||
var/obj/item/device/multitool/aiMulti = null
|
||||
|
||||
//MALFUNCTION
|
||||
var/datum/AI_Module/module_picker/malf_picker
|
||||
var/datum/module_picker/malf_picker
|
||||
var/processing_time = 100
|
||||
var/list/datum/AI_Module/current_modules = list()
|
||||
var/fire_res_on_core = 0
|
||||
@@ -48,6 +48,7 @@ var/list/ai_list = list()
|
||||
var/datum/trackable/track = null
|
||||
|
||||
var/last_paper_seen = null
|
||||
var/can_shunt = 1
|
||||
|
||||
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
|
||||
var/list/possibleNames = ai_names
|
||||
|
||||
@@ -33,7 +33,7 @@ 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) & ~(CHUNK_SIZE - 1)
|
||||
var/y1 = max(0, ai.y - 16) & ~(CHUNK_SIZE - 1)
|
||||
|
||||
@@ -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
|
||||
@@ -105,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)
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
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
|
||||
|
||||
@@ -3,40 +3,17 @@
|
||||
// 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))
|
||||
@@ -51,13 +28,16 @@
|
||||
var/obj/machinery/hologram/holopad/H = ai.current
|
||||
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
|
||||
|
||||
@@ -238,6 +238,9 @@
|
||||
adjustBruteLoss(60)
|
||||
updatehealth()
|
||||
return 1
|
||||
else
|
||||
gib()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/Stat()
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
stop_automated_movement = 1
|
||||
stance_step++
|
||||
if(stance_step >= 10) //rests for 10 ticks
|
||||
if(target_mob && target_mob in ListTargets())
|
||||
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
|
||||
@@ -72,15 +72,15 @@
|
||||
if(HOSTILE_STANCE_ALERT)
|
||||
stop_automated_movement = 1
|
||||
var/found_mob = 0
|
||||
if(target_mob && target_mob in ListTargets())
|
||||
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)
|
||||
@@ -105,14 +105,14 @@
|
||||
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)
|
||||
@@ -128,22 +128,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/limb/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
|
||||
|
||||
|
||||
@@ -64,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))
|
||||
@@ -82,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)
|
||||
@@ -107,7 +107,7 @@
|
||||
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
|
||||
@@ -149,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)
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
damage_type = BRUTE
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot
|
||||
name = "Hivebot"
|
||||
desc = "A small robot"
|
||||
name = "hivebot"
|
||||
desc = "A small robot."
|
||||
icon = 'icons/mob/hivebot.dmi'
|
||||
icon_state = "basic"
|
||||
icon_living = "basic"
|
||||
@@ -28,7 +28,7 @@
|
||||
minbodytemp = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/range
|
||||
name = "Hivebot"
|
||||
name = "hivebot"
|
||||
desc = "A smallish robot, this one is armed!"
|
||||
ranged = 1
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
rapid = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/strong
|
||||
name = "Strong Hivebot"
|
||||
name = "strong hivebot"
|
||||
desc = "A robot, this one is armed and looks tough!"
|
||||
health = 80
|
||||
ranged = 1
|
||||
@@ -54,8 +54,8 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/tele//this still needs work
|
||||
name = "Beacon"
|
||||
desc = "Some odd beacon thing"
|
||||
name = "beacon"
|
||||
desc = "Some odd beacon thing."
|
||||
icon = 'icons/mob/hivebot.dmi'
|
||||
icon_state = "def_radar-off"
|
||||
icon_living = "def_radar-off"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/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
|
||||
@@ -32,63 +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
|
||||
|
||||
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())
|
||||
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()))
|
||||
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
|
||||
|
||||
/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()
|
||||
@@ -125,7 +130,8 @@
|
||||
if(!stat)
|
||||
switch(stance)
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
target_mob = FindTarget()
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
DestroySurroundings()
|
||||
@@ -135,8 +141,8 @@
|
||||
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 <b>[src]</b> fires at [target]!", 1)
|
||||
|
||||
var/tturf = get_turf(target)
|
||||
@@ -159,7 +165,7 @@
|
||||
new casingtype
|
||||
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
target_mob = null
|
||||
target = null
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
* Sub-types
|
||||
*/
|
||||
|
||||
/*So you want to delete parrots eh?
|
||||
heres the locations of their snowflake code:
|
||||
lines 294-301 in living/say.dm (speech buffer)
|
||||
135 in living/say.dm (parrots talking into headsets)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Defines
|
||||
*/
|
||||
@@ -42,19 +48,25 @@
|
||||
speak_chance = 1 //1% (1 in 100) chance every tick; So about once per 150 seconds, assuming an average tick is 1.5s
|
||||
turns_per_move = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker/
|
||||
melee_damage_upper = 10
|
||||
melee_damage_lower = 5
|
||||
|
||||
response_help = "pets"
|
||||
response_disarm = "gently moves aside"
|
||||
response_harm = "swats"
|
||||
stop_automated_movement = 1
|
||||
a_intent = "harm" //parrots now start "aggressive" since only player parrots will nuzzle.
|
||||
attacktext = "chomps"
|
||||
friendly = "grooms"
|
||||
|
||||
var/parrot_damage_upper = 10
|
||||
var/parrot_state = PARROT_WANDER //Hunt for a perch when created
|
||||
var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick.
|
||||
var/parrot_sleep_dur = 25 //Same as above, this is the var that physically counts down
|
||||
var/parrot_dam_zone = list("chest", "head", "l_arm", "l_leg", "r_arm", "r_leg") //For humans, select a bodypart to attack
|
||||
|
||||
var/parrot_speed = 5 //"Delay in world ticks between movement." according to byond. Yeah, that's BS but it does directly affect movement. Higher number = slower.
|
||||
var/parrot_been_shot = 0 //Parrots get a speed bonus after being shot. This will deincrement every Life() and at 0 the parrot will return to regular speed.
|
||||
//var/parrot_been_shot = 0 this wasn't working right, and parrots don't survive bullets.((Parrots get a speed bonus after being shot. This will deincrement every Life() and at 0 the parrot will return to regular speed.))
|
||||
|
||||
var/parrot_lastmove = null //Updates/Stores position of the parrot while it's moving
|
||||
var/parrot_stuck = 0 //If parrot_lastmove hasnt changed, this will increment until it reaches parrot_stuck_threshold
|
||||
@@ -100,7 +112,8 @@
|
||||
verbs.Add(/mob/living/simple_animal/parrot/proc/steal_from_ground, \
|
||||
/mob/living/simple_animal/parrot/proc/steal_from_mob, \
|
||||
/mob/living/simple_animal/parrot/verb/drop_held_item_player, \
|
||||
/mob/living/simple_animal/parrot/proc/perch_player)
|
||||
/mob/living/simple_animal/parrot/proc/perch_player, \
|
||||
/mob/living/simple_animal/parrot/proc/toggle_mode)
|
||||
|
||||
|
||||
/mob/living/simple_animal/parrot/Die()
|
||||
@@ -113,6 +126,7 @@
|
||||
/mob/living/simple_animal/parrot/Stat()
|
||||
..()
|
||||
stat("Held Item", held_item)
|
||||
stat("Mode",a_intent)
|
||||
|
||||
/*
|
||||
* Inventory
|
||||
@@ -144,10 +158,11 @@
|
||||
switch(remove_from)
|
||||
if("ears")
|
||||
if(ears)
|
||||
if(available_channels.len)
|
||||
src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
else
|
||||
src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
if(!stat)
|
||||
if(available_channels.len)
|
||||
src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
else
|
||||
src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
ears.loc = src.loc
|
||||
ears = null
|
||||
for(var/possible_phrase in speak)
|
||||
@@ -197,10 +212,10 @@
|
||||
available_channels.Add(":n")
|
||||
if("Medical")
|
||||
available_channels.Add(":m")
|
||||
if("Mining")
|
||||
available_channels.Add(":d")
|
||||
if("Cargo")
|
||||
available_channels.Add(":q")
|
||||
if("Supply")
|
||||
available_channels.Add(":u")
|
||||
if("Service")
|
||||
available_channels.Add(":v")
|
||||
|
||||
if(headset_to_add.translate_binary)
|
||||
available_channels.Add(":b")
|
||||
@@ -240,29 +255,41 @@
|
||||
|
||||
//Simple animals
|
||||
/mob/living/simple_animal/parrot/attack_animal(mob/living/simple_animal/M as mob)
|
||||
..() //goodbye immortal parrots
|
||||
|
||||
if(client) return
|
||||
|
||||
|
||||
if(parrot_state == PARROT_PERCH)
|
||||
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
|
||||
|
||||
if(M.melee_damage_upper > 0)
|
||||
if(M.melee_damage_upper > 0 && !stat)
|
||||
parrot_interest = M
|
||||
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
|
||||
icon_state = "parrot_fly"
|
||||
|
||||
//Mobs with objects
|
||||
/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
..()
|
||||
if(!stat && !client && !istype(O, /obj/item/stack/medical))
|
||||
/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/living/user as mob)
|
||||
if(!stat && !client && !istype(O, /obj/item/stack/medical) && !istype(O,/obj/item/weapon/reagent_containers/food/snacks/cracker))
|
||||
if(O.force)
|
||||
if(parrot_state == PARROT_PERCH)
|
||||
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
|
||||
|
||||
parrot_interest = user
|
||||
parrot_state = PARROT_SWOOP | PARROT_FLEE
|
||||
parrot_state = PARROT_SWOOP
|
||||
if (user.health < 50)
|
||||
parrot_state |= PARROT_ATTACK //weakened mob? fight back!
|
||||
else
|
||||
parrot_state |= PARROT_FLEE
|
||||
icon_state = "parrot_fly"
|
||||
drop_held_item(0)
|
||||
else if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/cracker)) //Poly wants a cracker.
|
||||
del(O)
|
||||
user.drop_item()
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-10)
|
||||
user << "\blue [src] eagerly devours the cracker."
|
||||
..()
|
||||
return
|
||||
|
||||
//Bullets
|
||||
@@ -273,8 +300,8 @@
|
||||
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
|
||||
|
||||
parrot_interest = null
|
||||
parrot_state = PARROT_WANDER //OWFUCK, Been shot! RUN LIKE HELL!
|
||||
parrot_been_shot += 5
|
||||
parrot_state = PARROT_WANDER | PARROT_FLEE //Been shot and survived! RUN LIKE HELL!
|
||||
//parrot_been_shot += 5
|
||||
icon_state = "parrot_fly"
|
||||
drop_held_item(0)
|
||||
return
|
||||
@@ -462,8 +489,9 @@
|
||||
if(!parrot_interest || !isliving(parrot_interest)) //Sanity
|
||||
parrot_state = PARROT_WANDER
|
||||
|
||||
walk_away(src, parrot_interest, 1, parrot_speed-parrot_been_shot)
|
||||
parrot_been_shot--
|
||||
walk_away(src, parrot_interest, 1, parrot_speed)
|
||||
/*if(parrot_been_shot > 0)
|
||||
parrot_been_shot-- didn't work anyways, and besides, any bullet poly survives isn't worth the speed boost.*/
|
||||
if(isStuck()) return
|
||||
|
||||
return
|
||||
@@ -478,6 +506,9 @@
|
||||
return
|
||||
|
||||
var/mob/living/L = parrot_interest
|
||||
if(melee_damage_upper == 0)
|
||||
melee_damage_upper = parrot_damage_upper
|
||||
a_intent = "harm"
|
||||
|
||||
//If the mob is close enough to interact with
|
||||
if(in_range(src, parrot_interest))
|
||||
@@ -495,21 +526,8 @@
|
||||
parrot_state = PARROT_WANDER
|
||||
return
|
||||
|
||||
//Time for the hurt to begin!
|
||||
var/damage = rand(5,10)
|
||||
|
||||
if(ishuman(parrot_interest))
|
||||
var/mob/living/carbon/human/H = parrot_interest
|
||||
var/datum/limb/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
|
||||
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"))
|
||||
emote(pick("pecks [H]'s [affecting]", "cuts [H]'s [affecting] with its talons"))
|
||||
|
||||
else
|
||||
L.adjustBruteLoss(damage)
|
||||
emote(pick("pecks at [L]", "claws [L]"))
|
||||
return
|
||||
|
||||
attacktext = pick("claws at", "chomps")
|
||||
L.attack_animal(src)//Time for the hurt to begin!
|
||||
//Otherwise, fly towards the mob!
|
||||
else
|
||||
walk_to(src, parrot_interest, 1, parrot_speed)
|
||||
@@ -683,6 +701,17 @@
|
||||
src << "\red You have nothing to drop!"
|
||||
return 0
|
||||
|
||||
|
||||
//parrots will eat crackers instead of dropping them
|
||||
if(istype(held_item,/obj/item/weapon/reagent_containers/food/snacks/cracker) && (drop_gently))
|
||||
del(held_item)
|
||||
held_item = null
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-10)
|
||||
emote("[src] eagerly downs the cracker")
|
||||
return 1
|
||||
|
||||
|
||||
if(!drop_gently)
|
||||
if(istype(held_item, /obj/item/weapon/grenade))
|
||||
var/obj/item/weapon/grenade/G = held_item
|
||||
@@ -716,6 +745,22 @@
|
||||
src << "\red There is no perch nearby to sit on."
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/parrot/proc/toggle_mode()
|
||||
set name = "Toggle mode"
|
||||
set category = "Parrot"
|
||||
set desc = "Time to bear those claws!"
|
||||
|
||||
if(stat || !client)
|
||||
return
|
||||
|
||||
if(melee_damage_upper)
|
||||
melee_damage_upper = 0
|
||||
a_intent = "help"
|
||||
else
|
||||
melee_damage_upper = parrot_damage_upper
|
||||
a_intent = "harm"
|
||||
return
|
||||
|
||||
/*
|
||||
* Sub-types
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -225,6 +230,8 @@
|
||||
return "says, \"[text]\"";
|
||||
|
||||
/mob/living/simple_animal/emote(var/act)
|
||||
if(stat)
|
||||
return
|
||||
if(act)
|
||||
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))
|
||||
@@ -368,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 [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 [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.
|
||||
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
|
||||
@@ -440,14 +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
|
||||
/mob/living/simple_animal/proc/SA_attackable(target)
|
||||
if (isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!L.stat)
|
||||
return (0)
|
||||
if (istype(target_mob,/obj/mecha))
|
||||
var/obj/mecha/M = target_mob
|
||||
return 0
|
||||
if (istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
if (M.occupant)
|
||||
return (0)
|
||||
return (1)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -238,10 +238,10 @@ var/list/slot_equipment_priority = list( \
|
||||
<HR>
|
||||
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [l_hand ? l_hand : "Nothing"]</A>
|
||||
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [r_hand ? r_hand : "Nothing"]</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob[name];size=325x500")
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
/mob/verb/mode()
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
var/say_message = null // When you are understood by others. Currently only used by aliens and monkeys in their say_quote procs
|
||||
|
||||
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.
|
||||
|
||||
//The last mob/living/carbon to push/drag/grab this mob (mostly used by slimes friend recognition)
|
||||
var/mob/living/carbon/LAssailant = null
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code.
|
||||
/obj/item/weapon/grab/proc/throw()
|
||||
if(affecting)
|
||||
if(affecting.buckled)
|
||||
return null
|
||||
if(state >= GRAB_AGGRESSIVE)
|
||||
return affecting
|
||||
return null
|
||||
@@ -78,6 +80,7 @@
|
||||
affecting.drop_item()
|
||||
affecting.hand = h
|
||||
for(var/obj/item/weapon/grab/G in affecting.grabbed_by)
|
||||
if(G == src) continue
|
||||
if(G.state == GRAB_AGGRESSIVE)
|
||||
allow_upgrade = 0
|
||||
if(allow_upgrade)
|
||||
@@ -106,7 +109,7 @@
|
||||
return
|
||||
if(assailant.next_move > world.time)
|
||||
return
|
||||
if(last_upgrade > world.time + UPGRADE_COOLDOWN)
|
||||
if(world.time < (last_upgrade + UPGRADE_COOLDOWN))
|
||||
return
|
||||
if(!assailant.canmove || assailant.lying)
|
||||
del(src)
|
||||
|
||||
@@ -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/limb))
|
||||
return 1
|
||||
|
||||
@@ -211,16 +211,16 @@
|
||||
return 0 //This is sota the goto stop mobs from moving var
|
||||
if(mob.control_object)
|
||||
return Move_object(direct)
|
||||
if(isobserver(mob))
|
||||
return mob.Move(n,direct)
|
||||
if(moving)
|
||||
return 0
|
||||
if(world.time < move_delay)
|
||||
return 0
|
||||
if(mob.stat == DEAD)
|
||||
return 0
|
||||
if(isAI(mob))
|
||||
return AIMove(n,direct,mob)
|
||||
if(!isliving(mob))
|
||||
return mob.Move(n,direct)
|
||||
if(moving)
|
||||
return 0
|
||||
if(mob.stat == DEAD)
|
||||
return 0
|
||||
if(isliving(mob))
|
||||
var/mob/living/L = mob
|
||||
if(L.incorporeal_move) //Move though walls
|
||||
|
||||
@@ -389,27 +389,6 @@
|
||||
. = new_corgi
|
||||
del(src)
|
||||
|
||||
/mob/living/carbon/human/proc/blobize() // Oh boy, this is for you Int - Summoner
|
||||
if (monkeyizing)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
drop_from_inventory(W)
|
||||
regenerate_icons()
|
||||
monkeyizing = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
for(var/t in organs)
|
||||
del(t)
|
||||
|
||||
var/mob/living/blob/new_blob = new /mob/living/blob (loc)
|
||||
new_blob.a_intent = "harm"
|
||||
new_blob.key = key
|
||||
|
||||
new_blob << "<B>You are now a Blob Fragment. You can now sacrifice yourself to spawn blobs!</B>"
|
||||
. = new_blob
|
||||
del(src)
|
||||
|
||||
/mob/living/carbon/human/Animalize()
|
||||
|
||||
var/list/mobtypes = typesof(/mob/living/simple_animal)
|
||||
|
||||
@@ -796,6 +796,9 @@
|
||||
if(istype(malf.loc, /obj/machinery/power/apc)) // Already in an APC
|
||||
malf << "<span class='warning'>You must evacuate your current apc first.</span>"
|
||||
return
|
||||
if(!malf.can_shunt)
|
||||
malf << "<span class='warning'>You cannot shunt.</span>"
|
||||
return
|
||||
if(src.z != 1)
|
||||
return
|
||||
src.occupant = new /mob/living/silicon/ai(src,malf.laws,null,1)
|
||||
|
||||
@@ -140,8 +140,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)
|
||||
|
||||
@@ -276,6 +276,7 @@
|
||||
if(href_list["amount"])
|
||||
var/id = href_list["add"]
|
||||
var/amount = text2num(href_list["amount"])
|
||||
if (amount < 0) return
|
||||
R.trans_id_to(src, id, amount)
|
||||
|
||||
else if (href_list["addcustom"])
|
||||
@@ -290,6 +291,7 @@
|
||||
if(href_list["amount"])
|
||||
var/id = href_list["remove"]
|
||||
var/amount = text2num(href_list["amount"])
|
||||
if (amount < 0) return
|
||||
if(mode)
|
||||
reagents.trans_id_to(beaker, id, amount)
|
||||
else
|
||||
|
||||
@@ -122,10 +122,9 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(W,/obj/item/weapon/storage))
|
||||
..() // -> item/attackby()
|
||||
if(istype(W,/obj/item/weapon/storage))
|
||||
..() // -> item/attackby()
|
||||
return 0
|
||||
if((slices_num <= 0 || !slices_num) || !slice_path)
|
||||
return 1
|
||||
return 0
|
||||
var/inaccurate = 0
|
||||
if( \
|
||||
istype(W, /obj/item/weapon/kitchenknife) || \
|
||||
@@ -143,7 +142,7 @@
|
||||
inaccurate = 1
|
||||
else if(W.w_class <= 2 && istype(src,/obj/item/weapon/reagent_containers/food/snacks/sliceable))
|
||||
if(!iscarbon(user))
|
||||
return 1
|
||||
return 0
|
||||
user << "<span class='notice'>You slip [W] inside [src].</span>"
|
||||
user.u_equip(W)
|
||||
if ((user.client && user.s_active != src))
|
||||
@@ -151,9 +150,10 @@
|
||||
W.dropped(user)
|
||||
add_fingerprint(user)
|
||||
contents += W
|
||||
return
|
||||
return 1 // no afterattack here
|
||||
else
|
||||
return 1
|
||||
return 0 // --- this is everything that is NOT a slicing implement, and which is not being slipped into food; allow afterattack ---
|
||||
|
||||
if ( \
|
||||
!isturf(src.loc) || \
|
||||
!(locate(/obj/structure/table) in src.loc) && \
|
||||
@@ -162,6 +162,7 @@
|
||||
)
|
||||
user << "<span class='notice'>You cannot slice [src] here! You need a table or at least a tray.</span>"
|
||||
return 1
|
||||
|
||||
var/slices_lost = 0
|
||||
if (!inaccurate)
|
||||
user.visible_message( \
|
||||
@@ -178,7 +179,7 @@
|
||||
for(var/i=1 to (slices_num-slices_lost))
|
||||
var/obj/slice = new slice_path (src.loc)
|
||||
reagents.trans_to(slice,reagents_per_slice)
|
||||
del(src)
|
||||
del(src) // so long and thanks for all the fish
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/Del()
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
//gas.volume = 1.05 * CELLSTANDARD
|
||||
update()
|
||||
|
||||
Del()
|
||||
for(var/atom/movable/AM in contents)
|
||||
AM.loc = src.loc
|
||||
..()
|
||||
|
||||
// attack by item places it in to disposal
|
||||
attackby(var/obj/item/I, var/mob/user)
|
||||
@@ -143,6 +147,7 @@
|
||||
V.show_message("[usr] starts climbing into the disposal.", 3)
|
||||
if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
|
||||
if(target.anchored) return
|
||||
if(!ishuman(user) && !ismonkey(user)) return
|
||||
V.show_message("[usr] starts stuffing [target.name] into the disposal.", 3)
|
||||
if(!do_after(usr, 20))
|
||||
return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user