Merge pull request #2502 from comma/gunmode

Aiming Mode
This commit is contained in:
Christian Bielert
2013-03-09 00:13:19 -08:00
33 changed files with 1168 additions and 428 deletions

View File

@@ -1,7 +1,7 @@
// All mobs should have custom emote, really..
mob/proc/custom_emote(var/m_type=1,var/message = null)
if(!emote_allowed && usr == src)
if(!use_me && usr == src)
usr << "You are unable to emote."
return

View File

@@ -9,6 +9,7 @@
var/ghost_name = "Unknown"
var/creating_blob = 0
faction = "blob"
use_me = 0 //Blobs can't emote
New()

View File

@@ -3,7 +3,8 @@
#define X_SUIT_LAYER 2
#define X_L_HAND_LAYER 3
#define X_R_HAND_LAYER 4
#define X_TOTAL_LAYERS 4
#define TARGETED_LAYER 5
#define X_TOTAL_LAYERS 5
/////////////////////////////////
/mob/living/carbon/alien/humanoid
@@ -132,10 +133,22 @@
overlays_standing[X_L_HAND_LAYER] = null
if(update_icons) update_icons()
//Call when target overlay should be added/removed
/mob/living/carbon/alien/humanoid/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_lying[TARGETED_LAYER] = target_locked
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
del(target_locked)
if (!targeted_by)
overlays_lying[TARGETED_LAYER] = null
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
//Xeno Overlays Indexes//////////
#undef X_HEAD_LAYER
#undef X_SUIT_LAYER
#undef X_L_HAND_LAYER
#undef X_R_HAND_LAYER
#undef TARGETED_LAYER
#undef X_TOTAL_LAYERS

View File

@@ -5,6 +5,7 @@
var/timeofhostdeath = 0
var/emp_damage = 0//Handles a type of MMI damage
var/alert = null
use_me = 0 //Can't use the me verb, it's a freaking immobile brain
New()
var/datum/reagents/R = new/datum/reagents(1000)
@@ -48,6 +49,8 @@
/mob/living/carbon/brain/update_canmove()
if(in_contents_of(/obj/mecha)) canmove = 1
if(in_contents_of(/obj/mecha))
canmove = 1
use_me = 1 //If it can move, let it emote
else canmove = 0
return canmove

View File

@@ -485,9 +485,30 @@
mymob.zone_sel.overlays.Cut()
mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")
//Handle the gun settings buttons
mymob.gun_setting_icon = new /obj/screen/gun/mode(null)
if (mymob.client)
if (mymob.client.gun_mode) // If in aim mode, correct the sprite
mymob.gun_setting_icon.dir = 2
for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons
if (G.target)
mymob.item_use_icon = new /obj/screen/gun/item(null)
if (mymob.client.target_can_click)
mymob.item_use_icon.dir = 1
src.adding += mymob.item_use_icon
mymob.gun_move_icon = new /obj/screen/gun/move(null)
if (mymob.client.target_can_move)
mymob.gun_move_icon.dir = 1
mymob.gun_run_icon = new /obj/screen/gun/run(null)
if (mymob.client.target_can_run)
mymob.gun_run_icon.dir = 1
src.adding += mymob.gun_run_icon
src.adding += mymob.gun_move_icon
mymob.client.screen = null
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay, mymob.gun_setting_icon) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
mymob.client.screen += src.adding + src.hotkeybuttons
inventory_shown = 0;

View File

@@ -64,6 +64,7 @@ There are several things that need to be remembered:
update_body() //Handles updating your mob's icon to reflect their gender/race/complexion etc
update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and
...eyes were merged into update_body)
update_targeted() // Updates the target overlay when someone points a gun at you
> All of these procs update our overlays_lying and overlays_standing, and then call update_icons() by default.
If you wish to update several overlays at once, you can set the argument to 0 to disable the update and call
@@ -117,7 +118,8 @@ Please contact me on #coderbus IRC. ~Carn x
#define L_HAND_LAYER 19
#define R_HAND_LAYER 20
#define TAIL_LAYER 21 //bs12 specific. this hack is probably gonna come back to haunt me
#define TOTAL_LAYERS 21
#define TARGETED_LAYER 22 //BS12: Layer for the target overlay from weapon targeting system
#define TOTAL_LAYERS 22
//////////////////////////////////
/mob/living/carbon/human
@@ -130,7 +132,6 @@ Please contact me on #coderbus IRC. ~Carn x
//this proc is messy as I was forced to include some old laggy cloaking code to it so that I don't break cloakers
//I'll work on removing that stuff by rewriting some of the cloaking stuff at a later date.
/mob/living/carbon/human/update_icons()
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
update_hud() //TODO: remove the need for this
overlays.Cut()
@@ -472,6 +473,19 @@ proc/get_damage_icon_part(damage_state, body_part)
update_hair(0)
if(update_icons) update_icons()
//Call when target overlay should be added/removed
/mob/living/carbon/human/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_lying[TARGETED_LAYER] = target_locked
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
del(target_locked)
if (!targeted_by)
overlays_lying[TARGETED_LAYER] = null
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
/* --------------------------------------- */
//For legacy support.
/mob/living/carbon/human/regenerate_icons()
@@ -858,4 +872,5 @@ proc/get_damage_icon_part(damage_state, body_part)
#undef L_HAND_LAYER
#undef R_HAND_LAYER
#undef TAIL_LAYER
#undef TOTAL_LAYERS
#undef TARGETED_LAYER
#undef TOTAL_LAYERS

