[MIRROR] Fixes language code ignoring holder restrictions (#858)

* Fixes language code ignoring holder restrictions

* resolve .rej file.
This commit is contained in:
CitadelStationBot
2017-05-18 04:13:57 -05:00
committed by Poojawa
parent e84191b5c3
commit 8bcaa54cbe
30 changed files with 7396 additions and 7396 deletions
+42 -42
View File
@@ -1,43 +1,43 @@
#define ENGSEC (1<<0)
#define CAPTAIN (1<<0)
#define HOS (1<<1)
#define WARDEN (1<<2)
#define DETECTIVE (1<<3)
#define OFFICER (1<<4)
#define CHIEF (1<<5)
#define ENGINEER (1<<6)
#define ATMOSTECH (1<<7)
#define ROBOTICIST (1<<8)
#define AI_JF (1<<9)
#define CYBORG (1<<10)
#define MEDSCI (1<<1)
#define RD_JF (1<<0)
#define SCIENTIST (1<<1)
#define CHEMIST (1<<2)
#define CMO_JF (1<<3)
#define DOCTOR (1<<4)
#define GENETICIST (1<<5)
#define VIROLOGIST (1<<6)
#define CIVILIAN (1<<2)
#define HOP (1<<0)
#define BARTENDER (1<<1)
#define BOTANIST (1<<2)
#define COOK (1<<3)
#define JANITOR (1<<4)
#define CURATOR (1<<5)
#define QUARTERMASTER (1<<6)
#define CARGOTECH (1<<7)
#define MINER (1<<8)
#define LAWYER (1<<9)
#define CHAPLAIN (1<<10)
#define CLOWN (1<<11)
#define MIME (1<<12)
#define ENGSEC (1<<0)
#define CAPTAIN (1<<0)
#define HOS (1<<1)
#define WARDEN (1<<2)
#define DETECTIVE (1<<3)
#define OFFICER (1<<4)
#define CHIEF (1<<5)
#define ENGINEER (1<<6)
#define ATMOSTECH (1<<7)
#define ROBOTICIST (1<<8)
#define AI_JF (1<<9)
#define CYBORG (1<<10)
#define MEDSCI (1<<1)
#define RD_JF (1<<0)
#define SCIENTIST (1<<1)
#define CHEMIST (1<<2)
#define CMO_JF (1<<3)
#define DOCTOR (1<<4)
#define GENETICIST (1<<5)
#define VIROLOGIST (1<<6)
#define CIVILIAN (1<<2)
#define HOP (1<<0)
#define BARTENDER (1<<1)
#define BOTANIST (1<<2)
#define COOK (1<<3)
#define JANITOR (1<<4)
#define CURATOR (1<<5)
#define QUARTERMASTER (1<<6)
#define CARGOTECH (1<<7)
#define MINER (1<<8)
#define LAWYER (1<<9)
#define CHAPLAIN (1<<10)
#define CLOWN (1<<11)
#define MIME (1<<12)
#define ASSISTANT (1<<13)
+162 -162
View File
@@ -1,162 +1,162 @@
/*
These defines specificy screen locations. For more information, see the byond documentation on the screen_loc var.
The short version:
Everything is encoded as strings because apparently that's how Byond rolls.
"1,1" is the bottom left square of the user's screen. This aligns perfectly with the turf grid.
"1:2,3:4" is the square (1,3) with pixel offsets (+2, +4); slightly right and slightly above the turf grid.
Pixel offsets are used so you don't perfectly hide the turf under them, that would be crappy.
In addition, the keywords NORTH, SOUTH, EAST, WEST and CENTER can be used to represent their respective
screen borders. NORTH-1, for example, is the row just below the upper edge. Useful if you want your
UI to scale with screen size.
The size of the user's screen is defined by client.view (indirectly by world.view), in our case "15x15".
Therefore, the top right corner (except during admin shenanigans) is at "15,15"
*/
//Lower left, persistent menu
#define ui_inventory "WEST:6,SOUTH:5"
//Middle left indicators
#define ui_lingchemdisplay "WEST,CENTER-1:15"
#define ui_lingstingdisplay "WEST:6,CENTER-3:11"
#define ui_crafting "12:-10,1:5"
#define ui_building "12:-10,1:21"
#define ui_language_menu "11:6,2:-11"
#define ui_devilsouldisplay "WEST:6,CENTER-1:15"
//Lower center, persistent menu
#define ui_sstore1 "CENTER-5:10,SOUTH:5"
#define ui_id "CENTER-4:12,SOUTH:5"
#define ui_belt "CENTER-3:14,SOUTH:5"
#define ui_back "CENTER-2:14,SOUTH:5"
/proc/ui_hand_position(i) //values based on old hand ui positions (CENTER:-/+16,SOUTH:5)
var/x_off = -(!(i % 2))
var/y_off = round((i-1) / 2)
return"CENTER+[x_off]:16,SOUTH+[y_off]:5"
/proc/ui_equip_position(mob/M)
var/y_off = round((M.held_items.len-1) / 2) //values based on old equip ui position (CENTER: +/-16,SOUTH+1:5)
return "CENTER:-16,SOUTH+[y_off+1]:5"
/proc/ui_swaphand_position(mob/M, which = 1) //values based on old swaphand ui positions (CENTER: +/-16,SOUTH+1:5)
var/x_off = which == 1 ? -1 : 0
var/y_off = round((M.held_items.len-1) / 2)
return "CENTER+[x_off]:16,SOUTH+[y_off+1]:5"
#define ui_storage1 "CENTER+1:18,SOUTH:5"
#define ui_storage2 "CENTER+2:20,SOUTH:5"
#define ui_borg_sensor "CENTER-3:16, SOUTH:5" //borgs
#define ui_borg_lamp "CENTER-4:16, SOUTH:5" //borgs
#define ui_borg_thrusters "CENTER-5:16, SOUTH:5" //borgs
#define ui_inv1 "CENTER-2:16,SOUTH:5" //borgs
#define ui_inv2 "CENTER-1 :16,SOUTH:5" //borgs
#define ui_inv3 "CENTER :16,SOUTH:5" //borgs
#define ui_borg_module "CENTER+1:16,SOUTH:5" //borgs
#define ui_borg_store "CENTER+2:16,SOUTH:5" //borgs
#define ui_borg_camera "CENTER+3:21,SOUTH:5" //borgs
#define ui_borg_album "CENTER+4:21,SOUTH:5" //borgs
#define ui_borg_language_menu "CENTER+4:21,SOUTH+1:5" //borgs
#define ui_monkey_head "CENTER-5:13,SOUTH:5" //monkey
#define ui_monkey_mask "CENTER-4:14,SOUTH:5" //monkey
#define ui_monkey_neck "CENTER-3:15,SOUTH:5" //monkey
#define ui_monkey_back "CENTER-2:16,SOUTH:5" //monkey
#define ui_alien_storage_l "CENTER-2:14,SOUTH:5"//alien
#define ui_alien_storage_r "CENTER+1:18,SOUTH:5"//alien
#define ui_alien_language_menu "EAST-3:26,SOUTH:5" //alien
#define ui_drone_drop "CENTER+1:18,SOUTH:5" //maintenance drones
#define ui_drone_pull "CENTER+2:2,SOUTH:5" //maintenance drones
#define ui_drone_storage "CENTER-2:14,SOUTH:5" //maintenance drones
#define ui_drone_head "CENTER-3:14,SOUTH:5" //maintenance drones
//Lower right, persistent menu
#define ui_drop_throw "EAST-1:28,SOUTH+1:7"
#define ui_pull_resist "EAST-2:26,SOUTH+1:7"
#define ui_movi "EAST-2:26,SOUTH:5"
#define ui_acti "EAST-3:24,SOUTH:5"
#define ui_zonesel "EAST-1:28,SOUTH:5"
#define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12)
#define ui_borg_pull "EAST-2:26,SOUTH+1:7"
#define ui_borg_radio "EAST-1:28,SOUTH+1:7"
#define ui_borg_intents "EAST-2:26,SOUTH:5"
//Upper-middle right (alerts)
#define ui_alert1 "EAST-1:28,CENTER+5:27"
#define ui_alert2 "EAST-1:28,CENTER+4:25"
#define ui_alert3 "EAST-1:28,CENTER+3:23"
#define ui_alert4 "EAST-1:28,CENTER+2:21"
#define ui_alert5 "EAST-1:28,CENTER+1:19"
//Middle right (status indicators)
#define ui_healthdoll "EAST-1:28,CENTER-2:13"
#define ui_health "EAST-1:28,CENTER-1:15"
#define ui_internal "EAST-1:28,CENTER:17"
//borgs
#define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator.
//aliens
#define ui_alien_health "EAST,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator.
#define ui_alienplasmadisplay "EAST,CENTER-2:15"
#define ui_alien_queen_finder "EAST,CENTER-3:15"
//constructs
#define ui_construct_pull "EAST,CENTER-2:15"
#define ui_construct_health "EAST,CENTER:15" //same as borgs and humans
// AI
#define ui_ai_core "SOUTH:6,WEST"
#define ui_ai_camera_list "SOUTH:6,WEST+1"
#define ui_ai_track_with_camera "SOUTH:6,WEST+2"
#define ui_ai_camera_light "SOUTH:6,WEST+3"
#define ui_ai_crew_monitor "SOUTH:6,WEST+4"
#define ui_ai_crew_manifest "SOUTH:6,WEST+5"
#define ui_ai_alerts "SOUTH:6,WEST+6"
#define ui_ai_announcement "SOUTH:6,WEST+7"
#define ui_ai_shuttle "SOUTH:6,WEST+8"
#define ui_ai_state_laws "SOUTH:6,WEST+9"
#define ui_ai_pda_send "SOUTH:6,WEST+10"
#define ui_ai_pda_log "SOUTH:6,WEST+11"
#define ui_ai_take_picture "SOUTH:6,WEST+12"
#define ui_ai_view_images "SOUTH:6,WEST+13"
#define ui_ai_sensor "SOUTH:6,WEST+14"
//Pop-up inventory
#define ui_shoes "WEST+1:8,SOUTH:5"
#define ui_iclothing "WEST:6,SOUTH+1:7"
#define ui_oclothing "WEST+1:8,SOUTH+1:7"
#define ui_gloves "WEST+2:10,SOUTH+1:7"
#define ui_glasses "WEST:6,SOUTH+3:11"
#define ui_mask "WEST+1:8,SOUTH+2:9"
#define ui_ears "WEST+2:10,SOUTH+2:9"
#define ui_neck "WEST:6,SOUTH+2:9"
#define ui_head "WEST+1:8,SOUTH+3:11"
//Ghosts
#define ui_ghost_jumptomob "SOUTH:6,CENTER-2:24"
#define ui_ghost_orbit "SOUTH:6,CENTER-1:24"
#define ui_ghost_reenter_corpse "SOUTH:6,CENTER:24"
#define ui_ghost_teleport "SOUTH:6,CENTER+1:24"
#define ui_ghost_pai "SOUTH: 6, CENTER+2:24"
//Hand of God, god
#define ui_deityhealth "EAST-1:28,CENTER-2:13"
#define ui_deitypower "EAST-1:28,CENTER-1:15"
#define ui_deityfollowers "EAST-1:28,CENTER:17"
/*
These defines specificy screen locations. For more information, see the byond documentation on the screen_loc var.
The short version:
Everything is encoded as strings because apparently that's how Byond rolls.
"1,1" is the bottom left square of the user's screen. This aligns perfectly with the turf grid.
"1:2,3:4" is the square (1,3) with pixel offsets (+2, +4); slightly right and slightly above the turf grid.
Pixel offsets are used so you don't perfectly hide the turf under them, that would be crappy.
In addition, the keywords NORTH, SOUTH, EAST, WEST and CENTER can be used to represent their respective
screen borders. NORTH-1, for example, is the row just below the upper edge. Useful if you want your
UI to scale with screen size.
The size of the user's screen is defined by client.view (indirectly by world.view), in our case "15x15".
Therefore, the top right corner (except during admin shenanigans) is at "15,15"
*/
//Lower left, persistent menu
#define ui_inventory "WEST:6,SOUTH:5"
//Middle left indicators
#define ui_lingchemdisplay "WEST,CENTER-1:15"
#define ui_lingstingdisplay "WEST:6,CENTER-3:11"
#define ui_crafting "12:-10,1:5"
#define ui_building "12:-10,1:21"
#define ui_language_menu "11:6,2:-11"
#define ui_devilsouldisplay "WEST:6,CENTER-1:15"
//Lower center, persistent menu
#define ui_sstore1 "CENTER-5:10,SOUTH:5"
#define ui_id "CENTER-4:12,SOUTH:5"
#define ui_belt "CENTER-3:14,SOUTH:5"
#define ui_back "CENTER-2:14,SOUTH:5"
/proc/ui_hand_position(i) //values based on old hand ui positions (CENTER:-/+16,SOUTH:5)
var/x_off = -(!(i % 2))
var/y_off = round((i-1) / 2)
return"CENTER+[x_off]:16,SOUTH+[y_off]:5"
/proc/ui_equip_position(mob/M)
var/y_off = round((M.held_items.len-1) / 2) //values based on old equip ui position (CENTER: +/-16,SOUTH+1:5)
return "CENTER:-16,SOUTH+[y_off+1]:5"
/proc/ui_swaphand_position(mob/M, which = 1) //values based on old swaphand ui positions (CENTER: +/-16,SOUTH+1:5)
var/x_off = which == 1 ? -1 : 0
var/y_off = round((M.held_items.len-1) / 2)
return "CENTER+[x_off]:16,SOUTH+[y_off+1]:5"
#define ui_storage1 "CENTER+1:18,SOUTH:5"
#define ui_storage2 "CENTER+2:20,SOUTH:5"
#define ui_borg_sensor "CENTER-3:16, SOUTH:5" //borgs
#define ui_borg_lamp "CENTER-4:16, SOUTH:5" //borgs
#define ui_borg_thrusters "CENTER-5:16, SOUTH:5" //borgs
#define ui_inv1 "CENTER-2:16,SOUTH:5" //borgs
#define ui_inv2 "CENTER-1 :16,SOUTH:5" //borgs
#define ui_inv3 "CENTER :16,SOUTH:5" //borgs
#define ui_borg_module "CENTER+1:16,SOUTH:5" //borgs
#define ui_borg_store "CENTER+2:16,SOUTH:5" //borgs
#define ui_borg_camera "CENTER+3:21,SOUTH:5" //borgs
#define ui_borg_album "CENTER+4:21,SOUTH:5" //borgs
#define ui_borg_language_menu "CENTER+4:21,SOUTH+1:5" //borgs
#define ui_monkey_head "CENTER-5:13,SOUTH:5" //monkey
#define ui_monkey_mask "CENTER-4:14,SOUTH:5" //monkey
#define ui_monkey_neck "CENTER-3:15,SOUTH:5" //monkey
#define ui_monkey_back "CENTER-2:16,SOUTH:5" //monkey
#define ui_alien_storage_l "CENTER-2:14,SOUTH:5"//alien
#define ui_alien_storage_r "CENTER+1:18,SOUTH:5"//alien
#define ui_alien_language_menu "EAST-3:26,SOUTH:5" //alien
#define ui_drone_drop "CENTER+1:18,SOUTH:5" //maintenance drones
#define ui_drone_pull "CENTER+2:2,SOUTH:5" //maintenance drones
#define ui_drone_storage "CENTER-2:14,SOUTH:5" //maintenance drones
#define ui_drone_head "CENTER-3:14,SOUTH:5" //maintenance drones
//Lower right, persistent menu
#define ui_drop_throw "EAST-1:28,SOUTH+1:7"
#define ui_pull_resist "EAST-2:26,SOUTH+1:7"
#define ui_movi "EAST-2:26,SOUTH:5"
#define ui_acti "EAST-3:24,SOUTH:5"
#define ui_zonesel "EAST-1:28,SOUTH:5"
#define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12)
#define ui_borg_pull "EAST-2:26,SOUTH+1:7"
#define ui_borg_radio "EAST-1:28,SOUTH+1:7"
#define ui_borg_intents "EAST-2:26,SOUTH:5"
//Upper-middle right (alerts)
#define ui_alert1 "EAST-1:28,CENTER+5:27"
#define ui_alert2 "EAST-1:28,CENTER+4:25"
#define ui_alert3 "EAST-1:28,CENTER+3:23"
#define ui_alert4 "EAST-1:28,CENTER+2:21"
#define ui_alert5 "EAST-1:28,CENTER+1:19"
//Middle right (status indicators)
#define ui_healthdoll "EAST-1:28,CENTER-2:13"
#define ui_health "EAST-1:28,CENTER-1:15"
#define ui_internal "EAST-1:28,CENTER:17"
//borgs
#define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator.
//aliens
#define ui_alien_health "EAST,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator.
#define ui_alienplasmadisplay "EAST,CENTER-2:15"
#define ui_alien_queen_finder "EAST,CENTER-3:15"
//constructs
#define ui_construct_pull "EAST,CENTER-2:15"
#define ui_construct_health "EAST,CENTER:15" //same as borgs and humans
// AI
#define ui_ai_core "SOUTH:6,WEST"
#define ui_ai_camera_list "SOUTH:6,WEST+1"
#define ui_ai_track_with_camera "SOUTH:6,WEST+2"
#define ui_ai_camera_light "SOUTH:6,WEST+3"
#define ui_ai_crew_monitor "SOUTH:6,WEST+4"
#define ui_ai_crew_manifest "SOUTH:6,WEST+5"
#define ui_ai_alerts "SOUTH:6,WEST+6"
#define ui_ai_announcement "SOUTH:6,WEST+7"
#define ui_ai_shuttle "SOUTH:6,WEST+8"
#define ui_ai_state_laws "SOUTH:6,WEST+9"
#define ui_ai_pda_send "SOUTH:6,WEST+10"
#define ui_ai_pda_log "SOUTH:6,WEST+11"
#define ui_ai_take_picture "SOUTH:6,WEST+12"
#define ui_ai_view_images "SOUTH:6,WEST+13"
#define ui_ai_sensor "SOUTH:6,WEST+14"
//Pop-up inventory
#define ui_shoes "WEST+1:8,SOUTH:5"
#define ui_iclothing "WEST:6,SOUTH+1:7"
#define ui_oclothing "WEST+1:8,SOUTH+1:7"
#define ui_gloves "WEST+2:10,SOUTH+1:7"
#define ui_glasses "WEST:6,SOUTH+3:11"
#define ui_mask "WEST+1:8,SOUTH+2:9"
#define ui_ears "WEST+2:10,SOUTH+2:9"
#define ui_neck "WEST:6,SOUTH+2:9"
#define ui_head "WEST+1:8,SOUTH+3:11"
//Ghosts
#define ui_ghost_jumptomob "SOUTH:6,CENTER-2:24"
#define ui_ghost_orbit "SOUTH:6,CENTER-1:24"
#define ui_ghost_reenter_corpse "SOUTH:6,CENTER:24"
#define ui_ghost_teleport "SOUTH:6,CENTER+1:24"
#define ui_ghost_pai "SOUTH: 6, CENTER+2:24"
//Hand of God, god
#define ui_deityhealth "EAST-1:28,CENTER-2:13"
#define ui_deitypower "EAST-1:28,CENTER-1:15"
#define ui_deityfollowers "EAST-1:28,CENTER:17"
+269 -269
View File
@@ -1,270 +1,270 @@
/*
The hud datum
Used to show and hide huds for all the different mob types,
including inventories and item quick actions.
*/
/datum/hud
var/mob/mymob
var/hud_shown = 1 //Used for the HUD toggle (F12)
var/hud_version = 1 //Current displayed version of the HUD
var/inventory_shown = 0 //Equipped item inventory
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/ling/chems/lingchemdisplay
var/obj/screen/ling/sting/lingstingdisplay
var/obj/screen/blobpwrdisplay
var/obj/screen/alien_plasma_display
var/obj/screen/alien_queen_finder
var/obj/screen/devil/soul_counter/devilsouldisplay
var/obj/screen/deity_power_display
var/obj/screen/deity_follower_display
var/obj/screen/nightvisionicon
var/obj/screen/action_intent
var/obj/screen/zone_select
var/obj/screen/pull_icon
var/obj/screen/throw_icon
var/obj/screen/module_store_icon
var/list/static_inventory = list() //the screen objects which are static
var/list/toggleable_inventory = list() //the screen objects which can be hidden
var/list/obj/screen/hotkeybuttons = list() //the buttons that can be used via hotkeys
var/list/infodisplay = list() //the screen objects that display mob info (health, alien plasma, etc...)
var/list/screenoverlays = list() //the screen objects used as whole screen overlays (flash, damageoverlay, etc...)
var/list/inv_slots[slots_amt] // /obj/screen/inventory objects, ordered by their slot ID.
var/list/hand_slots // /obj/screen/inventory/hand objects, assoc list of "[held_index]" = object
var/list/obj/screen/plane_master/plane_masters = list() // see "appearance_flags" in the ref, assoc list of "[plane]" = object
var/obj/screen/movable/action_button/hide_toggle/hide_actions_toggle
var/action_buttons_hidden = 0
var/obj/screen/healths
var/obj/screen/healthdoll
var/obj/screen/internals
var/ui_style_icon = 'icons/mob/screen_midnight.dmi'
/datum/hud/New(mob/owner , ui_style = 'icons/mob/screen_midnight.dmi')
mymob = owner
ui_style_icon = ui_style
hide_actions_toggle = new
hide_actions_toggle.InitialiseIcon(src)
hand_slots = list()
for(var/mytype in subtypesof(/obj/screen/plane_master))
var/obj/screen/plane_master/instance = new mytype()
plane_masters["[instance.plane]"] = instance
instance.backdrop(mymob)
/datum/hud/Destroy()
if(mymob.hud_used == src)
mymob.hud_used = null
qdel(hide_actions_toggle)
hide_actions_toggle = null
qdel(module_store_icon)
module_store_icon = null
if(static_inventory.len)
for(var/thing in static_inventory)
qdel(thing)
static_inventory.Cut()
inv_slots.Cut()
action_intent = null
zone_select = null
pull_icon = null
if(toggleable_inventory.len)
for(var/thing in toggleable_inventory)
qdel(thing)
toggleable_inventory.Cut()
if(hotkeybuttons.len)
for(var/thing in hotkeybuttons)
qdel(thing)
hotkeybuttons.Cut()
throw_icon = null
if(infodisplay.len)
for(var/thing in infodisplay)
qdel(thing)
infodisplay.Cut()
healths = null
healthdoll = null
internals = null
lingchemdisplay = null
devilsouldisplay = null
lingstingdisplay = null
blobpwrdisplay = null
alien_plasma_display = null
alien_queen_finder = null
deity_power_display = null
deity_follower_display = null
nightvisionicon = null
if(plane_masters.len)
for(var/thing in plane_masters)
qdel(plane_masters[thing])
plane_masters.Cut()
if(screenoverlays.len)
for(var/thing in screenoverlays)
qdel(thing)
screenoverlays.Cut()
mymob = null
return ..()
/mob/proc/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud(src)
update_sight()
//Version denotes which style should be displayed. blank or 0 means "next version"
/datum/hud/proc/show_hud(version = 0,mob/viewmob)
if(!ismob(mymob))
return 0
var/mob/screenmob = viewmob || mymob
if(!screenmob.client)
return 0
screenmob.client.screen = list()
var/display_hud_version = version
if(!display_hud_version) //If 0 or blank, display the next hud version
display_hud_version = hud_version + 1
if(display_hud_version > HUD_VERSIONS) //If the requested version number is greater than the available versions, reset back to the first version
display_hud_version = 1
switch(display_hud_version)
if(HUD_STYLE_STANDARD) //Default HUD
hud_shown = 1 //Governs behavior of other procs
if(static_inventory.len)
screenmob.client.screen += static_inventory
if(toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.inventory_shown)
screenmob.client.screen += toggleable_inventory
if(hotkeybuttons.len && !hotkey_ui_hidden)
screenmob.client.screen += hotkeybuttons
if(infodisplay.len)
screenmob.client.screen += infodisplay
screenmob.client.screen += hide_actions_toggle
if(action_intent)
action_intent.screen_loc = initial(action_intent.screen_loc) //Restore intent selection to the original position
if(HUD_STYLE_REDUCED) //Reduced HUD
hud_shown = 0 //Governs behavior of other procs
if(static_inventory.len)
screenmob.client.screen -= static_inventory
if(toggleable_inventory.len)
screenmob.client.screen -= toggleable_inventory
if(hotkeybuttons.len)
screenmob.client.screen -= hotkeybuttons
if(infodisplay.len)
screenmob.client.screen += infodisplay
//These ones are a part of 'static_inventory', 'toggleable_inventory' or 'hotkeybuttons' but we want them to stay
for(var/h in hand_slots)
var/obj/screen/hand = hand_slots[h]
if(hand)
screenmob.client.screen += hand
if(action_intent)
screenmob.client.screen += action_intent //we want the intent switcher visible
action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is.
if(HUD_STYLE_NOHUD) //No HUD
hud_shown = 0 //Governs behavior of other procs
if(static_inventory.len)
screenmob.client.screen -= static_inventory
if(toggleable_inventory.len)
screenmob.client.screen -= toggleable_inventory
if(hotkeybuttons.len)
screenmob.client.screen -= hotkeybuttons
if(infodisplay.len)
screenmob.client.screen -= infodisplay
for(var/thing in plane_masters)
screenmob.client.screen += plane_masters[thing]
hud_version = display_hud_version
persistent_inventory_update(screenmob)
mymob.update_action_buttons(1)
reorganize_alerts()
mymob.reload_fullscreen()
update_parallax_pref(screenmob)
/datum/hud/human/show_hud(version = 0,mob/viewmob)
..()
hidden_inventory_update(viewmob)
/datum/hud/robot/show_hud(version = 0, mob/viewmob)
..()
update_robot_modules_display()
/datum/hud/proc/hidden_inventory_update()
return
/datum/hud/proc/persistent_inventory_update(mob/viewer)
if(!mymob)
return
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
/mob/verb/button_pressed_F12()
set name = "F12"
set hidden = 1
if(hud_used && client)
hud_used.show_hud() //Shows the next hud preset
to_chat(usr, "<span class ='info'>Switched HUD mode. Press F12 to toggle.</span>")
else
to_chat(usr, "<span class ='warning'>This mob type does not use a HUD.</span>")
//(re)builds the hand ui slots, throwing away old ones
//not really worth jugglying existing ones so we just scrap+rebuild
//9/10 this is only called once per mob and only for 2 hands
/datum/hud/proc/build_hand_slots(ui_style = 'icons/mob/screen_midnight.dmi')
for(var/h in hand_slots)
var/obj/screen/inventory/hand/H = hand_slots[h]
if(H)
static_inventory -= H
hand_slots = list()
var/obj/screen/inventory/hand/hand_box
for(var/i in 1 to mymob.held_items.len)
hand_box = new /obj/screen/inventory/hand()
hand_box.name = mymob.get_held_index_name(i)
hand_box.icon = ui_style
hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]"
hand_box.screen_loc = ui_hand_position(i)
hand_box.held_index = i
hand_slots["[i]"] = hand_box
hand_box.hud = src
static_inventory += hand_box
hand_box.update_icon()
var/i = 1
for(var/obj/screen/swap_hand/SH in static_inventory)
SH.screen_loc = ui_swaphand_position(mymob,!(i % 2) ? 2: 1)
i++
for(var/obj/screen/human/equip/E in static_inventory)
E.screen_loc = ui_equip_position(mymob)
if(mymob.hud_used)
show_hud(HUD_STYLE_STANDARD,mymob)
/datum/hud/proc/update_locked_slots()
/*
The hud datum
Used to show and hide huds for all the different mob types,
including inventories and item quick actions.
*/
/datum/hud
var/mob/mymob
var/hud_shown = 1 //Used for the HUD toggle (F12)
var/hud_version = 1 //Current displayed version of the HUD
var/inventory_shown = 0 //Equipped item inventory
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/ling/chems/lingchemdisplay
var/obj/screen/ling/sting/lingstingdisplay
var/obj/screen/blobpwrdisplay
var/obj/screen/alien_plasma_display
var/obj/screen/alien_queen_finder
var/obj/screen/devil/soul_counter/devilsouldisplay
var/obj/screen/deity_power_display
var/obj/screen/deity_follower_display
var/obj/screen/nightvisionicon
var/obj/screen/action_intent
var/obj/screen/zone_select
var/obj/screen/pull_icon
var/obj/screen/throw_icon
var/obj/screen/module_store_icon
var/list/static_inventory = list() //the screen objects which are static
var/list/toggleable_inventory = list() //the screen objects which can be hidden
var/list/obj/screen/hotkeybuttons = list() //the buttons that can be used via hotkeys
var/list/infodisplay = list() //the screen objects that display mob info (health, alien plasma, etc...)
var/list/screenoverlays = list() //the screen objects used as whole screen overlays (flash, damageoverlay, etc...)
var/list/inv_slots[slots_amt] // /obj/screen/inventory objects, ordered by their slot ID.
var/list/hand_slots // /obj/screen/inventory/hand objects, assoc list of "[held_index]" = object
var/list/obj/screen/plane_master/plane_masters = list() // see "appearance_flags" in the ref, assoc list of "[plane]" = object
var/obj/screen/movable/action_button/hide_toggle/hide_actions_toggle
var/action_buttons_hidden = 0
var/obj/screen/healths
var/obj/screen/healthdoll
var/obj/screen/internals
var/ui_style_icon = 'icons/mob/screen_midnight.dmi'
/datum/hud/New(mob/owner , ui_style = 'icons/mob/screen_midnight.dmi')
mymob = owner
ui_style_icon = ui_style
hide_actions_toggle = new
hide_actions_toggle.InitialiseIcon(src)
hand_slots = list()
for(var/mytype in subtypesof(/obj/screen/plane_master))
var/obj/screen/plane_master/instance = new mytype()
plane_masters["[instance.plane]"] = instance
instance.backdrop(mymob)
/datum/hud/Destroy()
if(mymob.hud_used == src)
mymob.hud_used = null
qdel(hide_actions_toggle)
hide_actions_toggle = null
qdel(module_store_icon)
module_store_icon = null
if(static_inventory.len)
for(var/thing in static_inventory)
qdel(thing)
static_inventory.Cut()
inv_slots.Cut()
action_intent = null
zone_select = null
pull_icon = null
if(toggleable_inventory.len)
for(var/thing in toggleable_inventory)
qdel(thing)
toggleable_inventory.Cut()
if(hotkeybuttons.len)
for(var/thing in hotkeybuttons)
qdel(thing)
hotkeybuttons.Cut()
throw_icon = null
if(infodisplay.len)
for(var/thing in infodisplay)
qdel(thing)
infodisplay.Cut()
healths = null
healthdoll = null
internals = null
lingchemdisplay = null
devilsouldisplay = null
lingstingdisplay = null
blobpwrdisplay = null
alien_plasma_display = null
alien_queen_finder = null
deity_power_display = null
deity_follower_display = null
nightvisionicon = null
if(plane_masters.len)
for(var/thing in plane_masters)
qdel(plane_masters[thing])
plane_masters.Cut()
if(screenoverlays.len)
for(var/thing in screenoverlays)
qdel(thing)
screenoverlays.Cut()
mymob = null
return ..()
/mob/proc/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud(src)
update_sight()
//Version denotes which style should be displayed. blank or 0 means "next version"
/datum/hud/proc/show_hud(version = 0,mob/viewmob)
if(!ismob(mymob))
return 0
var/mob/screenmob = viewmob || mymob
if(!screenmob.client)
return 0
screenmob.client.screen = list()
var/display_hud_version = version
if(!display_hud_version) //If 0 or blank, display the next hud version
display_hud_version = hud_version + 1
if(display_hud_version > HUD_VERSIONS) //If the requested version number is greater than the available versions, reset back to the first version
display_hud_version = 1
switch(display_hud_version)
if(HUD_STYLE_STANDARD) //Default HUD
hud_shown = 1 //Governs behavior of other procs
if(static_inventory.len)
screenmob.client.screen += static_inventory
if(toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.inventory_shown)
screenmob.client.screen += toggleable_inventory
if(hotkeybuttons.len && !hotkey_ui_hidden)
screenmob.client.screen += hotkeybuttons
if(infodisplay.len)
screenmob.client.screen += infodisplay
screenmob.client.screen += hide_actions_toggle
if(action_intent)
action_intent.screen_loc = initial(action_intent.screen_loc) //Restore intent selection to the original position
if(HUD_STYLE_REDUCED) //Reduced HUD
hud_shown = 0 //Governs behavior of other procs
if(static_inventory.len)
screenmob.client.screen -= static_inventory
if(toggleable_inventory.len)
screenmob.client.screen -= toggleable_inventory
if(hotkeybuttons.len)
screenmob.client.screen -= hotkeybuttons
if(infodisplay.len)
screenmob.client.screen += infodisplay
//These ones are a part of 'static_inventory', 'toggleable_inventory' or 'hotkeybuttons' but we want them to stay
for(var/h in hand_slots)
var/obj/screen/hand = hand_slots[h]
if(hand)
screenmob.client.screen += hand
if(action_intent)
screenmob.client.screen += action_intent //we want the intent switcher visible
action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is.
if(HUD_STYLE_NOHUD) //No HUD
hud_shown = 0 //Governs behavior of other procs
if(static_inventory.len)
screenmob.client.screen -= static_inventory
if(toggleable_inventory.len)
screenmob.client.screen -= toggleable_inventory
if(hotkeybuttons.len)
screenmob.client.screen -= hotkeybuttons
if(infodisplay.len)
screenmob.client.screen -= infodisplay
for(var/thing in plane_masters)
screenmob.client.screen += plane_masters[thing]
hud_version = display_hud_version
persistent_inventory_update(screenmob)
mymob.update_action_buttons(1)
reorganize_alerts()
mymob.reload_fullscreen()
update_parallax_pref(screenmob)
/datum/hud/human/show_hud(version = 0,mob/viewmob)
..()
hidden_inventory_update(viewmob)
/datum/hud/robot/show_hud(version = 0, mob/viewmob)
..()
update_robot_modules_display()
/datum/hud/proc/hidden_inventory_update()
return
/datum/hud/proc/persistent_inventory_update(mob/viewer)
if(!mymob)
return
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
/mob/verb/button_pressed_F12()
set name = "F12"
set hidden = 1
if(hud_used && client)
hud_used.show_hud() //Shows the next hud preset
to_chat(usr, "<span class ='info'>Switched HUD mode. Press F12 to toggle.</span>")
else
to_chat(usr, "<span class ='warning'>This mob type does not use a HUD.</span>")
//(re)builds the hand ui slots, throwing away old ones
//not really worth jugglying existing ones so we just scrap+rebuild
//9/10 this is only called once per mob and only for 2 hands
/datum/hud/proc/build_hand_slots(ui_style = 'icons/mob/screen_midnight.dmi')
for(var/h in hand_slots)
var/obj/screen/inventory/hand/H = hand_slots[h]
if(H)
static_inventory -= H
hand_slots = list()
var/obj/screen/inventory/hand/hand_box
for(var/i in 1 to mymob.held_items.len)
hand_box = new /obj/screen/inventory/hand()
hand_box.name = mymob.get_held_index_name(i)
hand_box.icon = ui_style
hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]"
hand_box.screen_loc = ui_hand_position(i)
hand_box.held_index = i
hand_slots["[i]"] = hand_box
hand_box.hud = src
static_inventory += hand_box
hand_box.update_icon()
var/i = 1
for(var/obj/screen/swap_hand/SH in static_inventory)
SH.screen_loc = ui_swaphand_position(mymob,!(i % 2) ? 2: 1)
i++
for(var/obj/screen/human/equip/E in static_inventory)
E.screen_loc = ui_equip_position(mymob)
if(mymob.hud_used)
show_hud(HUD_STYLE_STANDARD,mymob)
/datum/hud/proc/update_locked_slots()
return
+438 -438
View File
@@ -1,438 +1,438 @@
/obj/screen/human
icon = 'icons/mob/screen_midnight.dmi'
/obj/screen/human/toggle
name = "toggle"
icon_state = "toggle"
/obj/screen/human/toggle/Click()
var/mob/targetmob = usr
if(isobserver(usr))
if(ishuman(usr.client.eye) && (usr.client.eye != usr))
var/mob/M = usr.client.eye
targetmob = M
if(usr.hud_used.inventory_shown && targetmob.hud_used)
usr.hud_used.inventory_shown = 0
usr.client.screen -= targetmob.hud_used.toggleable_inventory
else
usr.hud_used.inventory_shown = 1
usr.client.screen += targetmob.hud_used.toggleable_inventory
targetmob.hud_used.hidden_inventory_update(usr)
/obj/screen/human/equip
name = "equip"
icon_state = "act_equip"
/obj/screen/human/equip/Click()
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
return 1
var/mob/living/carbon/human/H = usr
H.quick_equip()
/obj/screen/devil
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/devil/soul_counter
icon = 'icons/mob/screen_gen.dmi'
name = "souls owned"
icon_state = "Devil-6"
screen_loc = ui_devilsouldisplay
/obj/screen/devil/soul_counter/proc/update_counter(souls = 0)
invisibility = 0
maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#FF0000'>[souls]</font></div>"
switch(souls)
if(0,null)
icon_state = "Devil-1"
if(1,2)
icon_state = "Devil-2"
if(3 to 5)
icon_state = "Devil-3"
if(6 to 8)
icon_state = "Devil-4"
if(9 to INFINITY)
icon_state = "Devil-5"
else
icon_state = "Devil-6"
/obj/screen/devil/soul_counter/proc/clear()
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/ling
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/ling/sting
name = "current sting"
screen_loc = ui_lingstingdisplay
/obj/screen/ling/sting/Click()
if(isobserver(usr))
return
var/mob/living/carbon/U = usr
U.unset_sting()
/obj/screen/ling/chems
name = "chemical storage"
icon_state = "power_display"
screen_loc = ui_lingchemdisplay
/mob/living/carbon/human/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/human(src, ui_style2icon(client.prefs.UI_style))
/datum/hud/human/New(mob/living/carbon/human/owner, ui_style = 'icons/mob/screen_midnight.dmi')
..()
owner.overlay_fullscreen("see_through_darkness", /obj/screen/fullscreen/see_through_darkness)
var/obj/screen/using
var/obj/screen/inventory/inv_box
using = new /obj/screen/craft
using.icon = ui_style
static_inventory += using
using = new/obj/screen/language_menu
using.icon = ui_style
static_inventory += using
using = new /obj/screen/area_creator
using.icon = ui_style
static_inventory += using
action_intent = new /obj/screen/act_intent/segmented
action_intent.icon_state = mymob.a_intent
static_inventory += action_intent
using = new /obj/screen/mov_intent
using.icon = ui_style
using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking")
using.screen_loc = ui_movi
static_inventory += using
using = new /obj/screen/drop()
using.icon = ui_style
using.screen_loc = ui_drop_throw
static_inventory += using
inv_box = new /obj/screen/inventory()
inv_box.name = "i_clothing"
inv_box.icon = ui_style
inv_box.slot_id = slot_w_uniform
inv_box.icon_state = "uniform"
inv_box.screen_loc = ui_iclothing
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "o_clothing"
inv_box.icon = ui_style
inv_box.slot_id = slot_wear_suit
inv_box.icon_state = "suit"
inv_box.screen_loc = ui_oclothing
toggleable_inventory += inv_box
build_hand_slots(ui_style)
using = new /obj/screen/swap_hand()
using.icon = ui_style
using.icon_state = "swap_1"
using.screen_loc = ui_swaphand_position(owner,1)
static_inventory += using
using = new /obj/screen/swap_hand()
using.icon = ui_style
using.icon_state = "swap_2"
using.screen_loc = ui_swaphand_position(owner,2)
static_inventory += using
inv_box = new /obj/screen/inventory()
inv_box.name = "id"
inv_box.icon = ui_style
inv_box.icon_state = "id"
inv_box.screen_loc = ui_id
inv_box.slot_id = slot_wear_id
static_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "mask"
inv_box.icon = ui_style
inv_box.icon_state = "mask"
inv_box.screen_loc = ui_mask
inv_box.slot_id = slot_wear_mask
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "neck"
inv_box.icon = ui_style
inv_box.icon_state = "neck"
inv_box.screen_loc = ui_neck
inv_box.slot_id = slot_neck
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "back"
inv_box.icon = ui_style
inv_box.icon_state = "back"
inv_box.screen_loc = ui_back
inv_box.slot_id = slot_back
static_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "storage1"
inv_box.icon = ui_style
inv_box.icon_state = "pocket"
inv_box.screen_loc = ui_storage1
inv_box.slot_id = slot_l_store
static_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "storage2"
inv_box.icon = ui_style
inv_box.icon_state = "pocket"
inv_box.screen_loc = ui_storage2
inv_box.slot_id = slot_r_store
static_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "suit storage"
inv_box.icon = ui_style
inv_box.icon_state = "suit_storage"
inv_box.screen_loc = ui_sstore1
inv_box.slot_id = slot_s_store
static_inventory += inv_box
using = new /obj/screen/resist()
using.icon = ui_style
using.screen_loc = ui_pull_resist
hotkeybuttons += using
using = new /obj/screen/human/toggle()
using.icon = ui_style
using.screen_loc = ui_inventory
static_inventory += using
using = new /obj/screen/human/equip()
using.icon = ui_style
using.screen_loc = ui_equip_position(mymob)
static_inventory += using
inv_box = new /obj/screen/inventory()
inv_box.name = "gloves"
inv_box.icon = ui_style
inv_box.icon_state = "gloves"
inv_box.screen_loc = ui_gloves
inv_box.slot_id = slot_gloves
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "eyes"
inv_box.icon = ui_style
inv_box.icon_state = "glasses"
inv_box.screen_loc = ui_glasses
inv_box.slot_id = slot_glasses
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "ears"
inv_box.icon = ui_style
inv_box.icon_state = "ears"
inv_box.screen_loc = ui_ears
inv_box.slot_id = slot_ears
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "head"
inv_box.icon = ui_style
inv_box.icon_state = "head"
inv_box.screen_loc = ui_head
inv_box.slot_id = slot_head
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "shoes"
inv_box.icon = ui_style
inv_box.icon_state = "shoes"
inv_box.screen_loc = ui_shoes
inv_box.slot_id = slot_shoes
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "belt"
inv_box.icon = ui_style
inv_box.icon_state = "belt"
// inv_box.icon_full = "template_small"
inv_box.screen_loc = ui_belt
inv_box.slot_id = slot_belt
static_inventory += inv_box
throw_icon = new /obj/screen/throw_catch()
throw_icon.icon = ui_style
throw_icon.screen_loc = ui_drop_throw
hotkeybuttons += throw_icon
internals = new /obj/screen/internals()
infodisplay += internals
healths = new /obj/screen/healths()
infodisplay += healths
//citadel code
arousal = new /obj/screen/arousal()
infodisplay += arousal
healthdoll = new /obj/screen/healthdoll()
infodisplay += healthdoll
pull_icon = new /obj/screen/pull()
pull_icon.icon = ui_style
pull_icon.update_icon(mymob)
pull_icon.screen_loc = ui_pull_resist
static_inventory += pull_icon
lingchemdisplay = new /obj/screen/ling/chems()
infodisplay += lingchemdisplay
lingstingdisplay = new /obj/screen/ling/sting()
infodisplay += lingstingdisplay
devilsouldisplay = new /obj/screen/devil/soul_counter
infodisplay += devilsouldisplay
zone_select = new /obj/screen/zone_sel()
zone_select.icon = ui_style
zone_select.update_icon(mymob)
static_inventory += zone_select
for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory))
if(inv.slot_id)
inv.hud = src
inv_slots[inv.slot_id] = inv
inv.update_icon()
/datum/hud/human/update_locked_slots()
if(!mymob)
return
var/mob/living/carbon/human/H = mymob
var/datum/species/S = H.dna.species
for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory))
if(inv.slot_id)
if(inv.slot_id in S.no_equip)
inv.alpha = 128
else
inv.alpha = initial(inv.alpha)
/datum/hud/human/hidden_inventory_update(mob/viewer)
if(!mymob)
return
var/mob/living/carbon/human/H = mymob
var/mob/screenmob = viewer || H
if(screenmob.hud_used.inventory_shown && screenmob.hud_used.hud_shown)
if(H.shoes)
H.shoes.screen_loc = ui_shoes
screenmob.client.screen += H.shoes
if(H.gloves)
H.gloves.screen_loc = ui_gloves
screenmob.client.screen += H.gloves
if(H.ears)
H.ears.screen_loc = ui_ears
screenmob.client.screen += H.ears
if(H.glasses)
H.glasses.screen_loc = ui_glasses
screenmob.client.screen += H.glasses
if(H.w_uniform)
H.w_uniform.screen_loc = ui_iclothing
screenmob.client.screen += H.w_uniform
if(H.wear_suit)
H.wear_suit.screen_loc = ui_oclothing
screenmob.client.screen += H.wear_suit
if(H.wear_mask)
H.wear_mask.screen_loc = ui_mask
screenmob.client.screen += H.wear_mask
if(H.wear_neck)
H.wear_neck.screen_loc = ui_neck
screenmob.client.screen += H.wear_neck
if(H.head)
H.head.screen_loc = ui_head
screenmob.client.screen += H.head
else
if(H.shoes) screenmob.client.screen -= H.shoes
if(H.gloves) screenmob.client.screen -= H.gloves
if(H.ears) screenmob.client.screen -= H.ears
if(H.glasses) screenmob.client.screen -= H.glasses
if(H.w_uniform) screenmob.client.screen -= H.w_uniform
if(H.wear_suit) screenmob.client.screen -= H.wear_suit
if(H.wear_mask) screenmob.client.screen -= H.wear_mask
if(H.wear_neck) screenmob.client.screen -= H.wear_neck
if(H.head) screenmob.client.screen -= H.head
/datum/hud/human/persistent_inventory_update(mob/viewer)
if(!mymob)
return
..()
var/mob/living/carbon/human/H = mymob
var/mob/screenmob = viewer || H
if(screenmob.hud_used)
if(screenmob.hud_used.hud_shown)
if(H.s_store)
H.s_store.screen_loc = ui_sstore1
screenmob.client.screen += H.s_store
if(H.wear_id)
H.wear_id.screen_loc = ui_id
screenmob.client.screen += H.wear_id
if(H.belt)
H.belt.screen_loc = ui_belt
screenmob.client.screen += H.belt
if(H.back)
H.back.screen_loc = ui_back
screenmob.client.screen += H.back
if(H.l_store)
H.l_store.screen_loc = ui_storage1
screenmob.client.screen += H.l_store
if(H.r_store)
H.r_store.screen_loc = ui_storage2
screenmob.client.screen += H.r_store
else
if(H.s_store)
screenmob.client.screen -= H.s_store
if(H.wear_id)
screenmob.client.screen -= H.wear_id
if(H.belt)
screenmob.client.screen -= H.belt
if(H.back)
screenmob.client.screen -= H.back
if(H.l_store)
screenmob.client.screen -= H.l_store
if(H.r_store)
screenmob.client.screen -= H.r_store
if(hud_version != HUD_STYLE_NOHUD)
for(var/obj/item/I in H.held_items)
I.screen_loc = ui_hand_position(H.get_held_index_of_item(I))
screenmob.client.screen += I
else
for(var/obj/item/I in H.held_items)
I.screen_loc = null
screenmob.client.screen -= I
/mob/living/carbon/human/verb/toggle_hotkey_verbs()
set category = "OOC"
set name = "Toggle hotkey buttons"
set desc = "This disables or enables the user interface buttons which can be used with hotkeys."
if(hud_used.hotkey_ui_hidden)
client.screen += hud_used.hotkeybuttons
hud_used.hotkey_ui_hidden = 0
else
client.screen -= hud_used.hotkeybuttons
hud_used.hotkey_ui_hidden = 1
/obj/screen/human
icon = 'icons/mob/screen_midnight.dmi'
/obj/screen/human/toggle
name = "toggle"
icon_state = "toggle"
/obj/screen/human/toggle/Click()
var/mob/targetmob = usr
if(isobserver(usr))
if(ishuman(usr.client.eye) && (usr.client.eye != usr))
var/mob/M = usr.client.eye
targetmob = M
if(usr.hud_used.inventory_shown && targetmob.hud_used)
usr.hud_used.inventory_shown = 0
usr.client.screen -= targetmob.hud_used.toggleable_inventory
else
usr.hud_used.inventory_shown = 1
usr.client.screen += targetmob.hud_used.toggleable_inventory
targetmob.hud_used.hidden_inventory_update(usr)
/obj/screen/human/equip
name = "equip"
icon_state = "act_equip"
/obj/screen/human/equip/Click()
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
return 1
var/mob/living/carbon/human/H = usr
H.quick_equip()
/obj/screen/devil
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/devil/soul_counter
icon = 'icons/mob/screen_gen.dmi'
name = "souls owned"
icon_state = "Devil-6"
screen_loc = ui_devilsouldisplay
/obj/screen/devil/soul_counter/proc/update_counter(souls = 0)
invisibility = 0
maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#FF0000'>[souls]</font></div>"
switch(souls)
if(0,null)
icon_state = "Devil-1"
if(1,2)
icon_state = "Devil-2"
if(3 to 5)
icon_state = "Devil-3"
if(6 to 8)
icon_state = "Devil-4"
if(9 to INFINITY)
icon_state = "Devil-5"
else
icon_state = "Devil-6"
/obj/screen/devil/soul_counter/proc/clear()
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/ling
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/ling/sting
name = "current sting"
screen_loc = ui_lingstingdisplay
/obj/screen/ling/sting/Click()
if(isobserver(usr))
return
var/mob/living/carbon/U = usr
U.unset_sting()
/obj/screen/ling/chems
name = "chemical storage"
icon_state = "power_display"
screen_loc = ui_lingchemdisplay
/mob/living/carbon/human/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/human(src, ui_style2icon(client.prefs.UI_style))
/datum/hud/human/New(mob/living/carbon/human/owner, ui_style = 'icons/mob/screen_midnight.dmi')
..()
owner.overlay_fullscreen("see_through_darkness", /obj/screen/fullscreen/see_through_darkness)
var/obj/screen/using
var/obj/screen/inventory/inv_box
using = new /obj/screen/craft
using.icon = ui_style
static_inventory += using
using = new/obj/screen/language_menu
using.icon = ui_style
static_inventory += using
using = new /obj/screen/area_creator
using.icon = ui_style
static_inventory += using
action_intent = new /obj/screen/act_intent/segmented
action_intent.icon_state = mymob.a_intent
static_inventory += action_intent
using = new /obj/screen/mov_intent
using.icon = ui_style
using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking")
using.screen_loc = ui_movi
static_inventory += using
using = new /obj/screen/drop()
using.icon = ui_style
using.screen_loc = ui_drop_throw
static_inventory += using
inv_box = new /obj/screen/inventory()
inv_box.name = "i_clothing"
inv_box.icon = ui_style
inv_box.slot_id = slot_w_uniform
inv_box.icon_state = "uniform"
inv_box.screen_loc = ui_iclothing
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "o_clothing"
inv_box.icon = ui_style
inv_box.slot_id = slot_wear_suit
inv_box.icon_state = "suit"
inv_box.screen_loc = ui_oclothing
toggleable_inventory += inv_box
build_hand_slots(ui_style)
using = new /obj/screen/swap_hand()
using.icon = ui_style
using.icon_state = "swap_1"
using.screen_loc = ui_swaphand_position(owner,1)
static_inventory += using
using = new /obj/screen/swap_hand()
using.icon = ui_style
using.icon_state = "swap_2"
using.screen_loc = ui_swaphand_position(owner,2)
static_inventory += using
inv_box = new /obj/screen/inventory()
inv_box.name = "id"
inv_box.icon = ui_style
inv_box.icon_state = "id"
inv_box.screen_loc = ui_id
inv_box.slot_id = slot_wear_id
static_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "mask"
inv_box.icon = ui_style
inv_box.icon_state = "mask"
inv_box.screen_loc = ui_mask
inv_box.slot_id = slot_wear_mask
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "neck"
inv_box.icon = ui_style
inv_box.icon_state = "neck"
inv_box.screen_loc = ui_neck
inv_box.slot_id = slot_neck
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "back"
inv_box.icon = ui_style
inv_box.icon_state = "back"
inv_box.screen_loc = ui_back
inv_box.slot_id = slot_back
static_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "storage1"
inv_box.icon = ui_style
inv_box.icon_state = "pocket"
inv_box.screen_loc = ui_storage1
inv_box.slot_id = slot_l_store
static_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "storage2"
inv_box.icon = ui_style
inv_box.icon_state = "pocket"
inv_box.screen_loc = ui_storage2
inv_box.slot_id = slot_r_store
static_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "suit storage"
inv_box.icon = ui_style
inv_box.icon_state = "suit_storage"
inv_box.screen_loc = ui_sstore1
inv_box.slot_id = slot_s_store
static_inventory += inv_box
using = new /obj/screen/resist()
using.icon = ui_style
using.screen_loc = ui_pull_resist
hotkeybuttons += using
using = new /obj/screen/human/toggle()
using.icon = ui_style
using.screen_loc = ui_inventory
static_inventory += using
using = new /obj/screen/human/equip()
using.icon = ui_style
using.screen_loc = ui_equip_position(mymob)
static_inventory += using
inv_box = new /obj/screen/inventory()
inv_box.name = "gloves"
inv_box.icon = ui_style
inv_box.icon_state = "gloves"
inv_box.screen_loc = ui_gloves
inv_box.slot_id = slot_gloves
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "eyes"
inv_box.icon = ui_style
inv_box.icon_state = "glasses"
inv_box.screen_loc = ui_glasses
inv_box.slot_id = slot_glasses
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "ears"
inv_box.icon = ui_style
inv_box.icon_state = "ears"
inv_box.screen_loc = ui_ears
inv_box.slot_id = slot_ears
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "head"
inv_box.icon = ui_style
inv_box.icon_state = "head"
inv_box.screen_loc = ui_head
inv_box.slot_id = slot_head
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "shoes"
inv_box.icon = ui_style
inv_box.icon_state = "shoes"
inv_box.screen_loc = ui_shoes
inv_box.slot_id = slot_shoes
toggleable_inventory += inv_box
inv_box = new /obj/screen/inventory()
inv_box.name = "belt"
inv_box.icon = ui_style
inv_box.icon_state = "belt"
// inv_box.icon_full = "template_small"
inv_box.screen_loc = ui_belt
inv_box.slot_id = slot_belt
static_inventory += inv_box
throw_icon = new /obj/screen/throw_catch()
throw_icon.icon = ui_style
throw_icon.screen_loc = ui_drop_throw
hotkeybuttons += throw_icon
internals = new /obj/screen/internals()
infodisplay += internals
healths = new /obj/screen/healths()
infodisplay += healths
//citadel code
arousal = new /obj/screen/arousal()
infodisplay += arousal
healthdoll = new /obj/screen/healthdoll()
infodisplay += healthdoll
pull_icon = new /obj/screen/pull()
pull_icon.icon = ui_style
pull_icon.update_icon(mymob)
pull_icon.screen_loc = ui_pull_resist
static_inventory += pull_icon
lingchemdisplay = new /obj/screen/ling/chems()
infodisplay += lingchemdisplay
lingstingdisplay = new /obj/screen/ling/sting()
infodisplay += lingstingdisplay
devilsouldisplay = new /obj/screen/devil/soul_counter
infodisplay += devilsouldisplay
zone_select = new /obj/screen/zone_sel()
zone_select.icon = ui_style
zone_select.update_icon(mymob)
static_inventory += zone_select
for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory))
if(inv.slot_id)
inv.hud = src
inv_slots[inv.slot_id] = inv
inv.update_icon()
/datum/hud/human/update_locked_slots()
if(!mymob)
return
var/mob/living/carbon/human/H = mymob
var/datum/species/S = H.dna.species
for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory))
if(inv.slot_id)
if(inv.slot_id in S.no_equip)
inv.alpha = 128
else
inv.alpha = initial(inv.alpha)
/datum/hud/human/hidden_inventory_update(mob/viewer)
if(!mymob)
return
var/mob/living/carbon/human/H = mymob
var/mob/screenmob = viewer || H
if(screenmob.hud_used.inventory_shown && screenmob.hud_used.hud_shown)
if(H.shoes)
H.shoes.screen_loc = ui_shoes
screenmob.client.screen += H.shoes
if(H.gloves)
H.gloves.screen_loc = ui_gloves
screenmob.client.screen += H.gloves
if(H.ears)
H.ears.screen_loc = ui_ears
screenmob.client.screen += H.ears
if(H.glasses)
H.glasses.screen_loc = ui_glasses
screenmob.client.screen += H.glasses
if(H.w_uniform)
H.w_uniform.screen_loc = ui_iclothing
screenmob.client.screen += H.w_uniform
if(H.wear_suit)
H.wear_suit.screen_loc = ui_oclothing
screenmob.client.screen += H.wear_suit
if(H.wear_mask)
H.wear_mask.screen_loc = ui_mask
screenmob.client.screen += H.wear_mask
if(H.wear_neck)
H.wear_neck.screen_loc = ui_neck
screenmob.client.screen += H.wear_neck
if(H.head)
H.head.screen_loc = ui_head
screenmob.client.screen += H.head
else
if(H.shoes) screenmob.client.screen -= H.shoes
if(H.gloves) screenmob.client.screen -= H.gloves
if(H.ears) screenmob.client.screen -= H.ears
if(H.glasses) screenmob.client.screen -= H.glasses
if(H.w_uniform) screenmob.client.screen -= H.w_uniform
if(H.wear_suit) screenmob.client.screen -= H.wear_suit
if(H.wear_mask) screenmob.client.screen -= H.wear_mask
if(H.wear_neck) screenmob.client.screen -= H.wear_neck
if(H.head) screenmob.client.screen -= H.head
/datum/hud/human/persistent_inventory_update(mob/viewer)
if(!mymob)
return
..()
var/mob/living/carbon/human/H = mymob
var/mob/screenmob = viewer || H
if(screenmob.hud_used)
if(screenmob.hud_used.hud_shown)
if(H.s_store)
H.s_store.screen_loc = ui_sstore1
screenmob.client.screen += H.s_store
if(H.wear_id)
H.wear_id.screen_loc = ui_id
screenmob.client.screen += H.wear_id
if(H.belt)
H.belt.screen_loc = ui_belt
screenmob.client.screen += H.belt
if(H.back)
H.back.screen_loc = ui_back
screenmob.client.screen += H.back
if(H.l_store)
H.l_store.screen_loc = ui_storage1
screenmob.client.screen += H.l_store
if(H.r_store)
H.r_store.screen_loc = ui_storage2
screenmob.client.screen += H.r_store
else
if(H.s_store)
screenmob.client.screen -= H.s_store
if(H.wear_id)
screenmob.client.screen -= H.wear_id
if(H.belt)
screenmob.client.screen -= H.belt
if(H.back)
screenmob.client.screen -= H.back
if(H.l_store)
screenmob.client.screen -= H.l_store
if(H.r_store)
screenmob.client.screen -= H.r_store
if(hud_version != HUD_STYLE_NOHUD)
for(var/obj/item/I in H.held_items)
I.screen_loc = ui_hand_position(H.get_held_index_of_item(I))
screenmob.client.screen += I
else
for(var/obj/item/I in H.held_items)
I.screen_loc = null
screenmob.client.screen -= I
/mob/living/carbon/human/verb/toggle_hotkey_verbs()
set category = "OOC"
set name = "Toggle hotkey buttons"
set desc = "This disables or enables the user interface buttons which can be used with hotkeys."
if(hud_used.hotkey_ui_hidden)
client.screen += hud_used.hotkeybuttons
hud_used.hotkey_ui_hidden = 0
else
client.screen -= hud_used.hotkeybuttons
hud_used.hotkey_ui_hidden = 1
+1 -1
View File
@@ -169,7 +169,7 @@
opentime = 0
/datum/browser/alert/proc/wait()
while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time))
while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time))
stoplag()
/datum/browser/alert/Topic(href,href_list)
+3 -3
View File
@@ -615,7 +615,9 @@
if(!H.has_language(dt))
return FALSE
else if(H.omnitongue || could_speak_in_language(dt))
else if(H.omnitongue)
return TRUE
else if(could_speak_in_language(dt) && (!H.only_speaks_language || H.only_speaks_language == dt))
return TRUE
else
return FALSE
@@ -631,8 +633,6 @@
else
H.selected_default_language = null
var/datum/language/chosen_langtype
var/highest_priority
+177 -177
View File
@@ -1,177 +1,177 @@
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
/obj/item/weapon/pinpointer
name = "pinpointer"
desc = "A handheld tracking device that locks onto certain signals."
icon = 'icons/obj/device.dmi'
icon_state = "pinoff"
flags = CONDUCT
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/active = FALSE
var/atom/movable/target = null //The thing we're searching for
var/atom/movable/constant_target = null //The thing we're always focused on, if we're in the right mode
var/target_x = 0 //The target coordinates if we're tracking those
var/target_y = 0
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
var/nuke_warning = FALSE // If we've set off a miniature alarm about an armed nuke
var/mode = TRACK_NUKE_DISK //What are we looking for?
/obj/item/weapon/pinpointer/New()
..()
GLOB.pinpointer_list += src
/obj/item/weapon/pinpointer/Destroy()
STOP_PROCESSING(SSfastprocess, src)
GLOB.pinpointer_list -= src
return ..()
/obj/item/weapon/pinpointer/attack_self(mob/living/user)
active = !active
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1)
icon_state = "pin[active ? "onnull" : "off"]"
if(active)
START_PROCESSING(SSfastprocess, src)
else
target = null //Restarting the pinpointer forces a target reset
STOP_PROCESSING(SSfastprocess, src)
/obj/item/weapon/pinpointer/attackby(obj/item/I, mob/living/user, params)
if(mode != TRACK_ATOM)
return ..()
user.visible_message("<span class='notice'>[user] tunes [src] to [I].</span>", "<span class='notice'>You fine-tune [src]'s tracking to track [I].</span>")
playsound(src, 'sound/machines/click.ogg', 50, 1)
constant_target = I
/obj/item/weapon/pinpointer/examine(mob/user)
..()
var/msg = "Its tracking indicator reads "
switch(mode)
if(TRACK_NUKE_DISK)
msg += "\"nuclear_disk\"."
if(TRACK_MALF_AI)
msg += "\"01000001 01001001\"."
if(TRACK_INFILTRATOR)
msg += "\"vasvygengbefuvc\"."
if(TRACK_OPERATIVES)
msg += "\"[target ? "Operative [target]" : "friends"]\"."
if(TRACK_ATOM)
msg += "\"[initial(constant_target.name)]\"."
if(TRACK_COORDINATES)
msg += "\"([target_x], [target_y])\"."
else
msg = "Its tracking indicator is blank."
to_chat(user, msg)
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
if(bomb.timing)
to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.get_time_left()]")
/obj/item/weapon/pinpointer/process()
if(!active)
STOP_PROCESSING(SSfastprocess, src)
return
scan_for_target()
point_to_target()
my_god_jc_a_bomb()
addtimer(CALLBACK(src, .proc/refresh_target), 50, TIMER_UNIQUE)
/obj/item/weapon/pinpointer/proc/scan_for_target() //Looks for whatever it's tracking
if(target)
if(isliving(target))
var/mob/living/L = target
if(L.stat == DEAD)
target = null
return
switch(mode)
if(TRACK_NUKE_DISK)
var/obj/item/weapon/disk/nuclear/N = locate()
target = N
if(TRACK_MALF_AI)
for(var/V in GLOB.ai_list)
var/mob/living/silicon/ai/A = V
if(A.nuking)
target = A
for(var/V in GLOB.apcs_list)
var/obj/machinery/power/apc/A = V
if(A.malfhack && A.occupier)
target = A
if(TRACK_INFILTRATOR)
target = SSshuttle.getShuttle("syndicate")
if(TRACK_OPERATIVES)
var/list/possible_targets = list()
var/turf/here = get_turf(src)
for(var/V in SSticker.mode.syndicates)
var/datum/mind/M = V
if(M.current && M.current.stat != DEAD)
possible_targets |= M.current
var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here)
if(closest_operative)
target = closest_operative
if(TRACK_ATOM)
if(constant_target)
target = constant_target
if(TRACK_COORDINATES)
var/turf/T = get_turf(src)
target = locate(target_x, target_y, T.z)
/obj/item/weapon/pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction
if(!active)
return
if(!target || (mode == TRACK_ATOM && !constant_target))
icon_state = "pinon[nuke_warning ? "alert" : ""]null"
return
var/turf/here = get_turf(src)
var/turf/there = get_turf(target)
if(here.z != there.z)
icon_state = "pinon[nuke_warning ? "alert" : ""]null"
return
if(get_dist_euclidian(here,there)<=minimum_range)
icon_state = "pinon[nuke_warning ? "alert" : ""]direct"
else
setDir(get_dir(here, there))
switch(get_dist(here, there))
if(1 to 8)
icon_state = "pinon[nuke_warning ? "alert" : "close"]"
if(9 to 16)
icon_state = "pinon[nuke_warning ? "alert" : "medium"]"
if(16 to INFINITY)
icon_state = "pinon[nuke_warning ? "alert" : "far"]"
/obj/item/weapon/pinpointer/proc/my_god_jc_a_bomb() //If we should get the hell back to the ship
for(var/obj/machinery/nuclearbomb/bomb in GLOB.nuke_list)
if(bomb.timing)
if(!nuke_warning)
nuke_warning = TRUE
playsound(src, 'sound/items/Nuke_toy_lowpower.ogg', 50, 0)
if(isliving(loc))
var/mob/living/L = loc
to_chat(L, "<span class='userdanger'>Your [name] vibrates and lets out a tinny alarm. Uh oh.</span>")
/obj/item/weapon/pinpointer/proc/switch_mode_to(new_mode) //If we shouldn't be tracking what we are
if(isliving(loc))
var/mob/living/L = loc
to_chat(L, "<span class='userdanger'>Your [name] beeps as it reconfigures its tracking algorithms.</span>")
playsound(L, 'sound/machines/triple_beep.ogg', 50, 1)
mode = new_mode
target = null //Switch modes so we can find the new target
/obj/item/weapon/pinpointer/proc/refresh_target() //Periodically removes the target to allow the pinpointer to update (i.e. malf AI shunts, an operative dies)
target = null
/obj/item/weapon/pinpointer/syndicate //Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
name = "syndicate pinpointer"
desc = "A handheld tracking device that locks onto certain signals. It's configured to switch tracking modes once it detects the activation signal of a nuclear device."
/obj/item/weapon/pinpointer/syndicate/cyborg //Cyborg pinpointers just look for a random operative.
name = "cyborg syndicate pinpointer"
desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives."
mode = TRACK_OPERATIVES
flags = NODROP
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
/obj/item/weapon/pinpointer
name = "pinpointer"
desc = "A handheld tracking device that locks onto certain signals."
icon = 'icons/obj/device.dmi'
icon_state = "pinoff"
flags = CONDUCT
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/active = FALSE
var/atom/movable/target = null //The thing we're searching for
var/atom/movable/constant_target = null //The thing we're always focused on, if we're in the right mode
var/target_x = 0 //The target coordinates if we're tracking those
var/target_y = 0
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
var/nuke_warning = FALSE // If we've set off a miniature alarm about an armed nuke
var/mode = TRACK_NUKE_DISK //What are we looking for?
/obj/item/weapon/pinpointer/New()
..()
GLOB.pinpointer_list += src
/obj/item/weapon/pinpointer/Destroy()
STOP_PROCESSING(SSfastprocess, src)
GLOB.pinpointer_list -= src
return ..()
/obj/item/weapon/pinpointer/attack_self(mob/living/user)
active = !active
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1)
icon_state = "pin[active ? "onnull" : "off"]"
if(active)
START_PROCESSING(SSfastprocess, src)
else
target = null //Restarting the pinpointer forces a target reset
STOP_PROCESSING(SSfastprocess, src)
/obj/item/weapon/pinpointer/attackby(obj/item/I, mob/living/user, params)
if(mode != TRACK_ATOM)
return ..()
user.visible_message("<span class='notice'>[user] tunes [src] to [I].</span>", "<span class='notice'>You fine-tune [src]'s tracking to track [I].</span>")
playsound(src, 'sound/machines/click.ogg', 50, 1)
constant_target = I
/obj/item/weapon/pinpointer/examine(mob/user)
..()
var/msg = "Its tracking indicator reads "
switch(mode)
if(TRACK_NUKE_DISK)
msg += "\"nuclear_disk\"."
if(TRACK_MALF_AI)
msg += "\"01000001 01001001\"."
if(TRACK_INFILTRATOR)
msg += "\"vasvygengbefuvc\"."
if(TRACK_OPERATIVES)
msg += "\"[target ? "Operative [target]" : "friends"]\"."
if(TRACK_ATOM)
msg += "\"[initial(constant_target.name)]\"."
if(TRACK_COORDINATES)
msg += "\"([target_x], [target_y])\"."
else
msg = "Its tracking indicator is blank."
to_chat(user, msg)
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
if(bomb.timing)
to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.get_time_left()]")
/obj/item/weapon/pinpointer/process()
if(!active)
STOP_PROCESSING(SSfastprocess, src)
return
scan_for_target()
point_to_target()
my_god_jc_a_bomb()
addtimer(CALLBACK(src, .proc/refresh_target), 50, TIMER_UNIQUE)
/obj/item/weapon/pinpointer/proc/scan_for_target() //Looks for whatever it's tracking
if(target)
if(isliving(target))
var/mob/living/L = target
if(L.stat == DEAD)
target = null
return
switch(mode)
if(TRACK_NUKE_DISK)
var/obj/item/weapon/disk/nuclear/N = locate()
target = N
if(TRACK_MALF_AI)
for(var/V in GLOB.ai_list)
var/mob/living/silicon/ai/A = V
if(A.nuking)
target = A
for(var/V in GLOB.apcs_list)
var/obj/machinery/power/apc/A = V
if(A.malfhack && A.occupier)
target = A
if(TRACK_INFILTRATOR)
target = SSshuttle.getShuttle("syndicate")
if(TRACK_OPERATIVES)
var/list/possible_targets = list()
var/turf/here = get_turf(src)
for(var/V in SSticker.mode.syndicates)
var/datum/mind/M = V
if(M.current && M.current.stat != DEAD)
possible_targets |= M.current
var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here)
if(closest_operative)
target = closest_operative
if(TRACK_ATOM)
if(constant_target)
target = constant_target
if(TRACK_COORDINATES)
var/turf/T = get_turf(src)
target = locate(target_x, target_y, T.z)
/obj/item/weapon/pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction
if(!active)
return
if(!target || (mode == TRACK_ATOM && !constant_target))
icon_state = "pinon[nuke_warning ? "alert" : ""]null"
return
var/turf/here = get_turf(src)
var/turf/there = get_turf(target)
if(here.z != there.z)
icon_state = "pinon[nuke_warning ? "alert" : ""]null"
return
if(get_dist_euclidian(here,there)<=minimum_range)
icon_state = "pinon[nuke_warning ? "alert" : ""]direct"
else
setDir(get_dir(here, there))
switch(get_dist(here, there))
if(1 to 8)
icon_state = "pinon[nuke_warning ? "alert" : "close"]"
if(9 to 16)
icon_state = "pinon[nuke_warning ? "alert" : "medium"]"
if(16 to INFINITY)
icon_state = "pinon[nuke_warning ? "alert" : "far"]"
/obj/item/weapon/pinpointer/proc/my_god_jc_a_bomb() //If we should get the hell back to the ship
for(var/obj/machinery/nuclearbomb/bomb in GLOB.nuke_list)
if(bomb.timing)
if(!nuke_warning)
nuke_warning = TRUE
playsound(src, 'sound/items/Nuke_toy_lowpower.ogg', 50, 0)
if(isliving(loc))
var/mob/living/L = loc
to_chat(L, "<span class='userdanger'>Your [name] vibrates and lets out a tinny alarm. Uh oh.</span>")
/obj/item/weapon/pinpointer/proc/switch_mode_to(new_mode) //If we shouldn't be tracking what we are
if(isliving(loc))
var/mob/living/L = loc
to_chat(L, "<span class='userdanger'>Your [name] beeps as it reconfigures its tracking algorithms.</span>")
playsound(L, 'sound/machines/triple_beep.ogg', 50, 1)
mode = new_mode
target = null //Switch modes so we can find the new target
/obj/item/weapon/pinpointer/proc/refresh_target() //Periodically removes the target to allow the pinpointer to update (i.e. malf AI shunts, an operative dies)
target = null
/obj/item/weapon/pinpointer/syndicate //Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
name = "syndicate pinpointer"
desc = "A handheld tracking device that locks onto certain signals. It's configured to switch tracking modes once it detects the activation signal of a nuclear device."
/obj/item/weapon/pinpointer/syndicate/cyborg //Cyborg pinpointers just look for a random operative.
name = "cyborg syndicate pinpointer"
desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives."
mode = TRACK_OPERATIVES
flags = NODROP
@@ -1,223 +1,223 @@
#define NUKESCALINGMODIFIER 1
GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner"))
/obj/machinery/computer/telecrystals
name = "\improper Telecrystal assignment station"
desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..."
icon_state = "tcstation"
icon_keyboard = "tcstation_key"
icon_screen = "syndie"
clockwork = TRUE //it'd look weird, at least if ratvar ever got there
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
light_color = LIGHT_COLOR_RED
/////////////////////////////////////////////
/obj/machinery/computer/telecrystals/uplinker
name = "\improper Telecrystal upload/receive station"
desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \
you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant."
var/obj/item/uplinkholder = null
var/obj/machinery/computer/telecrystals/boss/linkedboss = null
/obj/machinery/computer/telecrystals/uplinker/Initialize()
..()
var/ID = pick_n_take(GLOB.possible_uplinker_IDs)
if(!ID)
ID = rand(1,999)
name = "[name] [ID]"
/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/O, mob/user, params)
if(uplinkholder)
to_chat(user, "<span class='notice'>The [src] already has an uplink in it.</span>")
return
if(O.hidden_uplink)
var/obj/item/I = user.get_active_held_item()
if(!user.drop_item())
return
uplinkholder = I
I.loc = src
I.add_fingerprint(user)
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='notice'>The [O] doesn't appear to be an uplink...</span>")
/obj/machinery/computer/telecrystals/uplinker/update_icon()
..()
if(uplinkholder)
add_overlay("[initial(icon_state)]-closed")
/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink()
if(uplinkholder)
uplinkholder.loc = get_turf(src.loc)
uplinkholder = null
update_icon()
/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
if(amt < 0)
linkedboss.storedcrystals += uplinkholder.hidden_uplink.telecrystals
if(addLog)
linkedboss.logTransfer("[src] donated [uplinkholder.hidden_uplink.telecrystals] telecrystals to [linkedboss].")
uplinkholder.hidden_uplink.telecrystals = 0
else if(amt <= uplinkholder.hidden_uplink.telecrystals)
uplinkholder.hidden_uplink.telecrystals -= amt
linkedboss.storedcrystals += amt
if(addLog)
linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].")
/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
if(amt < 0)
uplinkholder.hidden_uplink.telecrystals += linkedboss.storedcrystals
if(addLog)
linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].")
linkedboss.storedcrystals = 0
else if(amt <= linkedboss.storedcrystals)
uplinkholder.hidden_uplink.telecrystals += amt
linkedboss.storedcrystals -= amt
if(addLog)
linkedboss.logTransfer("[src] received [amt] telecrystals from [linkedboss].")
///////
/obj/machinery/computer/telecrystals/uplinker/attack_hand(mob/user)
if(..())
return
src.add_fingerprint(user)
user.set_machine(src)
var/dat = ""
if(linkedboss)
dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution. <BR><BR>"
else
dat += "No linked management consoles detected. Scan for uplink stations using the management console.<BR><BR>"
if(uplinkholder)
dat += "[uplinkholder.hidden_uplink.telecrystals] telecrystals remain in this uplink.<BR>"
if(linkedboss)
dat += "Donate TC: <a href='byond://?src=\ref[src];donate=1'>1</a> | <a href='byond://?src=\ref[src];donate=5'>5</a> | <a href='byond://?src=\ref[src];donate=-1'>All</a>"
dat += "<br><a href='byond://?src=\ref[src];eject=1'>Eject Uplink</a>"
var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Receive Station", 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list)
if(..())
return
if(href_list["donate"])
var/tcamt = text2num(href_list["donate"])
donateTC(tcamt)
if(href_list["eject"])
ejectuplink()
src.updateUsrDialog()
/////////////////////////////////////////
/obj/machinery/computer/telecrystals/boss
name = "team Telecrystal management console"
desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \
Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \
based on the danger rating of the mission."
icon_state = "computer"
icon_screen = "tcboss"
icon_keyboard = "syndie_key"
var/virgin = 1
var/scanrange = 10
var/storedcrystals = 0
var/list/TCstations = list()
var/list/transferlog = list()
/obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage)
transferlog += ("<b>[worldtime2text()]</b> [logmessage]")
/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers()
for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc))
if(!A.linkedboss)
TCstations += A
A.linkedboss = src
if(virgin)
getDangerous()
virgin = 0
/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population.
..()
var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len
danger = Ceiling(danger, 10)
scaleTC(danger)
/obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc.
storedcrystals += amt * NUKESCALINGMODIFIER
/////////
/obj/machinery/computer/telecrystals/boss/attack_hand(mob/user)
if(..())
return
src.add_fingerprint(user)
user.set_machine(src)
var/dat = ""
dat += "<a href='byond://?src=\ref[src];scan=1'>Scan for TC stations.</a><BR>"
dat += "[storedcrystals] telecrystals are available for distribution. <BR>"
dat += "<BR><BR>"
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
dat += "[A.name] | "
if(A.uplinkholder)
dat += "[A.uplinkholder.hidden_uplink.telecrystals] telecrystals."
if(storedcrystals)
dat+= "<BR>Add TC: <a href ='?src=\ref[src];target=\ref[A];give=1'>1</a> | <a href ='?src=\ref[src];target=\ref[A];give=5'>5</a> | <a href ='?src=\ref[src];target=\ref[A];give=10'>10</a> | <a href ='?src=\ref[src];target=\ref[A];give=-1'>All</a>"
dat += "<BR>"
if(TCstations.len && storedcrystals)
dat += "<BR><BR><a href='byond://?src=\ref[src];distrib=1'>Evenly distribute remaining TC.</a><BR><BR>"
for(var/entry in transferlog)
dat += "<small>[entry]</small><BR>"
var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/telecrystals/boss/Topic(href, href_list)
if(..())
return
if(href_list["scan"])
scanUplinkers()
if(href_list["give"])
var/tcamt = text2num(href_list["give"])
if(TCstations.len) // sanity
var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["target"]) in TCstations
A.giveTC(tcamt)
if(href_list["distrib"])
var/sanity = 0
while(storedcrystals && sanity < 100)
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
A.giveTC(1,0)
sanity++
logTransfer("[src] evenly distributed telecrystals.")
src.updateUsrDialog()
return
#undef NUKESCALINGMODIFIER
#define NUKESCALINGMODIFIER 1
GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner"))
/obj/machinery/computer/telecrystals
name = "\improper Telecrystal assignment station"
desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..."
icon_state = "tcstation"
icon_keyboard = "tcstation_key"
icon_screen = "syndie"
clockwork = TRUE //it'd look weird, at least if ratvar ever got there
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
light_color = LIGHT_COLOR_RED
/////////////////////////////////////////////
/obj/machinery/computer/telecrystals/uplinker
name = "\improper Telecrystal upload/receive station"
desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \
you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant."
var/obj/item/uplinkholder = null
var/obj/machinery/computer/telecrystals/boss/linkedboss = null
/obj/machinery/computer/telecrystals/uplinker/Initialize()
..()
var/ID = pick_n_take(GLOB.possible_uplinker_IDs)
if(!ID)
ID = rand(1,999)
name = "[name] [ID]"
/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/O, mob/user, params)
if(uplinkholder)
to_chat(user, "<span class='notice'>The [src] already has an uplink in it.</span>")
return
if(O.hidden_uplink)
var/obj/item/I = user.get_active_held_item()
if(!user.drop_item())
return
uplinkholder = I
I.loc = src
I.add_fingerprint(user)
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='notice'>The [O] doesn't appear to be an uplink...</span>")
/obj/machinery/computer/telecrystals/uplinker/update_icon()
..()
if(uplinkholder)
add_overlay("[initial(icon_state)]-closed")
/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink()
if(uplinkholder)
uplinkholder.loc = get_turf(src.loc)
uplinkholder = null
update_icon()
/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
if(amt < 0)
linkedboss.storedcrystals += uplinkholder.hidden_uplink.telecrystals
if(addLog)
linkedboss.logTransfer("[src] donated [uplinkholder.hidden_uplink.telecrystals] telecrystals to [linkedboss].")
uplinkholder.hidden_uplink.telecrystals = 0
else if(amt <= uplinkholder.hidden_uplink.telecrystals)
uplinkholder.hidden_uplink.telecrystals -= amt
linkedboss.storedcrystals += amt
if(addLog)
linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].")
/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
if(amt < 0)
uplinkholder.hidden_uplink.telecrystals += linkedboss.storedcrystals
if(addLog)
linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].")
linkedboss.storedcrystals = 0
else if(amt <= linkedboss.storedcrystals)
uplinkholder.hidden_uplink.telecrystals += amt
linkedboss.storedcrystals -= amt
if(addLog)
linkedboss.logTransfer("[src] received [amt] telecrystals from [linkedboss].")
///////
/obj/machinery/computer/telecrystals/uplinker/attack_hand(mob/user)
if(..())
return
src.add_fingerprint(user)
user.set_machine(src)
var/dat = ""
if(linkedboss)
dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution. <BR><BR>"
else
dat += "No linked management consoles detected. Scan for uplink stations using the management console.<BR><BR>"
if(uplinkholder)
dat += "[uplinkholder.hidden_uplink.telecrystals] telecrystals remain in this uplink.<BR>"
if(linkedboss)
dat += "Donate TC: <a href='byond://?src=\ref[src];donate=1'>1</a> | <a href='byond://?src=\ref[src];donate=5'>5</a> | <a href='byond://?src=\ref[src];donate=-1'>All</a>"
dat += "<br><a href='byond://?src=\ref[src];eject=1'>Eject Uplink</a>"
var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Receive Station", 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list)
if(..())
return
if(href_list["donate"])
var/tcamt = text2num(href_list["donate"])
donateTC(tcamt)
if(href_list["eject"])
ejectuplink()
src.updateUsrDialog()
/////////////////////////////////////////
/obj/machinery/computer/telecrystals/boss
name = "team Telecrystal management console"
desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \
Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \
based on the danger rating of the mission."
icon_state = "computer"
icon_screen = "tcboss"
icon_keyboard = "syndie_key"
var/virgin = 1
var/scanrange = 10
var/storedcrystals = 0
var/list/TCstations = list()
var/list/transferlog = list()
/obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage)
transferlog += ("<b>[worldtime2text()]</b> [logmessage]")
/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers()
for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc))
if(!A.linkedboss)
TCstations += A
A.linkedboss = src
if(virgin)
getDangerous()
virgin = 0
/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population.
..()
var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len
danger = Ceiling(danger, 10)
scaleTC(danger)
/obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc.
storedcrystals += amt * NUKESCALINGMODIFIER
/////////
/obj/machinery/computer/telecrystals/boss/attack_hand(mob/user)
if(..())
return
src.add_fingerprint(user)
user.set_machine(src)
var/dat = ""
dat += "<a href='byond://?src=\ref[src];scan=1'>Scan for TC stations.</a><BR>"
dat += "[storedcrystals] telecrystals are available for distribution. <BR>"
dat += "<BR><BR>"
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
dat += "[A.name] | "
if(A.uplinkholder)
dat += "[A.uplinkholder.hidden_uplink.telecrystals] telecrystals."
if(storedcrystals)
dat+= "<BR>Add TC: <a href ='?src=\ref[src];target=\ref[A];give=1'>1</a> | <a href ='?src=\ref[src];target=\ref[A];give=5'>5</a> | <a href ='?src=\ref[src];target=\ref[A];give=10'>10</a> | <a href ='?src=\ref[src];target=\ref[A];give=-1'>All</a>"
dat += "<BR>"
if(TCstations.len && storedcrystals)
dat += "<BR><BR><a href='byond://?src=\ref[src];distrib=1'>Evenly distribute remaining TC.</a><BR><BR>"
for(var/entry in transferlog)
dat += "<small>[entry]</small><BR>"
var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/telecrystals/boss/Topic(href, href_list)
if(..())
return
if(href_list["scan"])
scanUplinkers()
if(href_list["give"])
var/tcamt = text2num(href_list["give"])
if(TCstations.len) // sanity
var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["target"]) in TCstations
A.giveTC(tcamt)
if(href_list["distrib"])
var/sanity = 0
while(storedcrystals && sanity < 100)
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
A.giveTC(1,0)
sanity++
logTransfer("[src] evenly distributed telecrystals.")
src.updateUsrDialog()
return
#undef NUKESCALINGMODIFIER
+435 -435
View File
@@ -1,435 +1,435 @@
/obj/item/mecha_parts/mecha_equipment/weapon
name = "mecha weapon"
range = RANGED
origin_tech = "materials=3;combat=3"
var/projectile
var/fire_sound
var/projectiles_per_shot = 1
var/variance = 0
var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter
var/projectile_delay = 0
var/firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect //the visual effect appearing when the weapon is fired.
/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/mecha/combat/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/proc/get_shot_amount()
return projectiles_per_shot
/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target, params)
if(!action_checks(target))
return 0
var/turf/curloc = get_turf(chassis)
var/turf/targloc = get_turf(target)
if (!targloc || !istype(targloc) || !curloc)
return 0
if (targloc == curloc)
return 0
set_ready_state(0)
for(var/i=1 to get_shot_amount())
var/obj/item/projectile/A = new projectile(curloc)
A.firer = chassis.occupant
A.original = target
A.current = curloc
if(!A.suppressed && firing_effect_type)
new firing_effect_type(get_turf(src), chassis.dir)
var/spread = 0
if(variance)
if(randomspread)
spread = round((rand() - 0.5) * variance)
else
spread = round((i / projectiles_per_shot - 0.5) * variance)
A.preparePixelProjectile(target, targloc, chassis.occupant, params, spread)
A.fire()
playsound(chassis, fire_sound, 50, 1)
sleep(max(0, projectile_delay))
chassis.log_message("Fired from [src.name], targeting [target].")
return 1
//Base energy weapon type
/obj/item/mecha_parts/mecha_equipment/weapon/energy
name = "general energy weapon"
firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect/energy
/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount()
return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot)
/obj/item/mecha_parts/mecha_equipment/weapon/energy/start_cooldown()
set_ready_state(0)
chassis.use_power(energy_drain*get_shot_amount())
addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown)
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
equip_cooldown = 8
name = "\improper CH-PS \"Immolator\" laser"
desc = "A weapon for combat exosuits. Shoots basic lasers."
icon_state = "mecha_laser"
origin_tech = "magnets=3;combat=3;engineering=3"
energy_drain = 30
projectile = /obj/item/projectile/beam/laser
fire_sound = 'sound/weapons/Laser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
equip_cooldown = 15
name = "\improper CH-LC \"Solaris\" laser cannon"
desc = "A weapon for combat exosuits. Shoots heavy lasers."
icon_state = "mecha_laser"
origin_tech = "magnets=4;combat=4;engineering=3"
energy_drain = 60
projectile = /obj/item/projectile/beam/laser/heavylaser
fire_sound = 'sound/weapons/lasercannonfire.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion
equip_cooldown = 20
name = "\improper MKIV ion heavy cannon"
desc = "A weapon for combat exosuits. Shoots technology-disabling ion beams. Don't catch yourself in the blast!"
icon_state = "mecha_ion"
origin_tech = "materials=4;combat=5;magnets=4"
energy_drain = 120
projectile = /obj/item/projectile/ion
fire_sound = 'sound/weapons/Laser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla
equip_cooldown = 35
name = "\improper MKI Tesla Cannon"
desc = "A weapon for combat exosuits. Fires bolts of electricity similar to the experimental tesla engine"
icon_state = "mecha_ion"
origin_tech = "materials=4;engineering=4;combat=6;magnets=6"
energy_drain = 500
projectile = /obj/item/projectile/energy/tesla/cannon
fire_sound = 'sound/magic/lightningbolt.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse
equip_cooldown = 30
name = "eZ-13 MK2 heavy pulse rifle"
desc = "A weapon for combat exosuits. Shoots powerful destructive blasts capable of demolishing obstacles."
icon_state = "mecha_pulse"
energy_drain = 120
origin_tech = "materials=3;combat=6;powerstorage=4"
projectile = /obj/item/projectile/beam/pulse/heavy
fire_sound = 'sound/weapons/marauder.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma
equip_cooldown = 10
name = "217-D Heavy Plasma Cutter"
desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles."
icon_state = "mecha_plasmacutter"
item_state = "plasmacutter"
energy_drain = 30
origin_tech = "materials=3;plasmatech=4;engineering=3"
projectile = /obj/item/projectile/plasma/adv/mech
fire_sound = 'sound/weapons/plasma_cutter.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/mecha/working/M)
if(..()) //combat mech
return 1
else if(M.equipment.len < M.max_equip && istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser
name = "\improper PBT \"Pacifier\" mounted taser"
desc = "A weapon for combat exosuits. Shoots non-lethal stunning electrodes."
icon_state = "mecha_taser"
origin_tech = "combat=3"
energy_drain = 20
equip_cooldown = 8
projectile = /obj/item/projectile/energy/electrode
fire_sound = 'sound/weapons/Taser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/honker
name = "\improper HoNkER BlAsT 5000"
desc = "Equipment for clown exosuits. Spreads fun and joy to everyone around. Honk!"
icon_state = "mecha_honker"
energy_drain = 200
equip_cooldown = 150
range = MELEE|RANGED
/obj/item/mecha_parts/mecha_equipment/weapon/honker/can_attach(obj/mecha/combat/honker/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target, params)
if(!action_checks(target))
return
playsound(chassis, 'sound/items/AirHorn.ogg', 100, 1)
chassis.occupant_message("<font color='red' size='5'>HONK</font>")
for(var/mob/living/carbon/M in ohearers(6, chassis))
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
continue
to_chat(M, "<font color='red' size='7'>HONK</font>")
M.SetSleeping(0)
M.stuttering += 20
M.adjustEarDamage(0, 30)
M.Weaken(3)
if(prob(30))
M.Stun(10)
M.Paralyse(4)
else
M.Jitter(500)
log_message("Honked from [src.name]. HONK!")
var/turf/T = get_turf(src)
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Mecha Honker in [ADMIN_COORDJMP(T)]",0,1)
log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Mecha Honker in [COORD(T)]")
return 1
//Base ballistic weapon type
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic
name = "general ballisic weapon"
fire_sound = 'sound/weapons/Gunshot.ogg'
var/projectiles
var/projectile_energy_cost
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_shot_amount()
return min(projectiles, projectiles_per_shot)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action_checks(target)
if(!..())
return 0
if(projectiles <= 0)
return 0
return 1
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info()
return "[..()] \[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - <a href='?src=\ref[src];rearm=1'>Rearm</a>":null]"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/rearm()
if(projectiles < initial(projectiles))
var/projectiles_to_add = initial(projectiles) - projectiles
while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
projectiles++
projectiles_to_add--
chassis.use_power(projectile_energy_cost)
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
log_message("Rearmed [src.name].")
return 1
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/needs_rearm()
. = !(projectiles > 0)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/Topic(href, href_list)
..()
if (href_list["rearm"])
src.rearm()
return
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action(atom/target)
if(..())
projectiles -= get_shot_amount()
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
return 1
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine
name = "\improper FNX-99 \"Hades\" Carbine"
desc = "A weapon for combat exosuits. Shoots incendiary bullets."
icon_state = "mecha_carbine"
origin_tech = "materials=4;combat=4"
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/incendiary/shell
projectiles = 24
projectile_energy_cost = 15
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
name = "\improper S.H.H. \"Quietus\" Carbine"
desc = "A weapon for combat exosuits. A mime invention, field tests have shown that targets cannot even scream before going down."
fire_sound = 'sound/weapons/Gunshot_silenced.ogg'
icon_state = "mecha_mime"
equip_cooldown = 30
projectile = /obj/item/projectile/bullet/mime
projectiles = 6
projectile_energy_cost = 50
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
name = "\improper LBX AC 10 \"Scattershot\""
desc = "A weapon for combat exosuits. Shoots a spread of pellets."
icon_state = "mecha_scatter"
origin_tech = "combat=4"
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/midbullet
projectiles = 40
projectile_energy_cost = 25
projectiles_per_shot = 4
variance = 25
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
name = "\improper Ultra AC 2"
desc = "A weapon for combat exosuits. Shoots a rapid, three shot burst."
icon_state = "mecha_uac2"
origin_tech = "combat=4"
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/weakbullet3
projectiles = 300
projectile_energy_cost = 20
projectiles_per_shot = 3
variance = 6
randomspread = 1
projectile_delay = 2
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
name = "\improper SRM-8 missile rack"
desc = "A weapon for combat exosuits. Shoots light explosive missiles."
icon_state = "mecha_missilerack"
origin_tech = "combat=5;materials=4;engineering=4"
projectile = /obj/item/projectile/bullet/srmrocket
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 8
projectile_energy_cost = 1000
equip_cooldown = 60
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher
var/missile_speed = 2
var/missile_range = 30
var/diags_first = FALSE
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/action(target)
if(!action_checks(target))
return
var/obj/O = new projectile(chassis.loc)
playsound(chassis, fire_sound, 50, 1)
log_message("Launched a [O.name] from [name], targeting [target].")
projectiles--
proj_init(O)
O.throw_at(target, missile_range, missile_speed, spin = 0, diagonals_first = diags_first)
return 1
//used for projectile initilisation (priming flashbang) and additional logging
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/proc/proj_init(var/obj/O)
return
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang
name = "\improper SGL-6 grenade launcher"
desc = "A weapon for combat exosuits. Launches primed flashbangs."
icon_state = "mecha_grenadelnchr"
origin_tech = "combat=4;engineering=4"
projectile = /obj/item/weapon/grenade/flashbang
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 6
missile_speed = 1.5
projectile_energy_cost = 800
equip_cooldown = 60
var/det_time = 20
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/weapon/grenade/flashbang/F)
var/turf/T = get_turf(src)
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] fired a [src] in [ADMIN_COORDJMP(T)]",0,1)
log_game("[key_name(chassis.occupant)] fired a [src] [COORD(T)]")
addtimer(CALLBACK(F, /obj/item/weapon/grenade/flashbang.proc/prime), det_time)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze
name = "\improper SOB-3 grenade launcher"
desc = "A weapon for combat exosuits. Launches primed clusterbangs. You monster."
origin_tech = "combat=4;materials=4"
projectiles = 3
projectile = /obj/item/weapon/grenade/clusterbuster
projectile_energy_cost = 1600 //getting off cheap seeing as this is 3 times the flashbangs held in the grenade launcher.
equip_cooldown = 90
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar
name = "banana mortar"
desc = "Equipment for clown exosuits. Launches banana peels."
icon_state = "mecha_bananamrtr"
projectile = /obj/item/weapon/grown/bananapeel
fire_sound = 'sound/items/bikehorn.ogg'
projectiles = 15
missile_speed = 1.5
projectile_energy_cost = 100
equip_cooldown = 20
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/can_attach(obj/mecha/combat/honker/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar
name = "mousetrap mortar"
desc = "Equipment for clown exosuits. Launches armed mousetraps."
icon_state = "mecha_mousetrapmrtr"
projectile = /obj/item/device/assembly/mousetrap/armed
fire_sound = 'sound/items/bikehorn.ogg'
projectiles = 15
missile_speed = 1.5
projectile_energy_cost = 100
equip_cooldown = 10
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/can_attach(obj/mecha/combat/honker/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/proj_init(var/obj/item/device/assembly/mousetrap/armed/M)
M.secured = 1
//Classic extending punching glove, but weaponised!
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove
name = "\improper Oingo Boingo Punch-face"
desc = "Equipment for clown exosuits. Delivers fun right to your face!"
icon_state = "mecha_punching_glove"
energy_drain = 250
equip_cooldown = 20
range = MELEE|RANGED
missile_range = 5
projectile = /obj/item/punching_glove
fire_sound = 'sound/items/bikehorn.ogg'
projectiles = 10
projectile_energy_cost = 500
diags_first = TRUE
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/can_attach(obj/mecha/combat/honker/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/action(target)
. = ..()
if(.)
chassis.occupant_message("<font color='red' size='5'>HONK</font>")
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/proj_init(obj/item/punching_glove/PG)
if(!istype(PG))
return
//has to be low sleep or it looks weird, the beam doesn't exist for very long so it's a non-issue
chassis.Beam(PG, icon_state = "chain", time = missile_range * 20, maxdistance = missile_range + 2, beam_sleep_time = 1)
/obj/item/punching_glove
name = "punching glove"
desc = "INCOMING HONKS"
throwforce = 35
icon_state = "punching_glove"
/obj/item/punching_glove/throw_impact(atom/hit_atom)
if(!..())
if(istype(hit_atom, /atom/movable))
var/atom/movable/AM = hit_atom
AM.throw_at(get_edge_target_turf(AM,get_dir(src, AM)), 7, 2)
qdel(src)
/obj/item/mecha_parts/mecha_equipment/weapon
name = "mecha weapon"
range = RANGED
origin_tech = "materials=3;combat=3"
var/projectile
var/fire_sound
var/projectiles_per_shot = 1
var/variance = 0
var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter
var/projectile_delay = 0
var/firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect //the visual effect appearing when the weapon is fired.
/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/mecha/combat/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/proc/get_shot_amount()
return projectiles_per_shot
/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target, params)
if(!action_checks(target))
return 0
var/turf/curloc = get_turf(chassis)
var/turf/targloc = get_turf(target)
if (!targloc || !istype(targloc) || !curloc)
return 0
if (targloc == curloc)
return 0
set_ready_state(0)
for(var/i=1 to get_shot_amount())
var/obj/item/projectile/A = new projectile(curloc)
A.firer = chassis.occupant
A.original = target
A.current = curloc
if(!A.suppressed && firing_effect_type)
new firing_effect_type(get_turf(src), chassis.dir)
var/spread = 0
if(variance)
if(randomspread)
spread = round((rand() - 0.5) * variance)
else
spread = round((i / projectiles_per_shot - 0.5) * variance)
A.preparePixelProjectile(target, targloc, chassis.occupant, params, spread)
A.fire()
playsound(chassis, fire_sound, 50, 1)
sleep(max(0, projectile_delay))
chassis.log_message("Fired from [src.name], targeting [target].")
return 1
//Base energy weapon type
/obj/item/mecha_parts/mecha_equipment/weapon/energy
name = "general energy weapon"
firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect/energy
/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount()
return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot)
/obj/item/mecha_parts/mecha_equipment/weapon/energy/start_cooldown()
set_ready_state(0)
chassis.use_power(energy_drain*get_shot_amount())
addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown)
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
equip_cooldown = 8
name = "\improper CH-PS \"Immolator\" laser"
desc = "A weapon for combat exosuits. Shoots basic lasers."
icon_state = "mecha_laser"
origin_tech = "magnets=3;combat=3;engineering=3"
energy_drain = 30
projectile = /obj/item/projectile/beam/laser
fire_sound = 'sound/weapons/Laser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
equip_cooldown = 15
name = "\improper CH-LC \"Solaris\" laser cannon"
desc = "A weapon for combat exosuits. Shoots heavy lasers."
icon_state = "mecha_laser"
origin_tech = "magnets=4;combat=4;engineering=3"
energy_drain = 60
projectile = /obj/item/projectile/beam/laser/heavylaser
fire_sound = 'sound/weapons/lasercannonfire.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion
equip_cooldown = 20
name = "\improper MKIV ion heavy cannon"
desc = "A weapon for combat exosuits. Shoots technology-disabling ion beams. Don't catch yourself in the blast!"
icon_state = "mecha_ion"
origin_tech = "materials=4;combat=5;magnets=4"
energy_drain = 120
projectile = /obj/item/projectile/ion
fire_sound = 'sound/weapons/Laser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla
equip_cooldown = 35
name = "\improper MKI Tesla Cannon"
desc = "A weapon for combat exosuits. Fires bolts of electricity similar to the experimental tesla engine"
icon_state = "mecha_ion"
origin_tech = "materials=4;engineering=4;combat=6;magnets=6"
energy_drain = 500
projectile = /obj/item/projectile/energy/tesla/cannon
fire_sound = 'sound/magic/lightningbolt.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse
equip_cooldown = 30
name = "eZ-13 MK2 heavy pulse rifle"
desc = "A weapon for combat exosuits. Shoots powerful destructive blasts capable of demolishing obstacles."
icon_state = "mecha_pulse"
energy_drain = 120
origin_tech = "materials=3;combat=6;powerstorage=4"
projectile = /obj/item/projectile/beam/pulse/heavy
fire_sound = 'sound/weapons/marauder.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma
equip_cooldown = 10
name = "217-D Heavy Plasma Cutter"
desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles."
icon_state = "mecha_plasmacutter"
item_state = "plasmacutter"
energy_drain = 30
origin_tech = "materials=3;plasmatech=4;engineering=3"
projectile = /obj/item/projectile/plasma/adv/mech
fire_sound = 'sound/weapons/plasma_cutter.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/mecha/working/M)
if(..()) //combat mech
return 1
else if(M.equipment.len < M.max_equip && istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser
name = "\improper PBT \"Pacifier\" mounted taser"
desc = "A weapon for combat exosuits. Shoots non-lethal stunning electrodes."
icon_state = "mecha_taser"
origin_tech = "combat=3"
energy_drain = 20
equip_cooldown = 8
projectile = /obj/item/projectile/energy/electrode
fire_sound = 'sound/weapons/Taser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/honker
name = "\improper HoNkER BlAsT 5000"
desc = "Equipment for clown exosuits. Spreads fun and joy to everyone around. Honk!"
icon_state = "mecha_honker"
energy_drain = 200
equip_cooldown = 150
range = MELEE|RANGED
/obj/item/mecha_parts/mecha_equipment/weapon/honker/can_attach(obj/mecha/combat/honker/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target, params)
if(!action_checks(target))
return
playsound(chassis, 'sound/items/AirHorn.ogg', 100, 1)
chassis.occupant_message("<font color='red' size='5'>HONK</font>")
for(var/mob/living/carbon/M in ohearers(6, chassis))
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
continue
to_chat(M, "<font color='red' size='7'>HONK</font>")
M.SetSleeping(0)
M.stuttering += 20
M.adjustEarDamage(0, 30)
M.Weaken(3)
if(prob(30))
M.Stun(10)
M.Paralyse(4)
else
M.Jitter(500)
log_message("Honked from [src.name]. HONK!")
var/turf/T = get_turf(src)
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Mecha Honker in [ADMIN_COORDJMP(T)]",0,1)
log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Mecha Honker in [COORD(T)]")
return 1
//Base ballistic weapon type
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic
name = "general ballisic weapon"
fire_sound = 'sound/weapons/Gunshot.ogg'
var/projectiles
var/projectile_energy_cost
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_shot_amount()
return min(projectiles, projectiles_per_shot)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action_checks(target)
if(!..())
return 0
if(projectiles <= 0)
return 0
return 1
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info()
return "[..()] \[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - <a href='?src=\ref[src];rearm=1'>Rearm</a>":null]"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/rearm()
if(projectiles < initial(projectiles))
var/projectiles_to_add = initial(projectiles) - projectiles
while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
projectiles++
projectiles_to_add--
chassis.use_power(projectile_energy_cost)
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
log_message("Rearmed [src.name].")
return 1
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/needs_rearm()
. = !(projectiles > 0)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/Topic(href, href_list)
..()
if (href_list["rearm"])
src.rearm()
return
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action(atom/target)
if(..())
projectiles -= get_shot_amount()
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
return 1
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine
name = "\improper FNX-99 \"Hades\" Carbine"
desc = "A weapon for combat exosuits. Shoots incendiary bullets."
icon_state = "mecha_carbine"
origin_tech = "materials=4;combat=4"
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/incendiary/shell
projectiles = 24
projectile_energy_cost = 15
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
name = "\improper S.H.H. \"Quietus\" Carbine"
desc = "A weapon for combat exosuits. A mime invention, field tests have shown that targets cannot even scream before going down."
fire_sound = 'sound/weapons/Gunshot_silenced.ogg'
icon_state = "mecha_mime"
equip_cooldown = 30
projectile = /obj/item/projectile/bullet/mime
projectiles = 6
projectile_energy_cost = 50
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
name = "\improper LBX AC 10 \"Scattershot\""
desc = "A weapon for combat exosuits. Shoots a spread of pellets."
icon_state = "mecha_scatter"
origin_tech = "combat=4"
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/midbullet
projectiles = 40
projectile_energy_cost = 25
projectiles_per_shot = 4
variance = 25
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
name = "\improper Ultra AC 2"
desc = "A weapon for combat exosuits. Shoots a rapid, three shot burst."
icon_state = "mecha_uac2"
origin_tech = "combat=4"
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/weakbullet3
projectiles = 300
projectile_energy_cost = 20
projectiles_per_shot = 3
variance = 6
randomspread = 1
projectile_delay = 2
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
name = "\improper SRM-8 missile rack"
desc = "A weapon for combat exosuits. Shoots light explosive missiles."
icon_state = "mecha_missilerack"
origin_tech = "combat=5;materials=4;engineering=4"
projectile = /obj/item/projectile/bullet/srmrocket
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 8
projectile_energy_cost = 1000
equip_cooldown = 60
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher
var/missile_speed = 2
var/missile_range = 30
var/diags_first = FALSE
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/action(target)
if(!action_checks(target))
return
var/obj/O = new projectile(chassis.loc)
playsound(chassis, fire_sound, 50, 1)
log_message("Launched a [O.name] from [name], targeting [target].")
projectiles--
proj_init(O)
O.throw_at(target, missile_range, missile_speed, spin = 0, diagonals_first = diags_first)
return 1
//used for projectile initilisation (priming flashbang) and additional logging
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/proc/proj_init(var/obj/O)
return
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang
name = "\improper SGL-6 grenade launcher"
desc = "A weapon for combat exosuits. Launches primed flashbangs."
icon_state = "mecha_grenadelnchr"
origin_tech = "combat=4;engineering=4"
projectile = /obj/item/weapon/grenade/flashbang
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 6
missile_speed = 1.5
projectile_energy_cost = 800
equip_cooldown = 60
var/det_time = 20
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/weapon/grenade/flashbang/F)
var/turf/T = get_turf(src)
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] fired a [src] in [ADMIN_COORDJMP(T)]",0,1)
log_game("[key_name(chassis.occupant)] fired a [src] [COORD(T)]")
addtimer(CALLBACK(F, /obj/item/weapon/grenade/flashbang.proc/prime), det_time)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze
name = "\improper SOB-3 grenade launcher"
desc = "A weapon for combat exosuits. Launches primed clusterbangs. You monster."
origin_tech = "combat=4;materials=4"
projectiles = 3
projectile = /obj/item/weapon/grenade/clusterbuster
projectile_energy_cost = 1600 //getting off cheap seeing as this is 3 times the flashbangs held in the grenade launcher.
equip_cooldown = 90
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar
name = "banana mortar"
desc = "Equipment for clown exosuits. Launches banana peels."
icon_state = "mecha_bananamrtr"
projectile = /obj/item/weapon/grown/bananapeel
fire_sound = 'sound/items/bikehorn.ogg'
projectiles = 15
missile_speed = 1.5
projectile_energy_cost = 100
equip_cooldown = 20
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/can_attach(obj/mecha/combat/honker/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar
name = "mousetrap mortar"
desc = "Equipment for clown exosuits. Launches armed mousetraps."
icon_state = "mecha_mousetrapmrtr"
projectile = /obj/item/device/assembly/mousetrap/armed
fire_sound = 'sound/items/bikehorn.ogg'
projectiles = 15
missile_speed = 1.5
projectile_energy_cost = 100
equip_cooldown = 10
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/can_attach(obj/mecha/combat/honker/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/proj_init(var/obj/item/device/assembly/mousetrap/armed/M)
M.secured = 1
//Classic extending punching glove, but weaponised!
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove
name = "\improper Oingo Boingo Punch-face"
desc = "Equipment for clown exosuits. Delivers fun right to your face!"
icon_state = "mecha_punching_glove"
energy_drain = 250
equip_cooldown = 20
range = MELEE|RANGED
missile_range = 5
projectile = /obj/item/punching_glove
fire_sound = 'sound/items/bikehorn.ogg'
projectiles = 10
projectile_energy_cost = 500
diags_first = TRUE
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/can_attach(obj/mecha/combat/honker/M)
if(..())
if(istype(M))
return 1
return 0
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/action(target)
. = ..()
if(.)
chassis.occupant_message("<font color='red' size='5'>HONK</font>")
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/proj_init(obj/item/punching_glove/PG)
if(!istype(PG))
return
//has to be low sleep or it looks weird, the beam doesn't exist for very long so it's a non-issue
chassis.Beam(PG, icon_state = "chain", time = missile_range * 20, maxdistance = missile_range + 2, beam_sleep_time = 1)
/obj/item/punching_glove
name = "punching glove"
desc = "INCOMING HONKS"
throwforce = 35
icon_state = "punching_glove"
/obj/item/punching_glove/throw_impact(atom/hit_atom)
if(!..())
if(istype(hit_atom, /atom/movable))
var/atom/movable/AM = hit_atom
AM.throw_at(get_edge_target_turf(AM,get_dir(src, AM)), 7, 2)
qdel(src)
+333 -333
View File
@@ -1,333 +1,333 @@
/obj/effect/landmark
name = "landmark"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x2"
anchored = 1
invisibility = INVISIBILITY_ABSTRACT
/obj/effect/landmark/New()
..()
tag = text("landmark*[]", name)
GLOB.landmarks_list += src
/obj/effect/landmark/Destroy()
GLOB.landmarks_list -= src
return ..()
/obj/effect/landmark/start
name = "start"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x"
anchored = 1
/obj/effect/landmark/start/New()
GLOB.start_landmarks_list += src
..()
if(name != "start")
tag = "start*[name]"
/obj/effect/landmark/start/Destroy()
GLOB.start_landmarks_list -= src
return ..()
// START LANDMARKS FOLLOW. Don't change the names unless
// you are refactoring shitty landmark code.
/obj/effect/landmark/start/assistant
name = "Assistant"
/obj/effect/landmark/start/janitor
name = "Janitor"
/obj/effect/landmark/start/cargo_technician
name = "Cargo Technician"
/obj/effect/landmark/start/bartender
name = "Bartender"
/obj/effect/landmark/start/clown
name = "Clown"
/obj/effect/landmark/start/mime
name = "Mime"
/obj/effect/landmark/start/quartermaster
name = "Quartermaster"
/obj/effect/landmark/start/atmospheric_technician
name = "Atmospheric Technician"
/obj/effect/landmark/start/cook
name = "Cook"
/obj/effect/landmark/start/shaft_miner
name = "Shaft Miner"
/obj/effect/landmark/start/security_officer
name = "Security Officer"
/obj/effect/landmark/start/botanist
name = "Botanist"
/obj/effect/landmark/start/head_of_security
name = "Head of Security"
/obj/effect/landmark/start/ai
name = "AI"
/obj/effect/landmark/start/captain
name = "Captain"
/obj/effect/landmark/start/detective
name = "Detective"
/obj/effect/landmark/start/warden
name = "Warden"
/obj/effect/landmark/start/chief_engineer
name = "Chief Engineer"
/obj/effect/landmark/start/cyborg
name = "Cyborg"
/obj/effect/landmark/start/head_of_personnel
name = "Head of Personnel"
/obj/effect/landmark/start/librarian
name = "Curator"
/obj/effect/landmark/start/lawyer
name = "Lawyer"
/obj/effect/landmark/start/station_engineer
name = "Station Engineer"
/obj/effect/landmark/start/medical_doctor
name = "Medical Doctor"
/obj/effect/landmark/start/scientist
name = "Scientist"
/obj/effect/landmark/start/chemist
name = "Chemist"
/obj/effect/landmark/start/roboticist
name = "Roboticist"
/obj/effect/landmark/start/research_director
name = "Research Director"
/obj/effect/landmark/start/geneticist
name = "Geneticist"
/obj/effect/landmark/start/chief_medical_officer
name = "Chief Medical Officer"
/obj/effect/landmark/start/virologist
name = "Virologist"
/obj/effect/landmark/start/chaplain
name = "Chaplain"
//Department Security spawns
/obj/effect/landmark/start/depsec
name = "department_sec"
/obj/effect/landmark/start/depsec/New()
..()
GLOB.department_security_spawns += src
/obj/effect/landmark/start/depsec/Destroy()
GLOB.department_security_spawns -= src
return ..()
/obj/effect/landmark/start/depsec/supply
name = "supply_sec"
/obj/effect/landmark/start/depsec/medical
name = "medical_sec"
/obj/effect/landmark/start/depsec/engineering
name = "engineering_sec"
/obj/effect/landmark/start/depsec/science
name = "science_sec"
/obj/effect/landmark/start/wizard
name = "wizard"
/obj/effect/landmark/start/wizard/Initialize(mapload)
..()
GLOB.wizardstart += loc
qdel(src)
/obj/effect/landmark/start/new_player
name = "New Player"
// Must be on New() rather than Initialize, because players will
// join before SSatom initializes everything.
/obj/effect/landmark/start/new_player/New(loc)
..()
GLOB.newplayer_start += loc
/obj/effect/landmark/start/new_player/Initialize(mapload)
..()
qdel(src)
/obj/effect/landmark/latejoin
name = "JoinLate"
/obj/effect/landmark/latejoin/Initialize(mapload)
..()
GLOB.latejoin += loc
qdel(src)
// carp.
/obj/effect/landmark/carpspawn
name = "carpspawn"
// lightsout.
/obj/effect/landmark/lightsout
name = "lightsout"
// observer-start.
/obj/effect/landmark/observer_start
name = "Observer-Start"
// revenant spawn.
/obj/effect/landmark/revenantspawn
name = "revnantspawn"
// triple ais.
/obj/effect/landmark/tripai
name = "tripai"
// marauder entry (XXX WTF IS MAURADER ENTRY???)
/obj/effect/landmark/marauder_entry
name = "Marauder Entry"
// syndicate breach area (XXX I DON'T KNOW WHAT THIS IS EITHER)
/obj/effect/landmark/syndicate_breach_area
name = "Syndicate Breach Area"
// teleport scroll landmark, XXX DOES THIS DO ANYTHING?
/obj/effect/landmark/teleport_scroll
name = "Teleport-Scroll"
/obj/effect/landmark/syndicate_spawn
name = "Syndicate-Spawn"
// xenos.
/obj/effect/landmark/xeno_spawn
name = "xeno_spawn"
/obj/effect/landmark/xeno_spawn/Initialize(mapload)
..()
GLOB.xeno_spawn += loc
qdel(src)
// blobs.
/obj/effect/landmark/blobstart
name = "blobstart"
/obj/effect/landmark/blobstart/Initialize(mapload)
..()
GLOB.blobstart += loc
qdel(src)
/obj/effect/landmark/secequipment
name = "secequipment"
/obj/effect/landmark/secequipment/Initialize(mapload)
..()
GLOB.secequipment += loc
qdel(src)
/obj/effect/landmark/prisonwarp
name = "prisonwarp"
/obj/effect/landmark/prisonwarp/Initialize(mapload)
..()
GLOB.prisonwarp += loc
qdel(src)
/obj/effect/landmark/ert_spawn
name = "Emergencyresponseteam"
/obj/effect/landmark/ert_spawn/Initialize(mapload)
..()
GLOB.emergencyresponseteamspawn += loc
qdel(src)
/obj/effect/landmark/holding_facility
name = "Holding Facility"
/obj/effect/landmark/holding_facility/Initialize(mapload)
..()
GLOB.holdingfacility += loc
qdel(src)
/obj/effect/landmark/thunderdome/observe
name = "tdomeobserve"
/obj/effect/landmark/thunderdome/observe/Initialize(mapload)
..()
GLOB.tdomeobserve += loc
qdel(src)
/obj/effect/landmark/thunderdome/one
name = "tdome1"
/obj/effect/landmark/thunderdome/one/Initialize(mapload)
..()
GLOB.tdome1 += loc
qdel(src)
/obj/effect/landmark/thunderdome/two
name = "tdome2"
/obj/effect/landmark/thunderdome/two/Initialize(mapload)
..()
GLOB.tdome2 += loc
qdel(src)
/obj/effect/landmark/thunderdome/admin
name = "tdomeadmin"
/obj/effect/landmark/thunderdome/admin/Initialize(mapload)
..()
GLOB.tdomeadmin += loc
qdel(src)
//generic event spawns
/obj/effect/landmark/event_spawn
name = "generic event spawn"
icon_state = "x4"
/obj/effect/landmark/event_spawn/New()
..()
GLOB.generic_event_spawns += src
/obj/effect/landmark/event_spawn/Destroy()
GLOB.generic_event_spawns -= src
return ..()
/obj/effect/landmark/ruin
var/datum/map_template/ruin/ruin_template
/obj/effect/landmark/ruin/New(loc, my_ruin_template)
name = "ruin_[GLOB.ruin_landmarks.len + 1]"
..(loc)
ruin_template = my_ruin_template
GLOB.ruin_landmarks |= src
/obj/effect/landmark/ruin/Destroy()
GLOB.ruin_landmarks -= src
ruin_template = null
. = ..()
/obj/effect/landmark
name = "landmark"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x2"
anchored = 1
invisibility = INVISIBILITY_ABSTRACT
/obj/effect/landmark/New()
..()
tag = text("landmark*[]", name)
GLOB.landmarks_list += src
/obj/effect/landmark/Destroy()
GLOB.landmarks_list -= src
return ..()
/obj/effect/landmark/start
name = "start"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x"
anchored = 1
/obj/effect/landmark/start/New()
GLOB.start_landmarks_list += src
..()
if(name != "start")
tag = "start*[name]"
/obj/effect/landmark/start/Destroy()
GLOB.start_landmarks_list -= src
return ..()
// START LANDMARKS FOLLOW. Don't change the names unless
// you are refactoring shitty landmark code.
/obj/effect/landmark/start/assistant
name = "Assistant"
/obj/effect/landmark/start/janitor
name = "Janitor"
/obj/effect/landmark/start/cargo_technician
name = "Cargo Technician"
/obj/effect/landmark/start/bartender
name = "Bartender"
/obj/effect/landmark/start/clown
name = "Clown"
/obj/effect/landmark/start/mime
name = "Mime"
/obj/effect/landmark/start/quartermaster
name = "Quartermaster"
/obj/effect/landmark/start/atmospheric_technician
name = "Atmospheric Technician"
/obj/effect/landmark/start/cook
name = "Cook"
/obj/effect/landmark/start/shaft_miner
name = "Shaft Miner"
/obj/effect/landmark/start/security_officer
name = "Security Officer"
/obj/effect/landmark/start/botanist
name = "Botanist"
/obj/effect/landmark/start/head_of_security
name = "Head of Security"
/obj/effect/landmark/start/ai
name = "AI"
/obj/effect/landmark/start/captain
name = "Captain"
/obj/effect/landmark/start/detective
name = "Detective"
/obj/effect/landmark/start/warden
name = "Warden"
/obj/effect/landmark/start/chief_engineer
name = "Chief Engineer"
/obj/effect/landmark/start/cyborg
name = "Cyborg"
/obj/effect/landmark/start/head_of_personnel
name = "Head of Personnel"
/obj/effect/landmark/start/librarian
name = "Curator"
/obj/effect/landmark/start/lawyer
name = "Lawyer"
/obj/effect/landmark/start/station_engineer
name = "Station Engineer"
/obj/effect/landmark/start/medical_doctor
name = "Medical Doctor"
/obj/effect/landmark/start/scientist
name = "Scientist"
/obj/effect/landmark/start/chemist
name = "Chemist"
/obj/effect/landmark/start/roboticist
name = "Roboticist"
/obj/effect/landmark/start/research_director
name = "Research Director"
/obj/effect/landmark/start/geneticist
name = "Geneticist"
/obj/effect/landmark/start/chief_medical_officer
name = "Chief Medical Officer"
/obj/effect/landmark/start/virologist
name = "Virologist"
/obj/effect/landmark/start/chaplain
name = "Chaplain"
//Department Security spawns
/obj/effect/landmark/start/depsec
name = "department_sec"
/obj/effect/landmark/start/depsec/New()
..()
GLOB.department_security_spawns += src
/obj/effect/landmark/start/depsec/Destroy()
GLOB.department_security_spawns -= src
return ..()
/obj/effect/landmark/start/depsec/supply
name = "supply_sec"
/obj/effect/landmark/start/depsec/medical
name = "medical_sec"
/obj/effect/landmark/start/depsec/engineering
name = "engineering_sec"
/obj/effect/landmark/start/depsec/science
name = "science_sec"
/obj/effect/landmark/start/wizard
name = "wizard"
/obj/effect/landmark/start/wizard/Initialize(mapload)
..()
GLOB.wizardstart += loc
qdel(src)
/obj/effect/landmark/start/new_player
name = "New Player"
// Must be on New() rather than Initialize, because players will
// join before SSatom initializes everything.
/obj/effect/landmark/start/new_player/New(loc)
..()
GLOB.newplayer_start += loc
/obj/effect/landmark/start/new_player/Initialize(mapload)
..()
qdel(src)
/obj/effect/landmark/latejoin
name = "JoinLate"
/obj/effect/landmark/latejoin/Initialize(mapload)
..()
GLOB.latejoin += loc
qdel(src)
// carp.
/obj/effect/landmark/carpspawn
name = "carpspawn"
// lightsout.
/obj/effect/landmark/lightsout
name = "lightsout"
// observer-start.
/obj/effect/landmark/observer_start
name = "Observer-Start"
// revenant spawn.
/obj/effect/landmark/revenantspawn
name = "revnantspawn"
// triple ais.
/obj/effect/landmark/tripai
name = "tripai"
// marauder entry (XXX WTF IS MAURADER ENTRY???)
/obj/effect/landmark/marauder_entry
name = "Marauder Entry"
// syndicate breach area (XXX I DON'T KNOW WHAT THIS IS EITHER)
/obj/effect/landmark/syndicate_breach_area
name = "Syndicate Breach Area"
// teleport scroll landmark, XXX DOES THIS DO ANYTHING?
/obj/effect/landmark/teleport_scroll
name = "Teleport-Scroll"
/obj/effect/landmark/syndicate_spawn
name = "Syndicate-Spawn"
// xenos.
/obj/effect/landmark/xeno_spawn
name = "xeno_spawn"
/obj/effect/landmark/xeno_spawn/Initialize(mapload)
..()
GLOB.xeno_spawn += loc
qdel(src)
// blobs.
/obj/effect/landmark/blobstart
name = "blobstart"
/obj/effect/landmark/blobstart/Initialize(mapload)
..()
GLOB.blobstart += loc
qdel(src)
/obj/effect/landmark/secequipment
name = "secequipment"
/obj/effect/landmark/secequipment/Initialize(mapload)
..()
GLOB.secequipment += loc
qdel(src)
/obj/effect/landmark/prisonwarp
name = "prisonwarp"
/obj/effect/landmark/prisonwarp/Initialize(mapload)
..()
GLOB.prisonwarp += loc
qdel(src)
/obj/effect/landmark/ert_spawn
name = "Emergencyresponseteam"
/obj/effect/landmark/ert_spawn/Initialize(mapload)
..()
GLOB.emergencyresponseteamspawn += loc
qdel(src)
/obj/effect/landmark/holding_facility
name = "Holding Facility"
/obj/effect/landmark/holding_facility/Initialize(mapload)
..()
GLOB.holdingfacility += loc
qdel(src)
/obj/effect/landmark/thunderdome/observe
name = "tdomeobserve"
/obj/effect/landmark/thunderdome/observe/Initialize(mapload)
..()
GLOB.tdomeobserve += loc
qdel(src)
/obj/effect/landmark/thunderdome/one
name = "tdome1"
/obj/effect/landmark/thunderdome/one/Initialize(mapload)
..()
GLOB.tdome1 += loc
qdel(src)
/obj/effect/landmark/thunderdome/two
name = "tdome2"
/obj/effect/landmark/thunderdome/two/Initialize(mapload)
..()
GLOB.tdome2 += loc
qdel(src)
/obj/effect/landmark/thunderdome/admin
name = "tdomeadmin"
/obj/effect/landmark/thunderdome/admin/Initialize(mapload)
..()
GLOB.tdomeadmin += loc
qdel(src)
//generic event spawns
/obj/effect/landmark/event_spawn
name = "generic event spawn"
icon_state = "x4"
/obj/effect/landmark/event_spawn/New()
..()
GLOB.generic_event_spawns += src
/obj/effect/landmark/event_spawn/Destroy()
GLOB.generic_event_spawns -= src
return ..()
/obj/effect/landmark/ruin
var/datum/map_template/ruin/ruin_template
/obj/effect/landmark/ruin/New(loc, my_ruin_template)
name = "ruin_[GLOB.ruin_landmarks.len + 1]"
..(loc)
ruin_template = my_ruin_template
GLOB.ruin_landmarks |= src
/obj/effect/landmark/ruin/Destroy()
GLOB.ruin_landmarks -= src
ruin_template = null
. = ..()
+3 -3
View File
@@ -183,9 +183,9 @@
if(!T)
return
if(triggerer_only && ismob(A))
var/mob/B = A
B.playsound_local(T, sound, volume, freq_vary)
if(triggerer_only && ismob(A))
var/mob/B = A
B.playsound_local(T, sound, volume, freq_vary)
else
playsound(T, sound, volume, freq_vary, extra_range)
File diff suppressed because it is too large Load Diff
+403 -403
View File
@@ -1,403 +1,403 @@
// robot_upgrades.dm
// Contains various borg upgrades.
/obj/item/borg/upgrade
name = "borg upgrade module."
desc = "Protected by FRM."
icon = 'icons/obj/module.dmi'
icon_state = "cyborg_upgrade"
origin_tech = "programming=2"
var/locked = 0
var/installed = 0
var/require_module = 0
var/module_type = null
// if true, is not stored in the robot to be ejected
// if module is reset
var/one_use = FALSE
/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/R)
if(R.stat == DEAD)
to_chat(usr, "<span class='notice'>[src] will not function on a deceased cyborg.</span>")
return 1
if(module_type && !istype(R.module, module_type))
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
to_chat(usr, "There's no mounting point for the module!")
return 1
/obj/item/borg/upgrade/rename
name = "cyborg reclassification board"
desc = "Used to rename a cyborg."
icon_state = "cyborg_upgrade1"
var/heldname = ""
one_use = TRUE
/obj/item/borg/upgrade/rename/attack_self(mob/user)
heldname = stripped_input(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN)
/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R)
if(..())
return
var/oldname = R.real_name
R.custom_name = heldname
R.updatename()
if(oldname == R.real_name)
R.notify_ai(RENAME, oldname, R.real_name)
return 1
/obj/item/borg/upgrade/restart
name = "cyborg emergency reboot module"
desc = "Used to force a reboot of a disabled-but-repaired cyborg, bringing it back online."
icon_state = "cyborg_upgrade1"
one_use = TRUE
/obj/item/borg/upgrade/restart/action(mob/living/silicon/robot/R)
if(R.health < 0)
to_chat(usr, "<span class='warning'>You have to repair the cyborg before using this module!</span>")
return 0
if(R.mind)
R.mind.grab_ghost()
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
R.revive()
return 1
/obj/item/borg/upgrade/vtec
name = "cyborg VTEC module"
desc = "Used to kick in a cyborg's VTEC systems, increasing their speed."
icon_state = "cyborg_upgrade2"
require_module = 1
origin_tech = "engineering=4;materials=5;programming=4"
/obj/item/borg/upgrade/vtec/action(mob/living/silicon/robot/R)
if(..())
return
if(R.speed < 0)
to_chat(R, "<span class='notice'>A VTEC unit is already installed!</span>")
to_chat(usr, "<span class='notice'>There's no room for another VTEC unit!</span>")
return
R.speed = -2 // Gotta go fast.
return 1
/obj/item/borg/upgrade/disablercooler
name = "cyborg rapid disabler cooling module"
desc = "Used to cool a mounted disabler, increasing the potential current in it and thus its recharge rate."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/security
origin_tech = "engineering=4;powerstorage=4;combat=4"
/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R)
if(..())
return
var/obj/item/weapon/gun/energy/disabler/cyborg/T = locate() in R.module.modules
if(!T)
to_chat(usr, "<span class='notice'>There's no disabler in this unit!</span>")
return
if(T.charge_delay <= 2)
to_chat(R, "<span class='notice'>A cooling unit is already installed!</span>")
to_chat(usr, "<span class='notice'>There's no room for another cooling unit!</span>")
return
T.charge_delay = max(2 , T.charge_delay - 4)
return 1
/obj/item/borg/upgrade/thrusters
name = "ion thruster upgrade"
desc = "A energy-operated thruster system for cyborgs."
icon_state = "cyborg_upgrade3"
origin_tech = "engineering=4;powerstorage=4"
/obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/R)
if(..())
return
if(R.ionpulse)
to_chat(usr, "<span class='notice'>This unit already has ion thrusters installed!</span>")
return
R.ionpulse = TRUE
return 1
/obj/item/borg/upgrade/ddrill
name = "mining cyborg diamond drill"
desc = "A diamond drill replacement for the mining module's standard drill."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/miner
origin_tech = "engineering=4;materials=5"
/obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/pickaxe/drill/cyborg/D in R.module)
R.module.remove_module(D, TRUE)
for(var/obj/item/weapon/shovel/S in R.module)
R.module.remove_module(S, TRUE)
var/obj/item/weapon/pickaxe/drill/cyborg/diamond/DD = new /obj/item/weapon/pickaxe/drill/cyborg/diamond(R.module)
R.module.basic_modules += DD
R.module.add_module(DD, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/soh
name = "mining cyborg satchel of holding"
desc = "A satchel of holding replacement for mining cyborg's ore satchel module."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/miner
origin_tech = "engineering=4;materials=4;bluespace=4"
/obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/storage/bag/ore/cyborg/S in R.module)
R.module.remove_module(S, TRUE)
var/obj/item/weapon/storage/bag/ore/holding/H = new /obj/item/weapon/storage/bag/ore/holding(R.module)
R.module.basic_modules += H
R.module.add_module(H, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/syndicate
name = "illegal equipment module"
desc = "Unlocks the hidden, deadlier functions of a cyborg"
icon_state = "cyborg_upgrade3"
require_module = 1
origin_tech = "combat=4;syndicate=1"
/obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R)
if(..())
return
if(R.emagged)
return
R.SetEmagged(1)
return 1
/obj/item/borg/upgrade/lavaproof
name = "mining cyborg lavaproof tracks"
desc = "An upgrade kit to apply specialized coolant systems and insulation layers to mining cyborg tracks, enabling them to withstand exposure to molten rock."
icon_state = "ash_plating"
resistance_flags = LAVA_PROOF | FIRE_PROOF
require_module = 1
module_type = /obj/item/weapon/robot_module/miner
origin_tech = "engineering=4;materials=4;plasmatech=4"
/obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R)
if(..())
return
R.weather_immunities += "lava"
return 1
/obj/item/borg/upgrade/selfrepair
name = "self-repair module"
desc = "This module will repair the cyborg over time."
icon_state = "cyborg_upgrade5"
require_module = 1
var/repair_amount = -1
var/repair_tick = 1
var/msg_cooldown = 0
var/on = 0
var/powercost = 10
var/mob/living/silicon/robot/cyborg
var/datum/action/toggle_action
/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R)
if(..())
return
var/obj/item/borg/upgrade/selfrepair/U = locate() in R
if(U)
to_chat(usr, "<span class='warning'>This unit is already equipped with a self-repair module.</span>")
return 0
cyborg = R
icon_state = "selfrepair_off"
toggle_action = new /datum/action/item_action/toggle(src)
toggle_action.Grant(R)
return 1
/obj/item/borg/upgrade/selfrepair/dropped()
addtimer(CALLBACK(src, .proc/check_dropped), 1)
/obj/item/borg/upgrade/selfrepair/proc/check_dropped()
if(loc != cyborg)
toggle_action.Remove(cyborg)
QDEL_NULL(toggle_action)
cyborg = null
deactivate()
/obj/item/borg/upgrade/selfrepair/ui_action_click()
on = !on
if(on)
to_chat(cyborg, "<span class='notice'>You activate the self-repair module.</span>")
START_PROCESSING(SSobj, src)
else
to_chat(cyborg, "<span class='notice'>You deactivate the self-repair module.</span>")
STOP_PROCESSING(SSobj, src)
update_icon()
/obj/item/borg/upgrade/selfrepair/update_icon()
if(cyborg)
icon_state = "selfrepair_[on ? "on" : "off"]"
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
else
icon_state = "cyborg_upgrade5"
/obj/item/borg/upgrade/selfrepair/proc/deactivate()
STOP_PROCESSING(SSobj, src)
on = FALSE
update_icon()
/obj/item/borg/upgrade/selfrepair/process()
if(!repair_tick)
repair_tick = 1
return
if(cyborg && (cyborg.stat != DEAD) && on)
if(!cyborg.cell)
to_chat(cyborg, "<span class='warning'>Self-repair module deactivated. Please, insert the power cell.</span>")
deactivate()
return
if(cyborg.cell.charge < powercost * 2)
to_chat(cyborg, "<span class='warning'>Self-repair module deactivated. Please recharge.</span>")
deactivate()
return
if(cyborg.health < cyborg.maxHealth)
if(cyborg.health < 0)
repair_amount = -2.5
powercost = 30
else
repair_amount = -1
powercost = 10
cyborg.adjustBruteLoss(repair_amount)
cyborg.adjustFireLoss(repair_amount)
cyborg.updatehealth()
cyborg.cell.use(powercost)
else
cyborg.cell.use(5)
repair_tick = 0
if((world.time - 2000) > msg_cooldown )
var/msgmode = "standby"
if(cyborg.health < 0)
msgmode = "critical"
else if(cyborg.health < cyborg.maxHealth)
msgmode = "normal"
to_chat(cyborg, "<span class='notice'>Self-repair is active in <span class='boldnotice'>[msgmode]</span> mode.</span>")
msg_cooldown = world.time
else
deactivate()
/obj/item/borg/upgrade/hypospray
name = "medical cyborg hypospray advanced synthesiser"
desc = "An upgrade to the Medical module cyborg's hypospray, allowing it \
to produce more advanced and complex medical reagents."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/medical
origin_tech = null
var/list/additional_reagents = list()
/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/reagent_containers/borghypo/H in R.module)
if(H.accepts_reagent_upgrades)
for(var/re in additional_reagents)
H.add_reagent(re)
return 1
/obj/item/borg/upgrade/hypospray/expanded
name = "medical cyborg expanded hypospray"
desc = "An upgrade to the Medical module's hypospray, allowing it \
to treat a wider range of conditions and problems."
additional_reagents = list("mannitol", "oculine", "inacusiate",
"mutadone", "haloperidol")
origin_tech = "programming=5;engineering=4;biotech=5"
/obj/item/borg/upgrade/hypospray/high_strength
name = "medical cyborg high-strength hypospray"
desc = "An upgrade to the Medical module's hypospray, containing \
stronger versions of existing chemicals."
additional_reagents = list("oxandrolone", "sal_acid", "rezadone",
"pen_acid")
origin_tech = "programming=5;engineering=5;biotech=6"
/obj/item/borg/upgrade/piercing_hypospray
name = "cyborg piercing hypospray"
desc = "An upgrade to a cyborg's hypospray, allowing it to \
pierce armor and thick material."
origin_tech = "materials=5;engineering=7;combat=3"
icon_state = "cyborg_upgrade3"
/obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/R)
if(..())
return
var/found_hypo = FALSE
for(var/obj/item/weapon/reagent_containers/borghypo/H in R.module)
H.bypass_protection = TRUE
found_hypo = TRUE
if(!found_hypo)
return
return 1
/obj/item/borg/upgrade/defib
name = "medical cyborg defibrillator"
desc = "An upgrade to the Medical module, installing a builtin \
defibrillator, for on the scene revival."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/medical
origin_tech = "programming=4;engineering=6;materials=5;powerstorage=5;biotech=5"
/obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/R)
if(..())
return
var/obj/item/weapon/twohanded/shockpaddles/cyborg/S = new(R.module)
R.module.basic_modules += S
R.module.add_module(S, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/ai
name = "B.O.R.I.S. module"
desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI."
icon_state = "boris"
origin_tech = "engineering=4;magnets=4;programming=4"
/obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R)
if(..())
return
if(R.shell)
to_chat(usr, "<span class='warning'>This unit is already an AI shell!</span>")
return
if(R.key) //You cannot replace a player unless the key is completely removed.
to_chat(usr, "<span class='warning'>Intelligence patterns detected in this [R.braintype]. Aborting.</span>")
return
R.make_shell(src)
return TRUE
// robot_upgrades.dm
// Contains various borg upgrades.
/obj/item/borg/upgrade
name = "borg upgrade module."
desc = "Protected by FRM."
icon = 'icons/obj/module.dmi'
icon_state = "cyborg_upgrade"
origin_tech = "programming=2"
var/locked = 0
var/installed = 0
var/require_module = 0
var/module_type = null
// if true, is not stored in the robot to be ejected
// if module is reset
var/one_use = FALSE
/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/R)
if(R.stat == DEAD)
to_chat(usr, "<span class='notice'>[src] will not function on a deceased cyborg.</span>")
return 1
if(module_type && !istype(R.module, module_type))
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
to_chat(usr, "There's no mounting point for the module!")
return 1
/obj/item/borg/upgrade/rename
name = "cyborg reclassification board"
desc = "Used to rename a cyborg."
icon_state = "cyborg_upgrade1"
var/heldname = ""
one_use = TRUE
/obj/item/borg/upgrade/rename/attack_self(mob/user)
heldname = stripped_input(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN)
/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R)
if(..())
return
var/oldname = R.real_name
R.custom_name = heldname
R.updatename()
if(oldname == R.real_name)
R.notify_ai(RENAME, oldname, R.real_name)
return 1
/obj/item/borg/upgrade/restart
name = "cyborg emergency reboot module"
desc = "Used to force a reboot of a disabled-but-repaired cyborg, bringing it back online."
icon_state = "cyborg_upgrade1"
one_use = TRUE
/obj/item/borg/upgrade/restart/action(mob/living/silicon/robot/R)
if(R.health < 0)
to_chat(usr, "<span class='warning'>You have to repair the cyborg before using this module!</span>")
return 0
if(R.mind)
R.mind.grab_ghost()
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
R.revive()
return 1
/obj/item/borg/upgrade/vtec
name = "cyborg VTEC module"
desc = "Used to kick in a cyborg's VTEC systems, increasing their speed."
icon_state = "cyborg_upgrade2"
require_module = 1
origin_tech = "engineering=4;materials=5;programming=4"
/obj/item/borg/upgrade/vtec/action(mob/living/silicon/robot/R)
if(..())
return
if(R.speed < 0)
to_chat(R, "<span class='notice'>A VTEC unit is already installed!</span>")
to_chat(usr, "<span class='notice'>There's no room for another VTEC unit!</span>")
return
R.speed = -2 // Gotta go fast.
return 1
/obj/item/borg/upgrade/disablercooler
name = "cyborg rapid disabler cooling module"
desc = "Used to cool a mounted disabler, increasing the potential current in it and thus its recharge rate."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/security
origin_tech = "engineering=4;powerstorage=4;combat=4"
/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R)
if(..())
return
var/obj/item/weapon/gun/energy/disabler/cyborg/T = locate() in R.module.modules
if(!T)
to_chat(usr, "<span class='notice'>There's no disabler in this unit!</span>")
return
if(T.charge_delay <= 2)
to_chat(R, "<span class='notice'>A cooling unit is already installed!</span>")
to_chat(usr, "<span class='notice'>There's no room for another cooling unit!</span>")
return
T.charge_delay = max(2 , T.charge_delay - 4)
return 1
/obj/item/borg/upgrade/thrusters
name = "ion thruster upgrade"
desc = "A energy-operated thruster system for cyborgs."
icon_state = "cyborg_upgrade3"
origin_tech = "engineering=4;powerstorage=4"
/obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/R)
if(..())
return
if(R.ionpulse)
to_chat(usr, "<span class='notice'>This unit already has ion thrusters installed!</span>")
return
R.ionpulse = TRUE
return 1
/obj/item/borg/upgrade/ddrill
name = "mining cyborg diamond drill"
desc = "A diamond drill replacement for the mining module's standard drill."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/miner
origin_tech = "engineering=4;materials=5"
/obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/pickaxe/drill/cyborg/D in R.module)
R.module.remove_module(D, TRUE)
for(var/obj/item/weapon/shovel/S in R.module)
R.module.remove_module(S, TRUE)
var/obj/item/weapon/pickaxe/drill/cyborg/diamond/DD = new /obj/item/weapon/pickaxe/drill/cyborg/diamond(R.module)
R.module.basic_modules += DD
R.module.add_module(DD, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/soh
name = "mining cyborg satchel of holding"
desc = "A satchel of holding replacement for mining cyborg's ore satchel module."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/miner
origin_tech = "engineering=4;materials=4;bluespace=4"
/obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/storage/bag/ore/cyborg/S in R.module)
R.module.remove_module(S, TRUE)
var/obj/item/weapon/storage/bag/ore/holding/H = new /obj/item/weapon/storage/bag/ore/holding(R.module)
R.module.basic_modules += H
R.module.add_module(H, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/syndicate
name = "illegal equipment module"
desc = "Unlocks the hidden, deadlier functions of a cyborg"
icon_state = "cyborg_upgrade3"
require_module = 1
origin_tech = "combat=4;syndicate=1"
/obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R)
if(..())
return
if(R.emagged)
return
R.SetEmagged(1)
return 1
/obj/item/borg/upgrade/lavaproof
name = "mining cyborg lavaproof tracks"
desc = "An upgrade kit to apply specialized coolant systems and insulation layers to mining cyborg tracks, enabling them to withstand exposure to molten rock."
icon_state = "ash_plating"
resistance_flags = LAVA_PROOF | FIRE_PROOF
require_module = 1
module_type = /obj/item/weapon/robot_module/miner
origin_tech = "engineering=4;materials=4;plasmatech=4"
/obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R)
if(..())
return
R.weather_immunities += "lava"
return 1
/obj/item/borg/upgrade/selfrepair
name = "self-repair module"
desc = "This module will repair the cyborg over time."
icon_state = "cyborg_upgrade5"
require_module = 1
var/repair_amount = -1
var/repair_tick = 1
var/msg_cooldown = 0
var/on = 0
var/powercost = 10
var/mob/living/silicon/robot/cyborg
var/datum/action/toggle_action
/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R)
if(..())
return
var/obj/item/borg/upgrade/selfrepair/U = locate() in R
if(U)
to_chat(usr, "<span class='warning'>This unit is already equipped with a self-repair module.</span>")
return 0
cyborg = R
icon_state = "selfrepair_off"
toggle_action = new /datum/action/item_action/toggle(src)
toggle_action.Grant(R)
return 1
/obj/item/borg/upgrade/selfrepair/dropped()
addtimer(CALLBACK(src, .proc/check_dropped), 1)
/obj/item/borg/upgrade/selfrepair/proc/check_dropped()
if(loc != cyborg)
toggle_action.Remove(cyborg)
QDEL_NULL(toggle_action)
cyborg = null
deactivate()
/obj/item/borg/upgrade/selfrepair/ui_action_click()
on = !on
if(on)
to_chat(cyborg, "<span class='notice'>You activate the self-repair module.</span>")
START_PROCESSING(SSobj, src)
else
to_chat(cyborg, "<span class='notice'>You deactivate the self-repair module.</span>")
STOP_PROCESSING(SSobj, src)
update_icon()
/obj/item/borg/upgrade/selfrepair/update_icon()
if(cyborg)
icon_state = "selfrepair_[on ? "on" : "off"]"
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
else
icon_state = "cyborg_upgrade5"
/obj/item/borg/upgrade/selfrepair/proc/deactivate()
STOP_PROCESSING(SSobj, src)
on = FALSE
update_icon()
/obj/item/borg/upgrade/selfrepair/process()
if(!repair_tick)
repair_tick = 1
return
if(cyborg && (cyborg.stat != DEAD) && on)
if(!cyborg.cell)
to_chat(cyborg, "<span class='warning'>Self-repair module deactivated. Please, insert the power cell.</span>")
deactivate()
return
if(cyborg.cell.charge < powercost * 2)
to_chat(cyborg, "<span class='warning'>Self-repair module deactivated. Please recharge.</span>")
deactivate()
return
if(cyborg.health < cyborg.maxHealth)
if(cyborg.health < 0)
repair_amount = -2.5
powercost = 30
else
repair_amount = -1
powercost = 10
cyborg.adjustBruteLoss(repair_amount)
cyborg.adjustFireLoss(repair_amount)
cyborg.updatehealth()
cyborg.cell.use(powercost)
else
cyborg.cell.use(5)
repair_tick = 0
if((world.time - 2000) > msg_cooldown )
var/msgmode = "standby"
if(cyborg.health < 0)
msgmode = "critical"
else if(cyborg.health < cyborg.maxHealth)
msgmode = "normal"
to_chat(cyborg, "<span class='notice'>Self-repair is active in <span class='boldnotice'>[msgmode]</span> mode.</span>")
msg_cooldown = world.time
else
deactivate()
/obj/item/borg/upgrade/hypospray
name = "medical cyborg hypospray advanced synthesiser"
desc = "An upgrade to the Medical module cyborg's hypospray, allowing it \
to produce more advanced and complex medical reagents."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/medical
origin_tech = null
var/list/additional_reagents = list()
/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/reagent_containers/borghypo/H in R.module)
if(H.accepts_reagent_upgrades)
for(var/re in additional_reagents)
H.add_reagent(re)
return 1
/obj/item/borg/upgrade/hypospray/expanded
name = "medical cyborg expanded hypospray"
desc = "An upgrade to the Medical module's hypospray, allowing it \
to treat a wider range of conditions and problems."
additional_reagents = list("mannitol", "oculine", "inacusiate",
"mutadone", "haloperidol")
origin_tech = "programming=5;engineering=4;biotech=5"
/obj/item/borg/upgrade/hypospray/high_strength
name = "medical cyborg high-strength hypospray"
desc = "An upgrade to the Medical module's hypospray, containing \
stronger versions of existing chemicals."
additional_reagents = list("oxandrolone", "sal_acid", "rezadone",
"pen_acid")
origin_tech = "programming=5;engineering=5;biotech=6"
/obj/item/borg/upgrade/piercing_hypospray
name = "cyborg piercing hypospray"
desc = "An upgrade to a cyborg's hypospray, allowing it to \
pierce armor and thick material."
origin_tech = "materials=5;engineering=7;combat=3"
icon_state = "cyborg_upgrade3"
/obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/R)
if(..())
return
var/found_hypo = FALSE
for(var/obj/item/weapon/reagent_containers/borghypo/H in R.module)
H.bypass_protection = TRUE
found_hypo = TRUE
if(!found_hypo)
return
return 1
/obj/item/borg/upgrade/defib
name = "medical cyborg defibrillator"
desc = "An upgrade to the Medical module, installing a builtin \
defibrillator, for on the scene revival."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/medical
origin_tech = "programming=4;engineering=6;materials=5;powerstorage=5;biotech=5"
/obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/R)
if(..())
return
var/obj/item/weapon/twohanded/shockpaddles/cyborg/S = new(R.module)
R.module.basic_modules += S
R.module.add_module(S, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/ai
name = "B.O.R.I.S. module"
desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI."
icon_state = "boris"
origin_tech = "engineering=4;magnets=4;programming=4"
/obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R)
if(..())
return
if(R.shell)
to_chat(usr, "<span class='warning'>This unit is already an AI shell!</span>")
return
if(R.key) //You cannot replace a player unless the key is completely removed.
to_chat(usr, "<span class='warning'>Intelligence patterns detected in this [R.braintype]. Aborting.</span>")
return
R.make_shell(src)
return TRUE
@@ -1,39 +1,39 @@
/obj/item/weapon/grenade/spawnergrenade
desc = "It will unleash an unspecified anomaly into the vicinity."
name = "delivery grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "delivery"
item_state = "flashbang"
origin_tech = "materials=3;magnets=4"
var/spawner_type = null // must be an object path
var/deliveryamt = 1 // amount of type to deliver
/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/C in viewers(T, null))
C.flash_act()
// Spawn some hostile syndicate critters and spread them out
spawn_and_random_walk(spawner_type, T, deliveryamt, walk_chance=50, admin_spawn=admin_spawned)
qdel(src)
/obj/item/weapon/grenade/spawnergrenade/manhacks
name = "viscerator delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/viscerator
deliveryamt = 10
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/weapon/grenade/spawnergrenade/spesscarp
name = "carp delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/carp
deliveryamt = 5
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/weapon/grenade/spawnergrenade/syndiesoap
name = "Mister Scrubby"
spawner_type = /obj/item/weapon/soap/syndie
/obj/item/weapon/grenade/spawnergrenade
desc = "It will unleash an unspecified anomaly into the vicinity."
name = "delivery grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "delivery"
item_state = "flashbang"
origin_tech = "materials=3;magnets=4"
var/spawner_type = null // must be an object path
var/deliveryamt = 1 // amount of type to deliver
/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/C in viewers(T, null))
C.flash_act()
// Spawn some hostile syndicate critters and spread them out
spawn_and_random_walk(spawner_type, T, deliveryamt, walk_chance=50, admin_spawn=admin_spawned)
qdel(src)
/obj/item/weapon/grenade/spawnergrenade/manhacks
name = "viscerator delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/viscerator
deliveryamt = 10
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/weapon/grenade/spawnergrenade/spesscarp
name = "carp delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/carp
deliveryamt = 5
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/weapon/grenade/spawnergrenade/syndiesoap
name = "Mister Scrubby"
spawner_type = /obj/item/weapon/soap/syndie
@@ -1,305 +1,305 @@
/obj/item/weapon/storage/box/syndicate
/obj/item/weapon/storage/box/syndicate/PopulateContents()
switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1)))
if("bloodyspai") // 27 tc now this is more right
new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set
new /obj/item/clothing/mask/chameleon(src) // Goes with above
new /obj/item/weapon/card/id/syndicate(src) // 2 tc
new /obj/item/clothing/shoes/chameleon(src) // 2 tc
new /obj/item/device/camera_bug(src) // 1 tc
new /obj/item/device/multitool/ai_detect(src) // 1 tc
new /obj/item/device/encryptionkey/syndicate(src) // 2 tc
new /obj/item/weapon/reagent_containers/syringe/mulligan(src) // 4 tc
new /obj/item/weapon/switchblade(src) //I'll count this as 2 tc
new /obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals
new /obj/item/device/flashlight/emp(src) // 2 tc
new /obj/item/device/chameleon(src) // 7 tc
if("stealth") // 31 tc
new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow(src)
new /obj/item/weapon/pen/sleepy(src)
new /obj/item/device/healthanalyzer/rad_laser(src)
new /obj/item/device/chameleon(src)
new /obj/item/weapon/soap/syndie(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
if("bond") // 29 tc
new /obj/item/weapon/gun/ballistic/automatic/pistol(src)
new /obj/item/weapon/suppressor(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/clothing/under/chameleon(src)
new /obj/item/weapon/card/id/syndicate(src)
new /obj/item/weapon/reagent_containers/syringe/stimulants(src)
if("screwed") // 29 tc
new /obj/item/device/sbeacondrop/bomb(src)
new /obj/item/weapon/grenade/syndieminibomb(src)
new /obj/item/device/sbeacondrop/powersink(src)
new /obj/item/clothing/suit/space/syndicate/black/red(src)
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
new /obj/item/device/encryptionkey/syndicate(src)
if("guns") // 28 tc now
new /obj/item/weapon/gun/ballistic/revolver(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/weapon/card/emag(src)
new /obj/item/weapon/grenade/plastic/c4(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/clothing/under/suit_jacket/really_black(src)
if("murder") // 28 tc now
new /obj/item/weapon/melee/energy/sword/saber(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/weapon/card/emag(src)
new /obj/item/clothing/shoes/chameleon(src)
new /obj/item/device/encryptionkey/syndicate(src)
new /obj/item/weapon/grenade/syndieminibomb(src)
if("implant") // 55+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it?
new /obj/item/weapon/implanter/freedom(src)
new /obj/item/weapon/implanter/uplink/precharged(src)
new /obj/item/weapon/implanter/emp(src)
new /obj/item/weapon/implanter/adrenalin(src)
new /obj/item/weapon/implanter/explosive(src)
new /obj/item/weapon/implanter/storage(src)
if("hacker") // 26 tc
new /obj/item/weapon/aiModule/syndicate(src)
new /obj/item/weapon/card/emag(src)
new /obj/item/device/encryptionkey/binary(src)
new /obj/item/weapon/aiModule/toyAI(src)
new /obj/item/device/multitool/ai_detect(src)
if("lordsingulo") // 24 tc
new /obj/item/device/sbeacondrop(src)
new /obj/item/clothing/suit/space/syndicate/black/red(src)
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
new /obj/item/weapon/card/emag(src)
if("sabotage") // 26 tc now
new /obj/item/weapon/grenade/plastic/c4 (src)
new /obj/item/weapon/grenade/plastic/c4 (src)
new /obj/item/device/doorCharge(src)
new /obj/item/device/doorCharge(src)
new /obj/item/device/camera_bug(src)
new /obj/item/device/sbeacondrop/powersink(src)
new /obj/item/weapon/cartridge/syndicate(src)
new /obj/item/weapon/storage/toolbox/syndicate(src) //To actually get to those places
new /obj/item/pizzabox/bomb
if("darklord") //20 tc + tk + summon item close enough for now
new /obj/item/weapon/twohanded/dualsaber(src)
new /obj/item/weapon/dnainjector/telemut/darkbundle(src)
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
new /obj/item/weapon/card/id/syndicate(src)
new /obj/item/clothing/shoes/chameleon(src) //because slipping while being a dark lord sucks
new /obj/item/weapon/spellbook/oneuse/summonitem(src)
if("sniper") //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks
new /obj/item/weapon/gun/ballistic/automatic/sniper_rifle(src) // 12 tc
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/clothing/under/suit_jacket/really_black(src)
if("metaops") // 30 tc
new /obj/item/clothing/suit/space/hardsuit/syndi(src) // 8 tc
new /obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog/unrestricted(src) // 8 tc
new /obj/item/weapon/implanter/explosive(src) // 2 tc
new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc
new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc
new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc
new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc
new /obj/item/weapon/card/emag(src) // 6 tc
if("ninja") // 33 tc worth
new /obj/item/weapon/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc?
new /obj/item/weapon/implanter/adrenalin(src) // 8 tc
new /obj/item/weapon/throwing_star(src) // ~5 tc for all 6
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/storage/belt/chameleon(src) // Unique but worth at least 2 tc
new /obj/item/weapon/card/id/syndicate(src) // 2 tc
new /obj/item/device/chameleon(src) // 7 tc
/obj/item/weapon/storage/box/syndie_kit
name = "box"
desc = "A sleek, sturdy box."
icon_state = "syndiebox"
illustration = "writing_syndie"
/obj/item/weapon/storage/box/syndie_kit/imp_freedom
name = "boxed freedom implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_freedom/PopulateContents()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/freedom(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/imp_microbomb
name = "Microbomb Implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_microbomb/PopulateContents()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/explosive(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/imp_macrobomb
name = "Macrobomb Implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_macrobomb/PopulateContents()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/explosive/macro(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/imp_uplink
name = "boxed uplink implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_uplink/PopulateContents()
..()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/uplink(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/bioterror
name = "bioterror syringe box"
/obj/item/weapon/storage/box/syndie_kit/bioterror/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/weapon/reagent_containers/syringe/bioterror(src)
/obj/item/weapon/storage/box/syndie_kit/imp_adrenal
name = "boxed adrenal implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_adrenal/PopulateContents()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/adrenalin(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/imp_storage
name = "boxed storage implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_storage/PopulateContents()
new /obj/item/weapon/implanter/storage(src)
/obj/item/weapon/storage/box/syndie_kit/space
name = "boxed space suit and helmet"
can_hold = list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate)
max_w_class = WEIGHT_CLASS_NORMAL
/obj/item/weapon/storage/box/syndie_kit/space/PopulateContents()
new /obj/item/clothing/suit/space/syndicate/black/red(src) // Black and red is so in right now
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
/obj/item/weapon/storage/box/syndie_kit/emp
name = "boxed EMP kit"
/obj/item/weapon/storage/box/syndie_kit/emp/PopulateContents()
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/implanter/emp(src)
/obj/item/weapon/storage/box/syndie_kit/chemical
name = "boxed chemical kit"
storage_slots = 14
/obj/item/weapon/storage/box/syndie_kit/chemical/PopulateContents()
new /obj/item/weapon/reagent_containers/glass/bottle/polonium(src)
new /obj/item/weapon/reagent_containers/glass/bottle/venom(src)
new /obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2(src)
new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src)
new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src)
new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src)
new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src)
new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src)
new /obj/item/weapon/reagent_containers/glass/bottle/pancuronium(src)
new /obj/item/weapon/reagent_containers/glass/bottle/sodium_thiopental(src)
new /obj/item/weapon/reagent_containers/glass/bottle/coniine(src)
new /obj/item/weapon/reagent_containers/glass/bottle/curare(src)
new /obj/item/weapon/reagent_containers/glass/bottle/amanitin(src)
new /obj/item/weapon/reagent_containers/syringe(src)
/obj/item/weapon/storage/box/syndie_kit/nuke
name = "box"
/obj/item/weapon/storage/box/syndie_kit/nuke/PopulateContents()
new /obj/item/weapon/screwdriver/nuke(src)
new /obj/item/nuke_core_container(src)
new /obj/item/weapon/paper/nuke_instructions(src)
/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade
name = "boxed virus grenade kit"
/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade/PopulateContents()
new /obj/item/weapon/grenade/chem_grenade/tuberculosis(src)
for(var/i in 1 to 5)
new /obj/item/weapon/reagent_containers/hypospray/medipen/tuberculosiscure(src)
new /obj/item/weapon/reagent_containers/syringe(src)
new /obj/item/weapon/reagent_containers/glass/bottle/tuberculosiscure(src)
/obj/item/weapon/storage/box/syndie_kit/chameleon
name = "chameleon kit"
/obj/item/weapon/storage/box/syndie_kit/chameleon/PopulateContents()
new /obj/item/clothing/under/chameleon(src)
new /obj/item/clothing/suit/chameleon(src)
new /obj/item/clothing/gloves/chameleon(src)
new /obj/item/clothing/shoes/chameleon(src)
new /obj/item/clothing/glasses/chameleon(src)
new /obj/item/clothing/head/chameleon(src)
new /obj/item/clothing/mask/chameleon(src)
new /obj/item/weapon/storage/backpack/chameleon(src)
new /obj/item/device/radio/headset/chameleon(src)
new /obj/item/weapon/stamp/chameleon(src)
new /obj/item/device/pda/chameleon(src)
new /obj/item/weapon/gun/energy/laser/chameleon(src)
//5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars.
//Not counting the damage it will do while embedded (2*4 = 8, at 15% chance)
/obj/item/weapon/storage/box/syndie_kit/throwing_weapons/PopulateContents()
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/restraints/legcuffs/bola/tactical(src)
new /obj/item/weapon/restraints/legcuffs/bola/tactical(src)
/obj/item/weapon/storage/box/syndie_kit/cutouts/PopulateContents()
for(var/i in 1 to 3)
new/obj/item/cardboard_cutout/adaptive(src)
new/obj/item/toy/crayon/rainbow(src)
/obj/item/weapon/storage/box/syndie_kit/romerol/PopulateContents()
new /obj/item/weapon/reagent_containers/glass/bottle/romerol(src)
new /obj/item/weapon/reagent_containers/syringe(src)
new /obj/item/weapon/reagent_containers/dropper(src)
/obj/item/weapon/storage/box/syndie_kit/ez_clean/PopulateContents()
for(var/i in 1 to 3)
new/obj/item/weapon/grenade/chem_grenade/ez_clean(src)
/obj/item/weapon/storage/box/hug/reverse_revolver/PopulateContents()
new /obj/item/weapon/gun/ballistic/revolver/reverse(src)
/obj/item/weapon/storage/box/syndie_kit/mimery/PopulateContents()
new /obj/item/weapon/spellbook/oneuse/mimery_blockade(src)
new /obj/item/weapon/spellbook/oneuse/mimery_guns(src)
/obj/item/weapon/storage/box/syndie_kit/holoparasite
name = "box"
/obj/item/weapon/storage/box/syndie_kit/holoparasite/PopulateContents()
new /obj/item/weapon/guardiancreator/tech/choose/traitor(src)
/obj/item/weapon/storage/box/syndicate
/obj/item/weapon/storage/box/syndicate/PopulateContents()
switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1)))
if("bloodyspai") // 27 tc now this is more right
new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set
new /obj/item/clothing/mask/chameleon(src) // Goes with above
new /obj/item/weapon/card/id/syndicate(src) // 2 tc
new /obj/item/clothing/shoes/chameleon(src) // 2 tc
new /obj/item/device/camera_bug(src) // 1 tc
new /obj/item/device/multitool/ai_detect(src) // 1 tc
new /obj/item/device/encryptionkey/syndicate(src) // 2 tc
new /obj/item/weapon/reagent_containers/syringe/mulligan(src) // 4 tc
new /obj/item/weapon/switchblade(src) //I'll count this as 2 tc
new /obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals
new /obj/item/device/flashlight/emp(src) // 2 tc
new /obj/item/device/chameleon(src) // 7 tc
if("stealth") // 31 tc
new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow(src)
new /obj/item/weapon/pen/sleepy(src)
new /obj/item/device/healthanalyzer/rad_laser(src)
new /obj/item/device/chameleon(src)
new /obj/item/weapon/soap/syndie(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
if("bond") // 29 tc
new /obj/item/weapon/gun/ballistic/automatic/pistol(src)
new /obj/item/weapon/suppressor(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/clothing/under/chameleon(src)
new /obj/item/weapon/card/id/syndicate(src)
new /obj/item/weapon/reagent_containers/syringe/stimulants(src)
if("screwed") // 29 tc
new /obj/item/device/sbeacondrop/bomb(src)
new /obj/item/weapon/grenade/syndieminibomb(src)
new /obj/item/device/sbeacondrop/powersink(src)
new /obj/item/clothing/suit/space/syndicate/black/red(src)
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
new /obj/item/device/encryptionkey/syndicate(src)
if("guns") // 28 tc now
new /obj/item/weapon/gun/ballistic/revolver(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/weapon/card/emag(src)
new /obj/item/weapon/grenade/plastic/c4(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/clothing/under/suit_jacket/really_black(src)
if("murder") // 28 tc now
new /obj/item/weapon/melee/energy/sword/saber(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/weapon/card/emag(src)
new /obj/item/clothing/shoes/chameleon(src)
new /obj/item/device/encryptionkey/syndicate(src)
new /obj/item/weapon/grenade/syndieminibomb(src)
if("implant") // 55+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it?
new /obj/item/weapon/implanter/freedom(src)
new /obj/item/weapon/implanter/uplink/precharged(src)
new /obj/item/weapon/implanter/emp(src)
new /obj/item/weapon/implanter/adrenalin(src)
new /obj/item/weapon/implanter/explosive(src)
new /obj/item/weapon/implanter/storage(src)
if("hacker") // 26 tc
new /obj/item/weapon/aiModule/syndicate(src)
new /obj/item/weapon/card/emag(src)
new /obj/item/device/encryptionkey/binary(src)
new /obj/item/weapon/aiModule/toyAI(src)
new /obj/item/device/multitool/ai_detect(src)
if("lordsingulo") // 24 tc
new /obj/item/device/sbeacondrop(src)
new /obj/item/clothing/suit/space/syndicate/black/red(src)
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
new /obj/item/weapon/card/emag(src)
if("sabotage") // 26 tc now
new /obj/item/weapon/grenade/plastic/c4 (src)
new /obj/item/weapon/grenade/plastic/c4 (src)
new /obj/item/device/doorCharge(src)
new /obj/item/device/doorCharge(src)
new /obj/item/device/camera_bug(src)
new /obj/item/device/sbeacondrop/powersink(src)
new /obj/item/weapon/cartridge/syndicate(src)
new /obj/item/weapon/storage/toolbox/syndicate(src) //To actually get to those places
new /obj/item/pizzabox/bomb
if("darklord") //20 tc + tk + summon item close enough for now
new /obj/item/weapon/twohanded/dualsaber(src)
new /obj/item/weapon/dnainjector/telemut/darkbundle(src)
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
new /obj/item/weapon/card/id/syndicate(src)
new /obj/item/clothing/shoes/chameleon(src) //because slipping while being a dark lord sucks
new /obj/item/weapon/spellbook/oneuse/summonitem(src)
if("sniper") //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks
new /obj/item/weapon/gun/ballistic/automatic/sniper_rifle(src) // 12 tc
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/clothing/under/suit_jacket/really_black(src)
if("metaops") // 30 tc
new /obj/item/clothing/suit/space/hardsuit/syndi(src) // 8 tc
new /obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog/unrestricted(src) // 8 tc
new /obj/item/weapon/implanter/explosive(src) // 2 tc
new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc
new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc
new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc
new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc
new /obj/item/weapon/card/emag(src) // 6 tc
if("ninja") // 33 tc worth
new /obj/item/weapon/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc?
new /obj/item/weapon/implanter/adrenalin(src) // 8 tc
new /obj/item/weapon/throwing_star(src) // ~5 tc for all 6
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/storage/belt/chameleon(src) // Unique but worth at least 2 tc
new /obj/item/weapon/card/id/syndicate(src) // 2 tc
new /obj/item/device/chameleon(src) // 7 tc
/obj/item/weapon/storage/box/syndie_kit
name = "box"
desc = "A sleek, sturdy box."
icon_state = "syndiebox"
illustration = "writing_syndie"
/obj/item/weapon/storage/box/syndie_kit/imp_freedom
name = "boxed freedom implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_freedom/PopulateContents()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/freedom(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/imp_microbomb
name = "Microbomb Implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_microbomb/PopulateContents()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/explosive(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/imp_macrobomb
name = "Macrobomb Implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_macrobomb/PopulateContents()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/explosive/macro(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/imp_uplink
name = "boxed uplink implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_uplink/PopulateContents()
..()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/uplink(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/bioterror
name = "bioterror syringe box"
/obj/item/weapon/storage/box/syndie_kit/bioterror/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/weapon/reagent_containers/syringe/bioterror(src)
/obj/item/weapon/storage/box/syndie_kit/imp_adrenal
name = "boxed adrenal implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_adrenal/PopulateContents()
var/obj/item/weapon/implanter/O = new(src)
O.imp = new /obj/item/weapon/implant/adrenalin(O)
O.update_icon()
/obj/item/weapon/storage/box/syndie_kit/imp_storage
name = "boxed storage implant (with injector)"
/obj/item/weapon/storage/box/syndie_kit/imp_storage/PopulateContents()
new /obj/item/weapon/implanter/storage(src)
/obj/item/weapon/storage/box/syndie_kit/space
name = "boxed space suit and helmet"
can_hold = list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate)
max_w_class = WEIGHT_CLASS_NORMAL
/obj/item/weapon/storage/box/syndie_kit/space/PopulateContents()
new /obj/item/clothing/suit/space/syndicate/black/red(src) // Black and red is so in right now
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
/obj/item/weapon/storage/box/syndie_kit/emp
name = "boxed EMP kit"
/obj/item/weapon/storage/box/syndie_kit/emp/PopulateContents()
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/implanter/emp(src)
/obj/item/weapon/storage/box/syndie_kit/chemical
name = "boxed chemical kit"
storage_slots = 14
/obj/item/weapon/storage/box/syndie_kit/chemical/PopulateContents()
new /obj/item/weapon/reagent_containers/glass/bottle/polonium(src)
new /obj/item/weapon/reagent_containers/glass/bottle/venom(src)
new /obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2(src)
new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src)
new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src)
new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src)
new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src)
new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src)
new /obj/item/weapon/reagent_containers/glass/bottle/pancuronium(src)
new /obj/item/weapon/reagent_containers/glass/bottle/sodium_thiopental(src)
new /obj/item/weapon/reagent_containers/glass/bottle/coniine(src)
new /obj/item/weapon/reagent_containers/glass/bottle/curare(src)
new /obj/item/weapon/reagent_containers/glass/bottle/amanitin(src)
new /obj/item/weapon/reagent_containers/syringe(src)
/obj/item/weapon/storage/box/syndie_kit/nuke
name = "box"
/obj/item/weapon/storage/box/syndie_kit/nuke/PopulateContents()
new /obj/item/weapon/screwdriver/nuke(src)
new /obj/item/nuke_core_container(src)
new /obj/item/weapon/paper/nuke_instructions(src)
/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade
name = "boxed virus grenade kit"
/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade/PopulateContents()
new /obj/item/weapon/grenade/chem_grenade/tuberculosis(src)
for(var/i in 1 to 5)
new /obj/item/weapon/reagent_containers/hypospray/medipen/tuberculosiscure(src)
new /obj/item/weapon/reagent_containers/syringe(src)
new /obj/item/weapon/reagent_containers/glass/bottle/tuberculosiscure(src)
/obj/item/weapon/storage/box/syndie_kit/chameleon
name = "chameleon kit"
/obj/item/weapon/storage/box/syndie_kit/chameleon/PopulateContents()
new /obj/item/clothing/under/chameleon(src)
new /obj/item/clothing/suit/chameleon(src)
new /obj/item/clothing/gloves/chameleon(src)
new /obj/item/clothing/shoes/chameleon(src)
new /obj/item/clothing/glasses/chameleon(src)
new /obj/item/clothing/head/chameleon(src)
new /obj/item/clothing/mask/chameleon(src)
new /obj/item/weapon/storage/backpack/chameleon(src)
new /obj/item/device/radio/headset/chameleon(src)
new /obj/item/weapon/stamp/chameleon(src)
new /obj/item/device/pda/chameleon(src)
new /obj/item/weapon/gun/energy/laser/chameleon(src)
//5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars.
//Not counting the damage it will do while embedded (2*4 = 8, at 15% chance)
/obj/item/weapon/storage/box/syndie_kit/throwing_weapons/PopulateContents()
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/throwing_star(src)
new /obj/item/weapon/restraints/legcuffs/bola/tactical(src)
new /obj/item/weapon/restraints/legcuffs/bola/tactical(src)
/obj/item/weapon/storage/box/syndie_kit/cutouts/PopulateContents()
for(var/i in 1 to 3)
new/obj/item/cardboard_cutout/adaptive(src)
new/obj/item/toy/crayon/rainbow(src)
/obj/item/weapon/storage/box/syndie_kit/romerol/PopulateContents()
new /obj/item/weapon/reagent_containers/glass/bottle/romerol(src)
new /obj/item/weapon/reagent_containers/syringe(src)
new /obj/item/weapon/reagent_containers/dropper(src)
/obj/item/weapon/storage/box/syndie_kit/ez_clean/PopulateContents()
for(var/i in 1 to 3)
new/obj/item/weapon/grenade/chem_grenade/ez_clean(src)
/obj/item/weapon/storage/box/hug/reverse_revolver/PopulateContents()
new /obj/item/weapon/gun/ballistic/revolver/reverse(src)
/obj/item/weapon/storage/box/syndie_kit/mimery/PopulateContents()
new /obj/item/weapon/spellbook/oneuse/mimery_blockade(src)
new /obj/item/weapon/spellbook/oneuse/mimery_guns(src)
/obj/item/weapon/storage/box/syndie_kit/holoparasite
name = "box"
/obj/item/weapon/storage/box/syndie_kit/holoparasite/PopulateContents()
new /obj/item/weapon/guardiancreator/tech/choose/traitor(src)
new /obj/item/weapon/paper/guardian(src)
@@ -1,79 +1,79 @@
/obj/item/weapon/vending_refill
name = "resupply canister"
var/machine_name = "Generic"
icon = 'icons/obj/vending_restock.dmi'
icon_state = "refill_snack"
item_state = "restock_unit"
flags = CONDUCT
force = 7
throwforce = 10
throw_speed = 1
throw_range = 7
w_class = WEIGHT_CLASS_BULKY
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 30)
var/charges = list(0, 0, 0) //how many restocking "charges" the refill has for standard/contraband/coin products
var/init_charges = list(0, 0, 0)
/obj/item/weapon/vending_refill/New(amt = -1)
..()
name = "\improper [machine_name] restocking unit"
if(isnum(amt) && amt > -1)
charges[1] = amt
/obj/item/weapon/vending_refill/examine(mob/user)
..()
if(charges[1] > 0)
to_chat(user, "It can restock [charges[1]+charges[2]+charges[3]] item(s).")
else
to_chat(user, "It's empty!")
//NOTE I decided to go for about 1/3 of a machine's capacity
/obj/item/weapon/vending_refill/boozeomat
machine_name = "Booze-O-Mat"
icon_state = "refill_booze"
charges = list(54, 4, 0)//of 159 standard, 12 contraband
init_charges = list(54, 4, 0)
/obj/item/weapon/vending_refill/coffee
machine_name = "Solar's Best Hot Drinks"
icon_state = "refill_joe"
charges = list(25, 4, 0)//of 75 standard, 12 contraband
init_charges = list(25, 4, 0)
/obj/item/weapon/vending_refill/snack
machine_name = "Getmore Chocolate Corp"
charges = list(12, 2, 0)//of 36 standard, 6 contraband
init_charges = list(12, 2, 0)
/obj/item/weapon/vending_refill/cola
machine_name = "Robust Softdrinks"
icon_state = "refill_cola"
charges = list(30, 4, 1)//of 90 standard, 12 contraband, 1 premium
init_charges = list(30, 4, 1)
/obj/item/weapon/vending_refill/cigarette
machine_name = "ShadyCigs Deluxe"
icon_state = "refill_smoke"
charges = list(12, 3, 2)// of 36 standard, 9 contraband, 6 premium
init_charges = list(12, 3, 2)
/obj/item/weapon/vending_refill/autodrobe
machine_name = "AutoDrobe"
icon_state = "refill_costume"
charges = list(31, 2, 3)// of 94 standard, 6 contraband, 9 premium
init_charges = list(27, 2, 3)
/obj/item/weapon/vending_refill/clothing
machine_name = "ClothesMate"
icon_state = "refill_clothes"
charges = list(31, 4, 4)// of 101 standard, 12 contraband, 10 premium(?)
init_charges = list(31, 4, 4)
/obj/item/weapon/vending_refill/medical
machine_name = "NanoMed"
icon_state = "refill_medical"
charges = list(26, 5, 3)// of 76 standard, 13 contraband, 8 premium
/obj/item/weapon/vending_refill
name = "resupply canister"
var/machine_name = "Generic"
icon = 'icons/obj/vending_restock.dmi'
icon_state = "refill_snack"
item_state = "restock_unit"
flags = CONDUCT
force = 7
throwforce = 10
throw_speed = 1
throw_range = 7
w_class = WEIGHT_CLASS_BULKY
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 30)
var/charges = list(0, 0, 0) //how many restocking "charges" the refill has for standard/contraband/coin products
var/init_charges = list(0, 0, 0)
/obj/item/weapon/vending_refill/New(amt = -1)
..()
name = "\improper [machine_name] restocking unit"
if(isnum(amt) && amt > -1)
charges[1] = amt
/obj/item/weapon/vending_refill/examine(mob/user)
..()
if(charges[1] > 0)
to_chat(user, "It can restock [charges[1]+charges[2]+charges[3]] item(s).")
else
to_chat(user, "It's empty!")
//NOTE I decided to go for about 1/3 of a machine's capacity
/obj/item/weapon/vending_refill/boozeomat
machine_name = "Booze-O-Mat"
icon_state = "refill_booze"
charges = list(54, 4, 0)//of 159 standard, 12 contraband
init_charges = list(54, 4, 0)
/obj/item/weapon/vending_refill/coffee
machine_name = "Solar's Best Hot Drinks"
icon_state = "refill_joe"
charges = list(25, 4, 0)//of 75 standard, 12 contraband
init_charges = list(25, 4, 0)
/obj/item/weapon/vending_refill/snack
machine_name = "Getmore Chocolate Corp"
charges = list(12, 2, 0)//of 36 standard, 6 contraband
init_charges = list(12, 2, 0)
/obj/item/weapon/vending_refill/cola
machine_name = "Robust Softdrinks"
icon_state = "refill_cola"
charges = list(30, 4, 1)//of 90 standard, 12 contraband, 1 premium
init_charges = list(30, 4, 1)
/obj/item/weapon/vending_refill/cigarette
machine_name = "ShadyCigs Deluxe"
icon_state = "refill_smoke"
charges = list(12, 3, 2)// of 36 standard, 9 contraband, 6 premium
init_charges = list(12, 3, 2)
/obj/item/weapon/vending_refill/autodrobe
machine_name = "AutoDrobe"
icon_state = "refill_costume"
charges = list(31, 2, 3)// of 94 standard, 6 contraband, 9 premium
init_charges = list(27, 2, 3)
/obj/item/weapon/vending_refill/clothing
machine_name = "ClothesMate"
icon_state = "refill_clothes"
charges = list(31, 4, 4)// of 101 standard, 12 contraband, 10 premium(?)
init_charges = list(31, 4, 4)
/obj/item/weapon/vending_refill/medical
machine_name = "NanoMed"
icon_state = "refill_medical"
charges = list(26, 5, 3)// of 76 standard, 13 contraband, 8 premium
init_charges = list(26, 5, 3)
+361 -361
View File
@@ -1,361 +1,361 @@
/obj/structure/displaycase
name = "display case"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "glassbox0"
desc = "A display case for prized possessions."
density = 1
anchored = 1
resistance_flags = ACID_PROOF
armor = list(melee = 30, bullet = 0, laser = 0, energy = 0, bomb = 10, bio = 0, rad = 0, fire = 70, acid = 100)
obj_integrity = 200
max_integrity = 200
integrity_failure = 50
var/obj/item/showpiece = null
var/alert = TRUE
var/open = FALSE
var/openable = TRUE
var/obj/item/weapon/electronics/airlock/electronics
var/start_showpiece_type = null //add type for items on display
/obj/structure/displaycase/Initialize()
. = ..()
if(start_showpiece_type)
showpiece = new start_showpiece_type (src)
update_icon()
/obj/structure/displaycase/Destroy()
if(electronics)
QDEL_NULL(electronics)
if(showpiece)
QDEL_NULL(showpiece)
return ..()
/obj/structure/displaycase/examine(mob/user)
..()
if(alert)
to_chat(user, "<span class='notice'>Hooked up with an anti-theft system.</span>")
if(showpiece)
to_chat(user, "<span class='notice'>There's [showpiece] inside.</span>")
/obj/structure/displaycase/proc/dump()
if (showpiece)
showpiece.forceMove(loc)
showpiece = null
/obj/structure/displaycase/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
if(BURN)
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
/obj/structure/displaycase/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
dump()
if(!disassembled)
new /obj/item/weapon/shard( src.loc )
trigger_alarm()
qdel(src)
/obj/structure/displaycase/obj_break(damage_flag)
if(!broken && !(flags & NODECONSTRUCT))
density = 0
broken = 1
new /obj/item/weapon/shard( src.loc )
playsound(src, "shatter", 70, 1)
update_icon()
trigger_alarm()
/obj/structure/displaycase/proc/trigger_alarm()
//Activate Anti-theft
if(alert)
var/area/alarmed = get_area(src)
alarmed.burglaralert(src)
playsound(src, 'sound/effects/alert.ogg', 50, 1)
/*
*/
/obj/structure/displaycase/proc/is_directional(atom/A)
try
getFlatIcon(A,defdir=4)
catch
return FALSE
return TRUE
/obj/structure/displaycase/proc/get_flat_icon_directional(atom/A)
//Get flatIcon even if dir is mismatched for directionless icons
//SLOW
var/icon/I
if(is_directional(A))
I = getFlatIcon(A)
else
var/old_dir = A.dir
A.setDir(2)
I = getFlatIcon(A)
A.setDir(old_dir)
return I
/obj/structure/displaycase/update_icon()
var/icon/I
if(open)
I = icon('icons/obj/stationobjs.dmi',"glassbox_open")
else
I = icon('icons/obj/stationobjs.dmi',"glassbox0")
if(broken)
I = icon('icons/obj/stationobjs.dmi',"glassboxb0")
if(showpiece)
var/icon/S = get_flat_icon_directional(showpiece)
S.Scale(17,17)
I.Blend(S,ICON_UNDERLAY,8,8)
src.icon = I
return
/obj/structure/displaycase/attackby(obj/item/weapon/W, mob/user, params)
if(W.GetID() && !broken && openable)
if(allowed(user))
to_chat(user, "<span class='notice'>You [open ? "close":"open"] the [src]</span>")
toggle_lock(user)
else
to_chat(user, "<span class='warning'>Access denied.</span>")
else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent == INTENT_HELP && !broken)
var/obj/item/weapon/weldingtool/WT = W
if(obj_integrity < max_integrity && WT.remove_fuel(5, user))
to_chat(user, "<span class='notice'>You begin repairing [src].</span>")
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40*W.toolspeed, target = src))
obj_integrity = max_integrity
playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
update_icon()
to_chat(user, "<span class='notice'>You repair [src].</span>")
else
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
return
else if(!alert && istype(W,/obj/item/weapon/crowbar) && openable) //Only applies to the lab cage and player made display cases
if(broken)
if(showpiece)
to_chat(user, "<span class='notice'>Remove the displayed object first.</span>")
else
to_chat(user, "<span class='notice'>You remove the destroyed case</span>")
qdel(src)
else
to_chat(user, "<span class='notice'>You start to [open ? "close":"open"] the [src]</span>")
if(do_after(user, 20*W.toolspeed, target = src))
to_chat(user, "<span class='notice'>You [open ? "close":"open"] the [src]</span>")
toggle_lock(user)
else if(open && !showpiece)
if(user.transferItemToLoc(W, src))
showpiece = W
to_chat(user, "<span class='notice'>You put [W] on display</span>")
update_icon()
else if(istype(W, /obj/item/stack/sheet/glass) && broken)
var/obj/item/stack/sheet/glass/G = W
if(G.get_amount() < 2)
to_chat(user, "<span class='warning'>You need two glass sheets to fix the case!</span>")
return
to_chat(user, "<span class='notice'>You start fixing [src]...</span>")
if(do_after(user, 20, target = src))
G.use(2)
broken = 0
obj_integrity = max_integrity
update_icon()
else
return ..()
/obj/structure/displaycase/proc/toggle_lock(mob/user)
open = !open
update_icon()
/obj/structure/displaycase/attack_paw(mob/user)
return src.attack_hand(user)
/obj/structure/displaycase/attack_hand(mob/user)
user.changeNext_move(CLICK_CD_MELEE)
if (showpiece && (broken || open))
to_chat(user, "<span class='notice'>You deactivate the hover field built into the case.</span>")
dump()
src.add_fingerprint(user)
update_icon()
return
else
//prevents remote "kicks" with TK
if (!Adjacent(user))
return
user.visible_message("<span class='danger'>[user] kicks the display case.</span>", null, null, COMBAT_MESSAGE_RANGE)
user.do_attack_animation(src, ATTACK_EFFECT_KICK)
take_damage(2)
/obj/structure/displaycase_chassis
anchored = 1
density = 0
name = "display case chassis"
desc = "wooden base of display case"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "glassbox_chassis"
var/obj/item/weapon/electronics/airlock/electronics
/obj/structure/displaycase_chassis/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wrench)) //The player can only deconstruct the wooden frame
to_chat(user, "<span class='notice'>You start disassembling [src]...</span>")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 30*I.toolspeed, target = src))
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
new /obj/item/stack/sheet/mineral/wood(get_turf(src), 5)
qdel(src)
else if(istype(I, /obj/item/weapon/electronics/airlock))
to_chat(user, "<span class='notice'>You start installing the electronics into [src]...</span>")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 30, target = src) && user.transferItemToLoc(I,src))
electronics = I
to_chat(user, "<span class='notice'>You install the airlock electronics.</span>")
else if(istype(I, /obj/item/stack/sheet/glass))
var/obj/item/stack/sheet/glass/G = I
if(G.get_amount() < 10)
to_chat(user, "<span class='warning'>You need ten glass sheets to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [G] to [src]...</span>")
if(do_after(user, 20, target = src))
G.use(10)
var/obj/structure/displaycase/display = new(src.loc)
if(electronics)
electronics.loc = display
display.electronics = electronics
if(electronics.one_access)
display.req_one_access = electronics.accesses
else
display.req_access = electronics.accesses
qdel(src)
else
return ..()
//The captains display case requiring specops ID access is intentional.
//The lab cage and captains display case do not spawn with electronics, which is why req_access is needed.
/obj/structure/displaycase/captain
alert = 1
start_showpiece_type = /obj/item/weapon/gun/energy/laser/captain
req_access = list(GLOB.access_cent_specops)
/obj/structure/displaycase/labcage
name = "lab cage"
desc = "A glass lab container for storing interesting creatures."
start_showpiece_type = /obj/item/clothing/mask/facehugger/lamarr
req_access = list(GLOB.access_rd)
/obj/structure/displaycase/trophy
name = "trophy display case"
desc = "Store your trophies of accomplishment in here, and they will stay forever."
var/trophy_message = ""
var/placer_key = ""
var/added_roundstart = TRUE
var/is_locked = TRUE
alert = TRUE
integrity_failure = 0
openable = FALSE
/obj/structure/displaycase/trophy/Initialize()
. = ..()
GLOB.trophy_cases += src
/obj/structure/displaycase/trophy/Destroy()
GLOB.trophy_cases -= src
return ..()
/obj/structure/displaycase/trophy/examine(mob/user)
..()
if(trophy_message)
to_chat(user, "The plaque reads:")
to_chat(user, trophy_message)
/obj/structure/displaycase/trophy/attackby(obj/item/weapon/W, mob/user, params)
if(!user.Adjacent(src)) //no TK museology
return
if(user.a_intent == INTENT_HARM)
return ..()
if(user.is_holding_item_of_type(/obj/item/key/displaycase))
if(added_roundstart)
is_locked = !is_locked
to_chat(user, "You [!is_locked ? "un" : ""]lock the case.")
else
to_chat(user, "<span class='danger'>The lock is stuck shut!</span>")
return
if(is_locked)
to_chat(user, "<span class='danger'>The case is shut tight with an old fashioned physical lock. Maybe you should ask the curator for the key?</span>")
return
if(!added_roundstart)
to_chat(user, "You've already put something new in this case.")
return
if(is_type_in_typecache(W, GLOB.blacklisted_cargo_types))
to_chat(user, "<span class='danger'>The case rejects the [W].</span>")
return
for(var/a in W.GetAllContents())
if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types))
to_chat(user, "<span class='danger'>The case rejects the [W].</span>")
return
if(user.transferItemToLoc(W, src))
if(showpiece)
to_chat(user, "You press a button, and [showpiece] descends into the floor of the case.")
QDEL_NULL(showpiece)
to_chat(user, "You insert [W] into the case.")
showpiece = W
added_roundstart = FALSE
update_icon()
placer_key = user.ckey
trophy_message = W.desc //default value
var/chosen_plaque = stripped_input(user, "What would you like the plaque to say? Default value is item's description.", "Trophy Plaque")
if(chosen_plaque)
if(user.Adjacent(src))
trophy_message = chosen_plaque
to_chat(user, "You set the plaque's text.")
else
to_chat(user, "You are too far to set the plaque's text.")
SSpersistence.SaveTrophy(src)
return TRUE
else
to_chat(user, "<span class='warning'>\The [W] is stuck to your hand, you can't put it in the [src.name]!</span>")
return
/obj/structure/displaycase/trophy/dump()
if (showpiece)
if(added_roundstart)
visible_message("<span class='danger'>The [showpiece] crumbles to dust!</span>")
new /obj/effect/decal/cleanable/ash(loc)
QDEL_NULL(showpiece)
else
..()
/obj/item/key/displaycase
name = "display case key"
desc = "The key to the curator's display cases."
/obj/item/showpiece_dummy
name = "Cheap replica"
/obj/item/showpiece_dummy/Initialize(mapload, path)
. = ..()
var/obj/item/I = path
name = initial(I.name)
icon = initial(I.icon)
icon_state = initial(I.icon_state)
/obj/structure/displaycase
name = "display case"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "glassbox0"
desc = "A display case for prized possessions."
density = 1
anchored = 1
resistance_flags = ACID_PROOF
armor = list(melee = 30, bullet = 0, laser = 0, energy = 0, bomb = 10, bio = 0, rad = 0, fire = 70, acid = 100)
obj_integrity = 200
max_integrity = 200
integrity_failure = 50
var/obj/item/showpiece = null
var/alert = TRUE
var/open = FALSE
var/openable = TRUE
var/obj/item/weapon/electronics/airlock/electronics
var/start_showpiece_type = null //add type for items on display
/obj/structure/displaycase/Initialize()
. = ..()
if(start_showpiece_type)
showpiece = new start_showpiece_type (src)
update_icon()
/obj/structure/displaycase/Destroy()
if(electronics)
QDEL_NULL(electronics)
if(showpiece)
QDEL_NULL(showpiece)
return ..()
/obj/structure/displaycase/examine(mob/user)
..()
if(alert)
to_chat(user, "<span class='notice'>Hooked up with an anti-theft system.</span>")
if(showpiece)
to_chat(user, "<span class='notice'>There's [showpiece] inside.</span>")
/obj/structure/displaycase/proc/dump()
if (showpiece)
showpiece.forceMove(loc)
showpiece = null
/obj/structure/displaycase/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
if(BURN)
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
/obj/structure/displaycase/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
dump()
if(!disassembled)
new /obj/item/weapon/shard( src.loc )
trigger_alarm()
qdel(src)
/obj/structure/displaycase/obj_break(damage_flag)
if(!broken && !(flags & NODECONSTRUCT))
density = 0
broken = 1
new /obj/item/weapon/shard( src.loc )
playsound(src, "shatter", 70, 1)
update_icon()
trigger_alarm()
/obj/structure/displaycase/proc/trigger_alarm()
//Activate Anti-theft
if(alert)
var/area/alarmed = get_area(src)
alarmed.burglaralert(src)
playsound(src, 'sound/effects/alert.ogg', 50, 1)
/*
*/
/obj/structure/displaycase/proc/is_directional(atom/A)
try
getFlatIcon(A,defdir=4)
catch
return FALSE
return TRUE
/obj/structure/displaycase/proc/get_flat_icon_directional(atom/A)
//Get flatIcon even if dir is mismatched for directionless icons
//SLOW
var/icon/I
if(is_directional(A))
I = getFlatIcon(A)
else
var/old_dir = A.dir
A.setDir(2)
I = getFlatIcon(A)
A.setDir(old_dir)
return I
/obj/structure/displaycase/update_icon()
var/icon/I
if(open)
I = icon('icons/obj/stationobjs.dmi',"glassbox_open")
else
I = icon('icons/obj/stationobjs.dmi',"glassbox0")
if(broken)
I = icon('icons/obj/stationobjs.dmi',"glassboxb0")
if(showpiece)
var/icon/S = get_flat_icon_directional(showpiece)
S.Scale(17,17)
I.Blend(S,ICON_UNDERLAY,8,8)
src.icon = I
return
/obj/structure/displaycase/attackby(obj/item/weapon/W, mob/user, params)
if(W.GetID() && !broken && openable)
if(allowed(user))
to_chat(user, "<span class='notice'>You [open ? "close":"open"] the [src]</span>")
toggle_lock(user)
else
to_chat(user, "<span class='warning'>Access denied.</span>")
else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent == INTENT_HELP && !broken)
var/obj/item/weapon/weldingtool/WT = W
if(obj_integrity < max_integrity && WT.remove_fuel(5, user))
to_chat(user, "<span class='notice'>You begin repairing [src].</span>")
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40*W.toolspeed, target = src))
obj_integrity = max_integrity
playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
update_icon()
to_chat(user, "<span class='notice'>You repair [src].</span>")
else
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
return
else if(!alert && istype(W,/obj/item/weapon/crowbar) && openable) //Only applies to the lab cage and player made display cases
if(broken)
if(showpiece)
to_chat(user, "<span class='notice'>Remove the displayed object first.</span>")
else
to_chat(user, "<span class='notice'>You remove the destroyed case</span>")
qdel(src)
else
to_chat(user, "<span class='notice'>You start to [open ? "close":"open"] the [src]</span>")
if(do_after(user, 20*W.toolspeed, target = src))
to_chat(user, "<span class='notice'>You [open ? "close":"open"] the [src]</span>")
toggle_lock(user)
else if(open && !showpiece)
if(user.transferItemToLoc(W, src))
showpiece = W
to_chat(user, "<span class='notice'>You put [W] on display</span>")
update_icon()
else if(istype(W, /obj/item/stack/sheet/glass) && broken)
var/obj/item/stack/sheet/glass/G = W
if(G.get_amount() < 2)
to_chat(user, "<span class='warning'>You need two glass sheets to fix the case!</span>")
return
to_chat(user, "<span class='notice'>You start fixing [src]...</span>")
if(do_after(user, 20, target = src))
G.use(2)
broken = 0
obj_integrity = max_integrity
update_icon()
else
return ..()
/obj/structure/displaycase/proc/toggle_lock(mob/user)
open = !open
update_icon()
/obj/structure/displaycase/attack_paw(mob/user)
return src.attack_hand(user)
/obj/structure/displaycase/attack_hand(mob/user)
user.changeNext_move(CLICK_CD_MELEE)
if (showpiece && (broken || open))
to_chat(user, "<span class='notice'>You deactivate the hover field built into the case.</span>")
dump()
src.add_fingerprint(user)
update_icon()
return
else
//prevents remote "kicks" with TK
if (!Adjacent(user))
return
user.visible_message("<span class='danger'>[user] kicks the display case.</span>", null, null, COMBAT_MESSAGE_RANGE)
user.do_attack_animation(src, ATTACK_EFFECT_KICK)
take_damage(2)
/obj/structure/displaycase_chassis
anchored = 1
density = 0
name = "display case chassis"
desc = "wooden base of display case"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "glassbox_chassis"
var/obj/item/weapon/electronics/airlock/electronics
/obj/structure/displaycase_chassis/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wrench)) //The player can only deconstruct the wooden frame
to_chat(user, "<span class='notice'>You start disassembling [src]...</span>")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 30*I.toolspeed, target = src))
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
new /obj/item/stack/sheet/mineral/wood(get_turf(src), 5)
qdel(src)
else if(istype(I, /obj/item/weapon/electronics/airlock))
to_chat(user, "<span class='notice'>You start installing the electronics into [src]...</span>")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 30, target = src) && user.transferItemToLoc(I,src))
electronics = I
to_chat(user, "<span class='notice'>You install the airlock electronics.</span>")
else if(istype(I, /obj/item/stack/sheet/glass))
var/obj/item/stack/sheet/glass/G = I
if(G.get_amount() < 10)
to_chat(user, "<span class='warning'>You need ten glass sheets to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [G] to [src]...</span>")
if(do_after(user, 20, target = src))
G.use(10)
var/obj/structure/displaycase/display = new(src.loc)
if(electronics)
electronics.loc = display
display.electronics = electronics
if(electronics.one_access)
display.req_one_access = electronics.accesses
else
display.req_access = electronics.accesses
qdel(src)
else
return ..()
//The captains display case requiring specops ID access is intentional.
//The lab cage and captains display case do not spawn with electronics, which is why req_access is needed.
/obj/structure/displaycase/captain
alert = 1
start_showpiece_type = /obj/item/weapon/gun/energy/laser/captain
req_access = list(GLOB.access_cent_specops)
/obj/structure/displaycase/labcage
name = "lab cage"
desc = "A glass lab container for storing interesting creatures."
start_showpiece_type = /obj/item/clothing/mask/facehugger/lamarr
req_access = list(GLOB.access_rd)
/obj/structure/displaycase/trophy
name = "trophy display case"
desc = "Store your trophies of accomplishment in here, and they will stay forever."
var/trophy_message = ""
var/placer_key = ""
var/added_roundstart = TRUE
var/is_locked = TRUE
alert = TRUE
integrity_failure = 0
openable = FALSE
/obj/structure/displaycase/trophy/Initialize()
. = ..()
GLOB.trophy_cases += src
/obj/structure/displaycase/trophy/Destroy()
GLOB.trophy_cases -= src
return ..()
/obj/structure/displaycase/trophy/examine(mob/user)
..()
if(trophy_message)
to_chat(user, "The plaque reads:")
to_chat(user, trophy_message)
/obj/structure/displaycase/trophy/attackby(obj/item/weapon/W, mob/user, params)
if(!user.Adjacent(src)) //no TK museology
return
if(user.a_intent == INTENT_HARM)
return ..()
if(user.is_holding_item_of_type(/obj/item/key/displaycase))
if(added_roundstart)
is_locked = !is_locked
to_chat(user, "You [!is_locked ? "un" : ""]lock the case.")
else
to_chat(user, "<span class='danger'>The lock is stuck shut!</span>")
return
if(is_locked)
to_chat(user, "<span class='danger'>The case is shut tight with an old fashioned physical lock. Maybe you should ask the curator for the key?</span>")
return
if(!added_roundstart)
to_chat(user, "You've already put something new in this case.")
return
if(is_type_in_typecache(W, GLOB.blacklisted_cargo_types))
to_chat(user, "<span class='danger'>The case rejects the [W].</span>")
return
for(var/a in W.GetAllContents())
if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types))
to_chat(user, "<span class='danger'>The case rejects the [W].</span>")
return
if(user.transferItemToLoc(W, src))
if(showpiece)
to_chat(user, "You press a button, and [showpiece] descends into the floor of the case.")
QDEL_NULL(showpiece)
to_chat(user, "You insert [W] into the case.")
showpiece = W
added_roundstart = FALSE
update_icon()
placer_key = user.ckey
trophy_message = W.desc //default value
var/chosen_plaque = stripped_input(user, "What would you like the plaque to say? Default value is item's description.", "Trophy Plaque")
if(chosen_plaque)
if(user.Adjacent(src))
trophy_message = chosen_plaque
to_chat(user, "You set the plaque's text.")
else
to_chat(user, "You are too far to set the plaque's text.")
SSpersistence.SaveTrophy(src)
return TRUE
else
to_chat(user, "<span class='warning'>\The [W] is stuck to your hand, you can't put it in the [src.name]!</span>")
return
/obj/structure/displaycase/trophy/dump()
if (showpiece)
if(added_roundstart)
visible_message("<span class='danger'>The [showpiece] crumbles to dust!</span>")
new /obj/effect/decal/cleanable/ash(loc)
QDEL_NULL(showpiece)
else
..()
/obj/item/key/displaycase
name = "display case key"
desc = "The key to the curator's display cases."
/obj/item/showpiece_dummy
name = "Cheap replica"
/obj/item/showpiece_dummy/Initialize(mapload, path)
. = ..()
var/obj/item/I = path
name = initial(I.name)
icon = initial(I.icon)
icon_state = initial(I.icon_state)
+240 -240
View File
@@ -1,240 +1,240 @@
GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
/obj/machinery/gateway
name = "gateway"
desc = "A mysterious gateway built by unknown hands, it allows for faster than light travel to far-flung locations."
icon = 'icons/obj/machines/gateway.dmi'
icon_state = "off"
density = 1
anchored = 1
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/active = 0
var/checkparts = TRUE
var/list/obj/effect/landmark/randomspawns = list()
var/calibrated = TRUE
var/list/linked = list()
var/can_link = FALSE //Is this the centerpiece?
/obj/machinery/gateway/Initialize()
randomspawns = GLOB.awaydestinations
update_icon()
if(!istype(src, /obj/machinery/gateway/centerstation) && !istype(src, /obj/machinery/gateway/centeraway))
switch(dir)
if(SOUTH,SOUTHEAST,SOUTHWEST)
density = 0
..()
/obj/machinery/gateway/proc/toggleoff()
for(var/obj/machinery/gateway/G in linked)
G.active = 0
G.update_icon()
active = 0
update_icon()
/obj/machinery/gateway/proc/detect()
if(!can_link)
return FALSE
linked = list() //clear the list
var/turf/T = loc
var/ready = FALSE
for(var/i in GLOB.alldirs)
T = get_step(loc, i)
var/obj/machinery/gateway/G = locate(/obj/machinery/gateway) in T
if(G)
linked.Add(G)
continue
//this is only done if we fail to find a part
ready = FALSE
toggleoff()
break
if((linked.len == 8) || !checkparts)
ready = TRUE
return ready
/obj/machinery/gateway/update_icon()
if(active)
icon_state = "on"
return
icon_state = "off"
//prevents shuttles attempting to rotate this since it messes up sprites
/obj/machinery/gateway/shuttleRotate()
return
/obj/machinery/gateway/attack_hand(mob/user)
if(!detect())
return
if(!active)
toggleon(user)
return
toggleoff()
/obj/machinery/gateway/proc/toggleon(mob/user)
return FALSE
/obj/machinery/gateway/centerstation/New()
..()
if(!GLOB.the_gateway)
GLOB.the_gateway = src
/obj/machinery/gateway/centerstation/Destroy()
if(GLOB.the_gateway == src)
GLOB.the_gateway = null
return ..()
//this is da important part wot makes things go
/obj/machinery/gateway/centerstation
density = TRUE
icon_state = "offcenter"
use_power = TRUE
//warping vars
var/wait = 0 //this just grabs world.time at world start
var/obj/machinery/gateway/centeraway/awaygate = null
can_link = TRUE
/obj/machinery/gateway/centerstation/Initialize()
..()
update_icon()
wait = world.time + config.gateway_delay //+ thirty minutes default
awaygate = locate(/obj/machinery/gateway/centeraway)
/obj/machinery/gateway/centerstation/update_icon()
if(active)
icon_state = "oncenter"
return
icon_state = "offcenter"
/obj/machinery/gateway/centerstation/process()
if((stat & (NOPOWER)) && use_power)
if(active)
toggleoff()
return
if(active)
use_power(5000)
/obj/machinery/gateway/centerstation/toggleon(mob/user)
if(!detect())
return
if(!powered())
return
if(!awaygate)
to_chat(user, "<span class='notice'>Error: No destination found.</span>")
return
if(world.time < wait)
to_chat(user, "<span class='notice'>Error: Warpspace triangulation in progress. Estimated time to completion: [round(((wait - world.time) / 10) / 60)] minutes.</span>")
return
for(var/obj/machinery/gateway/G in linked)
G.active = 1
G.update_icon()
active = 1
update_icon()
//okay, here's the good teleporting stuff
/obj/machinery/gateway/centerstation/Bumped(atom/movable/AM)
if(!active)
return
if(!detect())
return
if(!awaygate || QDELETED(awaygate))
return
if(awaygate.calibrated)
AM.forceMove(get_step(awaygate.loc, SOUTH))
AM.setDir(SOUTH)
if (ismob(AM))
var/mob/M = AM
if (M.client)
M.client.move_delay = max(world.time + 5, M.client.move_delay)
return
else
var/obj/effect/landmark/dest = pick(randomspawns)
if(dest)
AM.forceMove(get_turf(dest))
AM.setDir(SOUTH)
use_power(5000)
return
/obj/machinery/gateway/centeraway/attackby(obj/item/device/W, mob/user, params)
if(istype(W,/obj/item/device/multitool))
if(calibrated)
to_chat(user, "\black The gate is already calibrated, there is no work for you to do here.")
return
else
to_chat(user, "<span class='boldnotice'>Recalibration successful!</span>: \black This gate's systems have been fine tuned. Travel to this gate will now be on target.")
calibrated = TRUE
return
/////////////////////////////////////Away////////////////////////
/obj/machinery/gateway/centeraway
density = TRUE
icon_state = "offcenter"
use_power = FALSE
var/obj/machinery/gateway/centeraway/stationgate = null
can_link = TRUE
/obj/machinery/gateway/centeraway/Initialize()
..()
update_icon()
stationgate = locate(/obj/machinery/gateway/centerstation)
/obj/machinery/gateway/centeraway/update_icon()
if(active)
icon_state = "oncenter"
return
icon_state = "offcenter"
/obj/machinery/gateway/centeraway/toggleon(mob/user)
if(!detect())
return
if(!stationgate)
to_chat(user, "<span class='notice'>Error: No destination found.</span>")
return
for(var/obj/machinery/gateway/G in linked)
G.active = 1
G.update_icon()
active = 1
update_icon()
/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/carbon/C)
for(var/obj/item/weapon/implant/exile/E in C.implants)//Checking that there is an exile implant
to_chat(C, "\black The station gate has detected your exile implant and is blocking your entry.")
return TRUE
return FALSE
/obj/machinery/gateway/centeraway/Bumped(atom/movable/AM)
if(!detect())
return
if(!active)
return
if(!stationgate || QDELETED(stationgate))
return
if(istype(AM, /mob/living/carbon))
if(check_exile_implant(AM))
return
else
for(var/mob/living/carbon/C in AM.contents)
if(check_exile_implant(C))
say("Rejecting [AM]: Exile implant detected in contained lifeform.")
return
if(AM.has_buckled_mobs())
for(var/mob/living/carbon/C in AM.buckled_mobs)
if(check_exile_implant(C))
say("Rejecting [AM]: Exile implant detected in close proximity lifeform.")
return
AM.forceMove(get_step(stationgate.loc, SOUTH))
AM.setDir(SOUTH)
if (ismob(AM))
var/mob/M = AM
if (M.client)
M.client.move_delay = max(world.time + 5, M.client.move_delay)
GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
/obj/machinery/gateway
name = "gateway"
desc = "A mysterious gateway built by unknown hands, it allows for faster than light travel to far-flung locations."
icon = 'icons/obj/machines/gateway.dmi'
icon_state = "off"
density = 1
anchored = 1
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/active = 0
var/checkparts = TRUE
var/list/obj/effect/landmark/randomspawns = list()
var/calibrated = TRUE
var/list/linked = list()
var/can_link = FALSE //Is this the centerpiece?
/obj/machinery/gateway/Initialize()
randomspawns = GLOB.awaydestinations
update_icon()
if(!istype(src, /obj/machinery/gateway/centerstation) && !istype(src, /obj/machinery/gateway/centeraway))
switch(dir)
if(SOUTH,SOUTHEAST,SOUTHWEST)
density = 0
..()
/obj/machinery/gateway/proc/toggleoff()
for(var/obj/machinery/gateway/G in linked)
G.active = 0
G.update_icon()
active = 0
update_icon()
/obj/machinery/gateway/proc/detect()
if(!can_link)
return FALSE
linked = list() //clear the list
var/turf/T = loc
var/ready = FALSE
for(var/i in GLOB.alldirs)
T = get_step(loc, i)
var/obj/machinery/gateway/G = locate(/obj/machinery/gateway) in T
if(G)
linked.Add(G)
continue
//this is only done if we fail to find a part
ready = FALSE
toggleoff()
break
if((linked.len == 8) || !checkparts)
ready = TRUE
return ready
/obj/machinery/gateway/update_icon()
if(active)
icon_state = "on"
return
icon_state = "off"
//prevents shuttles attempting to rotate this since it messes up sprites
/obj/machinery/gateway/shuttleRotate()
return
/obj/machinery/gateway/attack_hand(mob/user)
if(!detect())
return
if(!active)
toggleon(user)
return
toggleoff()
/obj/machinery/gateway/proc/toggleon(mob/user)
return FALSE
/obj/machinery/gateway/centerstation/New()
..()
if(!GLOB.the_gateway)
GLOB.the_gateway = src
/obj/machinery/gateway/centerstation/Destroy()
if(GLOB.the_gateway == src)
GLOB.the_gateway = null
return ..()
//this is da important part wot makes things go
/obj/machinery/gateway/centerstation
density = TRUE
icon_state = "offcenter"
use_power = TRUE
//warping vars
var/wait = 0 //this just grabs world.time at world start
var/obj/machinery/gateway/centeraway/awaygate = null
can_link = TRUE
/obj/machinery/gateway/centerstation/Initialize()
..()
update_icon()
wait = world.time + config.gateway_delay //+ thirty minutes default
awaygate = locate(/obj/machinery/gateway/centeraway)
/obj/machinery/gateway/centerstation/update_icon()
if(active)
icon_state = "oncenter"
return
icon_state = "offcenter"
/obj/machinery/gateway/centerstation/process()
if((stat & (NOPOWER)) && use_power)
if(active)
toggleoff()
return
if(active)
use_power(5000)
/obj/machinery/gateway/centerstation/toggleon(mob/user)
if(!detect())
return
if(!powered())
return
if(!awaygate)
to_chat(user, "<span class='notice'>Error: No destination found.</span>")
return
if(world.time < wait)
to_chat(user, "<span class='notice'>Error: Warpspace triangulation in progress. Estimated time to completion: [round(((wait - world.time) / 10) / 60)] minutes.</span>")
return
for(var/obj/machinery/gateway/G in linked)
G.active = 1
G.update_icon()
active = 1
update_icon()
//okay, here's the good teleporting stuff
/obj/machinery/gateway/centerstation/Bumped(atom/movable/AM)
if(!active)
return
if(!detect())
return
if(!awaygate || QDELETED(awaygate))
return
if(awaygate.calibrated)
AM.forceMove(get_step(awaygate.loc, SOUTH))
AM.setDir(SOUTH)
if (ismob(AM))
var/mob/M = AM
if (M.client)
M.client.move_delay = max(world.time + 5, M.client.move_delay)
return
else
var/obj/effect/landmark/dest = pick(randomspawns)
if(dest)
AM.forceMove(get_turf(dest))
AM.setDir(SOUTH)
use_power(5000)
return
/obj/machinery/gateway/centeraway/attackby(obj/item/device/W, mob/user, params)
if(istype(W,/obj/item/device/multitool))
if(calibrated)
to_chat(user, "\black The gate is already calibrated, there is no work for you to do here.")
return
else
to_chat(user, "<span class='boldnotice'>Recalibration successful!</span>: \black This gate's systems have been fine tuned. Travel to this gate will now be on target.")
calibrated = TRUE
return
/////////////////////////////////////Away////////////////////////
/obj/machinery/gateway/centeraway
density = TRUE
icon_state = "offcenter"
use_power = FALSE
var/obj/machinery/gateway/centeraway/stationgate = null
can_link = TRUE
/obj/machinery/gateway/centeraway/Initialize()
..()
update_icon()
stationgate = locate(/obj/machinery/gateway/centerstation)
/obj/machinery/gateway/centeraway/update_icon()
if(active)
icon_state = "oncenter"
return
icon_state = "offcenter"
/obj/machinery/gateway/centeraway/toggleon(mob/user)
if(!detect())
return
if(!stationgate)
to_chat(user, "<span class='notice'>Error: No destination found.</span>")
return
for(var/obj/machinery/gateway/G in linked)
G.active = 1
G.update_icon()
active = 1
update_icon()
/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/carbon/C)
for(var/obj/item/weapon/implant/exile/E in C.implants)//Checking that there is an exile implant
to_chat(C, "\black The station gate has detected your exile implant and is blocking your entry.")
return TRUE
return FALSE
/obj/machinery/gateway/centeraway/Bumped(atom/movable/AM)
if(!detect())
return
if(!active)
return
if(!stationgate || QDELETED(stationgate))
return
if(istype(AM, /mob/living/carbon))
if(check_exile_implant(AM))
return
else
for(var/mob/living/carbon/C in AM.contents)
if(check_exile_implant(C))
say("Rejecting [AM]: Exile implant detected in contained lifeform.")
return
if(AM.has_buckled_mobs())
for(var/mob/living/carbon/C in AM.buckled_mobs)
if(check_exile_implant(C))
say("Rejecting [AM]: Exile implant detected in close proximity lifeform.")
return
AM.forceMove(get_step(stationgate.loc, SOUTH))
AM.setDir(SOUTH)
if (ismob(AM))
var/mob/M = AM
if (M.client)
M.client.move_delay = max(world.time + 5, M.client.move_delay)
+147 -147
View File
@@ -1,147 +1,147 @@
//Hat Station 13
/obj/item/clothing/head/collectable
name = "collectable hat"
desc = "A rare collectable hat."
/obj/item/clothing/head/collectable/petehat
name = "ultra rare Pete's hat!"
desc = "It smells faintly of plasma."
icon_state = "petehat"
/obj/item/clothing/head/collectable/slime
name = "collectable slime cap!"
desc = "It just latches right in place!"
icon_state = "slime"
/obj/item/clothing/head/collectable/xenom
name = "collectable xenomorph helmet!"
desc = "Hiss hiss hiss!"
icon_state = "xenom"
/obj/item/clothing/head/collectable/chef
name = "collectable chef's hat"
desc = "A rare chef's hat meant for hat collectors!"
icon_state = "chef"
item_state = "chef"
dog_fashion = /datum/dog_fashion/head/chef
/obj/item/clothing/head/collectable/paper
name = "collectable paper hat"
desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from water, fire, and Curators."
icon_state = "paper"
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/collectable/tophat
name = "collectable top hat"
desc = "A top hat worn by only the most prestigious hat collectors."
icon_state = "tophat"
item_state = "that"
/obj/item/clothing/head/collectable/captain
name = "collectable captain's hat"
desc = "A collectable hat that'll make you look just like a real comdom!"
icon_state = "captain"
item_state = "caphat"
dog_fashion = /datum/dog_fashion/head/captain
/obj/item/clothing/head/collectable/police
name = "collectable police officer's hat"
desc = "A collectable police officer's Hat. This hat emphasizes that you are THE LAW."
icon_state = "policehelm"
dog_fashion = /datum/dog_fashion/head/warden
/obj/item/clothing/head/collectable/beret
name = "collectable beret"
desc = "A collectable red beret. It smells faintly of garlic."
icon_state = "beret"
dog_fashion = /datum/dog_fashion/head/beret
/obj/item/clothing/head/collectable/welding
name = "collectable welding helmet"
desc = "A collectable welding helmet. Now with 80% less lead! Not for actual welding. Any welding done while wearing this helmet is done so at the owner's own risk!"
icon_state = "welding"
item_state = "welding"
resistance_flags = 0
/obj/item/clothing/head/collectable/slime
name = "collectable slime hat"
desc = "Just like a real brain slug!"
icon_state = "headslime"
item_state = "headslime"
/obj/item/clothing/head/collectable/flatcap
name = "collectable flat cap"
desc = "A collectible farmer's flat cap!"
icon_state = "flat_cap"
item_state = "detective"
/obj/item/clothing/head/collectable/pirate
name = "collectable pirate hat"
desc = "You'd make a great Dread Syndie Roberts!"
icon_state = "pirate"
item_state = "pirate"
dog_fashion = /datum/dog_fashion/head/pirate
/obj/item/clothing/head/collectable/kitty
name = "collectable kitty ears"
desc = "The fur feels... a bit too realistic."
icon_state = "kitty"
item_state = "kitty"
dog_fashion = /datum/dog_fashion/head/kitty
/obj/item/clothing/head/collectable/rabbitears
name = "collectable rabbit ears"
desc = "Not as lucky as the feet!"
icon_state = "bunny"
item_state = "bunny"
dog_fashion = /datum/dog_fashion/head/rabbit
/obj/item/clothing/head/collectable/wizard
name = "collectable wizard's hat"
desc = "NOTE: Any magical powers gained from wearing this hat are purely coincidental."
icon_state = "wizard"
dog_fashion = /datum/dog_fashion/head/blue_wizard
/obj/item/clothing/head/collectable/hardhat
name = "collectable hard hat"
desc = "WARNING! Offers no real protection, or luminosity, but damn, is it fancy!"
icon_state = "hardhat0_yellow"
item_state = "hardhat0_yellow"
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/collectable/HoS
name = "collectable HoS hat"
desc = "Now you too can beat prisoners, set silly sentences, and arrest for no reason!"
icon_state = "hoscap"
/obj/item/clothing/head/collectable/HoP
name = "collectable HoP hat"
desc = "It's your turn to demand excessive paperwork, signatures, stamps, and hire more clowns! Papers, please!"
icon_state = "hopcap"
dog_fashion = /datum/dog_fashion/head/hop
/obj/item/clothing/head/collectable/thunderdome
name = "collectable Thunderdome helmet"
desc = "Go Red! I mean Green! I mean Red! No Green!"
icon_state = "thunderdome"
item_state = "thunderdome"
resistance_flags = 0
/obj/item/clothing/head/collectable/swat
name = "collectable SWAT helmet"
desc = "That's not real blood. That's red paint." //Reference to the actual description
icon_state = "swat"
item_state = "swat"
resistance_flags = 0
//Hat Station 13
/obj/item/clothing/head/collectable
name = "collectable hat"
desc = "A rare collectable hat."
/obj/item/clothing/head/collectable/petehat
name = "ultra rare Pete's hat!"
desc = "It smells faintly of plasma."
icon_state = "petehat"
/obj/item/clothing/head/collectable/slime
name = "collectable slime cap!"
desc = "It just latches right in place!"
icon_state = "slime"
/obj/item/clothing/head/collectable/xenom
name = "collectable xenomorph helmet!"
desc = "Hiss hiss hiss!"
icon_state = "xenom"
/obj/item/clothing/head/collectable/chef
name = "collectable chef's hat"
desc = "A rare chef's hat meant for hat collectors!"
icon_state = "chef"
item_state = "chef"
dog_fashion = /datum/dog_fashion/head/chef
/obj/item/clothing/head/collectable/paper
name = "collectable paper hat"
desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from water, fire, and Curators."
icon_state = "paper"
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/collectable/tophat
name = "collectable top hat"
desc = "A top hat worn by only the most prestigious hat collectors."
icon_state = "tophat"
item_state = "that"
/obj/item/clothing/head/collectable/captain
name = "collectable captain's hat"
desc = "A collectable hat that'll make you look just like a real comdom!"
icon_state = "captain"
item_state = "caphat"
dog_fashion = /datum/dog_fashion/head/captain
/obj/item/clothing/head/collectable/police
name = "collectable police officer's hat"
desc = "A collectable police officer's Hat. This hat emphasizes that you are THE LAW."
icon_state = "policehelm"
dog_fashion = /datum/dog_fashion/head/warden
/obj/item/clothing/head/collectable/beret
name = "collectable beret"
desc = "A collectable red beret. It smells faintly of garlic."
icon_state = "beret"
dog_fashion = /datum/dog_fashion/head/beret
/obj/item/clothing/head/collectable/welding
name = "collectable welding helmet"
desc = "A collectable welding helmet. Now with 80% less lead! Not for actual welding. Any welding done while wearing this helmet is done so at the owner's own risk!"
icon_state = "welding"
item_state = "welding"
resistance_flags = 0
/obj/item/clothing/head/collectable/slime
name = "collectable slime hat"
desc = "Just like a real brain slug!"
icon_state = "headslime"
item_state = "headslime"
/obj/item/clothing/head/collectable/flatcap
name = "collectable flat cap"
desc = "A collectible farmer's flat cap!"
icon_state = "flat_cap"
item_state = "detective"
/obj/item/clothing/head/collectable/pirate
name = "collectable pirate hat"
desc = "You'd make a great Dread Syndie Roberts!"
icon_state = "pirate"
item_state = "pirate"
dog_fashion = /datum/dog_fashion/head/pirate
/obj/item/clothing/head/collectable/kitty
name = "collectable kitty ears"
desc = "The fur feels... a bit too realistic."
icon_state = "kitty"
item_state = "kitty"
dog_fashion = /datum/dog_fashion/head/kitty
/obj/item/clothing/head/collectable/rabbitears
name = "collectable rabbit ears"
desc = "Not as lucky as the feet!"
icon_state = "bunny"
item_state = "bunny"
dog_fashion = /datum/dog_fashion/head/rabbit
/obj/item/clothing/head/collectable/wizard
name = "collectable wizard's hat"
desc = "NOTE: Any magical powers gained from wearing this hat are purely coincidental."
icon_state = "wizard"
dog_fashion = /datum/dog_fashion/head/blue_wizard
/obj/item/clothing/head/collectable/hardhat
name = "collectable hard hat"
desc = "WARNING! Offers no real protection, or luminosity, but damn, is it fancy!"
icon_state = "hardhat0_yellow"
item_state = "hardhat0_yellow"
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/collectable/HoS
name = "collectable HoS hat"
desc = "Now you too can beat prisoners, set silly sentences, and arrest for no reason!"
icon_state = "hoscap"
/obj/item/clothing/head/collectable/HoP
name = "collectable HoP hat"
desc = "It's your turn to demand excessive paperwork, signatures, stamps, and hire more clowns! Papers, please!"
icon_state = "hopcap"
dog_fashion = /datum/dog_fashion/head/hop
/obj/item/clothing/head/collectable/thunderdome
name = "collectable Thunderdome helmet"
desc = "Go Red! I mean Green! I mean Red! No Green!"
icon_state = "thunderdome"
item_state = "thunderdome"
resistance_flags = 0
/obj/item/clothing/head/collectable/swat
name = "collectable SWAT helmet"
desc = "That's not real blood. That's red paint." //Reference to the actual description
icon_state = "swat"
item_state = "swat"
resistance_flags = 0
+172 -172
View File
@@ -1,172 +1,172 @@
//CONTAINS: Detective's Scanner
// TODO: Split everything into easy to manage procs.
/obj/item/device/detective_scanner
name = "forensic scanner"
desc = "Used to remotely scan objects and biomass for DNA and fingerprints. Can print a report of the findings."
icon_state = "forensicnew"
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
var/scanning = 0
var/list/log = list()
origin_tech = "engineering=4;biotech=2;programming=5"
var/range = 8
var/view_check = TRUE
/obj/item/device/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
scanning = 1
to_chat(user, "<span class='notice'>Printing report, please wait...</span>")
addtimer(CALLBACK(src, .proc/PrintReport), 100)
else
to_chat(user, "<span class='notice'>The scanner has no logs or is in use.</span>")
/obj/item/device/detective_scanner/attack(mob/living/M, mob/user)
return
/obj/item/device/detective_scanner/proc/PrintReport()
// Create our paper
var/obj/item/weapon/paper/P = new(get_turf(src))
P.name = "paper- 'Scanner Report'"
P.info = "<center><font size='6'><B>Scanner Report</B></font></center><HR><BR>"
P.info += jointext(log, "<BR>")
P.info += "<HR><B>Notes:</B><BR>"
P.info_links = P.info
if(ismob(loc))
var/mob/M = loc
M.put_in_hands(P)
to_chat(M, "<span class='notice'>Report printed. Log cleared.<span>")
// Clear the logs
log = list()
scanning = 0
/obj/item/device/detective_scanner/afterattack(atom/A, mob/user, params)
scan(A, user)
return FALSE
/obj/item/device/detective_scanner/proc/scan(atom/A, mob/user)
set waitfor = 0
if(!scanning)
// Can remotely scan objects and mobs.
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
scanning = 1
user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.")
to_chat(user, "<span class='notice'>You scan \the [A]. The scanner is now analysing the results...</span>")
// GATHER INFORMATION
//Make our lists
var/list/fingerprints = list()
var/list/blood = list()
var/list/fibers = list()
var/list/reagents = list()
var/target_name = A.name
// Start gathering
if(A.blood_DNA && A.blood_DNA.len)
blood = A.blood_DNA.Copy()
if(A.suit_fibers && A.suit_fibers.len)
fibers = A.suit_fibers.Copy()
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(!H.gloves)
fingerprints += md5(H.dna.uni_identity)
else if(!ismob(A))
if(A.fingerprints && A.fingerprints.len)
fingerprints = A.fingerprints.Copy()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
for(var/datum/reagent/R in A.reagents.reagent_list)
reagents[R.name] = R.volume
// Get blood data from the blood reagent.
if(istype(R, /datum/reagent/blood))
if(R.data["blood_DNA"] && R.data["blood_type"])
var/blood_DNA = R.data["blood_DNA"]
var/blood_type = R.data["blood_type"]
blood[blood_DNA] = blood_type
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
var/found_something = 0
add_log("<B>[worldtime2text()][get_timestamp()] - [target_name]</B>", 0)
// Fingerprints
if(fingerprints && fingerprints.len)
sleep(30)
add_log("<span class='info'><B>Prints:</B></span>")
for(var/finger in fingerprints)
add_log("[finger]")
found_something = 1
// Blood
if (blood && blood.len)
sleep(30)
add_log("<span class='info'><B>Blood:</B></span>")
found_something = 1
for(var/B in blood)
add_log("Type: <font color='red'>[blood[B]]</font> DNA: <font color='red'>[B]</font>")
//Fibers
if(fibers && fibers.len)
sleep(30)
add_log("<span class='info'><B>Fibers:</B></span>")
for(var/fiber in fibers)
add_log("[fiber]")
found_something = 1
//Reagents
if(reagents && reagents.len)
sleep(30)
add_log("<span class='info'><B>Reagents:</B></span>")
for(var/R in reagents)
add_log("Reagent: <font color='red'>[R]</font> Volume: <font color='red'>[reagents[R]]</font>")
found_something = 1
// Get a new user
var/mob/holder = null
if(ismob(src.loc))
holder = src.loc
if(!found_something)
add_log("<I># No forensic traces found #</I>", 0) // Don't display this to the holder user
if(holder)
to_chat(holder, "<span class='warning'>Unable to locate any fingerprints, materials, fibers, or blood on \the [target_name]!</span>")
else
if(holder)
to_chat(holder, "<span class='notice'>You finish scanning \the [target_name].</span>")
add_log("---------------------------------------------------------", 0)
scanning = 0
return
/obj/item/device/detective_scanner/proc/add_log(msg, broadcast = 1)
if(scanning)
if(broadcast && ismob(loc))
var/mob/M = loc
to_chat(M, msg)
log += "&nbsp;&nbsp;[msg]"
else
CRASH("[src] \ref[src] is adding a log when it was never put in scanning mode!")
/proc/get_timestamp()
return time2text(world.time + 432000, ":ss")
//CONTAINS: Detective's Scanner
// TODO: Split everything into easy to manage procs.
/obj/item/device/detective_scanner
name = "forensic scanner"
desc = "Used to remotely scan objects and biomass for DNA and fingerprints. Can print a report of the findings."
icon_state = "forensicnew"
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
var/scanning = 0
var/list/log = list()
origin_tech = "engineering=4;biotech=2;programming=5"
var/range = 8
var/view_check = TRUE
/obj/item/device/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
scanning = 1
to_chat(user, "<span class='notice'>Printing report, please wait...</span>")
addtimer(CALLBACK(src, .proc/PrintReport), 100)
else
to_chat(user, "<span class='notice'>The scanner has no logs or is in use.</span>")
/obj/item/device/detective_scanner/attack(mob/living/M, mob/user)
return
/obj/item/device/detective_scanner/proc/PrintReport()
// Create our paper
var/obj/item/weapon/paper/P = new(get_turf(src))
P.name = "paper- 'Scanner Report'"
P.info = "<center><font size='6'><B>Scanner Report</B></font></center><HR><BR>"
P.info += jointext(log, "<BR>")
P.info += "<HR><B>Notes:</B><BR>"
P.info_links = P.info
if(ismob(loc))
var/mob/M = loc
M.put_in_hands(P)
to_chat(M, "<span class='notice'>Report printed. Log cleared.<span>")
// Clear the logs
log = list()
scanning = 0
/obj/item/device/detective_scanner/afterattack(atom/A, mob/user, params)
scan(A, user)
return FALSE
/obj/item/device/detective_scanner/proc/scan(atom/A, mob/user)
set waitfor = 0
if(!scanning)
// Can remotely scan objects and mobs.
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
scanning = 1
user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.")
to_chat(user, "<span class='notice'>You scan \the [A]. The scanner is now analysing the results...</span>")
// GATHER INFORMATION
//Make our lists
var/list/fingerprints = list()
var/list/blood = list()
var/list/fibers = list()
var/list/reagents = list()
var/target_name = A.name
// Start gathering
if(A.blood_DNA && A.blood_DNA.len)
blood = A.blood_DNA.Copy()
if(A.suit_fibers && A.suit_fibers.len)
fibers = A.suit_fibers.Copy()
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(!H.gloves)
fingerprints += md5(H.dna.uni_identity)
else if(!ismob(A))
if(A.fingerprints && A.fingerprints.len)
fingerprints = A.fingerprints.Copy()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
for(var/datum/reagent/R in A.reagents.reagent_list)
reagents[R.name] = R.volume
// Get blood data from the blood reagent.
if(istype(R, /datum/reagent/blood))
if(R.data["blood_DNA"] && R.data["blood_type"])
var/blood_DNA = R.data["blood_DNA"]
var/blood_type = R.data["blood_type"]
blood[blood_DNA] = blood_type
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
var/found_something = 0
add_log("<B>[worldtime2text()][get_timestamp()] - [target_name]</B>", 0)
// Fingerprints
if(fingerprints && fingerprints.len)
sleep(30)
add_log("<span class='info'><B>Prints:</B></span>")
for(var/finger in fingerprints)
add_log("[finger]")
found_something = 1
// Blood
if (blood && blood.len)
sleep(30)
add_log("<span class='info'><B>Blood:</B></span>")
found_something = 1
for(var/B in blood)
add_log("Type: <font color='red'>[blood[B]]</font> DNA: <font color='red'>[B]</font>")
//Fibers
if(fibers && fibers.len)
sleep(30)
add_log("<span class='info'><B>Fibers:</B></span>")
for(var/fiber in fibers)
add_log("[fiber]")
found_something = 1
//Reagents
if(reagents && reagents.len)
sleep(30)
add_log("<span class='info'><B>Reagents:</B></span>")
for(var/R in reagents)
add_log("Reagent: <font color='red'>[R]</font> Volume: <font color='red'>[reagents[R]]</font>")
found_something = 1
// Get a new user
var/mob/holder = null
if(ismob(src.loc))
holder = src.loc
if(!found_something)
add_log("<I># No forensic traces found #</I>", 0) // Don't display this to the holder user
if(holder)
to_chat(holder, "<span class='warning'>Unable to locate any fingerprints, materials, fibers, or blood on \the [target_name]!</span>")
else
if(holder)
to_chat(holder, "<span class='notice'>You finish scanning \the [target_name].</span>")
add_log("---------------------------------------------------------", 0)
scanning = 0
return
/obj/item/device/detective_scanner/proc/add_log(msg, broadcast = 1)
if(scanning)
if(broadcast && ismob(loc))
var/mob/M = loc
to_chat(M, msg)
log += "&nbsp;&nbsp;[msg]"
else
CRASH("[src] \ref[src] is adding a log when it was never put in scanning mode!")
/proc/get_timestamp()
return time2text(world.time + 432000, ":ss")
+481 -481
View File
@@ -1,481 +1,481 @@
GLOBAL_VAR_CONST(access_security, 1) // Security equipment
GLOBAL_VAR_CONST(access_brig, 2) // Brig timers and permabrig
GLOBAL_VAR_CONST(access_armory, 3)
GLOBAL_VAR_CONST(access_forensics_lockers, 4)
GLOBAL_VAR_CONST(access_medical, 5)
GLOBAL_VAR_CONST(access_morgue, 6)
GLOBAL_VAR_CONST(access_tox, 7)
GLOBAL_VAR_CONST(access_tox_storage, 8)
GLOBAL_VAR_CONST(access_genetics, 9)
GLOBAL_VAR_CONST(access_engine, 10)
GLOBAL_VAR_CONST(access_engine_equip, 11)
GLOBAL_VAR_CONST(access_maint_tunnels, 12)
GLOBAL_VAR_CONST(access_external_airlocks, 13)
GLOBAL_VAR_CONST(access_emergency_storage, 14)
GLOBAL_VAR_CONST(access_change_ids, 15)
GLOBAL_VAR_CONST(access_ai_upload, 16)
GLOBAL_VAR_CONST(access_teleporter, 17)
GLOBAL_VAR_CONST(access_eva, 18)
GLOBAL_VAR_CONST(access_heads, 19)
GLOBAL_VAR_CONST(access_captain, 20)
GLOBAL_VAR_CONST(access_all_personal_lockers, 21)
GLOBAL_VAR_CONST(access_chapel_office, 22)
GLOBAL_VAR_CONST(access_tech_storage, 23)
GLOBAL_VAR_CONST(access_atmospherics, 24)
GLOBAL_VAR_CONST(access_bar, 25)
GLOBAL_VAR_CONST(access_janitor, 26)
GLOBAL_VAR_CONST(access_crematorium, 27)
GLOBAL_VAR_CONST(access_kitchen, 28)
GLOBAL_VAR_CONST(access_robotics, 29)
GLOBAL_VAR_CONST(access_rd, 30)
GLOBAL_VAR_CONST(access_cargo, 31)
GLOBAL_VAR_CONST(access_construction, 32)
GLOBAL_VAR_CONST(access_chemistry, 33)
GLOBAL_VAR_CONST(access_cargo_bot, 34)
GLOBAL_VAR_CONST(access_hydroponics, 35)
GLOBAL_VAR_CONST(access_manufacturing, 36)
GLOBAL_VAR_CONST(access_library, 37)
GLOBAL_VAR_CONST(access_lawyer, 38)
GLOBAL_VAR_CONST(access_virology, 39)
GLOBAL_VAR_CONST(access_cmo, 40)
GLOBAL_VAR_CONST(access_qm, 41)
GLOBAL_VAR_CONST(access_court, 42)
GLOBAL_VAR_CONST(access_surgery, 45)
GLOBAL_VAR_CONST(access_theatre, 46)
GLOBAL_VAR_CONST(access_research, 47)
GLOBAL_VAR_CONST(access_mining, 48)
GLOBAL_VAR_CONST(access_mining_office, 49) //not in use
GLOBAL_VAR_CONST(access_mailsorting, 50)
GLOBAL_VAR_CONST(access_mint, 51)
GLOBAL_VAR_CONST(access_mint_vault, 52)
GLOBAL_VAR_CONST(access_heads_vault, 53)
GLOBAL_VAR_CONST(access_mining_station, 54)
GLOBAL_VAR_CONST(access_xenobiology, 55)
GLOBAL_VAR_CONST(access_ce, 56)
GLOBAL_VAR_CONST(access_hop, 57)
GLOBAL_VAR_CONST(access_hos, 58)
GLOBAL_VAR_CONST(access_RC_announce, 59) //Request console announcements
GLOBAL_VAR_CONST(access_keycard_auth, 60) //Used for events which require at least two people to confirm them
GLOBAL_VAR_CONST(access_tcomsat, 61) // has access to the entire telecomms satellite / machinery
GLOBAL_VAR_CONST(access_gateway, 62)
GLOBAL_VAR_CONST(access_sec_doors, 63) // Security front doors
GLOBAL_VAR_CONST(access_mineral_storeroom, 64)
GLOBAL_VAR_CONST(access_minisat, 65)
GLOBAL_VAR_CONST(access_weapons, 66) //Weapon authorization for secbots
GLOBAL_VAR_CONST(access_network, 67)
GLOBAL_VAR_CONST(access_cloning, 68) //Cloning room
//BEGIN CENTCOM ACCESS
/*Should leave plenty of room if we need to add more access levels.
Mostly for admin fun times.*/
GLOBAL_VAR_CONST(access_cent_general, 101)//General facilities.
GLOBAL_VAR_CONST(access_cent_thunder, 102)//Thunderdome.
GLOBAL_VAR_CONST(access_cent_specops, 103)//Special Ops.
GLOBAL_VAR_CONST(access_cent_medical, 104)//Medical/Research
GLOBAL_VAR_CONST(access_cent_living, 105)//Living quarters.
GLOBAL_VAR_CONST(access_cent_storage, 106)//Generic storage areas.
GLOBAL_VAR_CONST(access_cent_teleporter, 107)//Teleporter.
GLOBAL_VAR_CONST(access_cent_captain, 109)//Captain's office/ID comp/AI.
GLOBAL_VAR_CONST(access_cent_bar, 110) // The non-existent Centcom Bar
//The Syndicate
GLOBAL_VAR_CONST(access_syndicate, 150)//General Syndicate Access
GLOBAL_VAR_CONST(access_syndicate_leader, 151)//Nuke Op Leader Access
//Away Missions or Ruins
/*For generic away-mission/ruin access. Why would normal crew have access to a long-abandoned derelict
or a 2000 year-old temple? */
GLOBAL_VAR_CONST(access_away_general, 200)//General facilities.
GLOBAL_VAR_CONST(access_away_maint, 201)//Away maintenance
GLOBAL_VAR_CONST(access_away_med, 202)//Away medical
GLOBAL_VAR_CONST(access_away_sec, 203)//Away security
GLOBAL_VAR_CONST(access_away_engine, 204)//Away engineering
GLOBAL_VAR_CONST(access_away_generic1, 205)//Away generic access
GLOBAL_VAR_CONST(access_away_generic2, 206)
GLOBAL_VAR_CONST(access_away_generic3, 207)
GLOBAL_VAR_CONST(access_away_generic4, 208)
/obj/var/list/req_access = null
/obj/var/req_access_txt = "0"
/obj/var/list/req_one_access = null
/obj/var/req_one_access_txt = "0"
//returns 1 if this mob has sufficient access to use this object
/obj/proc/allowed(mob/M)
//check if it doesn't require any access at all
if(src.check_access(null))
return TRUE
if(issilicon(M))
if(ispAI(M))
return FALSE
return TRUE //AI can do whatever it wants
if(IsAdminGhost(M))
//Access can't stop the abuse
return TRUE
else if(ishuman(M))
var/mob/living/carbon/human/H = M
//if they are holding or wearing a card that has access, that works
if(check_access(H.get_active_held_item()) || src.check_access(H.wear_id))
return TRUE
else if(ismonkey(M) || isalienadult(M))
var/mob/living/carbon/george = M
//they can only hold things :(
if(check_access(george.get_active_held_item()))
return TRUE
else if(isanimal(M))
var/mob/living/simple_animal/A = M
if(check_access(A.get_active_held_item()) || check_access(A.access_card))
return TRUE
return FALSE
/obj/item/proc/GetAccess()
return list()
/obj/item/proc/GetID()
return null
//Call this before using req_access or req_one_access directly
/obj/proc/gen_access()
//These generations have been moved out of /obj/New() because they were slowing down the creation of objects that never even used the access system.
if(!src.req_access)
src.req_access = list()
if(src.req_access_txt)
var/list/req_access_str = splittext(req_access_txt,";")
for(var/x in req_access_str)
var/n = text2num(x)
if(n)
req_access += n
if(!src.req_one_access)
src.req_one_access = list()
if(src.req_one_access_txt)
var/list/req_one_access_str = splittext(req_one_access_txt,";")
for(var/x in req_one_access_str)
var/n = text2num(x)
if(n)
req_one_access += n
/obj/proc/check_access(obj/item/I)
gen_access()
if(!istype(src.req_access, /list)) //something's very wrong
return TRUE
var/list/L = src.req_access
if(!L.len && (!src.req_one_access || !src.req_one_access.len)) //no requirements
return TRUE
if(!I)
return FALSE
for(var/req in src.req_access)
if(!(req in I.GetAccess())) //doesn't have this access
return FALSE
if(src.req_one_access && src.req_one_access.len)
for(var/req in src.req_one_access)
if(req in I.GetAccess()) //has an access from the single access list
return TRUE
return FALSE
return TRUE
/obj/proc/check_access_list(list/L)
if(!src.req_access && !src.req_one_access)
return TRUE
if(!istype(src.req_access, /list))
return TRUE
if(!src.req_access.len && (!src.req_one_access || !src.req_one_access.len))
return TRUE
if(!L)
return FALSE
if(!istype(L, /list))
return FALSE
for(var/req in src.req_access)
if(!(req in L)) //doesn't have this access
return FALSE
if(src.req_one_access && src.req_one_access.len)
for(var/req in src.req_one_access)
if(req in L) //has an access from the single access list
return TRUE
return FALSE
return TRUE
/proc/get_centcom_access(job)
switch(job)
if("VIP Guest")
return list(GLOB.access_cent_general)
if("Custodian")
return list(GLOB.access_cent_general, GLOB.access_cent_living, GLOB.access_cent_storage)
if("Thunderdome Overseer")
return list(GLOB.access_cent_general, GLOB.access_cent_thunder)
if("Centcom Official")
return list(GLOB.access_cent_general, GLOB.access_cent_living)
if("Medical Officer")
return list(GLOB.access_cent_general, GLOB.access_cent_living, GLOB.access_cent_medical)
if("Death Commando")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_living, GLOB.access_cent_storage)
if("Research Officer")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_medical, GLOB.access_cent_teleporter, GLOB.access_cent_storage)
if("Special Ops Officer")
return list(GLOB.access_cent_general, GLOB.access_cent_thunder, GLOB.access_cent_specops, GLOB.access_cent_living, GLOB.access_cent_storage)
if("Admiral")
return get_all_centcom_access()
if("Centcom Commander")
return get_all_centcom_access()
if("Emergency Response Team Commander")
return get_ert_access("commander")
if("Security Response Officer")
return get_ert_access("sec")
if("Engineer Response Officer")
return get_ert_access("eng")
if("Medical Response Officer")
return get_ert_access("med")
if("Centcom Bartender")
return list(GLOB.access_cent_general, GLOB.access_cent_living, GLOB.access_cent_bar)
/proc/get_all_accesses()
return list(GLOB.access_security, GLOB.access_sec_doors, GLOB.access_brig, GLOB.access_armory, GLOB.access_forensics_lockers, GLOB.access_court,
GLOB.access_medical, GLOB.access_genetics, GLOB.access_morgue, GLOB.access_rd,
GLOB.access_tox, GLOB.access_tox_storage, GLOB.access_chemistry, GLOB.access_engine, GLOB.access_engine_equip, GLOB.access_maint_tunnels,
GLOB.access_external_airlocks, GLOB.access_change_ids, GLOB.access_ai_upload,
GLOB.access_teleporter, GLOB.access_eva, GLOB.access_heads, GLOB.access_captain, GLOB.access_all_personal_lockers,
GLOB.access_tech_storage, GLOB.access_chapel_office, GLOB.access_atmospherics, GLOB.access_kitchen,
GLOB.access_bar, GLOB.access_janitor, GLOB.access_crematorium, GLOB.access_robotics, GLOB.access_cargo, GLOB.access_construction,
GLOB.access_hydroponics, GLOB.access_library, GLOB.access_lawyer, GLOB.access_virology, GLOB.access_cmo, GLOB.access_qm, GLOB.access_surgery,
GLOB.access_theatre, GLOB.access_research, GLOB.access_mining, GLOB.access_mailsorting, GLOB.access_weapons,
GLOB.access_heads_vault, GLOB.access_mining_station, GLOB.access_xenobiology, GLOB.access_ce, GLOB.access_hop, GLOB.access_hos, GLOB.access_RC_announce,
GLOB.access_keycard_auth, GLOB.access_tcomsat, GLOB.access_gateway, GLOB.access_mineral_storeroom, GLOB.access_minisat, GLOB.access_network, GLOB.access_cloning)
/proc/get_all_centcom_access()
return list(GLOB.access_cent_general, GLOB.access_cent_thunder, GLOB.access_cent_specops, GLOB.access_cent_medical, GLOB.access_cent_living, GLOB.access_cent_storage, GLOB.access_cent_teleporter, GLOB.access_cent_captain)
/proc/get_ert_access(class)
switch(class)
if("commander")
return get_all_centcom_access()
if("sec")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_living)
if("eng")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_living, GLOB.access_cent_storage)
if("med")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_medical, GLOB.access_cent_living)
/proc/get_all_syndicate_access()
return list(GLOB.access_syndicate, GLOB.access_syndicate)
/proc/get_region_accesses(code)
switch(code)
if(0)
return get_all_accesses()
if(1) //station general
return list(GLOB.access_kitchen,GLOB.access_bar, GLOB.access_hydroponics, GLOB.access_janitor, GLOB.access_chapel_office, GLOB.access_crematorium, GLOB.access_library, GLOB.access_theatre, GLOB.access_lawyer)
if(2) //security
return list(GLOB.access_sec_doors, GLOB.access_weapons, GLOB.access_security, GLOB.access_brig, GLOB.access_armory, GLOB.access_forensics_lockers, GLOB.access_court, GLOB.access_hos)
if(3) //medbay
return list(GLOB.access_medical, GLOB.access_genetics, GLOB.access_cloning, GLOB.access_morgue, GLOB.access_chemistry, GLOB.access_virology, GLOB.access_surgery, GLOB.access_cmo)
if(4) //research
return list(GLOB.access_research, GLOB.access_tox, GLOB.access_tox_storage, GLOB.access_genetics, GLOB.access_robotics, GLOB.access_xenobiology, GLOB.access_minisat, GLOB.access_rd, GLOB.access_network)
if(5) //engineering and maintenance
return list(GLOB.access_construction, GLOB.access_maint_tunnels, GLOB.access_engine, GLOB.access_engine_equip, GLOB.access_external_airlocks, GLOB.access_tech_storage, GLOB.access_atmospherics, GLOB.access_tcomsat, GLOB.access_minisat, GLOB.access_ce)
if(6) //supply
return list(GLOB.access_mailsorting, GLOB.access_mining, GLOB.access_mining_station, GLOB.access_mineral_storeroom, GLOB.access_cargo, GLOB.access_qm)
if(7) //command
return list(GLOB.access_heads, GLOB.access_RC_announce, GLOB.access_keycard_auth, GLOB.access_change_ids, GLOB.access_ai_upload, GLOB.access_teleporter, GLOB.access_eva, GLOB.access_gateway, GLOB.access_all_personal_lockers, GLOB.access_heads_vault, GLOB.access_hop, GLOB.access_captain)
/proc/get_region_accesses_name(code)
switch(code)
if(0)
return "All"
if(1) //station general
return "General"
if(2) //security
return "Security"
if(3) //medbay
return "Medbay"
if(4) //research
return "Research"
if(5) //engineering and maintenance
return "Engineering"
if(6) //supply
return "Supply"
if(7) //command
return "Command"
/proc/get_access_desc(A)
switch(A)
if(GLOB.access_cargo)
return "Cargo Bay"
if(GLOB.access_cargo_bot)
return "Delivery Chutes"
if(GLOB.access_security)
return "Security"
if(GLOB.access_brig)
return "Holding Cells"
if(GLOB.access_court)
return "Courtroom"
if(GLOB.access_forensics_lockers)
return "Forensics"
if(GLOB.access_medical)
return "Medical"
if(GLOB.access_genetics)
return "Genetics Lab"
if(GLOB.access_morgue)
return "Morgue"
if(GLOB.access_tox)
return "R&D Lab"
if(GLOB.access_tox_storage)
return "Toxins Lab"
if(GLOB.access_chemistry)
return "Chemistry Lab"
if(GLOB.access_rd)
return "RD Office"
if(GLOB.access_bar)
return "Bar"
if(GLOB.access_janitor)
return "Custodial Closet"
if(GLOB.access_engine)
return "Engineering"
if(GLOB.access_engine_equip)
return "Power Equipment"
if(GLOB.access_maint_tunnels)
return "Maintenance"
if(GLOB.access_external_airlocks)
return "External Airlocks"
if(GLOB.access_emergency_storage)
return "Emergency Storage"
if(GLOB.access_change_ids)
return "ID Console"
if(GLOB.access_ai_upload)
return "AI Chambers"
if(GLOB.access_teleporter)
return "Teleporter"
if(GLOB.access_eva)
return "EVA"
if(GLOB.access_heads)
return "Bridge"
if(GLOB.access_captain)
return "Captain"
if(GLOB.access_all_personal_lockers)
return "Personal Lockers"
if(GLOB.access_chapel_office)
return "Chapel Office"
if(GLOB.access_tech_storage)
return "Technical Storage"
if(GLOB.access_atmospherics)
return "Atmospherics"
if(GLOB.access_crematorium)
return "Crematorium"
if(GLOB.access_armory)
return "Armory"
if(GLOB.access_construction)
return "Construction"
if(GLOB.access_kitchen)
return "Kitchen"
if(GLOB.access_hydroponics)
return "Hydroponics"
if(GLOB.access_library)
return "Library"
if(GLOB.access_lawyer)
return "Law Office"
if(GLOB.access_robotics)
return "Robotics"
if(GLOB.access_virology)
return "Virology"
if(GLOB.access_cmo)
return "CMO Office"
if(GLOB.access_qm)
return "Quartermaster"
if(GLOB.access_surgery)
return "Surgery"
if(GLOB.access_theatre)
return "Theatre"
if(GLOB.access_manufacturing)
return "Manufacturing"
if(GLOB.access_research)
return "Science"
if(GLOB.access_mining)
return "Mining"
if(GLOB.access_mining_office)
return "Mining Office"
if(GLOB.access_mailsorting)
return "Cargo Office"
if(GLOB.access_mint)
return "Mint"
if(GLOB.access_mint_vault)
return "Mint Vault"
if(GLOB.access_heads_vault)
return "Main Vault"
if(GLOB.access_mining_station)
return "Mining EVA"
if(GLOB.access_xenobiology)
return "Xenobiology Lab"
if(GLOB.access_hop)
return "HoP Office"
if(GLOB.access_hos)
return "HoS Office"
if(GLOB.access_ce)
return "CE Office"
if(GLOB.access_RC_announce)
return "RC Announcements"
if(GLOB.access_keycard_auth)
return "Keycode Auth."
if(GLOB.access_tcomsat)
return "Telecommunications"
if(GLOB.access_gateway)
return "Gateway"
if(GLOB.access_sec_doors)
return "Brig"
if(GLOB.access_mineral_storeroom)
return "Mineral Storage"
if(GLOB.access_minisat)
return "AI Satellite"
if(GLOB.access_weapons)
return "Weapon Permit"
if(GLOB.access_network)
return "Network Access"
if(GLOB.access_cloning)
return "Cloning Room"
/proc/get_centcom_access_desc(A)
switch(A)
if(GLOB.access_cent_general)
return "Code Grey"
if(GLOB.access_cent_thunder)
return "Code Yellow"
if(GLOB.access_cent_storage)
return "Code Orange"
if(GLOB.access_cent_living)
return "Code Green"
if(GLOB.access_cent_medical)
return "Code White"
if(GLOB.access_cent_teleporter)
return "Code Blue"
if(GLOB.access_cent_specops)
return "Code Black"
if(GLOB.access_cent_captain)
return "Code Gold"
if(GLOB.access_cent_bar)
return "Code Scotch"
/proc/get_all_jobs()
return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Cook", "Botanist", "Quartermaster", "Cargo Technician",
"Shaft Miner", "Clown", "Mime", "Janitor", "Curator", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer",
"Atmospheric Technician", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist",
"Research Director", "Scientist", "Roboticist", "Head of Security", "Warden", "Detective", "Security Officer")
/proc/get_all_job_icons() //For all existing HUD icons
return get_all_jobs() + list("Prisoner")
/proc/get_all_centcom_jobs()
return list("VIP Guest","Custodian","Thunderdome Overseer","Centcom Official","Medical Officer","Death Commando","Research Officer","Special Ops Officer","Admiral","Centcom Commander","Emergency Response Team Commander","Security Response Officer","Engineer Response Officer", "Medical Response Officer","Centcom Bartender")
/obj/item/proc/GetJobName() //Used in secHUD icon generation
var/obj/item/weapon/card/id/I = GetID()
if(!I)
return
var/jobName = I.assignment
if(jobName in get_all_job_icons()) //Check if the job has a hud icon
return jobName
if(jobName in get_all_centcom_jobs()) //Return with the NT logo if it is a Centcom job
return "Centcom"
return "Unknown" //Return unknown if none of the above apply
GLOBAL_VAR_CONST(access_security, 1) // Security equipment
GLOBAL_VAR_CONST(access_brig, 2) // Brig timers and permabrig
GLOBAL_VAR_CONST(access_armory, 3)
GLOBAL_VAR_CONST(access_forensics_lockers, 4)
GLOBAL_VAR_CONST(access_medical, 5)
GLOBAL_VAR_CONST(access_morgue, 6)
GLOBAL_VAR_CONST(access_tox, 7)
GLOBAL_VAR_CONST(access_tox_storage, 8)
GLOBAL_VAR_CONST(access_genetics, 9)
GLOBAL_VAR_CONST(access_engine, 10)
GLOBAL_VAR_CONST(access_engine_equip, 11)
GLOBAL_VAR_CONST(access_maint_tunnels, 12)
GLOBAL_VAR_CONST(access_external_airlocks, 13)
GLOBAL_VAR_CONST(access_emergency_storage, 14)
GLOBAL_VAR_CONST(access_change_ids, 15)
GLOBAL_VAR_CONST(access_ai_upload, 16)
GLOBAL_VAR_CONST(access_teleporter, 17)
GLOBAL_VAR_CONST(access_eva, 18)
GLOBAL_VAR_CONST(access_heads, 19)
GLOBAL_VAR_CONST(access_captain, 20)
GLOBAL_VAR_CONST(access_all_personal_lockers, 21)
GLOBAL_VAR_CONST(access_chapel_office, 22)
GLOBAL_VAR_CONST(access_tech_storage, 23)
GLOBAL_VAR_CONST(access_atmospherics, 24)
GLOBAL_VAR_CONST(access_bar, 25)
GLOBAL_VAR_CONST(access_janitor, 26)
GLOBAL_VAR_CONST(access_crematorium, 27)
GLOBAL_VAR_CONST(access_kitchen, 28)
GLOBAL_VAR_CONST(access_robotics, 29)
GLOBAL_VAR_CONST(access_rd, 30)
GLOBAL_VAR_CONST(access_cargo, 31)
GLOBAL_VAR_CONST(access_construction, 32)
GLOBAL_VAR_CONST(access_chemistry, 33)
GLOBAL_VAR_CONST(access_cargo_bot, 34)
GLOBAL_VAR_CONST(access_hydroponics, 35)
GLOBAL_VAR_CONST(access_manufacturing, 36)
GLOBAL_VAR_CONST(access_library, 37)
GLOBAL_VAR_CONST(access_lawyer, 38)
GLOBAL_VAR_CONST(access_virology, 39)
GLOBAL_VAR_CONST(access_cmo, 40)
GLOBAL_VAR_CONST(access_qm, 41)
GLOBAL_VAR_CONST(access_court, 42)
GLOBAL_VAR_CONST(access_surgery, 45)
GLOBAL_VAR_CONST(access_theatre, 46)
GLOBAL_VAR_CONST(access_research, 47)
GLOBAL_VAR_CONST(access_mining, 48)
GLOBAL_VAR_CONST(access_mining_office, 49) //not in use
GLOBAL_VAR_CONST(access_mailsorting, 50)
GLOBAL_VAR_CONST(access_mint, 51)
GLOBAL_VAR_CONST(access_mint_vault, 52)
GLOBAL_VAR_CONST(access_heads_vault, 53)
GLOBAL_VAR_CONST(access_mining_station, 54)
GLOBAL_VAR_CONST(access_xenobiology, 55)
GLOBAL_VAR_CONST(access_ce, 56)
GLOBAL_VAR_CONST(access_hop, 57)
GLOBAL_VAR_CONST(access_hos, 58)
GLOBAL_VAR_CONST(access_RC_announce, 59) //Request console announcements
GLOBAL_VAR_CONST(access_keycard_auth, 60) //Used for events which require at least two people to confirm them
GLOBAL_VAR_CONST(access_tcomsat, 61) // has access to the entire telecomms satellite / machinery
GLOBAL_VAR_CONST(access_gateway, 62)
GLOBAL_VAR_CONST(access_sec_doors, 63) // Security front doors
GLOBAL_VAR_CONST(access_mineral_storeroom, 64)
GLOBAL_VAR_CONST(access_minisat, 65)
GLOBAL_VAR_CONST(access_weapons, 66) //Weapon authorization for secbots
GLOBAL_VAR_CONST(access_network, 67)
GLOBAL_VAR_CONST(access_cloning, 68) //Cloning room
//BEGIN CENTCOM ACCESS
/*Should leave plenty of room if we need to add more access levels.
Mostly for admin fun times.*/
GLOBAL_VAR_CONST(access_cent_general, 101)//General facilities.
GLOBAL_VAR_CONST(access_cent_thunder, 102)//Thunderdome.
GLOBAL_VAR_CONST(access_cent_specops, 103)//Special Ops.
GLOBAL_VAR_CONST(access_cent_medical, 104)//Medical/Research
GLOBAL_VAR_CONST(access_cent_living, 105)//Living quarters.
GLOBAL_VAR_CONST(access_cent_storage, 106)//Generic storage areas.
GLOBAL_VAR_CONST(access_cent_teleporter, 107)//Teleporter.
GLOBAL_VAR_CONST(access_cent_captain, 109)//Captain's office/ID comp/AI.
GLOBAL_VAR_CONST(access_cent_bar, 110) // The non-existent Centcom Bar
//The Syndicate
GLOBAL_VAR_CONST(access_syndicate, 150)//General Syndicate Access
GLOBAL_VAR_CONST(access_syndicate_leader, 151)//Nuke Op Leader Access
//Away Missions or Ruins
/*For generic away-mission/ruin access. Why would normal crew have access to a long-abandoned derelict
or a 2000 year-old temple? */
GLOBAL_VAR_CONST(access_away_general, 200)//General facilities.
GLOBAL_VAR_CONST(access_away_maint, 201)//Away maintenance
GLOBAL_VAR_CONST(access_away_med, 202)//Away medical
GLOBAL_VAR_CONST(access_away_sec, 203)//Away security
GLOBAL_VAR_CONST(access_away_engine, 204)//Away engineering
GLOBAL_VAR_CONST(access_away_generic1, 205)//Away generic access
GLOBAL_VAR_CONST(access_away_generic2, 206)
GLOBAL_VAR_CONST(access_away_generic3, 207)
GLOBAL_VAR_CONST(access_away_generic4, 208)
/obj/var/list/req_access = null
/obj/var/req_access_txt = "0"
/obj/var/list/req_one_access = null
/obj/var/req_one_access_txt = "0"
//returns 1 if this mob has sufficient access to use this object
/obj/proc/allowed(mob/M)
//check if it doesn't require any access at all
if(src.check_access(null))
return TRUE
if(issilicon(M))
if(ispAI(M))
return FALSE
return TRUE //AI can do whatever it wants
if(IsAdminGhost(M))
//Access can't stop the abuse
return TRUE
else if(ishuman(M))
var/mob/living/carbon/human/H = M
//if they are holding or wearing a card that has access, that works
if(check_access(H.get_active_held_item()) || src.check_access(H.wear_id))
return TRUE
else if(ismonkey(M) || isalienadult(M))
var/mob/living/carbon/george = M
//they can only hold things :(
if(check_access(george.get_active_held_item()))
return TRUE
else if(isanimal(M))
var/mob/living/simple_animal/A = M
if(check_access(A.get_active_held_item()) || check_access(A.access_card))
return TRUE
return FALSE
/obj/item/proc/GetAccess()
return list()
/obj/item/proc/GetID()
return null
//Call this before using req_access or req_one_access directly
/obj/proc/gen_access()
//These generations have been moved out of /obj/New() because they were slowing down the creation of objects that never even used the access system.
if(!src.req_access)
src.req_access = list()
if(src.req_access_txt)
var/list/req_access_str = splittext(req_access_txt,";")
for(var/x in req_access_str)
var/n = text2num(x)
if(n)
req_access += n
if(!src.req_one_access)
src.req_one_access = list()
if(src.req_one_access_txt)
var/list/req_one_access_str = splittext(req_one_access_txt,";")
for(var/x in req_one_access_str)
var/n = text2num(x)
if(n)
req_one_access += n
/obj/proc/check_access(obj/item/I)
gen_access()
if(!istype(src.req_access, /list)) //something's very wrong
return TRUE
var/list/L = src.req_access
if(!L.len && (!src.req_one_access || !src.req_one_access.len)) //no requirements
return TRUE
if(!I)
return FALSE
for(var/req in src.req_access)
if(!(req in I.GetAccess())) //doesn't have this access
return FALSE
if(src.req_one_access && src.req_one_access.len)
for(var/req in src.req_one_access)
if(req in I.GetAccess()) //has an access from the single access list
return TRUE
return FALSE
return TRUE
/obj/proc/check_access_list(list/L)
if(!src.req_access && !src.req_one_access)
return TRUE
if(!istype(src.req_access, /list))
return TRUE
if(!src.req_access.len && (!src.req_one_access || !src.req_one_access.len))
return TRUE
if(!L)
return FALSE
if(!istype(L, /list))
return FALSE
for(var/req in src.req_access)
if(!(req in L)) //doesn't have this access
return FALSE
if(src.req_one_access && src.req_one_access.len)
for(var/req in src.req_one_access)
if(req in L) //has an access from the single access list
return TRUE
return FALSE
return TRUE
/proc/get_centcom_access(job)
switch(job)
if("VIP Guest")
return list(GLOB.access_cent_general)
if("Custodian")
return list(GLOB.access_cent_general, GLOB.access_cent_living, GLOB.access_cent_storage)
if("Thunderdome Overseer")
return list(GLOB.access_cent_general, GLOB.access_cent_thunder)
if("Centcom Official")
return list(GLOB.access_cent_general, GLOB.access_cent_living)
if("Medical Officer")
return list(GLOB.access_cent_general, GLOB.access_cent_living, GLOB.access_cent_medical)
if("Death Commando")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_living, GLOB.access_cent_storage)
if("Research Officer")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_medical, GLOB.access_cent_teleporter, GLOB.access_cent_storage)
if("Special Ops Officer")
return list(GLOB.access_cent_general, GLOB.access_cent_thunder, GLOB.access_cent_specops, GLOB.access_cent_living, GLOB.access_cent_storage)
if("Admiral")
return get_all_centcom_access()
if("Centcom Commander")
return get_all_centcom_access()
if("Emergency Response Team Commander")
return get_ert_access("commander")
if("Security Response Officer")
return get_ert_access("sec")
if("Engineer Response Officer")
return get_ert_access("eng")
if("Medical Response Officer")
return get_ert_access("med")
if("Centcom Bartender")
return list(GLOB.access_cent_general, GLOB.access_cent_living, GLOB.access_cent_bar)
/proc/get_all_accesses()
return list(GLOB.access_security, GLOB.access_sec_doors, GLOB.access_brig, GLOB.access_armory, GLOB.access_forensics_lockers, GLOB.access_court,
GLOB.access_medical, GLOB.access_genetics, GLOB.access_morgue, GLOB.access_rd,
GLOB.access_tox, GLOB.access_tox_storage, GLOB.access_chemistry, GLOB.access_engine, GLOB.access_engine_equip, GLOB.access_maint_tunnels,
GLOB.access_external_airlocks, GLOB.access_change_ids, GLOB.access_ai_upload,
GLOB.access_teleporter, GLOB.access_eva, GLOB.access_heads, GLOB.access_captain, GLOB.access_all_personal_lockers,
GLOB.access_tech_storage, GLOB.access_chapel_office, GLOB.access_atmospherics, GLOB.access_kitchen,
GLOB.access_bar, GLOB.access_janitor, GLOB.access_crematorium, GLOB.access_robotics, GLOB.access_cargo, GLOB.access_construction,
GLOB.access_hydroponics, GLOB.access_library, GLOB.access_lawyer, GLOB.access_virology, GLOB.access_cmo, GLOB.access_qm, GLOB.access_surgery,
GLOB.access_theatre, GLOB.access_research, GLOB.access_mining, GLOB.access_mailsorting, GLOB.access_weapons,
GLOB.access_heads_vault, GLOB.access_mining_station, GLOB.access_xenobiology, GLOB.access_ce, GLOB.access_hop, GLOB.access_hos, GLOB.access_RC_announce,
GLOB.access_keycard_auth, GLOB.access_tcomsat, GLOB.access_gateway, GLOB.access_mineral_storeroom, GLOB.access_minisat, GLOB.access_network, GLOB.access_cloning)
/proc/get_all_centcom_access()
return list(GLOB.access_cent_general, GLOB.access_cent_thunder, GLOB.access_cent_specops, GLOB.access_cent_medical, GLOB.access_cent_living, GLOB.access_cent_storage, GLOB.access_cent_teleporter, GLOB.access_cent_captain)
/proc/get_ert_access(class)
switch(class)
if("commander")
return get_all_centcom_access()
if("sec")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_living)
if("eng")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_living, GLOB.access_cent_storage)
if("med")
return list(GLOB.access_cent_general, GLOB.access_cent_specops, GLOB.access_cent_medical, GLOB.access_cent_living)
/proc/get_all_syndicate_access()
return list(GLOB.access_syndicate, GLOB.access_syndicate)
/proc/get_region_accesses(code)
switch(code)
if(0)
return get_all_accesses()
if(1) //station general
return list(GLOB.access_kitchen,GLOB.access_bar, GLOB.access_hydroponics, GLOB.access_janitor, GLOB.access_chapel_office, GLOB.access_crematorium, GLOB.access_library, GLOB.access_theatre, GLOB.access_lawyer)
if(2) //security
return list(GLOB.access_sec_doors, GLOB.access_weapons, GLOB.access_security, GLOB.access_brig, GLOB.access_armory, GLOB.access_forensics_lockers, GLOB.access_court, GLOB.access_hos)
if(3) //medbay
return list(GLOB.access_medical, GLOB.access_genetics, GLOB.access_cloning, GLOB.access_morgue, GLOB.access_chemistry, GLOB.access_virology, GLOB.access_surgery, GLOB.access_cmo)
if(4) //research
return list(GLOB.access_research, GLOB.access_tox, GLOB.access_tox_storage, GLOB.access_genetics, GLOB.access_robotics, GLOB.access_xenobiology, GLOB.access_minisat, GLOB.access_rd, GLOB.access_network)
if(5) //engineering and maintenance
return list(GLOB.access_construction, GLOB.access_maint_tunnels, GLOB.access_engine, GLOB.access_engine_equip, GLOB.access_external_airlocks, GLOB.access_tech_storage, GLOB.access_atmospherics, GLOB.access_tcomsat, GLOB.access_minisat, GLOB.access_ce)
if(6) //supply
return list(GLOB.access_mailsorting, GLOB.access_mining, GLOB.access_mining_station, GLOB.access_mineral_storeroom, GLOB.access_cargo, GLOB.access_qm)
if(7) //command
return list(GLOB.access_heads, GLOB.access_RC_announce, GLOB.access_keycard_auth, GLOB.access_change_ids, GLOB.access_ai_upload, GLOB.access_teleporter, GLOB.access_eva, GLOB.access_gateway, GLOB.access_all_personal_lockers, GLOB.access_heads_vault, GLOB.access_hop, GLOB.access_captain)
/proc/get_region_accesses_name(code)
switch(code)
if(0)
return "All"
if(1) //station general
return "General"
if(2) //security
return "Security"
if(3) //medbay
return "Medbay"
if(4) //research
return "Research"
if(5) //engineering and maintenance
return "Engineering"
if(6) //supply
return "Supply"
if(7) //command
return "Command"
/proc/get_access_desc(A)
switch(A)
if(GLOB.access_cargo)
return "Cargo Bay"
if(GLOB.access_cargo_bot)
return "Delivery Chutes"
if(GLOB.access_security)
return "Security"
if(GLOB.access_brig)
return "Holding Cells"
if(GLOB.access_court)
return "Courtroom"
if(GLOB.access_forensics_lockers)
return "Forensics"
if(GLOB.access_medical)
return "Medical"
if(GLOB.access_genetics)
return "Genetics Lab"
if(GLOB.access_morgue)
return "Morgue"
if(GLOB.access_tox)
return "R&D Lab"
if(GLOB.access_tox_storage)
return "Toxins Lab"
if(GLOB.access_chemistry)
return "Chemistry Lab"
if(GLOB.access_rd)
return "RD Office"
if(GLOB.access_bar)
return "Bar"
if(GLOB.access_janitor)
return "Custodial Closet"
if(GLOB.access_engine)
return "Engineering"
if(GLOB.access_engine_equip)
return "Power Equipment"
if(GLOB.access_maint_tunnels)
return "Maintenance"
if(GLOB.access_external_airlocks)
return "External Airlocks"
if(GLOB.access_emergency_storage)
return "Emergency Storage"
if(GLOB.access_change_ids)
return "ID Console"
if(GLOB.access_ai_upload)
return "AI Chambers"
if(GLOB.access_teleporter)
return "Teleporter"
if(GLOB.access_eva)
return "EVA"
if(GLOB.access_heads)
return "Bridge"
if(GLOB.access_captain)
return "Captain"
if(GLOB.access_all_personal_lockers)
return "Personal Lockers"
if(GLOB.access_chapel_office)
return "Chapel Office"
if(GLOB.access_tech_storage)
return "Technical Storage"
if(GLOB.access_atmospherics)
return "Atmospherics"
if(GLOB.access_crematorium)
return "Crematorium"
if(GLOB.access_armory)
return "Armory"
if(GLOB.access_construction)
return "Construction"
if(GLOB.access_kitchen)
return "Kitchen"
if(GLOB.access_hydroponics)
return "Hydroponics"
if(GLOB.access_library)
return "Library"
if(GLOB.access_lawyer)
return "Law Office"
if(GLOB.access_robotics)
return "Robotics"
if(GLOB.access_virology)
return "Virology"
if(GLOB.access_cmo)
return "CMO Office"
if(GLOB.access_qm)
return "Quartermaster"
if(GLOB.access_surgery)
return "Surgery"
if(GLOB.access_theatre)
return "Theatre"
if(GLOB.access_manufacturing)
return "Manufacturing"
if(GLOB.access_research)
return "Science"
if(GLOB.access_mining)
return "Mining"
if(GLOB.access_mining_office)
return "Mining Office"
if(GLOB.access_mailsorting)
return "Cargo Office"
if(GLOB.access_mint)
return "Mint"
if(GLOB.access_mint_vault)
return "Mint Vault"
if(GLOB.access_heads_vault)
return "Main Vault"
if(GLOB.access_mining_station)
return "Mining EVA"
if(GLOB.access_xenobiology)
return "Xenobiology Lab"
if(GLOB.access_hop)
return "HoP Office"
if(GLOB.access_hos)
return "HoS Office"
if(GLOB.access_ce)
return "CE Office"
if(GLOB.access_RC_announce)
return "RC Announcements"
if(GLOB.access_keycard_auth)
return "Keycode Auth."
if(GLOB.access_tcomsat)
return "Telecommunications"
if(GLOB.access_gateway)
return "Gateway"
if(GLOB.access_sec_doors)
return "Brig"
if(GLOB.access_mineral_storeroom)
return "Mineral Storage"
if(GLOB.access_minisat)
return "AI Satellite"
if(GLOB.access_weapons)
return "Weapon Permit"
if(GLOB.access_network)
return "Network Access"
if(GLOB.access_cloning)
return "Cloning Room"
/proc/get_centcom_access_desc(A)
switch(A)
if(GLOB.access_cent_general)
return "Code Grey"
if(GLOB.access_cent_thunder)
return "Code Yellow"
if(GLOB.access_cent_storage)
return "Code Orange"
if(GLOB.access_cent_living)
return "Code Green"
if(GLOB.access_cent_medical)
return "Code White"
if(GLOB.access_cent_teleporter)
return "Code Blue"
if(GLOB.access_cent_specops)
return "Code Black"
if(GLOB.access_cent_captain)
return "Code Gold"
if(GLOB.access_cent_bar)
return "Code Scotch"
/proc/get_all_jobs()
return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Cook", "Botanist", "Quartermaster", "Cargo Technician",
"Shaft Miner", "Clown", "Mime", "Janitor", "Curator", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer",
"Atmospheric Technician", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist",
"Research Director", "Scientist", "Roboticist", "Head of Security", "Warden", "Detective", "Security Officer")
/proc/get_all_job_icons() //For all existing HUD icons
return get_all_jobs() + list("Prisoner")
/proc/get_all_centcom_jobs()
return list("VIP Guest","Custodian","Thunderdome Overseer","Centcom Official","Medical Officer","Death Commando","Research Officer","Special Ops Officer","Admiral","Centcom Commander","Emergency Response Team Commander","Security Response Officer","Engineer Response Officer", "Medical Response Officer","Centcom Bartender")
/obj/item/proc/GetJobName() //Used in secHUD icon generation
var/obj/item/weapon/card/id/I = GetID()
if(!I)
return
var/jobName = I.assignment
if(jobName in get_all_job_icons()) //Check if the job has a hud icon
return jobName
if(jobName in get_all_centcom_jobs()) //Return with the NT logo if it is a Centcom job
return "Centcom"
return "Unknown" //Return unknown if none of the above apply
+3 -3
View File
@@ -35,8 +35,8 @@ Clown
/obj/item/weapon/reagent_containers/spray/waterflower = 1,
/obj/item/weapon/reagent_containers/food/snacks/grown/banana = 1,
/obj/item/device/megaphone/clown = 1,
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/canned_laughter = 1,
/obj/item/weapon/pneumatic_cannon/pie = 1
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/canned_laughter = 1,
/obj/item/weapon/pneumatic_cannon/pie = 1
)
implants = list(/obj/item/weapon/implant/sad_trombone)
@@ -129,7 +129,7 @@ Curator
outfit = /datum/outfit/job/curator
access = list(GLOB.access_library)
minimal_access = list(GLOB.access_library, GLOB.access_construction,GLOB.access_mining_station)
minimal_access = list(GLOB.access_library, GLOB.access_construction,GLOB.access_mining_station)
/datum/outfit/job/curator
name = "Curator"
+108 -108
View File
@@ -1,109 +1,109 @@
GLOBAL_LIST_INIT(command_positions, list(
"Captain",
"Head of Personnel",
"Head of Security",
"Chief Engineer",
"Research Director",
"Chief Medical Officer"))
GLOBAL_LIST_INIT(engineering_positions, list(
"Chief Engineer",
"Station Engineer",
"Atmospheric Technician"))
GLOBAL_LIST_INIT(medical_positions, list(
"Chief Medical Officer",
"Medical Doctor",
"Geneticist",
"Virologist",
"Chemist"))
GLOBAL_LIST_INIT(science_positions, list(
"Research Director",
"Scientist",
"Roboticist"))
GLOBAL_LIST_INIT(supply_positions, list(
"Head of Personnel",
"Quartermaster",
"Cargo Technician",
"Shaft Miner"))
GLOBAL_LIST_INIT(civilian_positions, list(
"Bartender",
"Botanist",
"Cook",
"Janitor",
"Curator",
"Lawyer",
"Chaplain",
"Clown",
"Mime",
"Assistant"))
GLOBAL_LIST_INIT(security_positions, list(
"Head of Security",
"Warden",
"Detective",
"Security Officer"))
GLOBAL_LIST_INIT(nonhuman_positions, list(
"AI",
"Cyborg",
"pAI"))
/proc/guest_jobbans(job)
return ((job in GLOB.command_positions) || (job in GLOB.nonhuman_positions) || (job in GLOB.security_positions))
//this is necessary because antags happen before job datums are handed out, but NOT before they come into existence
//so I can't simply use job datum.department_head straight from the mind datum, laaaaame.
/proc/get_department_heads(var/job_title)
if(!job_title)
return list()
for(var/datum/job/J in SSjob.occupations)
if(J.title == job_title)
return J.department_head //this is a list
/proc/get_full_job_name(job)
var/static/regex/cap_expand = new("cap(?!tain)")
var/static/regex/cmo_expand = new("cmo")
var/static/regex/hos_expand = new("hos")
var/static/regex/hop_expand = new("hop")
var/static/regex/rd_expand = new("rd")
var/static/regex/ce_expand = new("ce")
var/static/regex/qm_expand = new("qm")
var/static/regex/sec_expand = new("(?<!security )officer")
var/static/regex/engi_expand = new("(?<!station )engineer")
var/static/regex/atmos_expand = new("atmos tech")
var/static/regex/doc_expand = new("(?<!medical )doctor|medic(?!al)")
var/static/regex/mine_expand = new("(?<!shaft )miner")
var/static/regex/chef_expand = new("chef")
var/static/regex/borg_expand = new("(?<!cy)borg")
job = lowertext(job)
job = cap_expand.Replace(job, "captain")
job = cmo_expand.Replace(job, "chief medical officer")
job = hos_expand.Replace(job, "head of security")
job = hop_expand.Replace(job, "head of personnel")
job = rd_expand.Replace(job, "research director")
job = ce_expand.Replace(job, "chief engineer")
job = qm_expand.Replace(job, "quartermaster")
job = sec_expand.Replace(job, "security officer")
job = engi_expand.Replace(job, "station engineer")
job = atmos_expand.Replace(job, "atmospheric technician")
job = doc_expand.Replace(job, "medical doctor")
job = mine_expand.Replace(job, "shaft miner")
job = chef_expand.Replace(job, "cook")
job = borg_expand.Replace(job, "cyborg")
GLOBAL_LIST_INIT(command_positions, list(
"Captain",
"Head of Personnel",
"Head of Security",
"Chief Engineer",
"Research Director",
"Chief Medical Officer"))
GLOBAL_LIST_INIT(engineering_positions, list(
"Chief Engineer",
"Station Engineer",
"Atmospheric Technician"))
GLOBAL_LIST_INIT(medical_positions, list(
"Chief Medical Officer",
"Medical Doctor",
"Geneticist",
"Virologist",
"Chemist"))
GLOBAL_LIST_INIT(science_positions, list(
"Research Director",
"Scientist",
"Roboticist"))
GLOBAL_LIST_INIT(supply_positions, list(
"Head of Personnel",
"Quartermaster",
"Cargo Technician",
"Shaft Miner"))
GLOBAL_LIST_INIT(civilian_positions, list(
"Bartender",
"Botanist",
"Cook",
"Janitor",
"Curator",
"Lawyer",
"Chaplain",
"Clown",
"Mime",
"Assistant"))
GLOBAL_LIST_INIT(security_positions, list(
"Head of Security",
"Warden",
"Detective",
"Security Officer"))
GLOBAL_LIST_INIT(nonhuman_positions, list(
"AI",
"Cyborg",
"pAI"))
/proc/guest_jobbans(job)
return ((job in GLOB.command_positions) || (job in GLOB.nonhuman_positions) || (job in GLOB.security_positions))
//this is necessary because antags happen before job datums are handed out, but NOT before they come into existence
//so I can't simply use job datum.department_head straight from the mind datum, laaaaame.
/proc/get_department_heads(var/job_title)
if(!job_title)
return list()
for(var/datum/job/J in SSjob.occupations)
if(J.title == job_title)
return J.department_head //this is a list
/proc/get_full_job_name(job)
var/static/regex/cap_expand = new("cap(?!tain)")
var/static/regex/cmo_expand = new("cmo")
var/static/regex/hos_expand = new("hos")
var/static/regex/hop_expand = new("hop")
var/static/regex/rd_expand = new("rd")
var/static/regex/ce_expand = new("ce")
var/static/regex/qm_expand = new("qm")
var/static/regex/sec_expand = new("(?<!security )officer")
var/static/regex/engi_expand = new("(?<!station )engineer")
var/static/regex/atmos_expand = new("atmos tech")
var/static/regex/doc_expand = new("(?<!medical )doctor|medic(?!al)")
var/static/regex/mine_expand = new("(?<!shaft )miner")
var/static/regex/chef_expand = new("chef")
var/static/regex/borg_expand = new("(?<!cy)borg")
job = lowertext(job)
job = cap_expand.Replace(job, "captain")
job = cmo_expand.Replace(job, "chief medical officer")
job = hos_expand.Replace(job, "head of security")
job = hop_expand.Replace(job, "head of personnel")
job = rd_expand.Replace(job, "research director")
job = ce_expand.Replace(job, "chief engineer")
job = qm_expand.Replace(job, "quartermaster")
job = sec_expand.Replace(job, "security officer")
job = engi_expand.Replace(job, "station engineer")
job = atmos_expand.Replace(job, "atmospheric technician")
job = doc_expand.Replace(job, "medical doctor")
job = mine_expand.Replace(job, "shaft miner")
job = chef_expand.Replace(job, "cook")
job = borg_expand.Replace(job, "cyborg")
return job
+61 -61
View File
@@ -1,61 +1,61 @@
//*******************************
//
// Library SQL Configuration
//
//*******************************
// Deprecated! See global.dm for new SQL config vars
/*
#define SQL_ADDRESS ""
#define SQL_DB ""
#define SQL_PORT "3306"
#define SQL_LOGIN ""
#define SQL_PASS ""
*/
//*******************************
// Requires Dantom.DB library ( http://www.byond.com/developer/Dantom/DB )
/*
The Library
------------
A place for the crew to go, relax, and enjoy a good book.
Aspiring authors can even self publish and, if they're lucky
convince the on-staff Curator to submit it to the Archives
to be chronicled in history forever - some say even persisting
through alternate dimensions.
Written by TLE for /tg/station 13
Feel free to use this as you like. Some credit would be cool.
Check us out at http://nanotrasen.com/ if you're so inclined.
*/
// CONTAINS:
// Objects:
// - bookcase
// - book
// - barcode scanner
// Machinery:
// - library computer
// - visitor's computer
// - book binder
// - book scanner
// Datum:
// - borrowbook
// Ideas for the future
// ---------------------
// - Visitor's computer should be able to search the current in-round library inventory (that the Curator has stocked and checked in)
// -- Give computer other features like an Instant Messenger application, or the ability to edit, save, and print documents.
// - Admin interface directly tied to the Archive DB. Right now there's no way to delete uploaded books in-game.
// -- If this gets implemented, allow Curators to "tag" or "suggest" books to be deleted. The DB ID of the tagged books gets saved to a text file (or another table in the DB maybe?).
// The admin interface would automatically take these IDs and SELECT them all from the DB to be displayed along with a Delete link to drop the row from the table.
// - When the game sets up and the round begins, have it automatically pick random books from the DB to populate the library with. Even if the Curator is a useless fuck there are at least a few books around.
// - Allow books to be "hollowed out" like the Chaplain's Bible, allowing you to store one pocket-sized item inside.
// - Make books/book cases burn when exposed to flame.
// - Make book binder hackable.
// - Books shouldn't print straight from the library computer. Make it synch with a machine like the book binder to print instead. This should consume some sort of resource.
//*******************************
//
// Library SQL Configuration
//
//*******************************
// Deprecated! See global.dm for new SQL config vars
/*
#define SQL_ADDRESS ""
#define SQL_DB ""
#define SQL_PORT "3306"
#define SQL_LOGIN ""
#define SQL_PASS ""
*/
//*******************************
// Requires Dantom.DB library ( http://www.byond.com/developer/Dantom/DB )
/*
The Library
------------
A place for the crew to go, relax, and enjoy a good book.
Aspiring authors can even self publish and, if they're lucky
convince the on-staff Curator to submit it to the Archives
to be chronicled in history forever - some say even persisting
through alternate dimensions.
Written by TLE for /tg/station 13
Feel free to use this as you like. Some credit would be cool.
Check us out at http://nanotrasen.com/ if you're so inclined.
*/
// CONTAINS:
// Objects:
// - bookcase
// - book
// - barcode scanner
// Machinery:
// - library computer
// - visitor's computer
// - book binder
// - book scanner
// Datum:
// - borrowbook
// Ideas for the future
// ---------------------
// - Visitor's computer should be able to search the current in-round library inventory (that the Curator has stocked and checked in)
// -- Give computer other features like an Instant Messenger application, or the ability to edit, save, and print documents.
// - Admin interface directly tied to the Archive DB. Right now there's no way to delete uploaded books in-game.
// -- If this gets implemented, allow Curators to "tag" or "suggest" books to be deleted. The DB ID of the tagged books gets saved to a text file (or another table in the DB maybe?).
// The admin interface would automatically take these IDs and SELECT them all from the DB to be displayed along with a Delete link to drop the row from the table.
// - When the game sets up and the round begins, have it automatically pick random books from the DB to populate the library with. Even if the Curator is a useless fuck there are at least a few books around.
// - Allow books to be "hollowed out" like the Chaplain's Bible, allowing you to store one pocket-sized item inside.
// - Make books/book cases burn when exposed to flame.
// - Make book binder hackable.
// - Books shouldn't print straight from the library computer. Make it synch with a machine like the book binder to print instead. This should consume some sort of resource.
+178 -178
View File
@@ -1,178 +1,178 @@
/datum/emote/living/carbon/human
mob_type_allowed_typecache = list(/mob/living/carbon/human)
/datum/emote/living/carbon/human/cry
key = "cry"
key_third_person = "cries"
message = "cries."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/dap
key = "dap"
key_third_person = "daps"
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
message_param = "give daps to %t."
restraint_check = TRUE
/datum/emote/living/carbon/human/eyebrow
key = "eyebrow"
message = "raises an eyebrow."
/datum/emote/living/carbon/human/grumble
key = "grumble"
key_third_person = "grumbles"
message = "grumbles!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/handshake
key = "handshake"
message = "shakes their own hands."
message_param = "shakes hands with %t."
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/hug
key = "hug"
key_third_person = "hugs"
message = "hugs themself."
message_param = "hugs %t."
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/mumble
key = "mumble"
key_third_person = "mumbles"
message = "mumbles!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/pale
key = "pale"
message = "goes pale for a second."
/datum/emote/living/carbon/human/raise
key = "raise"
key_third_person = "raises"
message = "raises a hand."
restraint_check = TRUE
/datum/emote/living/carbon/human/salute
key = "salute"
key_third_person = "salutes"
message = "salutes."
message_param = "salutes to %t."
restraint_check = TRUE
/datum/emote/living/carbon/human/shrug
key = "shrug"
key_third_person = "shrugs"
message = "shrugs."
/datum/emote/living/carbon/human/wag
key = "wag"
key_third_person = "wags"
message = "wags their tail."
/datum/emote/living/carbon/human/wag/run_emote(mob/user, params)
. = ..()
var/mob/living/carbon/human/H = user
if(.)
H.startTailWag()
else
H.endTailWag()
/datum/emote/living/carbon/human/wag/can_run_emote(mob/user)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && ((H.dna.features["tail_lizard"] != "None") || (H.dna.features["tail_human"] != "None") || ("mam_tail" in H.dna.species.mutant_bodyparts)))
return TRUE
/datum/emote/living/carbon/human/wag/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if(("waggingtail_lizard" in H.dna.species.mutant_bodyparts) || ("waggingtail_human" in H.dna.species.mutant_bodyparts) || ("mam_waggingtail" in H.dna.species.mutant_bodyparts))
. = null
/datum/emote/living/carbon/human/wing
key = "wing"
key_third_person = "wings"
message = "their wings."
/datum/emote/living/carbon/human/wing/run_emote(mob/user, params)
. = ..()
if(.)
var/mob/living/carbon/human/H = user
if(findtext(select_message_type(user), "open"))
H.OpenWings()
else
H.CloseWings()
/datum/emote/living/carbon/human/wing/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if("wings" in H.dna.species.mutant_bodyparts)
. = "opens " + message
else
. = "closes " + message
/datum/emote/living/carbon/human/wing/can_run_emote(mob/user)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && (H.dna.features["wings"] != "None"))
return TRUE
//Don't know where else to put this, it's basically an emote
/mob/living/carbon/human/proc/startTailWag()
if(!dna || !dna.species)
return
if("tail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_lizard"
dna.species.mutant_bodyparts -= "spines"
dna.species.mutant_bodyparts |= "waggingtail_lizard"
dna.species.mutant_bodyparts |= "waggingspines"
if("tail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_human"
dna.species.mutant_bodyparts |= "waggingtail_human"
if("mam_tail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_tail"
dna.species.mutant_bodyparts |= "mam_waggingtail"
update_body()
/mob/living/carbon/human/proc/endTailWag()
if(!dna || !dna.species)
return
if("waggingtail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_lizard"
dna.species.mutant_bodyparts -= "waggingspines"
dna.species.mutant_bodyparts |= "tail_lizard"
dna.species.mutant_bodyparts |= "spines"
if("waggingtail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_human"
dna.species.mutant_bodyparts |= "tail_human"
if("mam_waggingtail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_waggingtail"
dna.species.mutant_bodyparts |= "mam_tail"
update_body()
/mob/living/carbon/human/proc/OpenWings()
if(!dna || !dna.species)
return
if("wings" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "wings"
dna.species.mutant_bodyparts |= "wingsopen"
update_body()
/mob/living/carbon/human/proc/CloseWings()
if(!dna || !dna.species)
return
if("wingsopen" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "wingsopen"
dna.species.mutant_bodyparts |= "wings"
update_body()
if(isturf(loc))
var/turf/T = loc
T.Entered(src)
//Ayy lmao
/datum/emote/living/carbon/human
mob_type_allowed_typecache = list(/mob/living/carbon/human)
/datum/emote/living/carbon/human/cry
key = "cry"
key_third_person = "cries"
message = "cries."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/dap
key = "dap"
key_third_person = "daps"
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
message_param = "give daps to %t."
restraint_check = TRUE
/datum/emote/living/carbon/human/eyebrow
key = "eyebrow"
message = "raises an eyebrow."
/datum/emote/living/carbon/human/grumble
key = "grumble"
key_third_person = "grumbles"
message = "grumbles!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/handshake
key = "handshake"
message = "shakes their own hands."
message_param = "shakes hands with %t."
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/hug
key = "hug"
key_third_person = "hugs"
message = "hugs themself."
message_param = "hugs %t."
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/mumble
key = "mumble"
key_third_person = "mumbles"
message = "mumbles!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/pale
key = "pale"
message = "goes pale for a second."
/datum/emote/living/carbon/human/raise
key = "raise"
key_third_person = "raises"
message = "raises a hand."
restraint_check = TRUE
/datum/emote/living/carbon/human/salute
key = "salute"
key_third_person = "salutes"
message = "salutes."
message_param = "salutes to %t."
restraint_check = TRUE
/datum/emote/living/carbon/human/shrug
key = "shrug"
key_third_person = "shrugs"
message = "shrugs."
/datum/emote/living/carbon/human/wag
key = "wag"
key_third_person = "wags"
message = "wags their tail."
/datum/emote/living/carbon/human/wag/run_emote(mob/user, params)
. = ..()
var/mob/living/carbon/human/H = user
if(.)
H.startTailWag()
else
H.endTailWag()
/datum/emote/living/carbon/human/wag/can_run_emote(mob/user)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && ((H.dna.features["tail_lizard"] != "None") || (H.dna.features["tail_human"] != "None") || ("mam_tail" in H.dna.species.mutant_bodyparts)))
return TRUE
/datum/emote/living/carbon/human/wag/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if(("waggingtail_lizard" in H.dna.species.mutant_bodyparts) || ("waggingtail_human" in H.dna.species.mutant_bodyparts) || ("mam_waggingtail" in H.dna.species.mutant_bodyparts))
. = null
/datum/emote/living/carbon/human/wing
key = "wing"
key_third_person = "wings"
message = "their wings."
/datum/emote/living/carbon/human/wing/run_emote(mob/user, params)
. = ..()
if(.)
var/mob/living/carbon/human/H = user
if(findtext(select_message_type(user), "open"))
H.OpenWings()
else
H.CloseWings()
/datum/emote/living/carbon/human/wing/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if("wings" in H.dna.species.mutant_bodyparts)
. = "opens " + message
else
. = "closes " + message
/datum/emote/living/carbon/human/wing/can_run_emote(mob/user)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && (H.dna.features["wings"] != "None"))
return TRUE
//Don't know where else to put this, it's basically an emote
/mob/living/carbon/human/proc/startTailWag()
if(!dna || !dna.species)
return
if("tail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_lizard"
dna.species.mutant_bodyparts -= "spines"
dna.species.mutant_bodyparts |= "waggingtail_lizard"
dna.species.mutant_bodyparts |= "waggingspines"
if("tail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_human"
dna.species.mutant_bodyparts |= "waggingtail_human"
if("mam_tail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_tail"
dna.species.mutant_bodyparts |= "mam_waggingtail"
update_body()
/mob/living/carbon/human/proc/endTailWag()
if(!dna || !dna.species)
return
if("waggingtail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_lizard"
dna.species.mutant_bodyparts -= "waggingspines"
dna.species.mutant_bodyparts |= "tail_lizard"
dna.species.mutant_bodyparts |= "spines"
if("waggingtail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_human"
dna.species.mutant_bodyparts |= "tail_human"
if("mam_waggingtail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_waggingtail"
dna.species.mutant_bodyparts |= "mam_tail"
update_body()
/mob/living/carbon/human/proc/OpenWings()
if(!dna || !dna.species)
return
if("wings" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "wings"
dna.species.mutant_bodyparts |= "wingsopen"
update_body()
/mob/living/carbon/human/proc/CloseWings()
if(!dna || !dna.species)
return
if("wingsopen" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "wingsopen"
dna.species.mutant_bodyparts |= "wings"
update_body()
if(isturf(loc))
var/turf/T = loc
T.Entered(src)
//Ayy lmao
File diff suppressed because it is too large Load Diff
@@ -1,421 +1,421 @@
/mob/living/simple_animal/bot/secbot
name = "\improper Securitron"
desc = "A little security robot. He looks less than thrilled."
icon = 'icons/mob/aibots.dmi'
icon_state = "secbot0"
density = 0
anchored = 0
health = 25
maxHealth = 25
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
pass_flags = PASSMOB
radio_key = /obj/item/device/encryptionkey/secbot //AI Priv + Security
radio_channel = "Security" //Security channel
bot_type = SEC_BOT
model = "Securitron"
bot_core_type = /obj/machinery/bot_core/secbot
var/baton_type = /obj/item/weapon/melee/baton
window_id = "autosec"
window_name = "Automatic Security Unit v1.6"
allow_pai = 0
data_hud_type = DATA_HUD_SECURITY_ADVANCED
var/mob/living/carbon/target
var/oldtarget_name
var/threatlevel = 0
var/target_lastloc //Loc of target when arrested.
var/last_found //There's a delay
var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel?
var/idcheck = 0 //If true, arrest people with no IDs
var/weaponscheck = 0 //If true, arrest people for weapons if they lack access
var/check_records = 1 //Does it check security records?
var/arrest_type = 0 //If true, don't handcuff
/mob/living/simple_animal/bot/secbot/beepsky
name = "Officer Beep O'sky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
idcheck = 0
weaponscheck = 0
auto_patrol = 1
/mob/living/simple_animal/bot/secbot/beepsky/jr
name = "Officer Pipsqueak"
desc = "It's Officer Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak."
/mob/living/simple_animal/bot/secbot/beepsky/jr/Initialize()
..()
resize = 0.8
update_transform()
/mob/living/simple_animal/bot/secbot/beepsky/explode()
var/turf/Tsec = get_turf(src)
new /obj/item/weapon/stock_parts/cell/potato(Tsec)
var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec)
S.reagents.add_reagent("whiskey", 15)
S.on_reagent_change()
..()
/mob/living/simple_animal/bot/secbot/pingsky
name = "Officer Pingsky"
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
radio_channel = "AI Private"
/mob/living/simple_animal/bot/secbot/Initialize()
..()
icon_state = "secbot[on]"
spawn(3)
var/datum/job/detective/J = new/datum/job/detective
access_card.access += J.get_access()
prev_access = access_card.access
//SECHUD
var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
secsensor.add_hud_to(src)
/mob/living/simple_animal/bot/secbot/turn_on()
..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/turn_off()
..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/bot_reset()
..()
target = null
oldtarget_name = null
anchored = 0
walk_to(src,0)
last_found = world.time
/mob/living/simple_animal/bot/secbot/set_custom_texts()
text_hack = "You overload [name]'s target identification system."
text_dehack = "You reboot [name] and restore the target identification."
text_dehack_fail = "[name] refuses to accept your authority!"
/mob/living/simple_animal/bot/secbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += text({"
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
Status: []<BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]"},
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
if(!locked || issilicon(user) || IsAdminGhost(user))
dat += text({"<BR>
Arrest Unidentifiable Persons: []<BR>
Arrest for Unauthorized Weapons: []<BR>
Arrest for Warrant: []<BR>
Operating Mode: []<BR>
Report Arrests[]<BR>
Auto Patrol: []"},
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
return dat
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
if(..())
return 1
switch(href_list["operation"])
if("idcheck")
idcheck = !idcheck
update_controls()
if("weaponscheck")
weaponscheck = !weaponscheck
update_controls()
if("ignorerec")
check_records = !check_records
update_controls()
if("switchmode")
arrest_type = !arrest_type
update_controls()
if("declarearrests")
declare_arrests = !declare_arrests
update_controls()
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
threatlevel = H.assess_threat(src)
threatlevel += 6
if(threatlevel >= 4)
target = H
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM))
retaliate(H)
return ..()
/mob/living/simple_animal/bot/secbot/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
return
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
retaliate(user)
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
..()
if(emagged == 2)
if(user)
to_chat(user, "<span class='danger'>You short out [src]'s target assessment circuits.</span>")
oldtarget_name = user.name
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
declare_arrests = 0
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if(!Proj.nodamage && Proj.damage < src.health)
retaliate(Proj.firer)
..()
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
if(!on)
return
if(iscarbon(A))
var/mob/living/carbon/C = A
if(!C.stunned || arrest_type)
stun_attack(A)
else if(C.canBeHandcuffed() && !C.handcuffed)
cuff(A)
else
..()
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
var/mob/living/carbon/human/H = I.thrownby
retaliate(H)
..()
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
mode = BOT_ARREST
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
spawn(60)
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
C.update_handcuffed()
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
back_to_idle()
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
icon_state = "secbot-c"
spawn(2)
icon_state = "secbot[on]"
var/threat = 5
if(ishuman(C))
C.stuttering = 5
C.Stun(5)
C.Weaken(5)
var/mob/living/carbon/human/H = C
threat = H.assess_threat(src)
else
C.Weaken(5)
C.stuttering = 5
C.Stun(5)
threat = C.assess_threat()
add_logs(src,C,"stunned")
if(declare_arrests)
var/area/location = get_area(src)
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
C.visible_message("<span class='danger'>[src] has stunned [C]!</span>",\
"<span class='userdanger'>[src] has stunned you!</span>")
/mob/living/simple_animal/bot/secbot/handle_automated_action()
if(!..())
return
switch(mode)
if(BOT_IDLE) // idle
walk_to(src,0)
look_for_perp() // see if any criminals are in range
if(!mode && auto_patrol) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
if(BOT_HUNT) // hunting for perp
// if can't reach perp for long enough, go idle
if(frustration >= 8)
walk_to(src,0)
back_to_idle()
return
if(target) // make sure target exists
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
stun_attack(target)
mode = BOT_PREP_ARREST
anchored = 1
target_lastloc = target.loc
return
else // not next to perp
var/turf/olddist = get_dist(src, target)
walk_to(src, target,1,4)
if((get_dist(src, target)) >= (olddist))
frustration++
else
frustration = 0
else
back_to_idle()
if(BOT_PREP_ARREST) // preparing to arrest target
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
back_to_hunt()
return
if(iscarbon(target) && target.canBeHandcuffed())
if(!arrest_type)
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
cuff(target)
else
back_to_idle()
return
else
back_to_idle()
return
if(BOT_ARREST)
if(!target)
anchored = 0
mode = BOT_IDLE
last_found = world.time
frustration = 0
return
if(target.handcuffed) //no target or target cuffed? back to idle.
back_to_idle()
return
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
back_to_hunt()
return
else //Try arresting again if the target escapes.
mode = BOT_PREP_ARREST
anchored = 0
if(BOT_START_PATROL)
look_for_perp()
start_patrol()
if(BOT_PATROL)
look_for_perp()
bot_patrol()
return
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
anchored = 0
mode = BOT_IDLE
target = null
last_found = world.time
frustration = 0
spawn(0)
handle_automated_action() //ensure bot quickly responds
/mob/living/simple_animal/bot/secbot/proc/back_to_hunt()
anchored = 0
frustration = 0
mode = BOT_HUNT
spawn(0)
handle_automated_action() //ensure bot quickly responds
// look for a criminal in view of the bot
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
anchored = 0
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
if((C.stat) || (C.handcuffed))
continue
if((C.name == oldtarget_name) && (world.time < last_found + 100))
continue
threatlevel = C.assess_threat(src)
if(!threatlevel)
continue
else if(threatlevel >= 4)
target = C
oldtarget_name = C.name
speak("Level [threatlevel] infraction alert!")
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
visible_message("<b>[src]</b> points at [C.name]!")
mode = BOT_HUNT
spawn(0)
handle_automated_action() // ensure bot quickly responds to a perp
break
else
continue
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item)
if(slot_item && slot_item.needs_permit)
return 1
return 0
/mob/living/simple_animal/bot/secbot/explode()
walk_to(src,0)
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/secbot_assembly(Tsec)
Sa.build_step = 1
Sa.add_overlay("hs_hole")
Sa.created_name = name
new /obj/item/device/assembly/prox_sensor(Tsec)
new baton_type(Tsec)
if(prob(50))
new /obj/item/bodypart/l_arm/robot(Tsec)
do_sparks(3, TRUE, src)
new /obj/effect/decal/cleanable/oil(loc)
..()
/mob/living/simple_animal/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
..()
if(!isalien(target))
target = user
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
if(ismob(AM) && target)
var/mob/living/carbon/C = AM
if(!istype(C) || !C || in_range(src, target))
return
knockOver(C)
return
..()
/obj/machinery/bot_core/secbot
req_access = list(GLOB.access_security)
/mob/living/simple_animal/bot/secbot
name = "\improper Securitron"
desc = "A little security robot. He looks less than thrilled."
icon = 'icons/mob/aibots.dmi'
icon_state = "secbot0"
density = 0
anchored = 0
health = 25
maxHealth = 25
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
pass_flags = PASSMOB
radio_key = /obj/item/device/encryptionkey/secbot //AI Priv + Security
radio_channel = "Security" //Security channel
bot_type = SEC_BOT
model = "Securitron"
bot_core_type = /obj/machinery/bot_core/secbot
var/baton_type = /obj/item/weapon/melee/baton
window_id = "autosec"
window_name = "Automatic Security Unit v1.6"
allow_pai = 0
data_hud_type = DATA_HUD_SECURITY_ADVANCED
var/mob/living/carbon/target
var/oldtarget_name
var/threatlevel = 0
var/target_lastloc //Loc of target when arrested.
var/last_found //There's a delay
var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel?
var/idcheck = 0 //If true, arrest people with no IDs
var/weaponscheck = 0 //If true, arrest people for weapons if they lack access
var/check_records = 1 //Does it check security records?
var/arrest_type = 0 //If true, don't handcuff
/mob/living/simple_animal/bot/secbot/beepsky
name = "Officer Beep O'sky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
idcheck = 0
weaponscheck = 0
auto_patrol = 1
/mob/living/simple_animal/bot/secbot/beepsky/jr
name = "Officer Pipsqueak"
desc = "It's Officer Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak."
/mob/living/simple_animal/bot/secbot/beepsky/jr/Initialize()
..()
resize = 0.8
update_transform()
/mob/living/simple_animal/bot/secbot/beepsky/explode()
var/turf/Tsec = get_turf(src)
new /obj/item/weapon/stock_parts/cell/potato(Tsec)
var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec)
S.reagents.add_reagent("whiskey", 15)
S.on_reagent_change()
..()
/mob/living/simple_animal/bot/secbot/pingsky
name = "Officer Pingsky"
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
radio_channel = "AI Private"
/mob/living/simple_animal/bot/secbot/Initialize()
..()
icon_state = "secbot[on]"
spawn(3)
var/datum/job/detective/J = new/datum/job/detective
access_card.access += J.get_access()
prev_access = access_card.access
//SECHUD
var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
secsensor.add_hud_to(src)
/mob/living/simple_animal/bot/secbot/turn_on()
..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/turn_off()
..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/bot_reset()
..()
target = null
oldtarget_name = null
anchored = 0
walk_to(src,0)
last_found = world.time
/mob/living/simple_animal/bot/secbot/set_custom_texts()
text_hack = "You overload [name]'s target identification system."
text_dehack = "You reboot [name] and restore the target identification."
text_dehack_fail = "[name] refuses to accept your authority!"
/mob/living/simple_animal/bot/secbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += text({"
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
Status: []<BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]"},
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
if(!locked || issilicon(user) || IsAdminGhost(user))
dat += text({"<BR>
Arrest Unidentifiable Persons: []<BR>
Arrest for Unauthorized Weapons: []<BR>
Arrest for Warrant: []<BR>
Operating Mode: []<BR>
Report Arrests[]<BR>
Auto Patrol: []"},
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
return dat
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
if(..())
return 1
switch(href_list["operation"])
if("idcheck")
idcheck = !idcheck
update_controls()
if("weaponscheck")
weaponscheck = !weaponscheck
update_controls()
if("ignorerec")
check_records = !check_records
update_controls()
if("switchmode")
arrest_type = !arrest_type
update_controls()
if("declarearrests")
declare_arrests = !declare_arrests
update_controls()
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
threatlevel = H.assess_threat(src)
threatlevel += 6
if(threatlevel >= 4)
target = H
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM))
retaliate(H)
return ..()
/mob/living/simple_animal/bot/secbot/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
return
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
retaliate(user)
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
..()
if(emagged == 2)
if(user)
to_chat(user, "<span class='danger'>You short out [src]'s target assessment circuits.</span>")
oldtarget_name = user.name
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
declare_arrests = 0
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if(!Proj.nodamage && Proj.damage < src.health)
retaliate(Proj.firer)
..()
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
if(!on)
return
if(iscarbon(A))
var/mob/living/carbon/C = A
if(!C.stunned || arrest_type)
stun_attack(A)
else if(C.canBeHandcuffed() && !C.handcuffed)
cuff(A)
else
..()
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
var/mob/living/carbon/human/H = I.thrownby
retaliate(H)
..()
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
mode = BOT_ARREST
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
spawn(60)
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
C.update_handcuffed()
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
back_to_idle()
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
icon_state = "secbot-c"
spawn(2)
icon_state = "secbot[on]"
var/threat = 5
if(ishuman(C))
C.stuttering = 5
C.Stun(5)
C.Weaken(5)
var/mob/living/carbon/human/H = C
threat = H.assess_threat(src)
else
C.Weaken(5)
C.stuttering = 5
C.Stun(5)
threat = C.assess_threat()
add_logs(src,C,"stunned")
if(declare_arrests)
var/area/location = get_area(src)
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
C.visible_message("<span class='danger'>[src] has stunned [C]!</span>",\
"<span class='userdanger'>[src] has stunned you!</span>")
/mob/living/simple_animal/bot/secbot/handle_automated_action()
if(!..())
return
switch(mode)
if(BOT_IDLE) // idle
walk_to(src,0)
look_for_perp() // see if any criminals are in range
if(!mode && auto_patrol) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
if(BOT_HUNT) // hunting for perp
// if can't reach perp for long enough, go idle
if(frustration >= 8)
walk_to(src,0)
back_to_idle()
return
if(target) // make sure target exists
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
stun_attack(target)
mode = BOT_PREP_ARREST
anchored = 1
target_lastloc = target.loc
return
else // not next to perp
var/turf/olddist = get_dist(src, target)
walk_to(src, target,1,4)
if((get_dist(src, target)) >= (olddist))
frustration++
else
frustration = 0
else
back_to_idle()
if(BOT_PREP_ARREST) // preparing to arrest target
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
back_to_hunt()
return
if(iscarbon(target) && target.canBeHandcuffed())
if(!arrest_type)
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
cuff(target)
else
back_to_idle()
return
else
back_to_idle()
return
if(BOT_ARREST)
if(!target)
anchored = 0
mode = BOT_IDLE
last_found = world.time
frustration = 0
return
if(target.handcuffed) //no target or target cuffed? back to idle.
back_to_idle()
return
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
back_to_hunt()
return
else //Try arresting again if the target escapes.
mode = BOT_PREP_ARREST
anchored = 0
if(BOT_START_PATROL)
look_for_perp()
start_patrol()
if(BOT_PATROL)
look_for_perp()
bot_patrol()
return
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
anchored = 0
mode = BOT_IDLE
target = null
last_found = world.time
frustration = 0
spawn(0)
handle_automated_action() //ensure bot quickly responds
/mob/living/simple_animal/bot/secbot/proc/back_to_hunt()
anchored = 0
frustration = 0
mode = BOT_HUNT
spawn(0)
handle_automated_action() //ensure bot quickly responds
// look for a criminal in view of the bot
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
anchored = 0
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
if((C.stat) || (C.handcuffed))
continue
if((C.name == oldtarget_name) && (world.time < last_found + 100))
continue
threatlevel = C.assess_threat(src)
if(!threatlevel)
continue
else if(threatlevel >= 4)
target = C
oldtarget_name = C.name
speak("Level [threatlevel] infraction alert!")
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
visible_message("<b>[src]</b> points at [C.name]!")
mode = BOT_HUNT
spawn(0)
handle_automated_action() // ensure bot quickly responds to a perp
break
else
continue
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item)
if(slot_item && slot_item.needs_permit)
return 1
return 0
/mob/living/simple_animal/bot/secbot/explode()
walk_to(src,0)
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/secbot_assembly(Tsec)
Sa.build_step = 1
Sa.add_overlay("hs_hole")
Sa.created_name = name
new /obj/item/device/assembly/prox_sensor(Tsec)
new baton_type(Tsec)
if(prob(50))
new /obj/item/bodypart/l_arm/robot(Tsec)
do_sparks(3, TRUE, src)
new /obj/effect/decal/cleanable/oil(loc)
..()
/mob/living/simple_animal/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
..()
if(!isalien(target))
target = user
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
if(ismob(AM) && target)
var/mob/living/carbon/C = AM
if(!istype(C) || !C || in_range(src, target))
return
knockOver(C)
return
..()
/obj/machinery/bot_core/secbot
req_access = list(GLOB.access_security)
@@ -1,57 +1,57 @@
/obj/item/projectile/hivebotbullet
damage = 10
damage_type = BRUTE
/mob/living/simple_animal/hostile/hivebot
name = "hivebot"
desc = "A small robot."
icon = 'icons/mob/hivebot.dmi'
icon_state = "basic"
icon_living = "basic"
icon_dead = "basic"
gender = NEUTER
health = 15
maxHealth = 15
healable = 0
melee_damage_lower = 2
melee_damage_upper = 3
attacktext = "claws"
attack_sound = 'sound/weapons/bladeslice.ogg'
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
faction = list("hivebot")
check_friendly_fire = 1
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
speak_emote = list("states")
gold_core_spawnable = 1
del_on_death = 1
loot = list(/obj/effect/decal/cleanable/robot_debris)
/mob/living/simple_animal/hostile/hivebot/Initialize()
..()
deathmessage = "[src] blows apart!"
/mob/living/simple_animal/hostile/hivebot/range
name = "hivebot"
desc = "A smallish robot, this one is armed!"
ranged = 1
retreat_distance = 5
minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/rapid
ranged = 1
rapid = 1
retreat_distance = 5
minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/strong
name = "strong hivebot"
desc = "A robot, this one is armed and looks tough!"
health = 80
maxHealth = 80
ranged = 1
/mob/living/simple_animal/hostile/hivebot/death(gibbed)
do_sparks(3, TRUE, src)
/obj/item/projectile/hivebotbullet
damage = 10
damage_type = BRUTE
/mob/living/simple_animal/hostile/hivebot
name = "hivebot"
desc = "A small robot."
icon = 'icons/mob/hivebot.dmi'
icon_state = "basic"
icon_living = "basic"
icon_dead = "basic"
gender = NEUTER
health = 15
maxHealth = 15
healable = 0
melee_damage_lower = 2
melee_damage_upper = 3
attacktext = "claws"
attack_sound = 'sound/weapons/bladeslice.ogg'
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
faction = list("hivebot")
check_friendly_fire = 1
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
speak_emote = list("states")
gold_core_spawnable = 1
del_on_death = 1
loot = list(/obj/effect/decal/cleanable/robot_debris)
/mob/living/simple_animal/hostile/hivebot/Initialize()
..()
deathmessage = "[src] blows apart!"
/mob/living/simple_animal/hostile/hivebot/range
name = "hivebot"
desc = "A smallish robot, this one is armed!"
ranged = 1
retreat_distance = 5
minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/rapid
ranged = 1
rapid = 1
retreat_distance = 5
minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/strong
name = "strong hivebot"
desc = "A robot, this one is armed and looks tough!"
health = 80
maxHealth = 80
ranged = 1
/mob/living/simple_animal/hostile/hivebot/death(gibbed)
do_sparks(3, TRUE, src)
..(1)
+236 -236
View File
@@ -1,236 +1,236 @@
/obj/item/ammo_casing/energy
name = "energy weapon lens"
desc = "The part of the gun that makes the laser go pew"
caliber = "energy"
projectile_type = /obj/item/projectile/energy
var/e_cost = 100 //The amount of energy a cell needs to expend to create this shot.
var/select_name = "energy"
fire_sound = 'sound/weapons/Laser.ogg'
firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect/energy
/obj/item/ammo_casing/energy/chameleon
e_cost = 0
var/list/projectile_vars = list()
/obj/item/ammo_casing/energy/chameleon/ready_proj()
. = ..()
if(!BB)
newshot()
for(var/V in projectile_vars)
if(BB.vars[V])
BB.vars[V] = projectile_vars[V]
/obj/item/ammo_casing/energy/laser
projectile_type = /obj/item/projectile/beam/laser
select_name = "kill"
/obj/item/ammo_casing/energy/lasergun
projectile_type = /obj/item/projectile/beam/laser
e_cost = 83
select_name = "kill"
/obj/item/ammo_casing/energy/laser/hos
e_cost = 100
/obj/item/ammo_casing/energy/laser/practice
projectile_type = /obj/item/projectile/beam/practice
select_name = "practice"
/obj/item/ammo_casing/energy/laser/scatter
projectile_type = /obj/item/projectile/beam/scatter
pellets = 5
variance = 25
select_name = "scatter"
/obj/item/ammo_casing/energy/laser/scatter/disabler
projectile_type = /obj/item/projectile/beam/disabler
pellets = 3
variance = 15
/obj/item/ammo_casing/energy/laser/heavy
projectile_type = /obj/item/projectile/beam/laser/heavylaser
select_name = "anti-vehicle"
fire_sound = 'sound/weapons/lasercannonfire.ogg'
/obj/item/ammo_casing/energy/laser/pulse
projectile_type = /obj/item/projectile/beam/pulse
e_cost = 200
select_name = "DESTROY"
fire_sound = 'sound/weapons/pulse.ogg'
/obj/item/ammo_casing/energy/laser/bluetag
projectile_type = /obj/item/projectile/beam/lasertag/bluetag
select_name = "bluetag"
/obj/item/ammo_casing/energy/laser/redtag
projectile_type = /obj/item/projectile/beam/lasertag/redtag
select_name = "redtag"
/obj/item/ammo_casing/energy/xray
projectile_type = /obj/item/projectile/beam/xray
e_cost = 50
fire_sound = 'sound/weapons/laser3.ogg'
/obj/item/ammo_casing/energy/electrode
projectile_type = /obj/item/projectile/energy/electrode
select_name = "stun"
fire_sound = 'sound/weapons/taser.ogg'
e_cost = 200
/obj/item/ammo_casing/energy/electrode/gun
fire_sound = 'sound/weapons/gunshot.ogg'
e_cost = 100
/obj/item/ammo_casing/energy/electrode/hos
e_cost = 200
/obj/item/ammo_casing/energy/ion
projectile_type = /obj/item/projectile/ion
select_name = "ion"
fire_sound = 'sound/weapons/IonRifle.ogg'
/obj/item/ammo_casing/energy/declone
projectile_type = /obj/item/projectile/energy/declone
select_name = "declone"
fire_sound = 'sound/weapons/pulse3.ogg'
/obj/item/ammo_casing/energy/mindflayer
projectile_type = /obj/item/projectile/beam/mindflayer
select_name = "MINDFUCK"
fire_sound = 'sound/weapons/Laser.ogg'
/obj/item/ammo_casing/energy/flora
fire_sound = 'sound/effects/stealthoff.ogg'
/obj/item/ammo_casing/energy/flora/yield
projectile_type = /obj/item/projectile/energy/florayield
select_name = "yield"
/obj/item/ammo_casing/energy/flora/mut
projectile_type = /obj/item/projectile/energy/floramut
select_name = "mutation"
/obj/item/ammo_casing/energy/temp
projectile_type = /obj/item/projectile/temp
select_name = "freeze"
e_cost = 250
fire_sound = 'sound/weapons/pulse3.ogg'
/obj/item/ammo_casing/energy/temp/hot
projectile_type = /obj/item/projectile/temp/hot
select_name = "bake"
/obj/item/ammo_casing/energy/meteor
projectile_type = /obj/item/projectile/meteor
select_name = "goddamn meteor"
/obj/item/ammo_casing/energy/disabler
projectile_type = /obj/item/projectile/beam/disabler
select_name = "disable"
e_cost = 50
fire_sound = 'sound/weapons/taser2.ogg'
/obj/item/ammo_casing/energy/plasma
projectile_type = /obj/item/projectile/plasma
select_name = "plasma burst"
fire_sound = 'sound/weapons/plasma_cutter.ogg'
delay = 15
e_cost = 25
/obj/item/ammo_casing/energy/plasma/adv
projectile_type = /obj/item/projectile/plasma/adv
delay = 10
e_cost = 10
/obj/item/ammo_casing/energy/wormhole
projectile_type = /obj/item/projectile/beam/wormhole
e_cost = 0
fire_sound = 'sound/weapons/pulse3.ogg'
var/obj/item/weapon/gun/energy/wormhole_projector/gun = null
select_name = "blue"
/obj/item/ammo_casing/energy/wormhole/orange
projectile_type = /obj/item/projectile/beam/wormhole/orange
select_name = "orange"
/obj/item/ammo_casing/energy/bolt
projectile_type = /obj/item/projectile/energy/bolt
select_name = "bolt"
e_cost = 500
fire_sound = 'sound/weapons/Genhit.ogg'
/obj/item/ammo_casing/energy/bolt/halloween
projectile_type = /obj/item/projectile/energy/bolt/halloween
/obj/item/ammo_casing/energy/bolt/large
projectile_type = /obj/item/projectile/energy/bolt/large
select_name = "heavy bolt"
/obj/item/ammo_casing/energy/net
projectile_type = /obj/item/projectile/energy/net
select_name = "netting"
pellets = 6
variance = 40
/obj/item/ammo_casing/energy/trap
projectile_type = /obj/item/projectile/energy/trap
select_name = "snare"
/obj/item/ammo_casing/energy/instakill
projectile_type = /obj/item/projectile/beam/instakill
e_cost = 0
select_name = "DESTROY"
/obj/item/ammo_casing/energy/instakill/blue
projectile_type = /obj/item/projectile/beam/instakill/blue
/obj/item/ammo_casing/energy/instakill/red
projectile_type = /obj/item/projectile/beam/instakill/red
/obj/item/ammo_casing/energy/tesla_revolver
fire_sound = 'sound/magic/lightningbolt.ogg'
e_cost = 200
select_name = "stun"
projectile_type = /obj/item/projectile/energy/tesla/revolver
/obj/item/ammo_casing/energy/gravityrepulse
projectile_type = /obj/item/projectile/gravityrepulse
e_cost = 0
fire_sound = 'sound/weapons/wave.ogg'
select_name = "repulse"
delay = 50
var/obj/item/weapon/gun/energy/gravity_gun/gun = null
/obj/item/ammo_casing/energy/gravityrepulse/New(var/obj/item/weapon/gun/energy/gravity_gun/G)
gun = G
/obj/item/ammo_casing/energy/gravityattract
projectile_type = /obj/item/projectile/gravityattract
e_cost = 0
fire_sound = 'sound/weapons/wave.ogg'
select_name = "attract"
delay = 50
var/obj/item/weapon/gun/energy/gravity_gun/gun = null
/obj/item/ammo_casing/energy/gravityattract/New(var/obj/item/weapon/gun/energy/gravity_gun/G)
gun = G
/obj/item/ammo_casing/energy/gravitychaos
projectile_type = /obj/item/projectile/gravitychaos
e_cost = 0
fire_sound = 'sound/weapons/wave.ogg'
select_name = "chaos"
delay = 50
var/obj/item/weapon/gun/energy/gravity_gun/gun = null
/obj/item/ammo_casing/energy/gravitychaos/New(var/obj/item/weapon/gun/energy/gravity_gun/G)
gun = G
/obj/item/ammo_casing/energy/plasma
projectile_type = /obj/item/projectile/plasma
select_name = "plasma burst"
fire_sound = 'sound/weapons/pulse.ogg'
/obj/item/ammo_casing/energy/plasma/adv
projectile_type = /obj/item/projectile/plasma/adv
/obj/item/ammo_casing/energy
name = "energy weapon lens"
desc = "The part of the gun that makes the laser go pew"
caliber = "energy"
projectile_type = /obj/item/projectile/energy
var/e_cost = 100 //The amount of energy a cell needs to expend to create this shot.
var/select_name = "energy"
fire_sound = 'sound/weapons/Laser.ogg'
firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect/energy
/obj/item/ammo_casing/energy/chameleon
e_cost = 0
var/list/projectile_vars = list()
/obj/item/ammo_casing/energy/chameleon/ready_proj()
. = ..()
if(!BB)
newshot()
for(var/V in projectile_vars)
if(BB.vars[V])
BB.vars[V] = projectile_vars[V]
/obj/item/ammo_casing/energy/laser
projectile_type = /obj/item/projectile/beam/laser
select_name = "kill"
/obj/item/ammo_casing/energy/lasergun
projectile_type = /obj/item/projectile/beam/laser
e_cost = 83
select_name = "kill"
/obj/item/ammo_casing/energy/laser/hos
e_cost = 100
/obj/item/ammo_casing/energy/laser/practice
projectile_type = /obj/item/projectile/beam/practice
select_name = "practice"
/obj/item/ammo_casing/energy/laser/scatter
projectile_type = /obj/item/projectile/beam/scatter
pellets = 5
variance = 25
select_name = "scatter"
/obj/item/ammo_casing/energy/laser/scatter/disabler
projectile_type = /obj/item/projectile/beam/disabler
pellets = 3
variance = 15
/obj/item/ammo_casing/energy/laser/heavy
projectile_type = /obj/item/projectile/beam/laser/heavylaser
select_name = "anti-vehicle"
fire_sound = 'sound/weapons/lasercannonfire.ogg'
/obj/item/ammo_casing/energy/laser/pulse
projectile_type = /obj/item/projectile/beam/pulse
e_cost = 200
select_name = "DESTROY"
fire_sound = 'sound/weapons/pulse.ogg'
/obj/item/ammo_casing/energy/laser/bluetag
projectile_type = /obj/item/projectile/beam/lasertag/bluetag
select_name = "bluetag"
/obj/item/ammo_casing/energy/laser/redtag
projectile_type = /obj/item/projectile/beam/lasertag/redtag
select_name = "redtag"
/obj/item/ammo_casing/energy/xray
projectile_type = /obj/item/projectile/beam/xray
e_cost = 50
fire_sound = 'sound/weapons/laser3.ogg'
/obj/item/ammo_casing/energy/electrode
projectile_type = /obj/item/projectile/energy/electrode
select_name = "stun"
fire_sound = 'sound/weapons/taser.ogg'
e_cost = 200
/obj/item/ammo_casing/energy/electrode/gun
fire_sound = 'sound/weapons/gunshot.ogg'
e_cost = 100
/obj/item/ammo_casing/energy/electrode/hos
e_cost = 200
/obj/item/ammo_casing/energy/ion
projectile_type = /obj/item/projectile/ion
select_name = "ion"
fire_sound = 'sound/weapons/IonRifle.ogg'
/obj/item/ammo_casing/energy/declone
projectile_type = /obj/item/projectile/energy/declone
select_name = "declone"
fire_sound = 'sound/weapons/pulse3.ogg'
/obj/item/ammo_casing/energy/mindflayer
projectile_type = /obj/item/projectile/beam/mindflayer
select_name = "MINDFUCK"
fire_sound = 'sound/weapons/Laser.ogg'
/obj/item/ammo_casing/energy/flora
fire_sound = 'sound/effects/stealthoff.ogg'
/obj/item/ammo_casing/energy/flora/yield
projectile_type = /obj/item/projectile/energy/florayield
select_name = "yield"
/obj/item/ammo_casing/energy/flora/mut
projectile_type = /obj/item/projectile/energy/floramut
select_name = "mutation"
/obj/item/ammo_casing/energy/temp
projectile_type = /obj/item/projectile/temp
select_name = "freeze"
e_cost = 250
fire_sound = 'sound/weapons/pulse3.ogg'
/obj/item/ammo_casing/energy/temp/hot
projectile_type = /obj/item/projectile/temp/hot
select_name = "bake"
/obj/item/ammo_casing/energy/meteor
projectile_type = /obj/item/projectile/meteor
select_name = "goddamn meteor"
/obj/item/ammo_casing/energy/disabler
projectile_type = /obj/item/projectile/beam/disabler
select_name = "disable"
e_cost = 50
fire_sound = 'sound/weapons/taser2.ogg'
/obj/item/ammo_casing/energy/plasma
projectile_type = /obj/item/projectile/plasma
select_name = "plasma burst"
fire_sound = 'sound/weapons/plasma_cutter.ogg'
delay = 15
e_cost = 25
/obj/item/ammo_casing/energy/plasma/adv
projectile_type = /obj/item/projectile/plasma/adv
delay = 10
e_cost = 10
/obj/item/ammo_casing/energy/wormhole
projectile_type = /obj/item/projectile/beam/wormhole
e_cost = 0
fire_sound = 'sound/weapons/pulse3.ogg'
var/obj/item/weapon/gun/energy/wormhole_projector/gun = null
select_name = "blue"
/obj/item/ammo_casing/energy/wormhole/orange
projectile_type = /obj/item/projectile/beam/wormhole/orange
select_name = "orange"
/obj/item/ammo_casing/energy/bolt
projectile_type = /obj/item/projectile/energy/bolt
select_name = "bolt"
e_cost = 500
fire_sound = 'sound/weapons/Genhit.ogg'
/obj/item/ammo_casing/energy/bolt/halloween
projectile_type = /obj/item/projectile/energy/bolt/halloween
/obj/item/ammo_casing/energy/bolt/large
projectile_type = /obj/item/projectile/energy/bolt/large
select_name = "heavy bolt"
/obj/item/ammo_casing/energy/net
projectile_type = /obj/item/projectile/energy/net
select_name = "netting"
pellets = 6
variance = 40
/obj/item/ammo_casing/energy/trap
projectile_type = /obj/item/projectile/energy/trap
select_name = "snare"
/obj/item/ammo_casing/energy/instakill
projectile_type = /obj/item/projectile/beam/instakill
e_cost = 0
select_name = "DESTROY"
/obj/item/ammo_casing/energy/instakill/blue
projectile_type = /obj/item/projectile/beam/instakill/blue
/obj/item/ammo_casing/energy/instakill/red
projectile_type = /obj/item/projectile/beam/instakill/red
/obj/item/ammo_casing/energy/tesla_revolver
fire_sound = 'sound/magic/lightningbolt.ogg'
e_cost = 200
select_name = "stun"
projectile_type = /obj/item/projectile/energy/tesla/revolver
/obj/item/ammo_casing/energy/gravityrepulse
projectile_type = /obj/item/projectile/gravityrepulse
e_cost = 0
fire_sound = 'sound/weapons/wave.ogg'
select_name = "repulse"
delay = 50
var/obj/item/weapon/gun/energy/gravity_gun/gun = null
/obj/item/ammo_casing/energy/gravityrepulse/New(var/obj/item/weapon/gun/energy/gravity_gun/G)
gun = G
/obj/item/ammo_casing/energy/gravityattract
projectile_type = /obj/item/projectile/gravityattract
e_cost = 0
fire_sound = 'sound/weapons/wave.ogg'
select_name = "attract"
delay = 50
var/obj/item/weapon/gun/energy/gravity_gun/gun = null
/obj/item/ammo_casing/energy/gravityattract/New(var/obj/item/weapon/gun/energy/gravity_gun/G)
gun = G
/obj/item/ammo_casing/energy/gravitychaos
projectile_type = /obj/item/projectile/gravitychaos
e_cost = 0
fire_sound = 'sound/weapons/wave.ogg'
select_name = "chaos"
delay = 50
var/obj/item/weapon/gun/energy/gravity_gun/gun = null
/obj/item/ammo_casing/energy/gravitychaos/New(var/obj/item/weapon/gun/energy/gravity_gun/G)
gun = G
/obj/item/ammo_casing/energy/plasma
projectile_type = /obj/item/projectile/plasma
select_name = "plasma burst"
fire_sound = 'sound/weapons/pulse.ogg'
/obj/item/ammo_casing/energy/plasma/adv
projectile_type = /obj/item/projectile/plasma/adv
+313 -313
View File
@@ -1,313 +1,313 @@
/obj/item/projectile
name = "projectile"
icon = 'icons/obj/projectiles.dmi'
icon_state = "bullet"
density = 0
anchored = 1
flags = ABSTRACT
pass_flags = PASSTABLE
mouse_opacity = 0
hitsound = 'sound/weapons/pierce.ogg'
var/hitsound_wall = ""
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/def_zone = "" //Aiming at
var/mob/firer = null//Who shot it
var/suppressed = 0 //Attack message
var/yo = null
var/xo = null
var/current = null
var/atom/original = null // the original target clicked
var/turf/starting = null // the projectile's starting turf
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
var/paused = FALSE //for suspending the projectile midair
var/p_x = 16
var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel
var/Angle = 0
var/spread = 0 //amount (in degrees) of projectile spread
var/legacy = 0 //legacy projectile system
animate_movement = 0 //Use SLIDE_STEPS in conjunction with legacy
var/damage = 10
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
var/nodamage = 0 //Determines if the projectile will skip any damage inflictions
var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb
var/projectile_type = /obj/item/projectile
var/range = 50 //This will de-increment every step. When 0, it will delete the projectile.
//Effects
var/stun = 0
var/weaken = 0
var/paralyze = 0
var/irradiate = 0
var/stutter = 0
var/slur = 0
var/eyeblur = 0
var/drowsy = 0
var/stamina = 0
var/jitter = 0
var/forcedodge = 0 //to pass through everything
var/dismemberment = 0 //The higher the number, the greater the bonus to dismembering. 0 will not dismember at all.
var/impact_effect_type //what type of impact effect to show when hitting something
var/log_override = FALSE //is this type spammed enough to not log? (KAs)
/obj/item/projectile/New()
permutated = list()
return ..()
/obj/item/projectile/proc/Range()
range--
if(range <= 0 && loc)
on_range()
/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range
qdel(src)
//to get the correct limb (if any) for the projectile hit message
/mob/living/proc/check_limb_hit(hit_zone)
if(has_limbs)
return hit_zone
/mob/living/carbon/check_limb_hit(hit_zone)
if(get_bodypart(hit_zone))
return hit_zone
else //when a limb is missing the damage is actually passed to the chest
return "chest"
/obj/item/projectile/proc/prehit(atom/target)
return
/obj/item/projectile/proc/on_hit(atom/target, blocked = 0)
var/turf/target_loca = get_turf(target)
if(!isliving(target))
if(impact_effect_type)
new impact_effect_type(target_loca, target, src)
return 0
var/mob/living/L = target
if(blocked != 100) // not completely blocked
if(damage && L.blood_volume && damage_type == BRUTE)
var/splatter_dir = dir
if(starting)
splatter_dir = get_dir(starting, target_loca)
if(isalien(L))
new /obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
else
new /obj/effect/overlay/temp/dir_setting/bloodsplatter(target_loca, splatter_dir)
if(prob(33))
L.add_splatter_floor(target_loca)
else if(impact_effect_type)
new impact_effect_type(target_loca, target, src)
var/organ_hit_text = ""
var/limb_hit = L.check_limb_hit(def_zone)//to get the correct message info.
if(limb_hit)
organ_hit_text = " in \the [parse_zone(limb_hit)]"
if(suppressed)
playsound(loc, hitsound, 5, 1, -1)
to_chat(L, "<span class='userdanger'>You're shot by \a [src][organ_hit_text]!</span>")
else
if(hitsound)
var/volume = vol_by_damage()
playsound(loc, hitsound, volume, 1, -1)
L.visible_message("<span class='danger'>[L] is hit by \a [src][organ_hit_text]!</span>", \
"<span class='userdanger'>[L] is hit by \a [src][organ_hit_text]!</span>", null, COMBAT_MESSAGE_RANGE)
L.on_hit(src)
var/reagent_note
if(reagents && reagents.reagent_list)
reagent_note = " REAGENTS:"
for(var/datum/reagent/R in reagents.reagent_list)
reagent_note += R.id + " ("
reagent_note += num2text(R.volume) + ") "
add_logs(firer, L, "shot", src, reagent_note)
return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
return Clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100
else
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
/obj/item/projectile/Bump(atom/A, yes)
if(!yes) //prevents double bumps.
return
if(firer)
if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech
loc = A.loc
return 0
var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
if(isturf(A) && hitsound_wall)
var/volume = Clamp(vol_by_damage() + 20, 0, 100)
if(suppressed)
volume = 5
playsound(loc, hitsound_wall, volume, 1, -1)
var/turf/target_turf = get_turf(A)
prehit(A)
var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null
if(permutation == -1 || forcedodge)// the bullet passes through a dense object!
loc = target_turf
if(A)
permutated.Add(A)
return 0
else
if(A && A.density && !ismob(A) && !(A.flags & ON_BORDER)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile.
var/list/mobs_list = list()
for(var/mob/living/L in target_turf)
mobs_list += L
if(mobs_list.len)
var/mob/living/picked_mob = pick(mobs_list)
prehit(picked_mob)
picked_mob.bullet_act(src, def_zone)
qdel(src)
/obj/item/projectile/Process_Spacemove(var/movement_dir = 0)
return 1 //Bullets don't drift in space
/obj/item/projectile/proc/fire(setAngle, atom/direct_target)
if(!log_override && firer && original)
add_logs(firer, original, "fired at", src, " [get_area(src)]")
if(direct_target)
prehit(direct_target)
direct_target.bullet_act(src, def_zone)
qdel(src)
return
if(setAngle)
Angle = setAngle
var/old_pixel_x = pixel_x
var/old_pixel_y = pixel_y
if(!legacy) //new projectiles
set waitfor = 0
var/next_run = world.time
while(loc)
if(paused)
next_run = world.time
sleep(1)
continue
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
if(!Angle)
Angle=round(Get_Angle(src,current))
if(spread)
Angle += (rand() - 0.5) * spread
var/matrix/M = new
M.Turn(Angle)
transform = M
var/Pixel_x=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
var/Pixel_y=round((cos(Angle)+16*cos(Angle)*2), 1)
var/pixel_x_offset = old_pixel_x + Pixel_x
var/pixel_y_offset = old_pixel_y + Pixel_y
var/new_x = x
var/new_y = y
while(pixel_x_offset > 16)
pixel_x_offset -= 32
old_pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
old_pixel_x += 32
new_x--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
old_pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
old_pixel_y += 32
new_y--
pixel_x = old_pixel_x
pixel_y = old_pixel_y
step_towards(src, locate(new_x, new_y, z))
next_run += max(world.tick_lag, speed)
var/delay = next_run - world.time
if(delay <= world.tick_lag*2)
pixel_x = pixel_x_offset
pixel_y = pixel_y_offset
else
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW)
old_pixel_x = pixel_x_offset
old_pixel_y = pixel_y_offset
if(original && (original.layer>=2.75) || ismob(original))
if(loc == get_turf(original))
if(!(original in permutated))
Bump(original, 1)
Range()
if (delay > 0)
sleep(delay)
else //old projectile system
set waitfor = 0
while(loc)
if(!paused)
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
step_towards(src, current)
if(original && (original.layer>=2.75) || ismob(original))
if(loc == get_turf(original))
if(!(original in permutated))
Bump(original, 1)
Range()
sleep(config.run_speed * 0.9)
/obj/item/projectile/proc/preparePixelProjectile(atom/target, var/turf/targloc, mob/living/user, params, spread)
var/turf/curloc = get_turf(user)
src.loc = get_turf(user)
src.starting = get_turf(user)
src.current = curloc
src.yo = targloc.y - curloc.y
src.xo = targloc.x - curloc.x
if(params)
var/list/mouse_control = params2list(params)
if(mouse_control["icon-x"])
src.p_x = text2num(mouse_control["icon-x"])
if(mouse_control["icon-y"])
src.p_y = text2num(mouse_control["icon-y"])
if(mouse_control["screen-loc"])
//Split screen-loc up into X+Pixel_X and Y+Pixel_Y
var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",")
//Split X+Pixel_X up into list(X, Pixel_X)
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
//Split Y+Pixel_Y up into list(Y, Pixel_Y)
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
// to_chat(world, "X: [screen_loc_X[1]] PixelX: [screen_loc_X[2]] / Y: [screen_loc_Y[1]] PixelY: [screen_loc_Y[2]]")
var/x = text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32
var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32
//Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average.
var/screenview = (user.client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths
var/ox = round(screenview/2) //"origin" x
var/oy = round(screenview/2) //"origin" y
// to_chat(world, "Pixel position: [x] [y]")
var/angle = Atan2(y - oy, x - ox)
// to_chat(world, "Angle: [angle]")
src.Angle = angle
if(spread)
src.Angle += spread
/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it.
..()
if(isliving(AM) && AM.density && !checkpass(PASSMOB))
Bump(AM, 1)
/obj/item/projectile/Destroy()
return ..()
/obj/item/projectile/experience_pressure_difference()
return
/obj/item/projectile
name = "projectile"
icon = 'icons/obj/projectiles.dmi'
icon_state = "bullet"
density = 0
anchored = 1
flags = ABSTRACT
pass_flags = PASSTABLE
mouse_opacity = 0
hitsound = 'sound/weapons/pierce.ogg'
var/hitsound_wall = ""
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/def_zone = "" //Aiming at
var/mob/firer = null//Who shot it
var/suppressed = 0 //Attack message
var/yo = null
var/xo = null
var/current = null
var/atom/original = null // the original target clicked
var/turf/starting = null // the projectile's starting turf
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
var/paused = FALSE //for suspending the projectile midair
var/p_x = 16
var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel
var/Angle = 0
var/spread = 0 //amount (in degrees) of projectile spread
var/legacy = 0 //legacy projectile system
animate_movement = 0 //Use SLIDE_STEPS in conjunction with legacy
var/damage = 10
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
var/nodamage = 0 //Determines if the projectile will skip any damage inflictions
var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb
var/projectile_type = /obj/item/projectile
var/range = 50 //This will de-increment every step. When 0, it will delete the projectile.
//Effects
var/stun = 0
var/weaken = 0
var/paralyze = 0
var/irradiate = 0
var/stutter = 0
var/slur = 0
var/eyeblur = 0
var/drowsy = 0
var/stamina = 0
var/jitter = 0
var/forcedodge = 0 //to pass through everything
var/dismemberment = 0 //The higher the number, the greater the bonus to dismembering. 0 will not dismember at all.
var/impact_effect_type //what type of impact effect to show when hitting something
var/log_override = FALSE //is this type spammed enough to not log? (KAs)
/obj/item/projectile/New()
permutated = list()
return ..()
/obj/item/projectile/proc/Range()
range--
if(range <= 0 && loc)
on_range()
/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range
qdel(src)
//to get the correct limb (if any) for the projectile hit message
/mob/living/proc/check_limb_hit(hit_zone)
if(has_limbs)
return hit_zone
/mob/living/carbon/check_limb_hit(hit_zone)
if(get_bodypart(hit_zone))
return hit_zone
else //when a limb is missing the damage is actually passed to the chest
return "chest"
/obj/item/projectile/proc/prehit(atom/target)
return
/obj/item/projectile/proc/on_hit(atom/target, blocked = 0)
var/turf/target_loca = get_turf(target)
if(!isliving(target))
if(impact_effect_type)
new impact_effect_type(target_loca, target, src)
return 0
var/mob/living/L = target
if(blocked != 100) // not completely blocked
if(damage && L.blood_volume && damage_type == BRUTE)
var/splatter_dir = dir
if(starting)
splatter_dir = get_dir(starting, target_loca)
if(isalien(L))
new /obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
else
new /obj/effect/overlay/temp/dir_setting/bloodsplatter(target_loca, splatter_dir)
if(prob(33))
L.add_splatter_floor(target_loca)
else if(impact_effect_type)
new impact_effect_type(target_loca, target, src)
var/organ_hit_text = ""
var/limb_hit = L.check_limb_hit(def_zone)//to get the correct message info.
if(limb_hit)
organ_hit_text = " in \the [parse_zone(limb_hit)]"
if(suppressed)
playsound(loc, hitsound, 5, 1, -1)
to_chat(L, "<span class='userdanger'>You're shot by \a [src][organ_hit_text]!</span>")
else
if(hitsound)
var/volume = vol_by_damage()
playsound(loc, hitsound, volume, 1, -1)
L.visible_message("<span class='danger'>[L] is hit by \a [src][organ_hit_text]!</span>", \
"<span class='userdanger'>[L] is hit by \a [src][organ_hit_text]!</span>", null, COMBAT_MESSAGE_RANGE)
L.on_hit(src)
var/reagent_note
if(reagents && reagents.reagent_list)
reagent_note = " REAGENTS:"
for(var/datum/reagent/R in reagents.reagent_list)
reagent_note += R.id + " ("
reagent_note += num2text(R.volume) + ") "
add_logs(firer, L, "shot", src, reagent_note)
return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
return Clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100
else
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
/obj/item/projectile/Bump(atom/A, yes)
if(!yes) //prevents double bumps.
return
if(firer)
if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech
loc = A.loc
return 0
var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
if(isturf(A) && hitsound_wall)
var/volume = Clamp(vol_by_damage() + 20, 0, 100)
if(suppressed)
volume = 5
playsound(loc, hitsound_wall, volume, 1, -1)
var/turf/target_turf = get_turf(A)
prehit(A)
var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null
if(permutation == -1 || forcedodge)// the bullet passes through a dense object!
loc = target_turf
if(A)
permutated.Add(A)
return 0
else
if(A && A.density && !ismob(A) && !(A.flags & ON_BORDER)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile.
var/list/mobs_list = list()
for(var/mob/living/L in target_turf)
mobs_list += L
if(mobs_list.len)
var/mob/living/picked_mob = pick(mobs_list)
prehit(picked_mob)
picked_mob.bullet_act(src, def_zone)
qdel(src)
/obj/item/projectile/Process_Spacemove(var/movement_dir = 0)
return 1 //Bullets don't drift in space
/obj/item/projectile/proc/fire(setAngle, atom/direct_target)
if(!log_override && firer && original)
add_logs(firer, original, "fired at", src, " [get_area(src)]")
if(direct_target)
prehit(direct_target)
direct_target.bullet_act(src, def_zone)
qdel(src)
return
if(setAngle)
Angle = setAngle
var/old_pixel_x = pixel_x
var/old_pixel_y = pixel_y
if(!legacy) //new projectiles
set waitfor = 0
var/next_run = world.time
while(loc)
if(paused)
next_run = world.time
sleep(1)
continue
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
if(!Angle)
Angle=round(Get_Angle(src,current))
if(spread)
Angle += (rand() - 0.5) * spread
var/matrix/M = new
M.Turn(Angle)
transform = M
var/Pixel_x=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
var/Pixel_y=round((cos(Angle)+16*cos(Angle)*2), 1)
var/pixel_x_offset = old_pixel_x + Pixel_x
var/pixel_y_offset = old_pixel_y + Pixel_y
var/new_x = x
var/new_y = y
while(pixel_x_offset > 16)
pixel_x_offset -= 32
old_pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
old_pixel_x += 32
new_x--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
old_pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
old_pixel_y += 32
new_y--
pixel_x = old_pixel_x
pixel_y = old_pixel_y
step_towards(src, locate(new_x, new_y, z))
next_run += max(world.tick_lag, speed)
var/delay = next_run - world.time
if(delay <= world.tick_lag*2)
pixel_x = pixel_x_offset
pixel_y = pixel_y_offset
else
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW)
old_pixel_x = pixel_x_offset
old_pixel_y = pixel_y_offset
if(original && (original.layer>=2.75) || ismob(original))
if(loc == get_turf(original))
if(!(original in permutated))
Bump(original, 1)
Range()
if (delay > 0)
sleep(delay)
else //old projectile system
set waitfor = 0
while(loc)
if(!paused)
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
step_towards(src, current)
if(original && (original.layer>=2.75) || ismob(original))
if(loc == get_turf(original))
if(!(original in permutated))
Bump(original, 1)
Range()
sleep(config.run_speed * 0.9)
/obj/item/projectile/proc/preparePixelProjectile(atom/target, var/turf/targloc, mob/living/user, params, spread)
var/turf/curloc = get_turf(user)
src.loc = get_turf(user)
src.starting = get_turf(user)
src.current = curloc
src.yo = targloc.y - curloc.y
src.xo = targloc.x - curloc.x
if(params)
var/list/mouse_control = params2list(params)
if(mouse_control["icon-x"])
src.p_x = text2num(mouse_control["icon-x"])
if(mouse_control["icon-y"])
src.p_y = text2num(mouse_control["icon-y"])
if(mouse_control["screen-loc"])
//Split screen-loc up into X+Pixel_X and Y+Pixel_Y
var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",")
//Split X+Pixel_X up into list(X, Pixel_X)
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
//Split Y+Pixel_Y up into list(Y, Pixel_Y)
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
// to_chat(world, "X: [screen_loc_X[1]] PixelX: [screen_loc_X[2]] / Y: [screen_loc_Y[1]] PixelY: [screen_loc_Y[2]]")
var/x = text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32
var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32
//Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average.
var/screenview = (user.client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths
var/ox = round(screenview/2) //"origin" x
var/oy = round(screenview/2) //"origin" y
// to_chat(world, "Pixel position: [x] [y]")
var/angle = Atan2(y - oy, x - ox)
// to_chat(world, "Angle: [angle]")
src.Angle = angle
if(spread)
src.Angle += spread
/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it.
..()
if(isliving(AM) && AM.density && !checkpass(PASSMOB))
Bump(AM, 1)
/obj/item/projectile/Destroy()
return ..()
/obj/item/projectile/experience_pressure_difference()
return