Merge branch 'master' of https://github.com/tgstation/-tg-station into reflectivejugs

This commit is contained in:
Malkevin
2013-07-21 19:30:16 +01:00
118 changed files with 2671 additions and 2288 deletions
+6 -5
View File
@@ -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
View File
@@ -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()
+2 -2
View File
@@ -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
View File
@@ -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>"
+5
View File
@@ -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
+94
View File
@@ -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()
+122 -98
View File
@@ -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
+16 -16
View File
@@ -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
+3
View File
@@ -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>"
+67 -42
View File
@@ -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
+21 -16
View File
@@ -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)
+6 -4
View File
@@ -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
+4 -6
View File
@@ -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
+17
View File
@@ -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)
+53
View File
@@ -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
+231
View File
@@ -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
+51 -103
View File
@@ -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
+47 -5
View File
@@ -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
+162 -121
View File
@@ -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
+181 -159
View File
@@ -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)
+19 -17
View File
@@ -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)
..()
+1
View File
@@ -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)
+7 -7
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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(), \
+1
View File
@@ -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()
+2 -2
View File
@@ -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 -1
View File
@@ -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
+4
View File
@@ -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
+11 -10
View File
@@ -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)
+2
View File
@@ -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]"
+5 -40
View File
@@ -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]&deg;C ([C.bodytemperature*1.8-459.67]&deg;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))
+46 -1
View File
@@ -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.
+56 -41
View File
@@ -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]&deg;C ([M.bodytemperature*1.8-459.67]&deg;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]&deg;C ([M.bodytemperature*1.8-459.67]&deg;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)
+54 -6
View File
@@ -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)
+5 -4
View File
@@ -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)
+15 -5
View File
@@ -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)
+14
View File
@@ -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)
+1 -1
View File
@@ -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."
-9
View File
@@ -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
+6 -1
View File
@@ -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>"
+8 -7
View File
@@ -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
View File
@@ -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)
+20 -11
View File
@@ -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!
+1 -1
View File
@@ -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
+2
View File
@@ -4,6 +4,8 @@
weight = 5
max_occurrences = 1
earliest_start = 48000 // 1 hour 20 minutes
/datum/round_event/blob
announceWhen = 12
endWhen = 120
+63 -43
View File
@@ -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()
+1 -1
View File
@@ -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
+14
View File
@@ -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
-258
View File
@@ -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)
+3 -3
View File
@@ -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)
..()
+23 -12
View File
@@ -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++
+35 -11
View File
@@ -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
+1 -1
View File
@@ -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()
+2 -1
View File
@@ -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
+79 -34
View File
@@ -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
+3 -3
View File
@@ -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()
+1
View File
@@ -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
+4 -1
View File
@@ -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)
+5
View File
@@ -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
+6 -6
View File
@@ -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
-21
View File
@@ -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)
+3
View File
@@ -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)
+1 -2
View File
@@ -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()
+5
View File
@@ -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