View File

@@ -220,9 +220,29 @@
mymob.zone_sel.overlays.Cut()
mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")
//Handle the gun settings buttons
mymob.gun_setting_icon = new /obj/screen/gun/mode(null)
if (mymob.client)
if (mymob.client.gun_mode) // If in aim mode, correct the sprite
mymob.gun_setting_icon.dir = 2
for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons
if (G.target)
mymob.item_use_icon = new /obj/screen/gun/item(null)
if (mymob.client.target_can_click)
mymob.item_use_icon.dir = 1
src.adding += mymob.item_use_icon
mymob.gun_move_icon = new /obj/screen/gun/move(null)
if (mymob.client.target_can_move)
mymob.gun_move_icon.dir = 1
mymob.gun_run_icon = new /obj/screen/gun/run(null)
if (mymob.client.target_can_run)
mymob.gun_run_icon.dir = 1
src.adding += mymob.gun_run_icon
src.adding += mymob.gun_move_icon
mymob.client.screen = null
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.pullin, mymob.blind, mymob.flash) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.pullin, mymob.blind, mymob.flash, mymob.gun_setting_icon) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += src.adding + src.other
return

View File

@@ -4,7 +4,8 @@
#define M_HANDCUFF_LAYER 3
#define M_L_HAND_LAYER 4
#define M_R_HAND_LAYER 5
#define M_TOTAL_LAYERS 5
#define TARGETED_LAYER 6
#define M_TOTAL_LAYERS 6
/////////////////////////////////
/mob/living/carbon/monkey
@@ -101,11 +102,24 @@
if (client)
client.screen |= contents
//Call when target overlay should be added/removed
/mob/living/carbon/monkey/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_lying[TARGETED_LAYER] = target_locked
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
del(target_locked)
if (!targeted_by)
overlays_lying[TARGETED_LAYER] = null
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
//Monkey Overlays Indexes////////
#undef M_MASK_LAYER
#undef M_BACK_LAYER
#undef M_HANDCUFF_LAYER
#undef M_L_HAND_LAYER
#undef M_R_HAND_LAYER
#undef TARGETED_LAYER
#undef M_TOTAL_LAYERS

View File

@@ -143,9 +143,29 @@
mymob.zone_sel.overlays.Cut()
mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")
//Handle the gun settings buttons
mymob.gun_setting_icon = new /obj/screen/gun/mode(null)
if (mymob.client)
if (mymob.client.gun_mode) // If in aim mode, correct the sprite
mymob.gun_setting_icon.dir = 2
for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons
if (G.target)
mymob.item_use_icon = new /obj/screen/gun/item(null)
if (mymob.client.target_can_click)
mymob.item_use_icon.dir = 1
src.adding += mymob.item_use_icon
mymob.gun_move_icon = new /obj/screen/gun/move(null)
if (mymob.client.target_can_move)
mymob.gun_move_icon.dir = 1
mymob.gun_run_icon = new /obj/screen/gun/run(null)
if (mymob.client.target_can_run)
mymob.gun_run_icon.dir = 1
src.adding += mymob.gun_run_icon
src.adding += mymob.gun_move_icon
mymob.client.screen = null
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, mymob.blind, mymob.flash) //, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, mymob.blind, mymob.flash, mymob.gun_setting_icon) //, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += src.adding + src.other
return

View File

@@ -1,7 +1,7 @@
/mob/living/silicon/robot
name = "Cyborg"
real_name = "Cyborg"
icon = 'icons/mob/robots.dmi'//
icon = 'icons/mob/robots.dmi'
icon_state = "robot"
maxHealth = 300
health = 300
@@ -806,7 +806,13 @@
overlays += "ov-openpanel -c"
return
//Call when target overlay should be added/removed
/mob/living/silicon/robot/update_targeted()
if(!targeted_by && target_locked)
del(target_locked)
updateicon()
if (targeted_by && target_locked)
overlays += target_locked
/mob/living/silicon/robot/proc/installed_modules()
if(weapon_lock)

