Merge branch 'bleeding-edge-freeze' of github.com:Baystation12/Baystation12 into feature

This commit is contained in:
cib
2013-03-04 12:20:38 +01:00
21 changed files with 6078 additions and 5424 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

@@ -0,0 +1,405 @@
// Basic transit tubes. Straight pieces, curved sections,
// and basic splits/joins (no routing logic).
// Mappers: you can use "Generate Instances from Icon-states"
// to get the different pieces.
/obj/structure/transit_tube
icon = 'transit_tube.dmi'
icon_state = "E-W"
density = 1
layer = 3.1
anchored = 1.0
var/list/tube_dirs = null
var/exit_delay = 2
var/enter_delay = 1
// A place where tube pods stop, and people can get in or out.
// Mappers: use "Generate Instances from Directions" for this
// one.
/obj/structure/transit_tube/station
icon = 'transit_tube_station.dmi'
icon_state = "closed"
exit_delay = 2
enter_delay = 3
var/pod_moving = 0
var/automatic_launch_time = 100
var/const/OPEN_DURATION = 6
var/const/CLOSE_DURATION = 6
/obj/structure/transit_tube_pod
icon = 'transit_tube_pod.dmi'
icon_state = "pod"
animate_movement = FORWARD_STEPS
var/moving = 0
var/datum/gas_mixture/air_contents
/obj/structure/transit_tube/station/New(loc)
..(loc)
spawn(automatic_launch_time)
launch_pod()
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
if(!pod_moving && icon_state == "open" && istype(AM, /mob))
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
AM.loc = pod
return
/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
if(!pod_moving)
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
if(icon_state == "closed")
open_animation()
else if(icon_state == "open")
close_animation()
/obj/structure/transit_tube/station/proc/open_animation()
if(icon_state == "closed")
icon_state = "opening"
spawn(OPEN_DURATION)
if(icon_state == "opening")
icon_state = "open"
/obj/structure/transit_tube/station/proc/close_animation()
if(icon_state == "open")
icon_state = "closing"
spawn(CLOSE_DURATION)
if(icon_state == "closing")
icon_state = "closed"
/obj/structure/transit_tube/station/proc/launch_pod()
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
spawn(5)
pod_moving = 1
close_animation()
sleep(CLOSE_DURATION + 2)
if(icon_state == "closed" && pod)
pod.follow_tube()
pod_moving = 0
return
/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
return 0
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
return 1
/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
return 0
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
pod_moving = 1
spawn(5)
open_animation()
sleep(OPEN_DURATION + 2)
pod_moving = 0
pod.mix_air()
if(automatic_launch_time)
var/const/wait_step = 5
var/i = 0
while(i < automatic_launch_time)
sleep(wait_step)
i += wait_step
if(pod_moving || icon_state != "open")
return
launch_pod()
// Returns a /list of directions this tube section can
// connect to.
/obj/structure/transit_tube/proc/directions()
return tube_dirs
/obj/structure/transit_tube/proc/has_entrance(from_dir)
from_dir = turn(from_dir, 180)
for(var/direction in directions())
if(direction == from_dir)
return 1
return 0
/obj/structure/transit_tube/proc/has_exit(in_dir)
for(var/direction in directions())
if(direction == in_dir)
return 1
return 0
// Searches for an exit direction within 45 degrees of the
// specified dir. Returns that direction, or 0 if none match.
/obj/structure/transit_tube/proc/get_exit(in_dir)
var/near_dir = 0
var/in_dir_cw = turn(in_dir, -45)
var/in_dir_ccw = turn(in_dir, 45)
for(var/direction in directions())
if(direction == in_dir)
return direction
else if(direction == in_dir_cw)
near_dir = direction
else if(direction == in_dir_ccw)
near_dir = direction
return near_dir
/obj/structure/transit_tube/proc/exit_delay(pod, to_dir)
return exit_delay
/obj/structure/transit_tube/proc/enter_delay(pod, to_dir)
return enter_delay
/obj/structure/transit_tube_pod/proc/follow_tube()
if(moving)
return
moving = 1
spawn()
var/obj/structure/transit_tube/current_tube = null
var/next_dir
var/next_loc
for(var/obj/structure/transit_tube/tube in loc)
if(tube.has_exit(dir))
current_tube = tube
break
while(current_tube)
next_dir = current_tube.get_exit(dir)
if(!next_dir)
break
sleep(current_tube.exit_delay(src, dir))
next_loc = get_step(loc, next_dir)
current_tube = null
for(var/obj/structure/transit_tube/tube in next_loc)
if(tube.has_entrance(next_dir))
current_tube = tube
break
if(current_tube == null)
dir = next_dir
step(src, dir)
break
sleep(current_tube.enter_delay(src, next_dir))
dir = next_dir
loc = next_loc
if(current_tube && current_tube.should_stop_pod(src, next_dir))
current_tube.pod_stopped(src, dir)
break
moving = 0
// HUGE HACK: Because the pod isn't a mecha, travelling through tubes over space
// won't protect people from space.
// This avoids editing an additional file, so that adding
// tubes to a SS13 codebase is a simple as dropping this code file and the
// required icon files somewhere where BYOND can find them.
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
if(!istype(loc, /obj/structure/transit_tube_pod))
return ..(environment)
/obj/structure/transit_tube_pod/return_air()
var/datum/gas_mixture/GM = new()
GM.oxygen = MOLES_O2STANDARD * 2
GM.nitrogen = MOLES_N2STANDARD
GM.temperature = T20C
return GM
// For now, copying what I found in an unused FEA file (and almost identical in a
// used ZAS file). Means that assume_air and remove_air don't actually alter the
// air contents.
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return 0
/obj/structure/transit_tube_pod/remove_air(amount)
var/oxygen = MOLES_O2STANDARD
var/carbon_dioxide = 0
var/nitrogen = MOLES_N2STANDARD
var/toxins = 0
var/datum/gas_mixture/GM = new()
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
if(sum>0)
GM.oxygen = (oxygen/sum)*amount
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
GM.nitrogen = (nitrogen/sum)*amount
GM.toxins = (toxins/sum)*amount
GM.temperature = T20C
GM.update_values() //Needed in ZAS to prevent suffocation. Not present in FEA. Comment/uncomment as nessecary.
return GM
// Called when a pod arrives at, and before a pod departs from a station,
// giving it a chance to mix its internal air supply with the turf it is
// currently on.
/obj/structure/transit_tube_pod/proc/mix_air()
//Needs to be implemented at some point
// When the player moves, check if the pos is currently stopped at a station.
// if it is, check the direction. If the direction matches the direction of
// the station, try to exit. If the direction matches one of the station's
// tube directions, launch the pod in that direction.
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
if(!moving && istype(mob, /mob) && mob.client)
for(var/obj/structure/transit_tube/station/station in loc)
if(!station.pod_moving && (dir in station.directions()))
if(direction == station.dir)
if(station.icon_state == "open")
mob.loc = loc
mob.client.Move(get_step(loc, direction), direction)
else
station.open_animation()
else if(direction in station.directions())
dir = direction
station.launch_pod()
/obj/structure/transit_tube/New(loc)
..(loc)
if(tube_dirs == null)
init_dirs()
// Parse the icon_state into a list of directions.
// This means that mappers can use Dream Maker's built in
// "Generate Instances from Icon-states" option to get all
// variations. Additionally, as a separate proc, sub-types
// can handle it more intelligently.
/obj/structure/transit_tube/proc/init_dirs()
tube_dirs = parse_dirs(icon_state)
if(copytext(icon_state, 1, 3) == "D-")
density = 0
// Tube station directions are simply 90 to either side of
// the exit.
/obj/structure/transit_tube/station/init_dirs()
tube_dirs = list(turn(dir, 90), turn(dir, -90))
// Uses a list() to cache return values. Since they should
// never be edited directly, all tubes with a certain
// icon_state can just reference the same list. In theory,
// reduces memory usage, and improves CPU cache usage.
// In reality, I don't know if that is quite how BYOND works,
// but it is probably safer to assume the existence of, and
// rely on, a sufficiently smart compiler/optimizer.
/obj/structure/transit_tube/proc/parse_dirs(text)
var/global/list/direction_table = list()
if(text in direction_table)
return direction_table[text]
var/list/split_text = stringsplit(text, "-")
// If the first token is D, the icon_state represents
// a purely decorative tube, and doesn't actually
// connect to anything.
if(split_text[1] == "D")
direction_table[text] = list()
return null
var/list/directions = list()
for(var/text_part in split_text)
var/direction = text2dir_extended(text_part)
if(direction > 0)
directions += direction
direction_table[text] = directions
return directions
// A copy of text2dir, extended to accept one and two letter
// directions, and to clearly return 0 otherwise.
/obj/structure/transit_tube/proc/text2dir_extended(direction)
switch(uppertext(direction))
if("NORTH", "N")
return 1
if("SOUTH", "S")
return 2
if("EAST", "E")
return 4
if("WEST", "W")
return 8
if("NORTHEAST", "NE")
return 5
if("NORTHWEST", "NW")
return 9
if("SOUTHEAST", "SE")
return 6
if("SOUTHWEST", "SW")
return 10
else
return 0
+4 -2
View File
@@ -10,7 +10,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
required_players = 2
required_players_secret = 5
required_players_secret = 10
required_enemies = 1
recommended_enemies = 4
@@ -37,7 +37,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
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/const/changeling_amount = 4
var/changeling_amount = 4
/datum/game_mode/changeling/announce()
world << "<B>The current game mode is - Changeling!</B>"
@@ -55,6 +55,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
if(player.assigned_role == job)
possible_changelings -= player
changeling_amount = 1 + round(num_players() / 10)
if(possible_changelings.len>0)
for(var/i = 0, i < changeling_amount, i++)
if(!possible_changelings.len) break
@@ -270,5 +270,12 @@
W.loc = src
src.flash1 = W
user << "\blue You insert the flash into the eye socket!"
else if(istype(W, /obj/item/weapon/stock_parts/manipulator))
user << "\blue You install some manipulators and modify the head, creating a functional spider-bot!"
new /mob/living/simple_animal/spiderbot(get_turf(loc))
user.drop_item()
del(W)
del(src)
return
return
+4 -2
View File
@@ -64,7 +64,8 @@ var/list/admin_verbs_admin = list(
/client/proc/cmd_admin_change_custom_event,
/client/proc/cmd_admin_rejuvenate,
/client/proc/toggleattacklogs,
/datum/admins/proc/show_skills
/datum/admins/proc/show_skills,
/client/proc/check_customitem_activity
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
@@ -115,7 +116,8 @@ var/list/admin_verbs_server = list(
/datum/admins/proc/adjump,
/datum/admins/proc/toggle_aliens,
/datum/admins/proc/toggle_space_ninja,
/client/proc/toggle_random_events
/client/proc/toggle_random_events,
/client/proc/check_customitem_activity
)
var/list/admin_verbs_debug = list(
/client/proc/restart_controller,
+4
View File
@@ -2418,6 +2418,10 @@
src.admincaster_signature = adminscrub(input(usr, "Provide your desired signature", "Network Identity Handler", ""))
src.access_news_network()
else if(href_list["populate_inactive_customitems"])
if(check_rights(R_ADMIN|R_SERVER))
populate_inactive_customitems_list(src.owner)
// player info stuff
if(href_list["add_player_info"])
@@ -0,0 +1,85 @@
var/checked_for_inactives = 0
var/inactive_keys = "None<br>"
/client/proc/check_customitem_activity()
set category = "Admin"
set name = "Check activity of players with custom items"
var/dat = "<b>Inactive players with custom items</b><br>"
dat += "<br>"
dat += "The list below contains players with custom items that have not logged\
in for the past two months, or have not logged in since this system was implemented.\
This system requires the feedback SQL database to be properly setup and linked.<br>"
dat += "<br>"
dat += "Populating this list is done automatically, but must be manually triggered on a per\
round basis. Populating the list may cause a lag spike, so use it sparingly.<br>"
dat += "<hr>"
if(checked_for_inactives)
dat += inactive_keys
dat += "<hr>"
dat += "This system was implemented on March 1 2013, and the database a few days before that. Root server access is required to add or disable access to specific custom items.<br>"
else
dat += "<a href='?src=\ref[src];_src_=holder;populate_inactive_customitems=1'>Populate list (requires an active database connection)</a><br>"
usr << browse(dat, "window=inactive_customitems;size=600x480")
/proc/populate_inactive_customitems_list(var/client/C)
set background = 1
if(checked_for_inactives)
return
establish_db_connection()
if(!dbcon.IsConnected())
return
//grab all ckeys associated with custom items
var/list/ckeys_with_customitems = list()
var/file = file2text("config/custom_items.txt")
var/lines = text2list(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = text2list(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
if(Entry.len < 1)
continue
var/cur_key = Entry[1]
if(!ckeys_with_customitems.Find(cur_key))
ckeys_with_customitems.Add(cur_key)
//run a query to get all ckeys inactive for over 2 months
var/list/inactive_ckeys = list()
if(ckeys_with_customitems.len)
var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey, lastseen FROM erro_player WHERE datediff(Now(),lastseen) > 2")
query_inactive.Execute()
while(query_inactive.NextRow())
var/cur_ckey = query_inactive.item[1]
//if the ckey has a custom item attached, output it
if(ckeys_with_customitems.Find(cur_ckey))
ckeys_with_customitems.Remove(cur_ckey)
inactive_ckeys[cur_ckey] = "last seen on [query_inactive.item[2]]"
//if there are ckeys left over, check whether they have a database entry at all
if(ckeys_with_customitems.len)
for(var/cur_ckey in ckeys_with_customitems)
var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey FROM erro_player WHERE ckey = '[cur_ckey]'")
query_inactive.Execute()
if(!query_inactive.RowCount())
inactive_ckeys += cur_ckey
if(inactive_ckeys.len)
inactive_keys = ""
for(var/cur_key in inactive_ckeys)
if(inactive_ckeys[cur_key])
inactive_keys += "<b>[cur_key]</b> - [inactive_ckeys[cur_key]]<br>"
else
inactive_keys += "[cur_key] - no database entry<br>"
checked_for_inactives = 1
if(C)
C.check_customitem_activity()
+1
View File
@@ -553,6 +553,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
"blue wizard",
"red wizard",
"marisa wizard",
"emergency rescue team",
)
var/dresscode = input("Select dress for [M]", "Robust quick dress shop") as null|anything in dresspacks
if (isnull(dresscode))
+3 -2
View File
@@ -124,8 +124,9 @@
icon_state = "rig-medical"
name = "medical hardsuit"
item_state = "medical_hardsuit"
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller)
slowdown = 2.0
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
//Security
/obj/item/clothing/head/helmet/space/rig/security
name = "security hardsuit helmet"
@@ -10,14 +10,13 @@
var/construction_time = 75
var/searching = 0
var/askDelay = 10 * 60 * 1
var/mob/living/carbon/brain/brainmob = null
req_access = list(access_robotics)
var/locked = 0
var/mob/living/carbon/brain/brainmob = null//The current occupant.
var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm.
attack_self(mob/user as mob)
if(!brainmob && searching == 0)
if(!brainmob.key && searching == 0)
//Start the process of searching for a new user.
user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process."
icon_state = "posibrain-searching"
@@ -37,7 +36,7 @@
spawn(0)
if(!C) return
var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round")
if(!C || brainmob) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(!C || brainmob.key) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(response == "Yes")
transfer_personality(C.mob)
else if (response == "Never for this round")
@@ -47,25 +46,10 @@
proc/transfer_personality(var/mob/candidate)
var/mob/living/carbon/brain/B = new(src)
src.searching = 0
src.brainmob = B
src.brainmob.mind = candidate.mind
src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
src.brainmob.real_name = src.brainmob.name
src.name = "positronic brain ([src.brainmob.name])"
src.brainmob.loc = src
src.brainmob.container = src
src.brainmob.robot_talk_understand = 1
src.brainmob.stat = 0
src.brainmob.silent = 0
src.brainmob.brain_op_stage = 4.0
src.brainmob.key = candidate.key
dead_mob_list -= src.brainmob
living_mob_list += src.brainmob
src.name = "positronic brain ([src.brainmob.name])"
src.brainmob << "<b>You are a positronic brain, brought into existence on [station_name()].</b>"
src.brainmob << "<b>As a synthetic intelligence, you answer to all crewmembers, as well as the AI.</b>"
@@ -101,7 +85,7 @@
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
msg += "<span class='warning'>"
if(src.brainmob)
if(src.brainmob.key)
switch(src.brainmob.stat)
if(CONSCIOUS)
if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk
@@ -124,4 +108,19 @@
brainmob.emp_damage += rand(10,20)
if(3)
brainmob.emp_damage += rand(0,10)
..()
/obj/item/device/posibrain/New()
src.brainmob = new(src)
src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
src.brainmob.real_name = src.brainmob.name
src.brainmob.loc = src
src.brainmob.container = src
src.brainmob.robot_talk_understand = 1
src.brainmob.stat = 0
src.brainmob.silent = 0
src.brainmob.brain_op_stage = 4.0
dead_mob_list -= src.brainmob
..()
+1 -1
View File
@@ -106,7 +106,7 @@
var/list/listening = hearers(1, src)
listening -= src
//listening += src
listening += src
var/list/heard = list()
for (var/mob/M in listening)
@@ -0,0 +1,325 @@
/mob/living/simple_animal/spiderbot
min_oxy = 0
max_tox = 0
max_co2 = 0
minbodytemp = 0
maxbodytemp = 500
var/obj/item/device/radio/borg/radio = null
var/mob/living/silicon/ai/connected_ai = null
var/obj/item/weapon/cell/cell = null
var/obj/machinery/camera/camera = null
var/obj/item/device/mmi/mmi = null
var/list/req_access = list(access_robotics) //Access needed to pop out the brain.
name = "Spider-bot"
desc = "A skittering robotic friend!"
icon = 'icons/mob/robots.dmi'
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
icon_dead = "spiderbot-smashed"
wander = 0
health = 10
maxHealth = 10
attacktext = "shocks"
attacktext = "shocks"
melee_damage_lower = 1
melee_damage_upper = 3
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
var/obj/item/held_item = null //Storage for single item they can hold.
var/emagged = 0 //IS WE EXPLODEN?
var/syndie = 0 //IS WE SYNDICAT? (currently unused)
speed = -1 //Spiderbots gotta go fast.
//pass_flags = PASSTABLE //Maybe griefy?
small = 1
speak_emote = list("beeps","clicks","chirps")
/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/posibrain))
var/obj/item/device/mmi/B = O
if(src.mmi) //There's already a brain in it.
user << "\red There's already a brain in [src]!"
return
if(!B.brainmob)
user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose."
return
if(!B.brainmob.key)
var/ghost_can_reenter = 0
if(B.brainmob.mind)
for(var/mob/dead/observer/G in player_list)
if(G.can_reenter_corpse && G.mind == B.brainmob.mind)
ghost_can_reenter = 1
break
if(!ghost_can_reenter)
user << "<span class='notice'>[O] is completely unresponsive; there's no point.</span>"
return
if(B.brainmob.stat == DEAD)
user << "\red [O] is dead. Sticking it into the frame would sort of defeat the purpose."
return
if(jobban_isbanned(B.brainmob, "Cyborg"))
user << "\red [O] does not seem to fit."
return
user << "\blue You install [O] in [src]!"
user.drop_item()
src.mmi = O
src.transfer_personality(O)
O.loc = src
src.update_icon()
return 1
if (istype(O, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = O
if (WT.remove_fuel(0))
if(health < maxHealth)
health += pick(1,1,1,2,2,3)
if(health > maxHealth)
health = maxHealth
add_fingerprint(user)
for(var/mob/W in viewers(user, null))
W.show_message(text("\red [user] has spot-welded some of the damage to [src]!"), 1)
else
user << "\blue [src] is undamaged!"
else
user << "Need more welding fuel!"
return
else if(istype(O, /obj/item/weapon/card/id)||istype(O, /obj/item/device/pda))
if (!mmi)
user << "\red There's no reason to swipe your ID - the spiderbot has no brain to remove."
return 0
var/obj/item/weapon/card/id/id_card
if(istype(O, /obj/item/weapon/card/id))
id_card = O
else
var/obj/item/device/pda/pda = O
id_card = pda.id
if(access_robotics in id_card.access)
user << "\blue You swipe your access card and pop the brain out of [src]."
eject_brain()
if(held_item)
held_item.loc = src.loc
held_item = null
return 1
else
user << "\red You swipe your card, with no effect."
return 0
else if (istype(O, /obj/item/weapon/card/emag))
if (emagged)
user << "\red [src] is already overloaded - better run."
return 0
else
emagged = 1
user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time."
spawn(100) src << "\red Your cell seems to be outputting a lot of power..."
spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!"
spawn(300) src.explode()
else
if(O.force)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with the [O] by [user]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with the [O]. ")
/mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj)
src.mind = M.brainmob.mind
src.mind.key = M.brainmob.key
src.name = "Spider-bot ([M.brainmob.name])"
/mob/living/simple_animal/spiderbot/proc/explode() //When emagged.
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [src] makes an odd warbling noise, fizzles, and explodes.")
explosion(get_turf(loc), -1, -1, 3, 5)
eject_brain()
Die()
/mob/living/simple_animal/spiderbot/proc/update_icon()
if(mmi)
if (istype(mmi,/obj/item/device/mmi))
icon_state = "spiderbot-chassis-mmi"
icon_living = "spiderbot-chassis-mmi"
else
icon_state = "spiderbot-chassis-posi"
icon_living = "spiderbot-chassis-posi"
else
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
/mob/living/simple_animal/spiderbot/proc/eject_brain()
if(mmi)
var/turf/T = get_turf(loc)
if(T)
mmi.loc = T
if(mind) mind.transfer_to(mmi.brainmob)
mmi = null
src.name = "Spider-bot"
update_icon()
/mob/living/simple_animal/spiderbot/Del()
eject_brain()
..()
/mob/living/simple_animal/spiderbot/New()
radio = new /obj/item/device/radio/borg(src)
camera = new /obj/machinery/camera(src)
camera.c_tag = "Spiderbot-[real_name]"
camera.network = list("SS13")
..()
/mob/living/simple_animal/spiderbot/Die()
living_mob_list -= src
dead_mob_list += src
if(camera)
camera.status = 0
robogibs(src.loc, viruses)
src.Del()
return
//copy paste from alien/larva, if that func is updated please update this one also
/mob/living/simple_animal/spiderbot/verb/ventcrawl()
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Spiderbot"
// if(!istype(V,/obj/machinery/atmoalter/siphs/fullairsiphon/air_vent))
// return
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
var/welded = 0
for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
if(!v.welded)
vent_found = v
break
else
welded = 1
if(vent_found)
if(vent_found.network&&vent_found.network.normal_members.len)
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
if(temp_vent.loc == loc)
continue
vents.Add(temp_vent)
var/list/choices = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
if(vent.loc.z != loc.z)
continue
var/atom/a = get_turf(vent)
choices.Add(a.loc)
var/turf/startloc = loc
var/obj/selection = input("Select a destination.", "Duct System") in choices
var/selection_position = choices.Find(selection)
if(loc==startloc)
var/obj/target_vent = vents[selection_position]
if(target_vent)
loc = target_vent.loc
else
src << "\blue You need to remain still while entering a vent."
else
src << "\blue This vent is not connected to anything."
else if(welded)
src << "\red That vent is welded."
else
src << "\blue You must be standing on or beside an air vent to enter it."
return
//copy paste from alien/larva, if that func is updated please update this one alsoghost
/mob/living/simple_animal/spiderbot/verb/hide()
set name = "Hide"
set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
set category = "Spiderbot"
if (layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
src << text("\blue You are now hiding.")
else
layer = MOB_LAYER
src << text("\blue You have stopped hiding.")
//Cannibalized from the parrot mob. ~Zuhayr
/mob/living/simple_animal/spiderbot/verb/drop_held_item()
set name = "Drop held item"
set category = "Spiderbot"
set desc = "Drop the item you're holding."
if(stat)
return
if(!held_item)
usr << "\red You have nothing to drop!"
return 0
if(istype(held_item, /obj/item/weapon/grenade))
visible_message("\red [src] launches the [held_item]!", "\red You launch the [held_item]!", "You hear a skittering noise and a thump!")
var/obj/item/weapon/grenade/G = held_item
G.loc = src.loc
G.prime()
held_item = null
return 1
visible_message("\blue [src] drops the [held_item]!", "\blue You drop the [held_item]!", "You hear a skittering noise and a soft thump.")
held_item.loc = src.loc
held_item = null
return 1
return
/mob/living/simple_animal/spiderbot/verb/get_item()
set name = "Pick up item"
set category = "Spiderbot"
set desc = "Allows you to take a nearby small item."
if(stat)
return -1
if(held_item)
src << "\red You are already holding the [held_item]"
return 1
var/list/items = list()
for(var/obj/item/I in view(1,src))
if(I.loc != src && I.w_class <= 2)
items.Add(I)
var/obj/selection = input("Select an item.", "Pickup") in items
if(selection)
held_item = selection
selection.loc = src
visible_message("\blue [src] scoops up the [held_item]!", "\blue You grab the [held_item]!", "You hear a skittering noise and a clink.")
return held_item
src << "\red There is nothing of interest to take."
return 0
+8
View File
@@ -127,6 +127,14 @@
/obj/item/device/camera/attack(mob/living/carbon/human/M as mob, mob/user as mob)
return
/obj/item/device/camera/attack_self(mob/user as mob)
on = !on
if(on)
src.icon_state = "camera"
else
src.icon_state = "camera_off"
user << "You switch the camera [on ? "on" : "off"]."
return
/obj/item/device/camera/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/device/camera_film))
+1 -1
View File
@@ -37,8 +37,8 @@
if(isnull(AC) || !istype(AC))
return 0
AC.loc = get_turf(src) //Eject casing onto ground.
AC.desc += " This one is spent." //descriptions are magic
if(AC.BB)
AC.desc += " This one is spent." //descriptions are magic - only when there's a projectile in the casing
in_chamber = AC.BB //Load projectile into chamber.
AC.BB.loc = src //Set projectile loc to gun.
return 1