Merge branch 'master' into premium-kas-for-borgs
This commit is contained in:
@@ -152,6 +152,10 @@
|
||||
#define ATMOS_PASS_PROC -1 //ask CanAtmosPass()
|
||||
#define ATMOS_PASS_DENSITY -2 //just check density
|
||||
|
||||
// Adjacency flags
|
||||
#define ATMOS_ADJACENT_ANY (1<<0)
|
||||
#define ATMOS_ADJACENT_FIRELOCK (1<<1)
|
||||
|
||||
#define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) )
|
||||
#define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) )
|
||||
|
||||
@@ -323,14 +327,6 @@
|
||||
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
|
||||
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
|
||||
|
||||
|
||||
#ifdef TESTING
|
||||
GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
|
||||
#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 }
|
||||
#else
|
||||
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
|
||||
#endif
|
||||
|
||||
//If you're doing spreading things related to atmos, DO NOT USE CANATMOSPASS, IT IS NOT CHEAP. use this instead, the info is cached after all. it's tweaked just a bit to allow for circular checks
|
||||
#define TURFS_CAN_SHARE(T1, T2) (LAZYACCESS(T2.atmos_adjacent_turfs, T1) || LAZYLEN(T1.atmos_adjacent_turfs & T2.atmos_adjacent_turfs))
|
||||
|
||||
|
||||
@@ -206,6 +206,19 @@
|
||||
///Time to spend without clicking on other things required for your shots to become accurate.
|
||||
#define GUN_AIMING_TIME (2 SECONDS)
|
||||
|
||||
//Autofire component
|
||||
/// Compatible firemode is in the gun. Wait until it's held in the user hands.
|
||||
#define AUTOFIRE_STAT_IDLE (1<<0)
|
||||
/// Gun is active and in the user hands. Wait until user does a valid click.
|
||||
#define AUTOFIRE_STAT_ALERT (1<<1)
|
||||
/// Gun is shooting.
|
||||
#define AUTOFIRE_STAT_FIRING (1<<2)
|
||||
|
||||
#define COMSIG_AUTOFIRE_ONMOUSEDOWN "autofire_onmousedown"
|
||||
#define COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS (1<<0)
|
||||
#define COMSIG_AUTOFIRE_SHOT "autofire_shot"
|
||||
#define COMPONENT_AUTOFIRE_SHOT_SUCCESS (1<<0)
|
||||
|
||||
//Object/Item sharpness
|
||||
#define SHARP_NONE 0
|
||||
#define SHARP_EDGED 1
|
||||
@@ -261,3 +274,4 @@
|
||||
* a "inefficiently" prefix will be added to the message.
|
||||
*/
|
||||
#define FEEBLE_ATTACK_MSG_THRESHOLD 0.5
|
||||
|
||||
|
||||
@@ -321,6 +321,12 @@
|
||||
///from base of mob/AltClickOn(): (atom/A)
|
||||
#define COMSIG_MOB_ALTCLICKON "mob_altclickon"
|
||||
|
||||
//Gun signals
|
||||
///When a gun is switched to automatic fire mode
|
||||
#define COMSIG_GUN_AUTOFIRE_SELECTED "gun_autofire_selected"
|
||||
///When a gun is switched off of automatic fire mode
|
||||
#define COMSIG_GUN_AUTOFIRE_DESELECTED "gun_autofire_deselected"
|
||||
|
||||
// Lighting:
|
||||
///from base of [atom/proc/set_light]: (l_range, l_power, l_color, l_on)
|
||||
#define COMSIG_ATOM_SET_LIGHT "atom_set_light"
|
||||
@@ -348,12 +354,22 @@
|
||||
#define COMSIG_ATOM_UPDATE_LIGHT_FLAGS "atom_update_light_flags"
|
||||
|
||||
// /client signals
|
||||
#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client)
|
||||
#define COMSIG_MOB_CLIENT_LOGOUT "mob_client_logout" //sent when a mob/logout() starts: (client)
|
||||
#define COMSIG_MOB_CLIENT_MOVE "mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc)
|
||||
#define COMSIG_MOB_CLIENT_CHANGE_VIEW "mob_client_change_view" //from base of /client/change_view(): (client, old_view, view)
|
||||
#define COMSIG_MOB_CLIENT_MOUSEMOVE "mob_client_mousemove" //from base of /client/MouseMove(): (object, location, control, params)
|
||||
|
||||
///sent when a mob/login() finishes: (client)
|
||||
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login"
|
||||
//from base of client/MouseDown(): (/client, object, location, control, params)
|
||||
#define COMSIG_CLIENT_MOUSEDOWN "client_mousedown"
|
||||
//from base of client/MouseUp(): (/client, object, location, control, params)
|
||||
#define COMSIG_CLIENT_MOUSEUP "client_mouseup"
|
||||
#define COMPONENT_CLIENT_MOUSEUP_INTERCEPT (1<<0)
|
||||
//from base of client/MouseUp(): (/client, object, location, control, params)
|
||||
#define COMSIG_CLIENT_MOUSEDRAG "client_mousedrag"
|
||||
|
||||
|
||||
// /mob/living signals
|
||||
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
|
||||
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
|
||||
|
||||
3
code/__DEFINES/gun.dm
Normal file
3
code/__DEFINES/gun.dm
Normal file
@@ -0,0 +1,3 @@
|
||||
#define SELECT_SEMI_AUTOMATIC 1
|
||||
#define SELECT_BURST_SHOT 2
|
||||
#define SELECT_FULLY_AUTOMATIC 3
|
||||
@@ -4,3 +4,6 @@
|
||||
#define HUD_STYLE_NOHUD 3 //No hud (for screenshots)
|
||||
|
||||
#define HUD_VERSIONS 3 //Used in show_hud(); Please ensure this is the same as the maximum index.
|
||||
|
||||
#define ui_borg_pda_send "CENTER+5:21,SOUTH:5" // To the right of the alert panel
|
||||
#define ui_borg_pda_log "CENTER+6:21,SOUTH:5"
|
||||
|
||||
@@ -388,6 +388,23 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
#define BEAT_SLOW 2
|
||||
#define BEAT_NONE 0
|
||||
|
||||
//Mouse buttons pressed/held/released
|
||||
#define RIGHT_CLICK "right"
|
||||
#define MIDDLE_CLICK "middle"
|
||||
#define LEFT_CLICK "left"
|
||||
|
||||
//Keys held down during the mouse action
|
||||
#define CTRL_CLICK "ctrl"
|
||||
#define ALT_CLICK "alt"
|
||||
#define SHIFT_CLICK "shift"
|
||||
|
||||
//Pixel coordinates within the icon, in the icon's coordinate space
|
||||
#define ICON_X "icon-x"
|
||||
#define ICON_Y "icon-y"
|
||||
|
||||
//Pixel coordinates in screen_loc format ("[tile_x]:[pixel_x],[tile_y]:[pixel_y]")
|
||||
#define SCREEN_LOC "screen-loc"
|
||||
|
||||
//https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity
|
||||
#define MOUSE_OPACITY_TRANSPARENT 0
|
||||
#define MOUSE_OPACITY_ICON 1
|
||||
|
||||
@@ -673,6 +673,27 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
if(final_x || final_y)
|
||||
return locate(final_x, final_y, T.z)
|
||||
|
||||
///Returns a turf based on text inputs, original turf and viewing client
|
||||
/proc/parse_caught_click_modifiers(list/modifiers, turf/origin, client/viewing_client)
|
||||
if(!modifiers)
|
||||
return null
|
||||
|
||||
var/screen_loc = splittext(LAZYACCESS(modifiers, SCREEN_LOC), ",")
|
||||
var/list/actual_view = getviewsize(viewing_client ? viewing_client.view : world.view)
|
||||
var/click_turf_x = splittext(screen_loc[1], ":")
|
||||
var/click_turf_y = splittext(screen_loc[2], ":")
|
||||
var/click_turf_z = origin.z
|
||||
|
||||
var/click_turf_px = text2num(click_turf_x[2])
|
||||
var/click_turf_py = text2num(click_turf_y[2])
|
||||
click_turf_x = origin.x + text2num(click_turf_x[1]) - round(actual_view[1] / 2) - 1
|
||||
click_turf_y = origin.y + text2num(click_turf_y[1]) - round(actual_view[2] / 2) - 1
|
||||
|
||||
var/turf/click_turf = locate(clamp(click_turf_x, 1, world.maxx), clamp(click_turf_y, 1, world.maxy), click_turf_z)
|
||||
LAZYSET(modifiers, ICON_X, "[(click_turf_px - click_turf.pixel_x) + ((click_turf_x - click_turf.x) * world.icon_size)]")
|
||||
LAZYSET(modifiers, ICON_Y, "[(click_turf_py - click_turf.pixel_y) + ((click_turf_y - click_turf.y) * world.icon_size)]")
|
||||
return click_turf
|
||||
|
||||
//Finds the distance between two atoms, in pixels
|
||||
//centered = FALSE counts from turf edge to edge
|
||||
//centered = TRUE counts from turf center to turf center
|
||||
|
||||
@@ -320,7 +320,7 @@ GLOBAL_LIST_INIT(redacted_strings, list("\[REDACTED\]", "\[CLASSIFIED\]", "\[ARC
|
||||
GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt"))
|
||||
|
||||
//LANGUAGE CHARACTER CUSTOMIZATION
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks"))
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks","mumbles","crackles"))
|
||||
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien/hybrid))
|
||||
|
||||
/proc/get_roundstart_languages()
|
||||
|
||||
@@ -23,23 +23,31 @@
|
||||
SEND_SIGNAL(src, COMSIG_MOUSEDROPPED_ONTO, dropping, user)
|
||||
return
|
||||
|
||||
|
||||
/client/MouseDown(object, location, control, params)
|
||||
if (mouse_down_icon)
|
||||
/client/MouseDown(datum/object, location, control, params)
|
||||
if(!control)
|
||||
return
|
||||
if(QDELETED(object)) //Yep, you can click on qdeleted things before they have time to nullspace. Fun.
|
||||
return
|
||||
SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDOWN, object, location, control, params)
|
||||
if(mouse_down_icon)
|
||||
mouse_pointer_icon = mouse_down_icon
|
||||
var/delay = mob.CanMobAutoclick(object, location, params)
|
||||
if(delay)
|
||||
selected_target[1] = object
|
||||
selected_target[2] = params
|
||||
while(selected_target[1])
|
||||
Click(selected_target[1], location, control, selected_target[2], TRUE)
|
||||
Click(selected_target[1], location, control, selected_target[2])
|
||||
sleep(delay)
|
||||
active_mousedown_item = mob.canMobMousedown(object, location, params)
|
||||
if(active_mousedown_item)
|
||||
active_mousedown_item.onMouseDown(object, location, params, mob)
|
||||
|
||||
/client/MouseUp(object, location, control, params)
|
||||
if (mouse_up_icon)
|
||||
if(!control)
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEUP, object, location, control, params) & COMPONENT_CLIENT_MOUSEUP_INTERCEPT)
|
||||
click_intercept_time = world.time
|
||||
if(mouse_up_icon)
|
||||
mouse_pointer_icon = mouse_up_icon
|
||||
selected_target[1] = null
|
||||
if(active_mousedown_item)
|
||||
@@ -74,9 +82,6 @@
|
||||
/obj/item/proc/onMouseUp(object, location, params, mob)
|
||||
return
|
||||
|
||||
/obj/item/gun/CanItemAutoclick(object, location, params)
|
||||
. = automatic
|
||||
|
||||
/atom/proc/IsAutoclickable()
|
||||
. = 1
|
||||
|
||||
@@ -110,6 +115,7 @@
|
||||
selected_target[2] = params
|
||||
if(active_mousedown_item)
|
||||
active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDRAG, src_object, over_object, src_location, over_location, src_control, over_control, params)
|
||||
|
||||
/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
return
|
||||
|
||||
@@ -342,3 +342,43 @@
|
||||
if(.)
|
||||
return
|
||||
robot.modularInterface?.interact(robot)
|
||||
|
||||
//borg pda
|
||||
/datum/hud/robot/New(mob/owner)
|
||||
. = ..()
|
||||
|
||||
var/atom/movable/screen/using
|
||||
|
||||
//PDA message
|
||||
using = new /atom/movable/screen/robot/pda_msg_send
|
||||
using.screen_loc = ui_borg_pda_send
|
||||
using.hud = src
|
||||
static_inventory += using
|
||||
|
||||
//PDA log
|
||||
using = new /atom/movable/screen/robot/pda_msg_show
|
||||
using.screen_loc = ui_borg_pda_log
|
||||
using.hud = src
|
||||
static_inventory += using
|
||||
|
||||
/atom/movable/screen/robot/pda_msg_send
|
||||
name = "PDA - Send Message"
|
||||
icon = 'icons/mob/screen_ai.dmi'
|
||||
icon_state = "pda_send"
|
||||
|
||||
/atom/movable/screen/robot/pda_msg_send/Click()
|
||||
if(..())
|
||||
return
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
R.cmd_send_pdamesg(usr)
|
||||
|
||||
/atom/movable/screen/robot/pda_msg_show
|
||||
name = "PDA - Show Message Log"
|
||||
icon = 'icons/mob/screen_ai.dmi'
|
||||
icon_state = "pda_receive"
|
||||
|
||||
/atom/movable/screen/robot/pda_msg_show/Click()
|
||||
if(..())
|
||||
return
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
R.cmd_show_message_log(usr)
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
SUBSYSTEM_DEF(adjacent_air)
|
||||
name = "Atmos Adjacency"
|
||||
flags = SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
wait = 10
|
||||
priority = FIRE_PRIORITY_ATMOS_ADJACENCY
|
||||
var/list/queue = list()
|
||||
|
||||
/datum/controller/subsystem/adjacent_air/stat_entry(msg)
|
||||
#ifdef TESTING
|
||||
msg = "P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]"
|
||||
#else
|
||||
msg = "P:[length(queue)]"
|
||||
#endif
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/adjacent_air/Initialize()
|
||||
while(length(queue))
|
||||
fire(mc_check = FALSE)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/adjacent_air/fire(resumed = FALSE, mc_check = TRUE)
|
||||
if(SSair.thread_running())
|
||||
pause()
|
||||
return
|
||||
|
||||
var/list/queue = src.queue
|
||||
|
||||
while (length(queue))
|
||||
var/turf/currT = queue[1]
|
||||
queue.Cut(1,2)
|
||||
|
||||
currT.ImmediateCalculateAdjacentTurfs()
|
||||
|
||||
if(mc_check)
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
else
|
||||
CHECK_TICK
|
||||
@@ -23,6 +23,8 @@
|
||||
var/icon_icon = 'icons/mob/actions.dmi' //This is the file for the ACTION icon
|
||||
var/button_icon_state = "default" //And this is the state for the action icon
|
||||
var/mob/owner
|
||||
///List of all mobs that are viewing our action button -> A unique movable for them to view.
|
||||
var/list/viewers = list()
|
||||
|
||||
/datum/action/New(Target)
|
||||
link_to(Target)
|
||||
@@ -121,6 +123,11 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/proc/UpdateButtons(status_only, force)
|
||||
for(var/datum/hud/hud in viewers)
|
||||
var/atom/movable/screen/movable/button = viewers[hud]
|
||||
UpdateButtonIcon(button, status_only, force)
|
||||
|
||||
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
|
||||
if(!button)
|
||||
return
|
||||
@@ -217,6 +224,8 @@
|
||||
name = "Toggle Hood"
|
||||
|
||||
/datum/action/item_action/toggle_firemode
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "fireselect_no"
|
||||
name = "Toggle Firemode"
|
||||
|
||||
/datum/action/item_action/rcl_col
|
||||
|
||||
278
code/datums/components/fullauto.dm
Normal file
278
code/datums/components/fullauto.dm
Normal file
@@ -0,0 +1,278 @@
|
||||
#define AUTOFIRE_MOUSEUP 0
|
||||
#define AUTOFIRE_MOUSEDOWN 1
|
||||
|
||||
/datum/component/automatic_fire
|
||||
var/client/clicker
|
||||
var/mob/living/shooter
|
||||
var/atom/target
|
||||
var/turf/target_loc //For dealing with locking on targets due to BYOND engine limitations (the mouse input only happening when mouse moves).
|
||||
var/autofire_stat = AUTOFIRE_STAT_IDLE
|
||||
var/mouse_parameters
|
||||
var/autofire_shot_delay = 0.3 SECONDS //Time between individual shots.
|
||||
var/mouse_status = AUTOFIRE_MOUSEUP //This seems hacky but there can be two MouseDown() without a MouseUp() in between if the user holds click and uses alt+tab, printscreen or similar.
|
||||
|
||||
COOLDOWN_DECLARE(next_shot_cd)
|
||||
|
||||
/datum/component/automatic_fire/Initialize(_autofire_shot_delay)
|
||||
. = ..()
|
||||
if(!isgun(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
var/obj/item/gun = parent
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/wake_up)
|
||||
RegisterSignal(parent, COMSIG_GUN_AUTOFIRE_SELECTED, .proc/wake_up)
|
||||
RegisterSignal(parent, list(COMSIG_PARENT_PREQDELETED, COMSIG_ITEM_DROPPED, COMSIG_GUN_AUTOFIRE_DESELECTED), .proc/autofire_off)
|
||||
if(_autofire_shot_delay)
|
||||
autofire_shot_delay = _autofire_shot_delay
|
||||
if(ismob(gun.loc))
|
||||
var/mob/user = gun.loc
|
||||
wake_up(src, user)
|
||||
|
||||
|
||||
/datum/component/automatic_fire/Destroy()
|
||||
UnregisterSignal(parent, list(COMSIG_PARENT_PREQDELETED, COMSIG_ITEM_DROPPED, COMSIG_GUN_AUTOFIRE_DESELECTED))
|
||||
autofire_off()
|
||||
return ..()
|
||||
|
||||
/datum/component/automatic_fire/process(delta_time)
|
||||
if(!(autofire_stat & AUTOFIRE_STAT_FIRING))
|
||||
STOP_PROCESSING(SSprojectiles, src)
|
||||
return
|
||||
|
||||
if(!COOLDOWN_FINISHED(src, next_shot_cd))
|
||||
return
|
||||
|
||||
process_shot()
|
||||
|
||||
/datum/component/automatic_fire/proc/wake_up(datum/source, mob/user, slot)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(autofire_stat & (AUTOFIRE_STAT_ALERT))
|
||||
return //We've updated the firemode. No need for more.
|
||||
if(autofire_stat & AUTOFIRE_STAT_FIRING)
|
||||
stop_autofiring() //Let's stop shooting to avoid issues.
|
||||
return
|
||||
|
||||
var/obj/item/gun/G = parent
|
||||
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/shooter = user
|
||||
if(shooter.is_holding(parent) && G.fire_select == SELECT_FULLY_AUTOMATIC)
|
||||
autofire_on(shooter.client)
|
||||
else
|
||||
autofire_off()
|
||||
|
||||
// There is a gun and there is a user wielding it. The component now waits for the mouse click.
|
||||
/datum/component/automatic_fire/proc/autofire_on(client/usercli)
|
||||
SIGNAL_HANDLER
|
||||
if(autofire_stat & (AUTOFIRE_STAT_ALERT|AUTOFIRE_STAT_FIRING))
|
||||
return
|
||||
autofire_stat = AUTOFIRE_STAT_ALERT
|
||||
clicker = usercli
|
||||
shooter = clicker.mob
|
||||
RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDOWN, .proc/on_mouse_down)
|
||||
RegisterSignal(shooter, COMSIG_MOB_CLIENT_LOGOUT, .proc/autofire_off)
|
||||
if(!QDELETED(shooter))
|
||||
UnregisterSignal(shooter, COMSIG_MOB_CLIENT_LOGIN)
|
||||
parent.RegisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, /obj/item/gun/.proc/autofire_bypass_check)
|
||||
parent.RegisterSignal(parent, COMSIG_AUTOFIRE_SHOT, /obj/item/gun/.proc/do_autofire)
|
||||
|
||||
|
||||
/datum/component/automatic_fire/proc/autofire_off(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
if(autofire_stat & (AUTOFIRE_STAT_IDLE))
|
||||
return
|
||||
if(autofire_stat & AUTOFIRE_STAT_FIRING)
|
||||
stop_autofiring()
|
||||
|
||||
autofire_stat = AUTOFIRE_STAT_IDLE
|
||||
|
||||
if(!QDELETED(clicker))
|
||||
UnregisterSignal(clicker, list(COMSIG_CLIENT_MOUSEDOWN, COMSIG_CLIENT_MOUSEUP, COMSIG_CLIENT_MOUSEDRAG))
|
||||
mouse_status = AUTOFIRE_MOUSEUP //In regards to the component there's no click anymore to care about.
|
||||
clicker = null
|
||||
RegisterSignal(shooter, COMSIG_MOB_CLIENT_LOGIN, .proc/on_client_login)
|
||||
if(!QDELETED(shooter))
|
||||
UnregisterSignal(shooter, COMSIG_MOB_CLIENT_LOGOUT)
|
||||
shooter = null
|
||||
parent.UnregisterSignal(parent, COMSIG_AUTOFIRE_SHOT)
|
||||
parent.UnregisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN)
|
||||
|
||||
/datum/component/automatic_fire/proc/on_client_login(mob/source)
|
||||
SIGNAL_HANDLER
|
||||
if(!source.client)
|
||||
return
|
||||
if(source.is_holding(parent))
|
||||
autofire_on(source.client)
|
||||
|
||||
/datum/component/automatic_fire/proc/on_mouse_down(client/source, atom/_target, turf/location, control, params)
|
||||
var/list/modifiers = params2list(params) //If they're shift+clicking, for example, let's not have them accidentally shoot.
|
||||
|
||||
if(LAZYACCESS(modifiers, SHIFT_CLICK))
|
||||
return
|
||||
if(LAZYACCESS(modifiers, CTRL_CLICK))
|
||||
return
|
||||
if(LAZYACCESS(modifiers, MIDDLE_CLICK))
|
||||
return
|
||||
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
return
|
||||
if(LAZYACCESS(modifiers, ALT_CLICK))
|
||||
return
|
||||
if(source.mob.in_throw_mode)
|
||||
return
|
||||
if(!isturf(source.mob.loc)) //No firing inside lockers and stuff.
|
||||
return
|
||||
if(get_dist(source.mob, _target) < 2) //Adjacent clicking.
|
||||
return
|
||||
|
||||
if(isnull(location)) //Clicking on a screen object.
|
||||
if(_target.plane != CLICKCATCHER_PLANE) //The clickcatcher is a special case. We want the click to trigger then, under it.
|
||||
return //If we click and drag on our worn backpack, for example, we want it to open instead.
|
||||
_target = params2turf(modifiers["screen-loc"], get_turf(source.eye), source)
|
||||
if(!_target)
|
||||
CRASH("Failed to get the turf under clickcatcher")
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, source, _target, location, control, params) & COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS)
|
||||
return
|
||||
|
||||
source.click_intercept_time = world.time //From this point onwards Click() will no longer be triggered.
|
||||
|
||||
if(autofire_stat & (AUTOFIRE_STAT_IDLE))
|
||||
CRASH("on_mouse_down() called with [autofire_stat] autofire_stat")
|
||||
if(autofire_stat & AUTOFIRE_STAT_FIRING)
|
||||
stop_autofiring() //This can happen if we click and hold and then alt+tab, printscreen or other such action. MouseUp won't be called then and it will keep autofiring.
|
||||
|
||||
target = _target
|
||||
target_loc = get_turf(target)
|
||||
mouse_parameters = params
|
||||
start_autofiring()
|
||||
|
||||
|
||||
//Dakka-dakka
|
||||
/datum/component/automatic_fire/proc/start_autofiring()
|
||||
if(autofire_stat == AUTOFIRE_STAT_FIRING)
|
||||
return //Already pew-pewing.
|
||||
autofire_stat = AUTOFIRE_STAT_FIRING
|
||||
|
||||
clicker.mouse_override_icon = 'icons/effects/mouse_pointers/weapon_pointer.dmi'
|
||||
clicker.mouse_pointer_icon = clicker.mouse_override_icon
|
||||
|
||||
if(mouse_status == AUTOFIRE_MOUSEUP) //See mouse_status definition for the reason for this.
|
||||
RegisterSignal(clicker, COMSIG_CLIENT_MOUSEUP, .proc/on_mouse_up)
|
||||
mouse_status = AUTOFIRE_MOUSEDOWN
|
||||
|
||||
RegisterSignal(shooter, COMSIG_MOB_SWAP_HANDS, .proc/stop_autofiring)
|
||||
|
||||
if(isgun(parent))
|
||||
var/obj/item/gun/shoota = parent
|
||||
if(!shoota.on_autofire_start(shooter)) //This is needed because the minigun has a do_after before firing and signals are async.
|
||||
stop_autofiring()
|
||||
return
|
||||
if(autofire_stat != AUTOFIRE_STAT_FIRING)
|
||||
return //Things may have changed while on_autofire_start() was being processed, due to do_after's sleep.
|
||||
|
||||
if(!process_shot()) //First shot is processed instantly.
|
||||
return //If it fails, such as when the gun is empty, then there's no need to schedule a second shot.
|
||||
|
||||
START_PROCESSING(SSprojectiles, src)
|
||||
RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG, .proc/on_mouse_drag)
|
||||
|
||||
|
||||
/datum/component/automatic_fire/proc/on_mouse_up(datum/source, atom/object, turf/location, control, params)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEUP)
|
||||
mouse_status = AUTOFIRE_MOUSEUP
|
||||
if(autofire_stat == AUTOFIRE_STAT_FIRING)
|
||||
stop_autofiring()
|
||||
return COMPONENT_CLIENT_MOUSEUP_INTERCEPT
|
||||
|
||||
|
||||
/datum/component/automatic_fire/proc/stop_autofiring(datum/source, atom/object, turf/location, control, params)
|
||||
SIGNAL_HANDLER
|
||||
switch(autofire_stat)
|
||||
if(AUTOFIRE_STAT_IDLE, AUTOFIRE_STAT_ALERT)
|
||||
return
|
||||
STOP_PROCESSING(SSprojectiles, src)
|
||||
autofire_stat = AUTOFIRE_STAT_ALERT
|
||||
if(clicker)
|
||||
clicker.mouse_override_icon = null
|
||||
clicker.mouse_pointer_icon = clicker.mouse_override_icon
|
||||
UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG)
|
||||
if(!QDELETED(shooter))
|
||||
UnregisterSignal(shooter, COMSIG_MOB_SWAP_HANDS)
|
||||
target = null
|
||||
target_loc = null
|
||||
mouse_parameters = null
|
||||
|
||||
/datum/component/automatic_fire/proc/on_mouse_drag(client/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(over_location)) //This happens when the mouse is over an inventory or screen object, or on entering deep darkness, for example.
|
||||
var/list/modifiers = params2list(params)
|
||||
var/new_target = params2turf(modifiers["screen-loc"], get_turf(source.eye), source)
|
||||
mouse_parameters = params
|
||||
if(!new_target)
|
||||
if(QDELETED(target)) //No new target acquired, and old one was deleted, get us out of here.
|
||||
stop_autofiring()
|
||||
CRASH("on_mouse_drag failed to get the turf under screen object [over_object.type]. Old target was incidentally QDELETED.")
|
||||
target = get_turf(target) //If previous target wasn't a turf, let's turn it into one to avoid locking onto a potentially moving target.
|
||||
target_loc = target
|
||||
CRASH("on_mouse_drag failed to get the turf under screen object [over_object.type]")
|
||||
target = new_target
|
||||
target_loc = new_target
|
||||
return
|
||||
target = over_object
|
||||
target_loc = get_turf(over_object)
|
||||
mouse_parameters = params
|
||||
|
||||
|
||||
/datum/component/automatic_fire/proc/process_shot()
|
||||
if(autofire_stat != AUTOFIRE_STAT_FIRING)
|
||||
return
|
||||
if(QDELETED(target) || get_turf(target) != target_loc) //Target moved or got destroyed since we last aimed.
|
||||
target = target_loc //So we keep firing on the emptied tile until we move our mouse and find a new target.
|
||||
if(get_dist(shooter, target) <= 0)
|
||||
target = get_step(shooter, shooter.dir) //Shoot in the direction faced if the mouse is on the same tile as we are.
|
||||
target_loc = target
|
||||
else if(!in_view_range(shooter, target))
|
||||
stop_autofiring() //Elvis has left the building.
|
||||
return FALSE
|
||||
shooter.face_atom(target)
|
||||
COOLDOWN_START(src, next_shot_cd, autofire_shot_delay)
|
||||
if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS)
|
||||
return TRUE
|
||||
stop_autofiring()
|
||||
return FALSE
|
||||
|
||||
// Gun procs.
|
||||
|
||||
/obj/item/gun/proc/on_autofire_start(mob/living/shooter)
|
||||
if(!can_shoot(shooter) || !can_trigger_gun(shooter) || semicd)
|
||||
return FALSE
|
||||
var/obj/item/bodypart/other_hand = shooter.has_hand_for_held_index(shooter.get_inactive_hand_index())
|
||||
if(weapon_weight == WEAPON_HEAVY && (shooter.get_inactive_held_item() || !other_hand))
|
||||
to_chat(shooter, "<span class='warning'>You need two hands to fire [src]!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/gun/proc/autofire_bypass_check(datum/source, client/clicker, atom/target, turf/location, control, params)
|
||||
SIGNAL_HANDLER
|
||||
if(clicker.mob.get_active_held_item() != src)
|
||||
return COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS
|
||||
|
||||
|
||||
/obj/item/gun/proc/do_autofire(datum/source, atom/target, mob/living/shooter, params)
|
||||
SIGNAL_HANDLER_DOES_SLEEP
|
||||
if(!can_shoot())
|
||||
shoot_with_empty_chamber(shooter)
|
||||
return NONE
|
||||
var/obj/item/gun/akimbo_gun = shooter.get_inactive_held_item()
|
||||
var/bonus_spread = 0
|
||||
if(istype(akimbo_gun) && weapon_weight < WEAPON_MEDIUM)
|
||||
if(akimbo_gun.weapon_weight < WEAPON_MEDIUM && akimbo_gun.can_trigger_gun(shooter))
|
||||
bonus_spread = dual_wield_spread
|
||||
addtimer(CALLBACK(akimbo_gun, /obj/item/gun.proc/process_fire, target, shooter, TRUE, params, null, bonus_spread), 1)
|
||||
process_fire(target, shooter, TRUE, params, null, bonus_spread)
|
||||
return COMPONENT_AUTOFIRE_SHOT_SUCCESS //All is well, we can continue shooting.
|
||||
|
||||
#undef AUTOFIRE_MOUSEUP
|
||||
#undef AUTOFIRE_MOUSEDOWN
|
||||
@@ -86,6 +86,9 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/ready(forced = FALSE)
|
||||
return ..() && (length(dead_players) + length(list_observers) >= required_applicants)
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/execute()
|
||||
var/list/possible_candidates = list()
|
||||
possible_candidates.Add(dead_players)
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
/obj/machinery/door/firedoor/Initialize(mapload)
|
||||
. = ..()
|
||||
CalculateAffectingAreas()
|
||||
UpdateAdjacencyFlags()
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -53,6 +55,20 @@
|
||||
var/area/A = I
|
||||
LAZYADD(A.firedoors, src)
|
||||
|
||||
/obj/machinery/door/firedoor/proc/UpdateAdjacencyFlags()
|
||||
var/turf/T = get_turf(src)
|
||||
if(flags_1 & ON_BORDER_1)
|
||||
for(var/t in T.atmos_adjacent_turfs)
|
||||
if(get_dir(loc, t) == dir)
|
||||
var/turf/open/T2 = t
|
||||
T.atmos_adjacent_turfs[T2] |= ATMOS_ADJACENT_FIRELOCK
|
||||
T2.atmos_adjacent_turfs[T] |= ATMOS_ADJACENT_FIRELOCK
|
||||
else
|
||||
for(var/t in T.atmos_adjacent_turfs)
|
||||
var/turf/open/T2 = t
|
||||
T.atmos_adjacent_turfs[T2] |= ATMOS_ADJACENT_FIRELOCK
|
||||
T2.atmos_adjacent_turfs[T] |= ATMOS_ADJACENT_FIRELOCK
|
||||
|
||||
/obj/machinery/door/firedoor/closed
|
||||
icon_state = "door_closed"
|
||||
opacity = TRUE
|
||||
|
||||
55
code/game/machinery/posi_alert.dm
Normal file
55
code/game/machinery/posi_alert.dm
Normal file
@@ -0,0 +1,55 @@
|
||||
/obj/machinery/posialert
|
||||
name = "automated positronic alert console"
|
||||
desc = "A console that will ping when a positronic personality is available for download."
|
||||
icon = 'icons/obj/machines/terminals.dmi'
|
||||
icon_state = "posialert"
|
||||
var/inuse = FALSE
|
||||
var/online = TRUE
|
||||
|
||||
var/obj/item/radio/radio
|
||||
var/radio_key = /obj/item/encryptionkey/headset_sci
|
||||
var/science_channel = "Science"
|
||||
|
||||
/obj/machinery/posialert/Initialize(mapload, ndir, building)
|
||||
. = ..()
|
||||
radio = new(src)
|
||||
radio.keyslot = new radio_key
|
||||
radio.listening = 0
|
||||
radio.recalculateChannels()
|
||||
if(building)
|
||||
setDir(ndir)
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -32 : 32)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? -32 : 32) : 0
|
||||
|
||||
|
||||
/obj/machinery/posialert/Destroy()
|
||||
QDEL_NULL(radio)
|
||||
return ..()
|
||||
|
||||
/obj/item/wallframe/posialert
|
||||
name = "automated positronic alert console frame"
|
||||
desc = "Used to build positronic alert consoles, just secure to the wall."
|
||||
icon_state = "newscaster"
|
||||
custom_materials = list(/datum/material/iron=14000, /datum/material/glass=8000)
|
||||
result_path = /obj/machinery/posialert
|
||||
|
||||
/obj/machinery/posialert/attack_hand(mob/living/user)
|
||||
online = !online
|
||||
to_chat(user, "<span class='warning'>You turn the posi-alert system [online ? "on" : "off"]!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/posialert/attack_ghost(mob/user)
|
||||
. = ..()
|
||||
if(!online)
|
||||
return
|
||||
if(inuse)
|
||||
return
|
||||
inuse = TRUE
|
||||
flick("posialertflash",src)
|
||||
visible_message("There are positronic personalities available!")
|
||||
radio.talk_into(src, "There are positronic personalities available!", science_channel)
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50)
|
||||
addtimer(CALLBACK(src, .proc/liftcooldown), 300)
|
||||
|
||||
/obj/machinery/posialert/proc/liftcooldown()
|
||||
inuse = FALSE
|
||||
@@ -1232,6 +1232,51 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
continue
|
||||
. += P
|
||||
|
||||
//borg pda stuff
|
||||
/mob/living/silicon/robot/proc/cmd_send_pdamesg(mob/user)
|
||||
var/list/plist = list()
|
||||
var/list/namecounts = list()
|
||||
|
||||
if(aiPDA.toff)
|
||||
to_chat(user, "Turn on your receiver in order to send messages.")
|
||||
return
|
||||
|
||||
for (var/obj/item/pda/P in get_viewable_pdas())
|
||||
if (P == src)
|
||||
continue
|
||||
else if (P == aiPDA)
|
||||
continue
|
||||
|
||||
plist[avoid_assoc_duplicate_keys(P.owner, namecounts)] = P
|
||||
|
||||
var/c = input(user, "Please select a PDA") as null|anything in sortList(plist)
|
||||
|
||||
if (!c)
|
||||
return
|
||||
|
||||
var/selected = plist[c]
|
||||
|
||||
if(aicamera.stored.len)
|
||||
var/add_photo = input(user,"Do you want to attach a photo?","Photo","No") as null|anything in list("Yes","No")
|
||||
if(add_photo=="Yes")
|
||||
var/datum/picture/Pic = aicamera.selectpicture(user)
|
||||
aiPDA.picture = Pic
|
||||
|
||||
if(incapacitated())
|
||||
return
|
||||
|
||||
aiPDA.create_message(src, selected)
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/cmd_show_message_log(mob/user)
|
||||
if(incapacitated())
|
||||
return
|
||||
if(!isnull(aiPDA))
|
||||
var/HTML = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>AI PDA Message Log</title></head><body>[aiPDA.tnote]</body></html>"
|
||||
user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
|
||||
else
|
||||
to_chat(user, "You do not have a PDA. You should make an issue report about this.")
|
||||
|
||||
#undef PDA_SCANNER_NONE
|
||||
#undef PDA_SCANNER_MEDICAL
|
||||
#undef PDA_SCANNER_FORENSICS
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
item_state = "walkietalkie"
|
||||
desc = "A basic handheld radio that communicates with local telecommunication networks."
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
var/list/extra_channels = list() //Allows indivudal channels, used for borgs
|
||||
|
||||
flags_1 = CONDUCT_1 | HEAR_1
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
@@ -69,6 +70,11 @@
|
||||
if(keyslot.independent)
|
||||
independent = TRUE
|
||||
|
||||
if(extra_channels)
|
||||
for(var/ch_name in extra_channels)
|
||||
if(!(ch_name in channels))
|
||||
channels[ch_name] = extra_channels[ch_name]
|
||||
|
||||
for(var/ch_name in channels)
|
||||
secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name])
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
|
||||
|
||||
if(turf_type)
|
||||
var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags)
|
||||
CALCULATE_ADJACENT_TURFS(newT)
|
||||
newT.ImmediateCalculateAdjacentTurfs()
|
||||
|
||||
/turf/proc/copyTurf(turf/T)
|
||||
if(T.type != type)
|
||||
@@ -285,10 +285,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
|
||||
//If you modify this function, ensure it works correctly with lateloaded map templates.
|
||||
/turf/proc/AfterChange(flags) //called after a turf has been replaced in ChangeTurf()
|
||||
levelupdate()
|
||||
if(flags & CHANGETURF_RECALC_ADJACENT)
|
||||
ImmediateCalculateAdjacentTurfs()
|
||||
else
|
||||
CALCULATE_ADJACENT_TURFS(src)
|
||||
ImmediateCalculateAdjacentTurfs()
|
||||
|
||||
//update firedoor adjacency
|
||||
var/list/turfs_to_check = get_adjacent_open_turfs(src) | src
|
||||
|
||||
@@ -75,7 +75,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
add_overlay(/obj/effect/fullbright)
|
||||
|
||||
if(requires_activation)
|
||||
CALCULATE_ADJACENT_TURFS(src)
|
||||
ImmediateCalculateAdjacentTurfs()
|
||||
|
||||
if (light_power && light_range)
|
||||
update_light()
|
||||
@@ -111,7 +111,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
/turf/proc/set_temperature()
|
||||
|
||||
/turf/proc/Initalize_Atmos(times_fired)
|
||||
CALCULATE_ADJACENT_TURFS(src)
|
||||
ImmediateCalculateAdjacentTurfs()
|
||||
|
||||
/turf/Destroy(force)
|
||||
. = QDEL_HINT_IWILLGC
|
||||
|
||||
@@ -40,21 +40,19 @@
|
||||
return FALSE
|
||||
|
||||
/turf/proc/ImmediateCalculateAdjacentTurfs()
|
||||
if(SSair.thread_running())
|
||||
CALCULATE_ADJACENT_TURFS(src)
|
||||
return
|
||||
var/canpass = CANATMOSPASS(src, src)
|
||||
var/canvpass = CANVERTICALATMOSPASS(src, src)
|
||||
for(var/direction in GLOB.cardinals_multiz)
|
||||
var/turf/T = get_step_multiz(src, direction)
|
||||
if(!istype(T))
|
||||
continue
|
||||
var/opp_dir = REVERSE_DIR(direction)
|
||||
if(isopenturf(T) && !(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
|
||||
LAZYINITLIST(atmos_adjacent_turfs)
|
||||
LAZYINITLIST(T.atmos_adjacent_turfs)
|
||||
atmos_adjacent_turfs[T] = direction
|
||||
T.atmos_adjacent_turfs[src] = opp_dir
|
||||
atmos_adjacent_turfs[T] = ATMOS_ADJACENT_ANY
|
||||
T.atmos_adjacent_turfs[src] = ATMOS_ADJACENT_ANY
|
||||
for(var/obj/machinery/door/firedoor/FD in T)
|
||||
FD.UpdateAdjacencyFlags()
|
||||
else
|
||||
if (atmos_adjacent_turfs)
|
||||
atmos_adjacent_turfs -= T
|
||||
@@ -65,7 +63,8 @@
|
||||
T.__update_auxtools_turf_adjacency_info(isspaceturf(T.get_z_base_turf()), -1)
|
||||
UNSETEMPTY(atmos_adjacent_turfs)
|
||||
src.atmos_adjacent_turfs = atmos_adjacent_turfs
|
||||
set_sleeping(blocks_air)
|
||||
for(var/obj/machinery/door/firedoor/FD in src)
|
||||
FD.UpdateAdjacencyFlags()
|
||||
__update_auxtools_turf_adjacency_info(isspaceturf(get_z_base_turf()))
|
||||
|
||||
/turf/proc/set_sleeping(should_sleep)
|
||||
|
||||
@@ -280,7 +280,11 @@ we use a hook instead
|
||||
parse_gas_string(model.initial_gas_mix)
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/__auxtools_parse_gas_string(gas_string)
|
||||
|
||||
/datum/gas_mixture/parse_gas_string(gas_string)
|
||||
return __auxtools_parse_gas_string(gas_string)
|
||||
/*
|
||||
gas_string = SSair.preprocess_gas_string(gas_string)
|
||||
|
||||
var/list/gas = params2list(gas_string)
|
||||
@@ -295,6 +299,7 @@ we use a hook instead
|
||||
set_moles(id, text2num(gas[id]))
|
||||
archive()
|
||||
return 1
|
||||
*/
|
||||
/*
|
||||
/datum/gas_mixture/react(datum/holder)
|
||||
. = NO_REACTION
|
||||
|
||||
@@ -567,7 +567,8 @@
|
||||
else if(picking_dropoff_turf)
|
||||
holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_pickturf.dmi' //Icon for when mouse is released
|
||||
holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_pickturf_down.dmi' //Icon for when mouse is pressed
|
||||
holder.mouse_pointer_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released)
|
||||
holder.mouse_override_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released)
|
||||
holder.mouse_pointer_icon = holder.mouse_override_icon
|
||||
holder.click_intercept = src //Create a click_intercept so we know where the user is clicking
|
||||
else
|
||||
var/mob/holder_mob = holder.mob
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
///Contains admin info. Null if client is not an admin.
|
||||
var/datum/admins/holder = null
|
||||
var/datum/click_intercept = null // Needs to implement InterceptClickOn(user,params,atom) proc
|
||||
///Time when the click was intercepted
|
||||
var/click_intercept_time = 0
|
||||
var/AI_Interact = 0
|
||||
|
||||
var/jobbancache = null //Used to cache this client's jobbans to save on DB queries
|
||||
@@ -78,6 +80,8 @@
|
||||
//These two vars are used to make a special mouse cursor, with a unique icon for clicking
|
||||
var/mouse_up_icon = null
|
||||
var/mouse_down_icon = null
|
||||
///used to override the mouse cursor so it doesnt get reset
|
||||
var/mouse_override_icon = null
|
||||
|
||||
var/ip_intel = "Disabled"
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
if( (world.address == address || !address) && !GLOB.host )
|
||||
GLOB.host = key
|
||||
world.update_status()
|
||||
|
||||
|
||||
if(holder)
|
||||
add_admin_verbs()
|
||||
var/admin_memo_note = get_message_output("memo")
|
||||
@@ -871,6 +871,16 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
return
|
||||
last_activity = world.time
|
||||
last_click = world.time
|
||||
//fullauto stuff
|
||||
/*
|
||||
if(!control)
|
||||
return
|
||||
*/
|
||||
if(click_intercept_time)
|
||||
if(click_intercept_time >= world.time)
|
||||
click_intercept_time = 0 //Reset and return. Next click should work, but not this one.
|
||||
return
|
||||
click_intercept_time = 0 //Just reset. Let's not keep re-checking forever.
|
||||
var/list/L = params2list(params)
|
||||
|
||||
if(L["drag"])
|
||||
|
||||
@@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars_by_type, typecacheof_assoc_list(list(
|
||||
|
||||
if(toupdate.len)
|
||||
for(var/turf/T1 in toupdate)
|
||||
CALCULATE_ADJACENT_TURFS(T1)
|
||||
T1.ImmediateCalculateAdjacentTurfs()
|
||||
|
||||
|
||||
return copiedobjs
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
. = list()
|
||||
var/mob/living/carbon/human/H
|
||||
var/obj/item/card/id/C
|
||||
if(ishuman(user))
|
||||
if(ishuman(user) || iscyborg(user))
|
||||
H = user
|
||||
C = H.get_idcard(TRUE)
|
||||
if(C)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "robot"
|
||||
bubble_icon = "robot"
|
||||
var/obj/item/pda/ai/aiPDA
|
||||
|
||||
/mob/living/silicon/robot/get_cell()
|
||||
return cell
|
||||
@@ -27,6 +28,12 @@
|
||||
inv2 = new /atom/movable/screen/robot/module2()
|
||||
inv3 = new /atom/movable/screen/robot/module3()
|
||||
|
||||
if(!shell)
|
||||
aiPDA = new/obj/item/pda/ai(src)
|
||||
aiPDA.owner = real_name
|
||||
aiPDA.ownjob = "Cyborg"
|
||||
aiPDA.name = real_name + " (" + aiPDA.ownjob + ")"
|
||||
|
||||
previous_health = health
|
||||
|
||||
if(ispath(cell))
|
||||
@@ -968,6 +975,9 @@
|
||||
notify_ai(RENAME, oldname, newname)
|
||||
if(!QDELETED(builtInCamera))
|
||||
builtInCamera.c_tag = real_name
|
||||
if(aiPDA && !shell)
|
||||
aiPDA.owner = newname
|
||||
aiPDA.name = newname + " (" + aiPDA.ownjob + ")"
|
||||
custom_name = newname
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
var/list/modules = list() //holds all the usable modules
|
||||
var/list/added_modules = list() //modules not inherient to the robot module, are kept when the module changes
|
||||
var/list/storages = list()
|
||||
var/list/added_channels = list() //Borg radio stuffs
|
||||
|
||||
var/cyborg_base_icon = "robot" //produces the icon for the borg and, if no special_light_key is set, the lights
|
||||
var/special_light_key //if we want specific lights, use this instead of copying lights in the dmi
|
||||
@@ -236,6 +237,8 @@
|
||||
R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine/dogborg
|
||||
else
|
||||
R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine
|
||||
R.radio.extra_channels = RM.added_channels
|
||||
R.radio.recalculateChannels()
|
||||
R.maxHealth = borghealth
|
||||
R.health = min(borghealth, R.health)
|
||||
qdel(src)
|
||||
@@ -322,6 +325,7 @@
|
||||
|
||||
/obj/item/robot_module/medical
|
||||
name = "Medical"
|
||||
added_channels = list(RADIO_CHANNEL_MEDICAL = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
@@ -432,6 +436,7 @@
|
||||
|
||||
/obj/item/robot_module/engineering
|
||||
name = "Engineering"
|
||||
added_channels = list(RADIO_CHANNEL_ENGINEERING = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/borg/sight/meson,
|
||||
@@ -546,6 +551,7 @@
|
||||
|
||||
/obj/item/robot_module/security
|
||||
name = "Security"
|
||||
added_channels = list(RADIO_CHANNEL_SECURITY = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
@@ -648,6 +654,7 @@
|
||||
|
||||
/obj/item/robot_module/peacekeeper
|
||||
name = "Peacekeeper"
|
||||
added_channels = list(RADIO_CHANNEL_SECURITY = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
@@ -734,6 +741,7 @@
|
||||
|
||||
/obj/item/robot_module/clown
|
||||
name = "Clown"
|
||||
added_channels = list(RADIO_CHANNEL_SERVICE = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
@@ -766,6 +774,7 @@
|
||||
|
||||
/obj/item/robot_module/butler
|
||||
name = "Service"
|
||||
added_channels = list(RADIO_CHANNEL_SERVICE = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
@@ -909,6 +918,7 @@
|
||||
|
||||
/obj/item/robot_module/miner
|
||||
name = "Miner"
|
||||
added_channels = list(RADIO_CHANNEL_SUPPLY = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
@@ -999,6 +1009,7 @@
|
||||
|
||||
/obj/item/robot_module/syndicate
|
||||
name = "Syndicate Assault"
|
||||
added_channels = list(RADIO_CHANNEL_SYNDICATE = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
@@ -1029,6 +1040,7 @@
|
||||
|
||||
/obj/item/robot_module/syndicate_medical
|
||||
name = "Syndicate Medical"
|
||||
added_channels = list(RADIO_CHANNEL_SYNDICATE = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
@@ -1061,6 +1073,7 @@
|
||||
|
||||
/obj/item/robot_module/saboteur
|
||||
name = "Syndicate Saboteur"
|
||||
added_channels = list(RADIO_CHANNEL_SYNDICATE = 1)
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/borg/sight/thermal,
|
||||
|
||||
@@ -878,10 +878,12 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
if (!client)
|
||||
return
|
||||
client.mouse_pointer_icon = initial(client.mouse_pointer_icon)
|
||||
if (ismecha(loc))
|
||||
var/obj/vehicle/sealed/mecha/M = loc
|
||||
if(M.mouse_pointer)
|
||||
client.mouse_pointer_icon = M.mouse_pointer
|
||||
if(istype(loc, /obj/vehicle/sealed))
|
||||
var/obj/vehicle/sealed/mecha/E = loc
|
||||
if(E.mouse_pointer)
|
||||
client.mouse_pointer_icon = E.mouse_pointer
|
||||
if(client.mouse_override_icon)
|
||||
client.mouse_pointer_icon = client.mouse_override_icon
|
||||
|
||||
/mob/proc/is_literate()
|
||||
return 0
|
||||
|
||||
@@ -952,7 +952,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
playsound(T, 'sound/effects/supermatter.ogg', 50, 1)
|
||||
T.visible_message("<span class='danger'>[T] smacks into [src] and rapidly flashes to ash.</span>",\
|
||||
"<span class='italics'>You hear a loud crack as you are washed with a wave of heat.</span>")
|
||||
CALCULATE_ADJACENT_TURFS(T)
|
||||
T.ImmediateCalculateAdjacentTurfs()
|
||||
|
||||
//Do not blow up our internal radio
|
||||
/obj/machinery/power/supermatter_crystal/contents_explosion(severity, target, origin)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
var/ranged_attack_speed = CLICK_CD_RANGE
|
||||
var/melee_attack_speed = CLICK_CD_MELEE
|
||||
|
||||
var/gun_flags = NONE
|
||||
var/fire_sound = "gunshot"
|
||||
var/suppressed = null //whether or not a message is displayed when fired
|
||||
var/can_suppress = FALSE
|
||||
@@ -32,6 +33,7 @@
|
||||
trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers
|
||||
var/sawn_desc = null //description change if weapon is sawn-off
|
||||
var/sawn_off = FALSE
|
||||
var/firing_burst = 0 //Prevent the weapon from firing again while already firing
|
||||
|
||||
/// can we be put into a turret
|
||||
var/can_turret = TRUE
|
||||
@@ -57,6 +59,8 @@
|
||||
var/burst_spread = 0 //Spread induced by the gun itself during burst fire per iteration. Only checked if spread is 0.
|
||||
var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once.
|
||||
var/inaccuracy_modifier = 1
|
||||
var/semicd = 0 //cooldown handler
|
||||
var/dual_wield_spread = 24 //additional spread when dual wielding
|
||||
|
||||
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
|
||||
@@ -87,27 +91,64 @@
|
||||
var/zoom_out_amt = 0
|
||||
var/datum/action/item_action/toggle_scope_zoom/azoom
|
||||
|
||||
//Firemodes
|
||||
var/datum/action/item_action/toggle_firemode/firemode_action
|
||||
/// Current fire selection, can choose between burst, single, and full auto.
|
||||
var/fire_select = SELECT_SEMI_AUTOMATIC
|
||||
var/fire_select_index = 1
|
||||
/// What modes does this weapon have? Put SELECT_FULLY_AUTOMATIC in here to enable fully automatic behaviours.
|
||||
var/list/fire_select_modes = list(SELECT_SEMI_AUTOMATIC)
|
||||
/// if i`1t has an icon for a selector switch indicating current firemode.
|
||||
var/selector_switch_icon = FALSE
|
||||
|
||||
var/dualwield_spread_mult = 1 //dualwield spread multiplier
|
||||
|
||||
/// Just 'slightly' snowflakey way to modify projectile damage for projectiles fired from this gun.
|
||||
var/projectile_damage_multiplier = 1
|
||||
|
||||
var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds
|
||||
|
||||
/// directional recoil multiplier
|
||||
var/dir_recoil_amp = 10
|
||||
|
||||
/obj/item/gun/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/toggle_firemode))
|
||||
fire_select()
|
||||
else if(istype(action, /datum/action/item_action/toggle_scope_zoom))
|
||||
zoom(user, user.dir)
|
||||
else if(istype(action, alight))
|
||||
toggle_gunlight()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/gun/Initialize(mapload)
|
||||
. = ..()
|
||||
if(no_pin_required)
|
||||
pin = null
|
||||
else if(pin)
|
||||
if(pin)
|
||||
pin = new pin(src)
|
||||
|
||||
if(gun_light)
|
||||
alight = new (src)
|
||||
alight = new(src)
|
||||
|
||||
if(zoomable)
|
||||
azoom = new (src)
|
||||
|
||||
if(burst_size > 1 && !(SELECT_BURST_SHOT in fire_select_modes))
|
||||
fire_select_modes.Add(SELECT_BURST_SHOT)
|
||||
else if(burst_size <= 1 && (SELECT_BURST_SHOT in fire_select_modes))
|
||||
fire_select_modes.Remove(SELECT_BURST_SHOT)
|
||||
|
||||
burst_size = 1
|
||||
|
||||
sortList(fire_select_modes, /proc/cmp_numeric_asc)
|
||||
|
||||
if(fire_select_modes.len > 1)
|
||||
firemode_action = new(src)
|
||||
firemode_action.button_icon_state = "fireselect_[fire_select]"
|
||||
firemode_action.UpdateButtonIcon()
|
||||
|
||||
/obj/item/gun/ComponentInitialize()
|
||||
. = ..()
|
||||
if(SELECT_FULLY_AUTOMATIC in fire_select_modes)
|
||||
AddComponent(/datum/component/automatic_fire, fire_delay)
|
||||
|
||||
/obj/item/gun/Destroy()
|
||||
if(pin)
|
||||
QDEL_NULL(pin)
|
||||
@@ -117,6 +158,10 @@
|
||||
QDEL_NULL(bayonet)
|
||||
if(chambered)
|
||||
QDEL_NULL(chambered)
|
||||
if(azoom)
|
||||
QDEL_NULL(azoom)
|
||||
if(firemode_action)
|
||||
QDEL_NULL(firemode_action)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/examine(mob/user)
|
||||
@@ -142,6 +187,41 @@
|
||||
else if(can_bayonet)
|
||||
. += "It has a <b>bayonet</b> lug on it."
|
||||
|
||||
/obj/item/gun/proc/fire_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
|
||||
var/max_mode = fire_select_modes.len
|
||||
|
||||
if(max_mode <= 1)
|
||||
to_chat(user, "<span class='warning'>[src] is not capable of switching firemodes!</span>")
|
||||
return
|
||||
|
||||
fire_select_index = 1 + fire_select_index % max_mode //Magic math to cycle through this shit!
|
||||
|
||||
fire_select = fire_select_modes[fire_select_index]
|
||||
|
||||
switch(fire_select)
|
||||
if(SELECT_SEMI_AUTOMATIC)
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_DESELECTED, user)
|
||||
to_chat(user, "<span class='notice'>You switch [src] to semi-automatic.</span>")
|
||||
if(SELECT_BURST_SHOT)
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_DESELECTED, user)
|
||||
to_chat(user, "<span class='notice'>You switch [src] to [burst_size]-round burst.</span>")
|
||||
if(SELECT_FULLY_AUTOMATIC)
|
||||
burst_size = 1
|
||||
SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_SELECTED, user)
|
||||
to_chat(user, "<span class='notice'>You switch [src] to automatic.</span>")
|
||||
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
|
||||
update_appearance()
|
||||
firemode_action.button_icon_state = "fireselect_[fire_select]"
|
||||
firemode_action.UpdateButtonIcon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun/equipped(mob/living/user, slot)
|
||||
. = ..()
|
||||
if(zoomed && user.get_active_held_item() != src)
|
||||
@@ -567,12 +647,6 @@
|
||||
|
||||
gun_light = new_light
|
||||
|
||||
/obj/item/gun/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/toggle_scope_zoom))
|
||||
zoom(user, user.dir)
|
||||
else if(istype(action, alight))
|
||||
toggle_gunlight()
|
||||
|
||||
/obj/item/gun/proc/toggle_gunlight()
|
||||
if(!gun_light)
|
||||
return
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
var/automatic_burst_overlay = TRUE
|
||||
can_suppress = TRUE
|
||||
burst_size = 3
|
||||
burst_shot_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
fire_delay = 2
|
||||
fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT, SELECT_FULLY_AUTOMATIC)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/proto
|
||||
name = "\improper Nanotrasen Saber SMG"
|
||||
@@ -15,6 +15,7 @@
|
||||
fire_sound = "sound/weapons/gunshot_smg_alt.ogg"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm9mm
|
||||
pin = null
|
||||
burst_size = 1
|
||||
|
||||
/obj/item/gun/ballistic/automatic/proto/unrestricted
|
||||
pin = /obj/item/firing_pin
|
||||
@@ -55,34 +56,6 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You cannot seem to get \the [src] out of your hands!</span>")
|
||||
|
||||
/obj/item/gun/ballistic/automatic/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/toggle_firemode))
|
||||
burst_select()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/ballistic/automatic/proc/burst_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
select = !select
|
||||
if(!select)
|
||||
disable_burst()
|
||||
to_chat(user, "<span class='notice'>You switch to semi-automatic.</span>")
|
||||
else
|
||||
enable_burst()
|
||||
to_chat(user, "<span class='notice'>You switch to [burst_size]-rnd burst.</span>")
|
||||
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
update_icon()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/gun/ballistic/automatic/proc/enable_burst()
|
||||
burst_size = initial(burst_size)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/proc/disable_burst()
|
||||
burst_size = 1
|
||||
|
||||
/obj/item/gun/ballistic/automatic/can_shoot()
|
||||
return get_ammo()
|
||||
|
||||
@@ -136,18 +109,10 @@
|
||||
knife_y_offset = 12
|
||||
automatic_burst_overlay = FALSE
|
||||
|
||||
/obj/item/gun/ballistic/automatic/wt550/enable_burst()
|
||||
. = ..()
|
||||
spread = 15
|
||||
|
||||
/obj/item/gun/ballistic/automatic/wt550/afterattack()
|
||||
. = ..()
|
||||
empty_alarm()
|
||||
|
||||
/obj/item/gun/ballistic/automatic/wt550/disable_burst()
|
||||
. = ..()
|
||||
spread = 0
|
||||
|
||||
/obj/item/gun/ballistic/automatic/wt550/update_icon_state()
|
||||
icon_state = "wt550[magazine ? "-[CEILING(((get_ammo(FALSE) / magazine.max_ammo) * 20) /4, 1)*4]" : "-0"]" //Sprites only support up to 20.
|
||||
|
||||
@@ -211,6 +176,7 @@
|
||||
/obj/item/gun/ballistic/automatic/m90/update_icon_state()
|
||||
icon_state = "[initial(icon_state)][magazine ? "" : "-e"]"
|
||||
|
||||
/*
|
||||
/obj/item/gun/ballistic/automatic/m90/burst_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
switch(select)
|
||||
@@ -228,6 +194,7 @@
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
update_icon()
|
||||
return
|
||||
*/
|
||||
|
||||
/obj/item/gun/ballistic/automatic/tommygun
|
||||
name = "\improper Thompson SMG"
|
||||
@@ -304,14 +271,17 @@
|
||||
slot_flags = 0
|
||||
mag_type = /obj/item/ammo_box/magazine/mm712x82
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
var/cover_open = FALSE
|
||||
can_suppress = FALSE
|
||||
burst_size = 3
|
||||
burst_shot_delay = 1
|
||||
burst_size = 1
|
||||
actions_types = list()
|
||||
spread = 7
|
||||
pin = /obj/item/firing_pin/implant/pindicate
|
||||
automatic_burst_overlay = FALSE
|
||||
var/cover_open = FALSE
|
||||
|
||||
/obj/item/gun/ballistic/automatic/l6_saw/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
AddComponent(/datum/component/automatic_fire, 0.2 SECONDS)
|
||||
/obj/item/gun/ballistic/automatic/l6_saw/unrestricted
|
||||
pin = /obj/item/firing_pin
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/m75
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
actions_types = list()
|
||||
fire_select_modes = list(SELECT_SEMI_AUTOMATIC)
|
||||
casing_ejector = FALSE
|
||||
|
||||
/obj/item/gun/ballistic/automatic/gyropistol/update_icon_state()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
can_suppress = TRUE
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
actions_types = list()
|
||||
fire_select_modes = list(SELECT_SEMI_AUTOMATIC)
|
||||
automatic_burst_overlay = FALSE
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/no_mag
|
||||
@@ -104,7 +104,7 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/pistolm9mm
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT, SELECT_FULLY_AUTOMATIC)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/stickman
|
||||
name = "flat gun"
|
||||
@@ -137,7 +137,7 @@
|
||||
burst_size = 1
|
||||
can_suppress = FALSE
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
actions_types = list()
|
||||
fire_select_modes = list(SELECT_SEMI_AUTOMATIC)
|
||||
fire_sound = 'sound/weapons/noscope.ogg'
|
||||
spread = 20 //damn thing has no rifling.
|
||||
automatic_burst_overlay = FALSE
|
||||
|
||||
@@ -101,8 +101,6 @@
|
||||
slot_flags = null
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
custom_materials = null
|
||||
automatic = 0.5
|
||||
fire_delay = 2
|
||||
ammo_type = list(
|
||||
/obj/item/ammo_casing/energy/laser
|
||||
)
|
||||
|
||||
@@ -75,6 +75,14 @@
|
||||
build_path = /obj/item/wallframe/newscaster
|
||||
category = list("initial", "Construction")
|
||||
|
||||
/datum/design/posialert
|
||||
name = "Posialert Frame"
|
||||
id = "posialert_frame"
|
||||
build_type = AUTOLATHE
|
||||
materials = list(/datum/material/iron = 14000, /datum/material/glass = 8000)
|
||||
build_path = /obj/item/wallframe/posialert
|
||||
category = list("initial", "Construction")
|
||||
|
||||
/datum/design/status_display_frame
|
||||
name = "Status Display Frame"
|
||||
id = "status_display_frame"
|
||||
|
||||
Reference in New Issue
Block a user