View File

@@ -27,7 +27,7 @@
regenerate_icons()
/mob/living/simple_animal/corgi/show_inv(mob/user as mob)
/*
/* If you're turning this back on, scroll down and uncomment target_updated
user.set_machine(src)
if(user.stat) return
@@ -404,7 +404,6 @@
return
/mob/living/simple_animal/corgi/puppy
name = "\improper corgi puppy"
real_name = "corgi"

View File

@@ -456,4 +456,12 @@
var/obj/machinery/bot/B = target_mob
if(B.health > 0)
return (0)
return (1)
return (1)
//Call when target overlay should be added/removed
/mob/living/simple_animal/update_targeted()
if(!targeted_by && target_locked)
del(target_locked)
overlays = null
if (targeted_by && target_locked)
overlays += target_locked

View File

@@ -27,6 +27,10 @@
var/obj/screen/pressure = null
var/obj/screen/damageoverlay = null
var/obj/screen/pain = null
var/obj/screen/gun/item/item_use_icon = null
var/obj/screen/gun/move/gun_move_icon = null
var/obj/screen/gun/run/gun_run_icon = null
var/obj/screen/gun/mode/gun_setting_icon = null
/*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such.
@@ -36,6 +40,7 @@
*/
var/obj/screen/zone_sel/zone_sel = null
var/use_me = 1 //Allows all mobs to use the me verb by default, will have to manually specify they cannot
var/damageoverlaytemp = 0
var/computer_id = null
var/lastattacker = null
@@ -210,4 +215,4 @@
var/has_limbs = 1 //Whether this mob have any limbs he can move with
var/can_stand = 1 //Whether this mob have ability to stand
var/immune_to_ssd = 0
var/immune_to_ssd = 0

View File

@@ -280,7 +280,7 @@
return 0
move_delay = world.time//set move delay
mob.last_move_intent = world.time + 10
switch(mob.m_intent)
if("run")
if(mob.drowsyness > 0)

View File

@@ -24,7 +24,7 @@
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if(ishuman(src) || isrobot(src))
if(use_me)
usr.emote("me",1,message)
else
usr.emote(message)

View File

@@ -5,6 +5,7 @@
unacidable = 1
var/id = 0.0
var/obj/master
var/gun_click_time = -100 //I'm lazy.
/obj/screen/text
icon = null
@@ -72,6 +73,33 @@
var/selecting = "chest"
screen_loc = ui_zonesel
/obj/screen/gun
name = "gun"
icon = 'screen1.dmi'
master = null
dir = 2
move
name = "Allow Walking"
icon_state = "no_walk0"
screen_loc = ui_gun2
run
name = "Allow Running"
icon_state = "no_run0"
screen_loc = ui_gun3
item
name = "Allow Item Use"
icon_state = "no_item0"
screen_loc = ui_gun1
mode
name = "Toggle Gun Mode"
icon_state = "gun0"
screen_loc = ui_gun_select
//dir = 1
/obj/screen/zone_sel/MouseDown(location, control,params)
// Changes because of 4.0
@@ -460,6 +488,64 @@
usr:inv3.icon_state = "inv3"
usr:module_active = null
if("Allow Walking")
if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes.
return
if(!istype(usr.equipped(),/obj/item/weapon/gun))
usr << "You need your gun in your active hand to do that!"
return
usr.client.AllowTargetMove()
gun_click_time = world.time
if("Disallow Walking")
if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes.
return
if(!istype(usr.equipped(),/obj/item/weapon/gun))
usr << "You need your gun in your active hand to do that!"
return
usr.client.AllowTargetMove()
gun_click_time = world.time
if("Allow Running")
if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes.
return
if(!istype(usr.equipped(),/obj/item/weapon/gun))
usr << "You need your gun in your active hand to do that!"
return
usr.client.AllowTargetRun()
gun_click_time = world.time
if("Disallow Running")
if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes.
return
if(!istype(usr.equipped(),/obj/item/weapon/gun))
usr << "You need your gun in your active hand to do that!"
return
usr.client.AllowTargetRun()
gun_click_time = world.time
if("Allow Item Use")
if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes.
return
if(!istype(usr.equipped(),/obj/item/weapon/gun))
usr << "You need your gun in your active hand to do that!"
return
usr.client.AllowTargetClick()
gun_click_time = world.time
if("Disallow Item Use")
if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes.
return
if(!istype(usr.equipped(),/obj/item/weapon/gun))
usr << "You need your gun in your active hand to do that!"
return
usr.client.AllowTargetClick()
gun_click_time = world.time
if("Toggle Gun Mode")
usr.client.ToggleGunMode()
else
DblClick()
return

View File

@@ -63,3 +63,6 @@
/mob/proc/update_inv_ears()
return
/mob/proc/update_targeted()
return

View File

@@ -22,7 +22,14 @@
var/recoil = 0
var/ejectshell = 1
var/clumsy_check = 1
var/tmp/list/mob/living/target //List of who yer targeting.
var/tmp/lock_time = -100
var/tmp/mouthshoot = 0 ///To stop people from suiciding twice... >.>
var/automatic = 0 //Used to determine if you can target multiple people.
var/tmp/mob/living/last_moved_mob //Used to fire faster at more than one person.
var/tmp/told_cant_shoot = 0 //So that it doesn't spam them with the fact they cannot hit them.
var/firerate = 1 // 0 for one bullet after tarrget moves and aim is lowered,
//1 for keep shooting until aim is lowered
proc/load_into_chamber()
return 0
@@ -30,107 +37,157 @@
proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver.
return 1
emp_act(severity)
for(var/obj/O in contents)
O.emp_act(severity)
afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params)//TODO: go over this
if(flag) return //we're placing gun on a table or in backpack
if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this?
//Exclude lasertag guns from the CLUMSY check.
if(clumsy_check)
if(istype(user, /mob/living))
var/mob/living/M = user
if ((CLUMSY in M.mutations) && prob(50))
M << "<span class='danger'>[src] blows up in your face.</span>"
M.take_organ_damage(0,20)
M.drop_item()
del(src)
return
if (!user.IsAdvancedToolUser())
user << "\red You don't have the dexterity to do this!"
return
if(istype(user, /mob/living))
var/mob/living/M = user
if (HULK in M.mutations)
M << "\red Your meaty finger is much too large for the trigger guard!"
return
if(ishuman(user))
if(user.dna && user.dna.mutantrace == "adamantine")
user << "\red Your metal fingers don't fit in the trigger guard!"
return
add_fingerprint(user)
var/turf/curloc = user.loc
var/turf/targloc = get_turf(target)
if (!istype(targloc) || !istype(curloc))
return
if(!special_check(user))
return
if(!load_into_chamber())
user << "\red *click*";
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
if(!in_chamber)
return
in_chamber.firer = user
in_chamber.def_zone = user.zone_sel.selecting
if(targloc == curloc)
user.bullet_act(in_chamber)
del(in_chamber)
update_icon()
return
if(recoil)
spawn()
shake_camera(user, recoil + 1, recoil)
if(silenced)
playsound(user, fire_sound, 10, 1)
else
playsound(user, fire_sound, 50, 1)
user.visible_message("<span class='warning'>[user] fires [src]!</span>", "<span class='warning'>You fire [src]!</span>", "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!")
in_chamber.original = target
in_chamber.loc = get_turf(user)
in_chamber.starting = get_turf(user)
in_chamber.shot_from = src
user.next_move = world.time + 4
in_chamber.silenced = silenced
in_chamber.current = curloc
in_chamber.yo = targloc.y - curloc.y
in_chamber.xo = targloc.x - curloc.x
if(params)
var/list/mouse_control = params2list(params)
if(mouse_control["icon-x"])
in_chamber.p_x = text2num(mouse_control["icon-x"])
if(mouse_control["icon-y"])
in_chamber.p_y = text2num(mouse_control["icon-y"])
spawn()
if(in_chamber)
in_chamber.process()
sleep(1)
in_chamber = null
update_icon()
if(user.hand)
user.update_inv_l_hand()
else
user.update_inv_r_hand()
/obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
if(flag) return //we're placing gun on a table or in backpack
if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this?
if(user && user.client && user.client.gun_mode && !(A in target))
PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at.
else
Fire(A,user,params) //Otherwise, fire normally.
/obj/item/weapon/gun/proc/isHandgun()
return 1
/obj/item/weapon/gun/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)//TODO: go over this
//Exclude lasertag guns from the CLUMSY check.
if(clumsy_check)
if(istype(user, /mob/living))
var/mob/living/M = user
if ((CLUMSY in M.mutations) && prob(50))
M << "<span class='danger'>[src] blows up in your face.</span>"
M.take_organ_damage(0,20)
M.drop_item()
del(src)
return
if (!user.IsAdvancedToolUser())
user << "\red You don't have the dexterity to do this!"
return
if(istype(user, /mob/living))
var/mob/living/M = user
if (HULK in M.mutations)
M << "\red Your meaty finger is much too large for the trigger guard!"
return
if(ishuman(user))
if(user.dna && user.dna.mutantrace == "adamantine")
user << "\red Your metal fingers don't fit in the trigger guard!"
return
add_fingerprint(user)
var/turf/curloc = get_turf(user)
var/turf/targloc = get_turf(target)
if (!istype(targloc) || !istype(curloc))
return
if(!special_check(user))
return
if(!load_into_chamber()) //CHECK
return click_empty(user)
if(!in_chamber)
return
in_chamber.firer = user
in_chamber.def_zone = user.zone_sel.selecting
if(targloc == curloc)
user.bullet_act(in_chamber)
del(in_chamber)
update_icon()
return
if(recoil)
spawn()
shake_camera(user, recoil + 1, recoil)
if(silenced)
playsound(user, fire_sound, 10, 1)
else
playsound(user, fire_sound, 50, 1)
user.visible_message("<span class='warning'>[user] fires [src][reflex ? " by reflex":""]!</span>", \
"<span class='warning'>You fire [src][reflex ? "by reflex":""]!</span>", \
"You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!")
in_chamber.original = target
in_chamber.loc = get_turf(user)
in_chamber.starting = get_turf(user)
in_chamber.shot_from = src
user.next_move = world.time + 4
in_chamber.silenced = silenced
in_chamber.current = curloc
in_chamber.yo = targloc.y - curloc.y
in_chamber.xo = targloc.x - curloc.x
if(params)
var/list/mouse_control = params2list(params)
if(mouse_control["icon-x"])
in_chamber.p_x = text2num(mouse_control["icon-x"])
if(mouse_control["icon-y"])
in_chamber.p_y = text2num(mouse_control["icon-y"])
spawn()
if(in_chamber)
in_chamber.process()
sleep(1)
in_chamber = null
update_icon()
if(user.hand)
user.update_inv_l_hand()
else
user.update_inv_r_hand()
/obj/item/weapon/gun/proc/click_empty(mob/user = null)
if (user)
user.visible_message("*click click*", "\red <b>*click*</b>")
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
else
src.visible_message("*click click*")
playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1)
/obj/item/weapon/gun/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
//Suicide handling.
if (M == user && user.zone_sel.selecting == "mouth" && !mouthshoot)
mouthshoot = 1
M.visible_message("\red [user] sticks their gun in their mouth, ready to pull the trigger...")
if(!do_after(user, 40))
M.visible_message("\blue [user] decided life was worth living")
mouthshoot = 0
return
if (load_into_chamber())
user.visible_message("<span class = 'warning'>[user] pulls the trigger. Ow.</span>")
if(silenced)
playsound(user, fire_sound, 10, 1)
else
playsound(user, fire_sound, 50, 1)
in_chamber.on_hit(M)
if (!in_chamber.nodamage)
user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]")
else
user << "<span class = 'notice'>You feel dumb for trying this...</span>"
del(in_chamber)
mouthshoot = 0
return
else
click_empty(user)
mouthshoot = 0
return
if (load_into_chamber())
//Point blank shooting if on harm intent or target we were targeting.
if(user.a_intent == "hurt")
user.visible_message("\red <b> \The [user] fires \the [src] point blank at [M]!</b>")
in_chamber.damage *= 1.3
Fire(M,user)
return
else if(target && M in target)
Fire(M,user) ///Otherwise, shoot!
return
else
return ..() //Pistolwhippin'

View File

@@ -10,7 +10,7 @@
origin_tech = "combat=2;materials=2"
w_class = 3.0
m_amt = 1000
recoil = 1
var/ammo_type = "/obj/item/ammo_casing/a357"
var/list/loaded = list()
var/max_shells = 7
@@ -27,8 +27,8 @@
/obj/item/weapon/gun/projectile/load_into_chamber()
// if(in_chamber)
// return 1 {R}
if(in_chamber)
return 1 //{R}
if(!loaded.len)
return 0
@@ -77,6 +77,8 @@
return
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
if (target)
return ..()
if (loaded.len)
if (load_method == SPEEDLOADER)
var/obj/item/ammo_casing/AC = loaded[1]

View File

@@ -7,6 +7,7 @@
caliber = "9mm"
origin_tech = "combat=4;materials=2"
ammo_type = "/obj/item/ammo_casing/c9mm"
automatic = 1
isHandgun()
return 0
@@ -18,7 +19,7 @@
icon_state = "mini-uzi"
w_class = 3.0
max_shells = 16
caliber = ".45"
caliber = " .45"
origin_tech = "combat=5;materials=2;syndicate=8"
ammo_type = "/obj/item/ammo_casing/c45"

View File

@@ -55,7 +55,7 @@
icon_state = "cshotgun"
max_shells = 8
origin_tech = "combat=5;materials=2"
ammo_type = "/obj/item/ammo_casing/shotgun"
ammo_type = "/obj/item/ammo_casing/shotgun/beanbag"
//this is largely hacky and bad :( -Pete
/obj/item/weapon/gun/projectile/shotgun/doublebarrel

View File

@@ -58,6 +58,17 @@
L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, blocked)
return 1
proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not.
if(!istype(target) || !istype(user))
return 0
var/obj/item/projectile/test/in_chamber = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test....
in_chamber.target = target
in_chamber.flags = flags //Set the flags...
in_chamber.pass_flags = pass_flags //And the pass flags to that of the real projectile...
in_chamber.firer = user
var/output = in_chamber.process() //Test it!
del(in_chamber) //No need for it anymore
return output //Send it back to the gun!
Bump(atom/A as mob|obj|turf|area)
if(A == firer)
@@ -74,9 +85,14 @@
loc = A.loc
return 0// nope.avi
var/distance = get_dist(starting,loc)
//Lower accurancy/longer range tradeoff. Distance matters a lot here, so at
// close distance, actually RAISE the chance to hit.
var/distance = get_dist(starting,loc)
var/miss_modifier = -30
if (istype(shot_from,/obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often.
var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim
if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew
miss_modifier += -30
def_zone = get_zone_with_miss_chance(def_zone, M, -30 + 8*distance)
if(!def_zone)
@@ -148,3 +164,44 @@
Bump(original)
sleep(1)
return
/obj/item/projectile/test //Used to see if you can hit them.
invisibility = 101 //Nope! Can't see me!
yo = null
xo = null
var/target = null
var/result = 0 //To pass the message back to the gun.
Bump(atom/A as mob|obj|turf|area)
if(A == firer)
loc = A.loc
return //cannot shoot yourself
if(istype(A, /obj/item/projectile))
return
if(istype(A, /mob/living))
result = 2 //We hit someone, return 1!
return
result = 1
return
process()
var/turf/curloc = get_turf(src)
var/turf/targloc = get_turf(target)
if(!curloc || !targloc)
return 0
yo = targloc.y - curloc.y
xo = targloc.x - curloc.x
target = targloc
while(src) //Loop on through!
if(result)
return (result - 1)
if((!( target ) || loc == target))
target = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge
step_towards(src, target)
var/mob/living/M = locate() in get_turf(src)
if(istype(M)) //If there is someting living...
return 1 //Return 1
else
M = locate() in get_step(src,target)
if(istype(M))
return 1

View File

@@ -0,0 +1,374 @@
/obj/item/weapon/gun/verb/toggle_firerate()
set name = "Toggle Firerate"
set category = "Object"
firerate = !firerate
if (firerate == 0)
loc << "You will now continue firing when your target moves."
else
loc << "You will now only fire once, then lower your aim, when your target moves."
/obj/item/weapon/gun/verb/lower_aim()
set name = "Lower Aim"
set category = "Object"
if(target)
stop_aim()
usr.visible_message("\blue \The [usr] lowers \the [src]...")
//Clicking gun will still lower aim for guns that don't overwrite this
/obj/item/weapon/gun/attack_self()
lower_aim()
//Removing the lock and the buttons.
/obj/item/weapon/gun/dropped(mob/user as mob)
stop_aim()
if (user.client)
user.client.remove_gun_icons()
return ..()
//Removes lock fro mall targets
/obj/item/weapon/gun/proc/stop_aim()
if(target)
for(var/mob/living/M in target)
if(M)
M.NotTargeted(src) //Untargeting people.
del(target)
//Compute how to fire.....
/obj/item/weapon/gun/proc/PreFire(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, params)
//Lets not spam it.
if(lock_time > world.time - 2) return
.
if(ismob(A) && isliving(A) && !(A in target))
Aim(A) //Clicked a mob, aim at them
else //Didn't click someone, check if there is anyone along that guntrace
var/mob/living/M = GunTrace(usr.x,usr.y,A.x,A.y,usr.z,usr) //Find dat mob.
if(M && isliving(M) && M in view(user) && !(M in target))
Aim(M) //Aha! Aim at them!
else if(!ismob(M) || (ismob(M) && !(M in view(user)))) //Nope! They weren't there!
Fire(A,user,params) //Fire like normal, then.
usr.dir = get_cardinal_dir(src, A)
//Aiming at the target mob.
/obj/item/weapon/gun/proc/Aim(var/mob/living/M)
if(!target || !(M in target))
lock_time = world.time
if(target && !automatic) //If they're targeting someone and they have a non automatic weapon.
for(var/mob/living/L in target)
if(L)
L.NotTargeted(src)
del(target)
usr.visible_message("\red <b>[usr] turns \the [src] on [M]!</b>")
else
usr.visible_message("\red <b>[usr] aims \a [src] at [M]!</b>")
M.Targeted(src)
//HE MOVED, SHOOT HIM!
/obj/item/weapon/gun/proc/TargetActed(var/mob/living/T)
var/mob/living/M = loc
if(M == T) return
if(!istype(M)) return
if(src != M.equipped())
stop_aim()
M.last_move_intent = world.time
if(load_into_chamber())
var/firing_check = in_chamber.check_fire(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing.
if(firing_check > 0)
if(firing_check == 1)
Fire(T,usr, reflex = 1)
else if(!told_cant_shoot)
M << "\red They can't be hit from here!"
told_cant_shoot = 1
spawn(30)
told_cant_shoot = 0
else
click_empty(M)
usr.dir = get_cardinal_dir(src, T)
if (!firerate) // If firerate is set to lower aim after one shot, untarget the target
T.NotTargeted(src)
//Yay, math!
#define SIGN(X) ((X<0)?-1:1)
proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16)
//bluh << "Tracin' [X1],[Y1] to [X2],[Y2] on floor [Z]."
var/turf/T
var/mob/living/M
if(X1==X2)
if(Y1==Y2) return 0 //Light cannot be blocked on same tile
else
var/s = SIGN(Y2-Y1)
Y1+=s
while(1)
T = locate(X1,Y1,Z)
if(!T) return 0
M = locate() in T
if(M) return M
M = locate() in orange(1,T)-exc_obj
if(M) return M
Y1+=s
else
var
m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
signX = SIGN(X2-X1)
signY = SIGN(Y2-Y1)
if(X1<X2) b+=m
while(1)
var/xvert = round(m*X1+b-Y1)
if(xvert) Y1+=signY //Line exits tile vertically
else X1+=signX //Line exits tile horizontally
T = locate(X1,Y1,Z)
if(!T) return 0
M = locate() in T
if(M) return M
M = locate() in orange(1,T)-exc_obj
if(M) return M
return 0
//Targeting management procs
mob/var
list/targeted_by
target_time = -100
last_move_intent = -100
last_target_click = -5
target_locked = null
mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory.
if(!I.target)
I.target = list(src)
else if(I.automatic && I.target.len < 5) //Automatic weapon, they can hold down a room.
I.target += src
else if(I.target.len >= 5)
if(ismob(I.loc))
I.loc << "You can only target 5 people at once!"
return
else
return
for(var/mob/living/K in viewers(usr))
K << 'TargetOn.ogg'
if(!targeted_by) targeted_by = list()
targeted_by += I
I.lock_time = world.time + 20 //Target has 2 second to realize they're targeted and stop (or target the opponent).
src << "((\red <b>Your character is being targeted. They have 2 seconds to stop any click or move actions.</b> \black While targeted, they may \
drag and drop items in or into the map, speak, and click on interface buttons. Clicking on the map, their items \
(other than a weapon to de-target), or moving will result in being fired upon. \red The aggressor may also fire manually, \
so try not to get on their bad side.\black ))"
if(targeted_by.len == 1)
spawn(0)
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locking")
overlays += target_locked
spawn(0)
sleep(20)
if(target_locked)
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locked")
update_targeted()
//Adding the buttons to the controler person
var/mob/living/T = I.loc
if(T)
if(T.client)
T.client.add_gun_icons()
else
I.lower_aim()
return
if(m_intent == "run" && T.client.target_can_move == 1 && T.client.target_can_run == 0)
src << "\red Your move intent is now set to walk, as your targeter permits it." //Self explanitory.
set_m_intent("walk")
//Processing the aiming. Should be probably in separate object with process() but lasy.
while(targeted_by && T.client)
if(last_move_intent > I.lock_time + 10 && !T.client.target_can_move) //If target moved when not allowed to
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
else if(last_move_intent > I.lock_time + 10 && !T.client.target_can_run && m_intent == "run") //If the target ran while targeted
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
if(last_target_click > I.lock_time + 10 && !T.client.target_can_click) //If the target clicked the map to pick something up/shoot/etc
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
sleep(1)
mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I)
if(!I.silenced)
for(var/mob/living/M in viewers(src))
M << 'TargetOff.ogg'
targeted_by -= I
I.target.Remove(src) //De-target them
if(!I.target.len)
del(I.target)
var/mob/living/T = I.loc //Remove the targeting icons
if(T && ismob(T) && !I.target)
T.client.remove_gun_icons()
if(!targeted_by.len)
del target_locked //Remove the overlay
del targeted_by
spawn(1) update_targeted()
mob/living/Move()
. = ..()
for(var/obj/item/weapon/gun/G in targeted_by) //Handle moving out of the gunner's view.
var/mob/living/M = G.loc
if(!(M in view(src)))
NotTargeted(G)
for(var/obj/item/weapon/gun/G in src) //Handle the gunner loosing sight of their target/s
if(G.target)
for(var/mob/living/M in G.target)
if(M && !(M in view(src)))
M.NotTargeted(G)
//If you move out of range, it isn't going to still stay locked on you any more.
client/var
target_can_move = 0
target_can_run = 0
target_can_click = 0
gun_mode = 0
//These are called by the on-screen buttons, adjusting what the victim can and cannot do.
client/proc/add_gun_icons()
if (!usr.item_use_icon)
usr.item_use_icon = new /obj/screen/gun/item(null)
usr.item_use_icon.icon_state = "no_item[target_can_click]"
usr.item_use_icon.name = "[target_can_click ? "Disallow" : "Allow"] Item Use"
if (!usr.gun_move_icon)
usr.gun_move_icon = new /obj/screen/gun/move(null)
usr.gun_move_icon.icon_state = "no_walk[target_can_move]"
usr.gun_move_icon.name = "[target_can_move ? "Disallow" : "Allow"] Walking"
if (target_can_move && !usr.gun_run_icon)
usr.gun_run_icon = new /obj/screen/gun/run(null)
usr.gun_run_icon.icon_state = "no_run[target_can_run]"
usr.gun_run_icon.name = "[target_can_run ? "Disallow" : "Allow"] Running"
screen += usr.item_use_icon
screen += usr.gun_move_icon
if (target_can_move)
screen += usr.gun_run_icon
client/proc/remove_gun_icons()
screen -= usr.item_use_icon
screen -= usr.gun_move_icon
if (target_can_move)
screen -= usr.gun_run_icon
del usr.gun_move_icon
del usr.item_use_icon
del usr.gun_run_icon
client/verb/ToggleGunMode()
set hidden = 1
gun_mode = !gun_mode
if(gun_mode)
usr << "You will now take people captive."
add_gun_icons()
else
usr << "You will now shoot where you target."
for(var/obj/item/weapon/gun/G in usr)
G.stop_aim()
remove_gun_icons()
if(usr.gun_setting_icon)
usr.gun_setting_icon.icon_state = "gun[gun_mode]"
client/verb/AllowTargetMove()
set hidden=1
//Changing client's permissions
target_can_move = !target_can_move
if(target_can_move)
usr << "Target may now walk."
usr.gun_run_icon = new /obj/screen/gun/run(null) //adding icon for running permission
screen += usr.gun_run_icon
else
usr << "Target may no longer move."
target_can_run = 0
del(usr.gun_run_icon) //no need for icon for running permission
//Updating walking permission button
if(usr.gun_move_icon)
usr.gun_move_icon.icon_state = "no_walk[target_can_move]"
usr.gun_move_icon.name = "[target_can_move ? "Disallow" : "Allow"] Walking"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in usr)
G.lock_time = world.time + 5
if(G.target)
for(var/mob/living/M in G.target)
if(target_can_move)
M << "Your character may now <b>walk</b> at the discretion of their targeter."
if(!target_can_run)
M << "\red Your move intent is now set to walk, as your targeter permits it."
M.set_m_intent("walk")
else
M << "\red <b>Your character will now be shot if they move.</b>"
mob/living/proc/set_m_intent(var/intent)
if (intent != "walk" && intent != "run")
return 0
m_intent = intent
if(hud_used)
if (hud_used.move_intent)
hud_used.move_intent.icon_state = intent == "walk" ? "walking" : "running"
client/verb/AllowTargetRun()
set hidden=1
//Changing client's permissions
target_can_run = !target_can_run
if(target_can_run)
usr << "Target may now run."
else
usr << "Target may no longer run."
//Updating running permission button
if(usr.gun_run_icon)
usr.gun_run_icon.icon_state = "no_run[target_can_run]"
usr.gun_run_icon.name = "[target_can_run ? "Disallow" : "Allow"] Running"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in src)
G.lock_time = world.time + 5
if(G.target)
for(var/mob/living/M in G.target)
if(target_can_run)
M << "Your character may now <b>run</b> at the discretion of their targeter."
else
M << "\red <b>Your character will now be shot if they run.</b>"
client/verb/AllowTargetClick()
set hidden=1
//Changing client's permissions
target_can_click = !target_can_click
if(target_can_click)
usr << "Target may now use items."
else
usr << "Target may no longer use items."
if(usr.item_use_icon)
usr.item_use_icon.icon_state = "no_item[target_can_click]"
usr.item_use_icon.name = "[target_can_click ? "Disallow" : "Allow"] Item Use"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in src)
G.lock_time = world.time + 5
if(G.target)
for(var/mob/living/M in G.target)
if(target_can_click)
M << "Your character may now <b>use items</b> at the discretion of their targeter."
else
M << "\red <b>Your character will now be shot if they use items.</b>"