diff --git a/code/__defines/targeting.dm b/code/__defines/targeting.dm new file mode 100644 index 00000000000..4bbe7345920 --- /dev/null +++ b/code/__defines/targeting.dm @@ -0,0 +1,4 @@ +#define TARGET_CAN_MOVE 1 +#define TARGET_CAN_RUN 2 +#define TARGET_CAN_CLICK 4 +#define TARGET_CAN_RADIO 8 \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 797f0385d42..42d815205ac 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -38,8 +38,10 @@ * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed */ /mob/proc/ClickOn(var/atom/A, var/params) + if(world.time <= next_click) // Hard check, before anything else, to avoid crashing return + next_click = world.time + 1 if(client.buildmode) @@ -49,19 +51,19 @@ var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) - return + return 1 if(modifiers["middle"]) MiddleClickOn(A) - return + return 1 if(modifiers["shift"]) ShiftClickOn(A) - return + return 0 if(modifiers["alt"]) // alt and alt-gr (rightalt) AltClickOn(A) - return + return 1 if(modifiers["ctrl"]) CtrlClickOn(A) - return + return 1 if(stat || paralysis || stunned || weakened) return @@ -80,17 +82,14 @@ if(restrained()) setClickCooldown(10) RestrainedClickOn(A) - return + return 1 if(in_throw_mode) if(isturf(A) || isturf(A.loc)) throw_item(A) - return + return 1 throw_mode_off() - if(!istype(A, /obj/item/weapon/gun) && !isturf(A) && !istype(A, /obj/screen)) - last_target_click = world.time - var/obj/item/W = get_active_hand() if(W == A) // Handle attack_self @@ -99,7 +98,7 @@ update_inv_l_hand(0) else update_inv_r_hand(0) - return + return 1 //Atoms on your person // A is your location but is not a turf; or is on you (backpack); or is on something on you (box in backpack); sdepth is needed here because contents depth does not equate inventory storage depth. @@ -117,7 +116,7 @@ if(ismob(A)) // No instant mob attacking setClickCooldown(DEFAULT_ATTACK_COOLDOWN) UnarmedAttack(A, 1) - return + return 1 if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that return @@ -144,8 +143,7 @@ W.afterattack(A, src, 0, params) // 0: not Adjacent else RangedAttack(A, params) - - return + return 1 /mob/proc/setClickCooldown(var/timeout) next_move = max(world.time + timeout, next_move) diff --git a/code/_onclick/hud/gun_mode.dm b/code/_onclick/hud/gun_mode.dm new file mode 100644 index 00000000000..e5d1fbce37d --- /dev/null +++ b/code/_onclick/hud/gun_mode.dm @@ -0,0 +1,66 @@ +/obj/screen/gun + name = "gun" + icon = 'icons/mob/screen1.dmi' + master = null + dir = 2 + +/obj/screen/gun/Click(location, control, params) + if(!usr) + return + return 1 + +/obj/screen/gun/move + name = "Allow Movement" + icon_state = "no_walk0" + screen_loc = ui_gun2 + +/obj/screen/gun/move/Click(location, control, params) + if(..()) + var/mob/living/user = usr + if(istype(user)) + if(!user.aiming) user.aiming = new(user) + user.aiming.toggle_permission(TARGET_CAN_MOVE) + return 1 + return 0 + +/obj/screen/gun/item + name = "Allow Item Use" + icon_state = "no_item0" + screen_loc = ui_gun1 + +/obj/screen/gun/item/Click(location, control, params) + if(..()) + var/mob/living/user = usr + if(istype(user)) + if(!user.aiming) user.aiming = new(user) + user.aiming.toggle_permission(TARGET_CAN_CLICK) + return 1 + return 0 + +/obj/screen/gun/mode + name = "Toggle Gun Mode" + icon_state = "gun0" + screen_loc = ui_gun_select + +/obj/screen/gun/mode/Click(location, control, params) + if(..()) + var/mob/living/user = usr + if(istype(user)) + if(!user.aiming) user.aiming = new(user) + user.aiming.toggle_active() + return 1 + return 0 + +/obj/screen/gun/radio + name = "Allow Radio Use" + icon_state = "no_radio0" + screen_loc = ui_gun4 + +/obj/screen/gun/radio/Click(location, control, params) + if(..()) + var/mob/living/user = usr + if(istype(user)) + if(!user.aiming) user.aiming = new(user) + user.aiming.toggle_permission(TARGET_CAN_RADIO) + return 1 + return 0 diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 5a9b45bfca3..a73779ef722 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -257,8 +257,6 @@ datum/hud/New(mob/owner) human_hud(ui_style, ui_color, ui_alpha, mymob) // Pass the player the UI style chosen in preferences else if(isrobot(mymob)) robot_hud() - else if(issmall(mymob)) - monkey_hud(ui_style, ui_color, ui_alpha) else if(isbrain(mymob)) brain_hud(ui_style) else if(isalien(mymob)) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index ab5d0f6a123..2ee17dedced 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -1,5 +1,7 @@ -/datum/hud/proc/human_hud(var/ui_style='icons/mob/screen1_White.dmi', var/ui_color = "#ffffff", var/ui_alpha = 255, var/mob/living/carbon/human/target) +/mob/living/carbon/human/instantiate_hud(var/datum/hud/HUD, var/ui_style, var/ui_color, var/ui_alpha) + HUD.human_hud(ui_style, ui_color, ui_alpha, src) +/datum/hud/proc/human_hud(var/ui_style='icons/mob/screen1_White.dmi', var/ui_color = "#ffffff", var/ui_alpha = 255, var/mob/living/carbon/human/target) var/datum/hud_data/hud_data if(!istype(target)) hud_data = new() @@ -354,17 +356,11 @@ mymob.gun_move_icon.color = ui_color mymob.gun_move_icon.alpha = ui_alpha - mymob.gun_run_icon = new /obj/screen/gun/run(null) - mymob.gun_run_icon.icon = ui_style - mymob.gun_run_icon.color = ui_color - mymob.gun_run_icon.alpha = ui_alpha - mymob.radio_use_icon = new /obj/screen/gun/radio(null) mymob.radio_use_icon.icon = ui_style mymob.radio_use_icon.color = ui_color mymob.radio_use_icon.alpha = ui_alpha - mymob.client.screen = null mymob.client.screen += hud_elements diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm deleted file mode 100644 index d24d9322a56..00000000000 --- a/code/_onclick/hud/monkey.dm +++ /dev/null @@ -1,282 +0,0 @@ -/datum/hud/proc/monkey_hud(var/ui_style='icons/mob/screen1_old.dmi', var/ui_color = "#ffffff", var/ui_alpha = 255) - - src.adding = list() - src.other = list() - - var/obj/screen/using - var/obj/screen/inventory/inv_box - - using = new /obj/screen() - using.name = "act_intent" - using.icon = ui_style - using.color = ui_color - using.alpha = ui_alpha - using.icon_state = mymob.a_intent - using.screen_loc = ui_acti - using.layer = 20 - src.adding += using - action_intent = using - -//intent small hud objects - var/icon/ico - - ico = new(ui_style, "black") - ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) - ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height()) - using = new /obj/screen( src ) - using.name = I_HELP - using.icon = ico - using.screen_loc = ui_acti - using.layer = 21 - src.adding += using - help_intent = using - - ico = new(ui_style, "black") - ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) - ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height()) - using = new /obj/screen( src ) - using.name = I_DISARM - using.icon = ico - using.screen_loc = ui_acti - using.layer = 21 - src.adding += using - disarm_intent = using - - ico = new(ui_style, "black") - ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) - ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2) - using = new /obj/screen( src ) - using.name = I_GRAB - using.icon = ico - using.screen_loc = ui_acti - using.layer = 21 - src.adding += using - grab_intent = using - - ico = new(ui_style, "black") - ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) - ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2) - using = new /obj/screen( src ) - using.name = I_HURT - using.icon = ico - using.screen_loc = ui_acti - using.layer = 21 - src.adding += using - hurt_intent = using - -//end intent small hud objects - - using = new /obj/screen() - using.name = "mov_intent" - using.icon = ui_style - using.color = ui_color - using.alpha = ui_alpha - using.icon_state = (mymob.m_intent == "run" ? "running" : "walking") - using.screen_loc = ui_movi - using.layer = 20 - src.adding += using - move_intent = using - - using = new /obj/screen() - using.name = "drop" - using.icon = ui_style - using.color = ui_color - using.alpha = ui_alpha - using.icon_state = "act_drop" - using.screen_loc = ui_drop_throw - using.layer = 19 - src.adding += using - - inv_box = new /obj/screen/inventory() - inv_box.name = "r_hand" - inv_box.icon = ui_style - using.color = ui_color - using.alpha = ui_alpha - inv_box.icon_state = "r_hand_inactive" - if(mymob && !mymob.hand) //This being 0 or null means the right hand is in use - inv_box.icon_state = "hand_active" - inv_box.screen_loc = ui_rhand - inv_box.slot_id = slot_r_hand - inv_box.layer = 19 - src.r_hand_hud_object = inv_box - src.adding += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "l_hand" - inv_box.icon = ui_style - using.color = ui_color - using.alpha = ui_alpha - inv_box.icon_state = "l_hand_inactive" - if(mymob && mymob.hand) //This being 1 means the left hand is in use - inv_box.icon_state = "hand_active" - inv_box.screen_loc = ui_lhand - inv_box.slot_id = slot_l_hand - inv_box.layer = 19 - src.l_hand_hud_object = inv_box - src.adding += inv_box - - using = new /obj/screen/inventory() - using.name = "hand" - using.icon = ui_style - using.color = ui_color - using.alpha = ui_alpha - using.icon_state = "hand1" - using.screen_loc = ui_swaphand1 - using.layer = 19 - src.adding += using - - using = new /obj/screen/inventory() - using.name = "hand" - using.icon = ui_style - using.color = ui_color - using.alpha = ui_alpha - using.icon_state = "hand2" - using.screen_loc = ui_swaphand2 - using.layer = 19 - src.adding += using - - inv_box = new /obj/screen/inventory() - inv_box.name = "mask" - inv_box.icon = ui_style - inv_box.color = ui_color - inv_box.alpha = ui_alpha - inv_box.icon_state = "equip" - inv_box.screen_loc = ui_monkey_mask - inv_box.slot_id = slot_wear_mask - inv_box.layer = 19 - src.adding += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "back" - inv_box.icon = ui_style - inv_box.color = ui_color - inv_box.alpha = ui_alpha - inv_box.icon_state = "equip" - inv_box.screen_loc = ui_back - inv_box.slot_id = slot_back - inv_box.layer = 19 - src.adding += inv_box - - mymob.throw_icon = new /obj/screen() - mymob.throw_icon.icon = ui_style - mymob.throw_icon.color = ui_color - mymob.throw_icon.alpha = ui_alpha - mymob.throw_icon.icon_state = "act_throw_off" - mymob.throw_icon.name = "throw" - mymob.throw_icon.screen_loc = ui_drop_throw - - mymob.oxygen = new /obj/screen() - mymob.oxygen.icon = ui_style - mymob.oxygen.color = ui_color - mymob.oxygen.alpha = ui_alpha - mymob.oxygen.icon_state = "oxy0" - mymob.oxygen.name = "oxygen" - mymob.oxygen.screen_loc = ui_oxygen - - mymob.pressure = new /obj/screen() - mymob.pressure.icon = ui_style - mymob.pressure.color = ui_color - mymob.pressure.alpha = ui_alpha - mymob.pressure.icon_state = "pressure0" - mymob.pressure.name = "pressure" - mymob.pressure.screen_loc = ui_pressure - - mymob.toxin = new /obj/screen() - mymob.toxin.icon = ui_style - mymob.toxin.color = ui_color - mymob.toxin.alpha = ui_alpha - mymob.toxin.icon_state = "tox0" - mymob.toxin.name = "toxin" - mymob.toxin.screen_loc = ui_toxin - - mymob.internals = new /obj/screen() - mymob.internals.icon = ui_style - mymob.internals.color = ui_color - mymob.internals.alpha = ui_alpha - mymob.internals.icon_state = "internal0" - mymob.internals.name = "internal" - mymob.internals.screen_loc = ui_internal - - mymob.fire = new /obj/screen() - mymob.fire.icon = ui_style - mymob.fire.color = ui_color - mymob.fire.alpha = ui_alpha - mymob.fire.icon_state = "fire0" - mymob.fire.name = "fire" - mymob.fire.screen_loc = ui_fire - - mymob.bodytemp = new /obj/screen() - mymob.bodytemp.icon = ui_style - mymob.bodytemp.color = ui_color - mymob.bodytemp.alpha = ui_alpha - mymob.bodytemp.icon_state = "temp1" - mymob.bodytemp.name = "body temperature" - mymob.bodytemp.screen_loc = ui_temp - - mymob.healths = new /obj/screen() - mymob.healths.icon = ui_style - mymob.healths.color = ui_color - mymob.healths.alpha = ui_alpha - mymob.healths.icon_state = "health0" - mymob.healths.name = "health" - mymob.healths.screen_loc = ui_health - - mymob.pullin = new /obj/screen() - mymob.pullin.icon = ui_style - mymob.pullin.color = ui_color - mymob.pullin.alpha = ui_alpha - mymob.pullin.icon_state = "pull0" - mymob.pullin.name = "pull" - mymob.pullin.screen_loc = ui_pull_resist - - mymob.blind = new /obj/screen() - mymob.blind.icon = 'icons/mob/screen1_full.dmi' - mymob.blind.icon_state = "blackimageoverlay" - mymob.blind.name = " " - mymob.blind.screen_loc = "1,1" - mymob.blind.layer = 0 - - mymob.flash = new /obj/screen() - mymob.flash.icon = ui_style - mymob.flash.icon_state = "blank" - mymob.flash.name = "flash" - mymob.flash.screen_loc = ui_entire_screen - mymob.flash.layer = 17 - - mymob.zone_sel = new /obj/screen/zone_sel() - mymob.zone_sel.icon = ui_style - mymob.zone_sel.color = ui_color - mymob.zone_sel.alpha = ui_alpha - 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.set_dir(2) - for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons - if (G.aim_targets) - mymob.item_use_icon = new /obj/screen/gun/item(null) - if (mymob.client.target_can_click) - mymob.item_use_icon.set_dir(1) - src.adding += mymob.item_use_icon - mymob.radio_use_icon = new /obj/screen/gun/radio(null) - if (mymob.client.target_can_radio) - mymob.radio_use_icon.set_dir(1) - src.adding += mymob.radio_use_icon - mymob.gun_move_icon = new /obj/screen/gun/move(null) - if (mymob.client.target_can_move) - mymob.gun_move_icon.set_dir(1) - mymob.gun_run_icon = new /obj/screen/gun/run(null) - if (mymob.client.target_can_run) - mymob.gun_run_icon.set_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.gun_setting_icon) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach ) - mymob.client.screen += src.adding + src.other - - return diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index eb31c7019b5..95f8f3c9d3a 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -153,31 +153,13 @@ var/obj/screen/robot_inventory //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.set_dir(2) - for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons - if (G.aim_targets) - mymob.item_use_icon = new /obj/screen/gun/item(null) - if (mymob.client.target_can_click) - mymob.item_use_icon.set_dir(1) - src.adding += mymob.item_use_icon - mymob.radio_use_icon = new /obj/screen/gun/radio(null) - if (mymob.client.target_can_radio) - mymob.radio_use_icon.set_dir(1) - src.adding += mymob.radio_use_icon - mymob.gun_move_icon = new /obj/screen/gun/move(null) - if (mymob.client.target_can_move) - mymob.gun_move_icon.set_dir(1) - mymob.gun_run_icon = new /obj/screen/gun/run(null) - if (mymob.client.target_can_run) - mymob.gun_run_icon.set_dir(1) - src.adding += mymob.gun_run_icon - src.adding += mymob.gun_move_icon + mymob.item_use_icon = new /obj/screen/gun/item(null) + mymob.gun_move_icon = new /obj/screen/gun/move(null) + mymob.radio_use_icon = new /obj/screen/gun/radio(null) 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.gun_setting_icon, robot_inventory) //, 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, robot_inventory, mymob.gun_setting_icon) mymob.client.screen += src.adding + src.other return diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 1f30726c072..d0904aa4664 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -12,7 +12,6 @@ layer = 20.0 unacidable = 1 var/obj/master = null //A reference to the object in the slot. Grabs or items, generally. - var/gun_click_time = -100 //I'm lazy. /obj/screen/Destroy() master = null @@ -95,38 +94,6 @@ usr.ClickOn(master) return 1 -/obj/screen/gun - name = "gun" - icon = 'icons/mob/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 - - radio - name = "Allow Radio Use" - icon_state = "no_radio0" - screen_loc = ui_gun4 - /obj/screen/zone_sel name = "damage zone" icon_state = "zone_sel" @@ -201,7 +168,6 @@ /obj/screen/Click(location, control, params) if(!usr) return 1 - switch(name) if("toggle") if(usr.hud_used.inventory_shown) @@ -431,46 +397,6 @@ if("module3") if(istype(usr, /mob/living/silicon/robot)) usr:toggle_module(3) - - if("Allow Walking", "Disallow Walking") - if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. - return - if(!istype(usr.get_active_hand(),/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", "Disallow Running") - if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. - return - if(!istype(usr.get_active_hand(),/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", "Disallow Item Use") - if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. - return - if(!istype(usr.get_active_hand(),/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() - - if("Allow Radio Use", "Disallow Radio Use") - if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. - return - if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) - usr << "You need your gun in your active hand to do that!" - return - usr.client.AllowTargetRadio() - gun_click_time = world.time - else return 0 return 1 diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index e0d7ddad3a0..a27dd2d84b3 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -949,7 +949,6 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/proc/create_message(var/mob/living/U = usr, var/obj/item/device/pda/P, var/tap = 1) if(tap) U.visible_message("\The [U] taps on \his PDA's screen.") - U.last_target_click = world.time var/t = input(U, "Please enter message", P.name, null) as text t = sanitize(t) //t = readd_quotes(t) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index affde77733b..16c810a8a0c 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -273,13 +273,13 @@ var/global/list/default_medbay_channels = list( // Fix for permacell radios, but kinda eh about actually fixing them. if(!M || !message) return 0 + if(istype(M)) M.trigger_aiming(TARGET_CAN_RADIO) + // Uncommenting this. To the above comment: // The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom if(wires.IsIndexCut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact return 0 - M.last_target_radio = world.time // For the projectile targeting system - if(!radio_connection) set_frequency(frequency) diff --git a/code/modules/client/ui_style.dm b/code/modules/client/ui_style.dm index 12521a6a1eb..2802d25e60b 100644 --- a/code/modules/client/ui_style.dm +++ b/code/modules/client/ui_style.dm @@ -38,7 +38,6 @@ icons.Add(usr.gun_setting_icon) icons.Add(usr.item_use_icon) icons.Add(usr.gun_move_icon) - icons.Add(usr.gun_run_icon) icons.Add(usr.radio_use_icon) var/icon/ic = all_ui_styles[UI_style_new] diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index b3d59aaf7d4..f123f17b55c 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -851,7 +851,6 @@ return 0 // AIs are a bit slower than regular and ignore move intent. - wearer.last_move_intent = world.time + ai_controlled_move_delay wearer_move_delay = world.time + ai_controlled_move_delay var/tickcomp = 0 diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index 5d71a004203..9ba4ffa5e34 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -5,8 +5,8 @@ slot = "utility" var/obj/item/holstered = null -/obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user as mob) - if(holstered) +/obj/item/clothing/accessory/holster/proc/holster(var/obj/item/I, var/mob/living/user) + if(holstered && istype(user)) user << "There is already \a [holstered] holstered here!" return @@ -14,6 +14,8 @@ user << "[I] won't fit in [src]!" return + if(istype(user)) + user.stop_aiming(no_message=1) holstered = I user.drop_from_inventory(holstered) holstered.loc = src diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 7924bd21296..b2e8c3ca0e0 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -165,6 +165,7 @@ var/list/slot_equipment_priority = list( \ // Removes an item from inventory and places it in the target atom. // If canremove or other conditions need to be checked then use unEquip instead. /mob/proc/drop_from_inventory(var/obj/item/W, var/atom/Target = null) + if(W) if(!Target) Target = loc diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 29eff929dce..ca81defe0f9 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -49,6 +49,8 @@ if(shock_stage >= 10) tally += 3 + if(aiming && aiming.aiming_at) tally += 5 // Iron sights make you slower, it's a well-known fact. + if(FAT in src.mutations) tally += 1.5 if (bodytemperature < 283.222) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index d89268fe1b9..3e5731543c8 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -429,17 +429,6 @@ var/global/list/damage_icon_parts = list() overlays_standing[MUTATIONS_LAYER] = null 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_standing[TARGETED_LAYER] = target_locked - else if (!targeted_by && target_locked) - qdel(target_locked) - if (!targeted_by) - overlays_standing[TARGETED_LAYER] = null - if(update_icons) update_icons() - - /* --------------------------------------- */ //For legacy support. /mob/living/carbon/human/regenerate_icons() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 93f9e409224..8507053e232 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -703,14 +703,6 @@ icon_state = module_sprites[icontype] return -//Call when target overlay should be added/removed -/mob/living/silicon/robot/update_targeted() - if(!targeted_by && target_locked) - qdel(target_locked) - updateicon() - if (targeted_by && target_locked) - overlays += target_locked - /mob/living/silicon/robot/proc/installed_modules() if(weapon_lock) src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]" diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index acce1e39b19..a66f6b772cd 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -365,14 +365,6 @@ return (0) return 1 -//Call when target overlay should be added/removed -/mob/living/simple_animal/update_targeted() - if(!targeted_by && target_locked) - qdel(target_locked) - overlays = null - if (targeted_by && target_locked) - overlays += target_locked - /mob/living/simple_animal/say(var/message) var/verb = "says" if(speak_emote.len) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index d26f5242624..d30e23765ee 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -39,7 +39,6 @@ pain = null item_use_icon = null gun_move_icon = null - gun_run_icon = null gun_setting_icon = null spell_masters = null zone_sel = null @@ -765,8 +764,8 @@ if(lying) density = 0 - drop_l_hand() - drop_r_hand() + if(l_hand) unEquip(l_hand) + if(r_hand) unEquip(r_hand) else density = initial(density) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index d8b8778f420..e946a9df41d 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -265,7 +265,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) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 733b086669b..ee40394c78c 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -107,7 +107,7 @@ if(process_projectile(P, user, user, pick("l_foot", "r_foot"))) handle_post_fire(user, user) user.visible_message( - "[user] shoots \himself in the foot with \the [src]!", + "\The [user] shoots \himself in the foot with \the [src]!", "You shoot yourself in the foot with \the [src]!" ) M.drop_item() @@ -123,17 +123,17 @@ /obj/item/weapon/gun/afterattack(atom/A, mob/living/user, adjacent, params) if(adjacent) return //A is adjacent, is the user, or is on the user's person - //decide whether to aim or shoot normally - var/aiming = 0 - if(user && user.client && !(A in aim_targets)) - if(user.client.gun_mode) - aiming = PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at. + if(!user.aiming) + user.aiming = new(user) - if (!aiming) - if(user && user.a_intent == I_HELP) //regardless of what happens, refuse to shoot if help intent is on - user << "\red You refrain from firing your [src] as your intent is set to help." - else - Fire(A,user,params) //Otherwise, fire normally. + if(user && user.client && user.aiming && user.aiming.active && user.aiming.aiming_at != A) + PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at. + return + + if(user && user.a_intent == I_HELP) //regardless of what happens, refuse to shoot if help intent is on + user << "You refrain from firing your [src] as your intent is set to help." + else + Fire(A,user,params) //Otherwise, fire normally. /obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone) if (A == user && user.zone_sel.selecting == "mouth" && !mouthshoot) diff --git a/code/modules/projectiles/targeting.dm b/code/modules/projectiles/targeting.dm deleted file mode 100644 index de9e115b8ec..00000000000 --- a/code/modules/projectiles/targeting.dm +++ /dev/null @@ -1,407 +0,0 @@ -/obj/item/weapon/gun/verb/toggle_firerate() - set name = "Toggle Continue Aiming" - set category = "Object" - - keep_aim = !keep_aim - - if (keep_aim) - 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(aim_targets) - stop_aim() - usr.visible_message(" \The [usr] lowers \the [src]...") - -//Removing the lock and the buttons. -/obj/item/weapon/gun/dropped(mob/user as mob) - stop_aim() - if(user && user.client) - user.client.remove_gun_icons() - return ..() - -/obj/item/weapon/gun/equipped(var/mob/user, var/slot) - if (slot != slot_l_hand && slot != slot_r_hand) - stop_aim() - if (user.client) - user.client.remove_gun_icons() - return ..() - -//Removes lock from all targets -/obj/item/weapon/gun/proc/stop_aim() - if(aim_targets) - for(var/mob/living/M in aim_targets) - if(M) - M.NotTargeted(src) //Untargeting people. - aim_targets = null - -//Compute how to fire..... -//Return 1 if a target was found, 0 otherwise. -/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 - - user.set_dir(get_cardinal_dir(src, A)) - if(isliving(A) && !(A in aim_targets)) - Aim(A) //Clicked a mob, aim at them - return 1 - - //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(isliving(M) && (M in view(user)) && !(M in aim_targets)) - Aim(M) //Aha! Aim at them! - return 1 - - return 0 - -//Aiming at the target mob. -/obj/item/weapon/gun/proc/Aim(var/mob/living/M) - if(!aim_targets || !(M in aim_targets)) - admin_attack_log(usr, M, "Pointed a [src] at [M]", "Had a [src] aimed at them, by [usr]", "aims a gun ([src]) (MODE: [src.mode_name]) at") - lock_time = world.time - if(aim_targets && !multi_aim) //If they're targeting someone and they have a non multi_aim weapon. - for(var/mob/living/L in aim_targets) - if(L) - L.NotTargeted(src) - aim_targets = null - usr.visible_message("[usr] turns \the [src] on [M]!") - else - usr.visible_message("[usr] aims \a [src] at [M]!") - 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.get_active_hand()) - stop_aim() - return - - //reflex firing is disabled when help intent is set - if (M.a_intent == I_HELP) - M << "You refrain from firing your [src] as your intent is set to help." - return - - M.last_move_intent = world.time - var/firing_check = can_hit(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 << "They can't be hit from here!" - told_cant_shoot = 1 - spawn(30) - told_cant_shoot = 0 - - usr.set_dir(get_cardinal_dir(src, T)) - - if (!keep_aim) // If keep_aim 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= 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 << 'sound/weapons/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 << "((Your character is being targeted. They have 2 seconds to stop any click or move actions. While targeted, they may \ - drag and drop items in or into the map, speak, and click on interface buttons. Clicking on the map objects (floors and walls are fine), their items \ - (other than a weapon to de-target), moving, or talking into a radio will result in being fired upon. The aggressor may also fire manually, \ - so try not to get on their bad side.))" - - 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 controller person - var/mob/living/T = I.loc - if(T) - if(T.client) - T.client.add_gun_icons() - else - I.lower_aim() - return - if(iscarbon(src) && m_intent == "run" && T.client.target_can_move == 1 && T.client.target_can_run == 0) - src << "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 - if(last_target_radio > I.lock_time + 10 && !T.client.target_can_radio) - 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 << 'sound/weapons/TargetOff.ogg' - targeted_by -= I - I.aim_targets.Remove(src) //De-target them - if(!I.aim_targets.len) - I.aim_targets = null - var/mob/living/T = I.loc //Remove the targeting icons - if(T && ismob(T) && !I.aim_targets && T.client) - T.client.remove_gun_icons() - if(!targeted_by.len) - qdel(target_locked) //Remove the overlay - targeted_by.Cut() - 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.aim_targets) - for(var/mob/living/M in G.aim_targets) - 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 - target_can_radio = 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) return 1 // This can runtime if someone manages to throw a gun out of their hand before the proc is called. - screen += usr.item_use_icon - screen += usr.gun_move_icon - screen += usr.radio_use_icon - if (target_can_move) - screen += usr.gun_run_icon - - - -/client/proc/remove_gun_icons() - if(!usr) return 1 // Runtime prevention on N00k agents spawning with SMG - screen -= usr.item_use_icon - screen -= usr.gun_move_icon - screen -= usr.radio_use_icon - if (target_can_move) - screen -= usr.gun_run_icon - -/client/verb/ToggleGunMode() - set name = "Toggle Gun Mode" - set hidden = 1 - gun_mode = !gun_mode - if(gun_mode) - usr << "You will now take people captive." - 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 - qdel(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.aim_targets) - for(var/mob/living/M in G.aim_targets) - if(target_can_move) - M << "Your character may now walk at the discretion of their targeter." - if(!target_can_run) - M << "Your move intent is now set to walk, as your targeter permits it." - M.set_m_intent("walk") - else - M << "Your character will now be shot if they move." - -/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.aim_targets) - for(var/mob/living/M in G.aim_targets) - if(target_can_run) - M << "Your character may now run at the discretion of their targeter." - else - M << "Your character will now be shot if they run." - -/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.aim_targets) - for(var/mob/living/M in G.aim_targets) - if(target_can_click) - M << "Your character may now use items at the discretion of their targeter." - else - M << "Your character will now be shot if they use items." - -/client/verb/AllowTargetRadio() - set hidden=1 - - target_can_radio = !target_can_radio - if(target_can_radio) - usr << "Target may now use radio." - else - usr << "Target may no longer use radio." - - if(usr.radio_use_icon) - usr.radio_use_icon.icon_state = "no_radio[target_can_radio]" - usr.radio_use_icon.name = "[target_can_radio ? "Disallow" : "Allow"] Radio 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.aim_targets) - for(var/mob/living/M in G.aim_targets) - if(target_can_radio) - M << "Your character may now use the radio at the discretion of their targeter." - else - M << "Your character will now be shot if they use the radio." diff --git a/code/modules/projectiles/targeting/targeting_client.dm b/code/modules/projectiles/targeting/targeting_client.dm new file mode 100644 index 00000000000..42a0e3e6a1c --- /dev/null +++ b/code/modules/projectiles/targeting/targeting_client.dm @@ -0,0 +1,12 @@ +//These are called by the on-screen buttons, adjusting what the victim can and cannot do. +/client/proc/add_gun_icons() + if(!usr) return 1 // This can runtime if someone manages to throw a gun out of their hand before the proc is called. + screen |= usr.item_use_icon + screen |= usr.gun_move_icon + screen |= usr.radio_use_icon + +/client/proc/remove_gun_icons() + if(!usr) return 1 // Runtime prevention on N00k agents spawning with SMG + screen -= usr.item_use_icon + screen -= usr.gun_move_icon + screen -= usr.radio_use_icon diff --git a/code/modules/projectiles/targeting/targeting_gun.dm b/code/modules/projectiles/targeting/targeting_gun.dm new file mode 100644 index 00000000000..e2ef466255e --- /dev/null +++ b/code/modules/projectiles/targeting/targeting_gun.dm @@ -0,0 +1,21 @@ +//Removing the lock and the buttons. +/obj/item/weapon/gun/dropped(var/mob/living/user) + if(istype(user)) + user.stop_aiming(src) + return ..() + +/obj/item/weapon/gun/equipped(var/mob/living/user, var/slot) + if(istype(user) && (slot != slot_l_hand && slot != slot_r_hand)) + user.stop_aiming(src) + return ..() + +//Compute how to fire..... +//Return 1 if a target was found, 0 otherwise. +/obj/item/weapon/gun/proc/PreFire(var/atom/A, var/mob/living/user, var/params) + if(!user.aiming) + user.aiming = new(user) + user.face_atom(A) + if(ismob(A) && user.aiming) + user.aiming.aim_at(A, src) + return 1 + return 0 \ No newline at end of file diff --git a/code/modules/projectiles/targeting/targeting_mob.dm b/code/modules/projectiles/targeting/targeting_mob.dm new file mode 100644 index 00000000000..a89bbc2c9a5 --- /dev/null +++ b/code/modules/projectiles/targeting/targeting_mob.dm @@ -0,0 +1,52 @@ +/mob/living/var/obj/aiming_overlay/aiming +/mob/living/var/list/aimed = list() + +/mob/living/proc/stop_aiming(var/obj/item/thing, var/no_message = 0) + if(!aiming) + aiming = new(src) + if(thing && aiming.aiming_with != thing) + return + aiming.cancel_aiming(no_message) + +/mob/living/death(gibbed,deathmessage="seizes up and falls limp...") + if(..()) + stop_aiming(no_message=1) + +/mob/living/update_canmove() + ..() + if(lying) + stop_aiming(no_message=1) + +/mob/living/Weaken(amount) + stop_aiming(no_message=1) + ..() + +/mob/living/Destroy() + if(aiming) + qdel(aiming) + aiming = null + aimed.Cut() + return ..() + +/turf/Enter(var/mob/living/mover) + . = ..() + if(istype(mover)) + if(mover.aiming && mover.aiming.aiming_at) + mover.aiming.update_aiming() + if(mover.aimed.len) + mover.trigger_aiming(TARGET_CAN_MOVE) + +/mob/living/forceMove(var/atom/destination) + . = ..() + if(aiming && aiming.aiming_at) + aiming.update_aiming() + if(aimed.len) + trigger_aiming(TARGET_CAN_MOVE) + +/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" \ No newline at end of file diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm new file mode 100644 index 00000000000..e0a2885a857 --- /dev/null +++ b/code/modules/projectiles/targeting/targeting_overlay.dm @@ -0,0 +1,213 @@ +/obj/aiming_overlay + name = "target indicator" + desc = "Stick 'em up!" + icon = 'icons/effects/Targeted.dmi' + icon_state = "locking" + anchored = 1 + density = 0 + opacity = 0 + layer = FLY_LAYER + simulated = 0 + + var/mob/living/aiming_at // Who are we currently targeting, if anyone? + var/obj/item/aiming_with // What are we targeting with? + var/mob/owner // Who do we belong to? + var/locked = 0 // Have we locked on? + var/lock_time = 0 // When -will- we lock on? + var/active = 0 // Is our owner intending to take hostages? + var/target_permissions = 0 // Permission bitflags. + +/obj/aiming_overlay/New(var/newowner) + ..() + owner = newowner + loc = null + +/obj/aiming_overlay/proc/toggle_permission(var/perm) + + if(target_permissions & perm) + target_permissions &= ~perm + else + target_permissions |= perm + + // Update HUD icons. + if(owner.gun_move_icon) + if(!(target_permissions & TARGET_CAN_MOVE)) + owner.gun_move_icon.icon_state = "no_walk0" + owner.gun_move_icon.name = "Allow Movement" + else + owner.gun_move_icon.icon_state = "no_walk1" + owner.gun_move_icon.name = "Disallow Movement" + + if(owner.item_use_icon) + if(!(target_permissions & TARGET_CAN_CLICK)) + owner.item_use_icon.icon_state = "no_item0" + owner.item_use_icon.name = "Allow Item Use" + else + owner.item_use_icon.icon_state = "no_item1" + owner.item_use_icon.name = "Disallow Item Use" + + if(owner.radio_use_icon) + if(!(target_permissions & TARGET_CAN_RADIO)) + owner.radio_use_icon.icon_state = "no_radio0" + owner.radio_use_icon.name = "Allow Radio Use" + else + owner.radio_use_icon.icon_state = "no_radio1" + owner.radio_use_icon.name = "Disallow Radio Use" + + var/message = "no longer permitted to " + var/use_span = "warning" + if(target_permissions & perm) + message = "now permitted to " + use_span = "notice" + + switch(perm) + if(TARGET_CAN_MOVE) + message += "move" + if(TARGET_CAN_CLICK) + message += "use items" + if(TARGET_CAN_RADIO) + message += "use a radio" + else + return + + owner << "[aiming_at ? "\The [aiming_at] is" : "Your targets are"] [message]." + if(aiming_at) + aiming_at << "You are [message]." + +/obj/aiming_overlay/process() + if(!owner) + qdel(src) + return + ..() + update_aiming() + +/obj/aiming_overlay/Destroy() + if(aiming_at) + aiming_at.aimed -= src + aiming_at = null + owner = null + aiming_with = null + processing_objects -= src + return ..() + +obj/aiming_overlay/proc/update_aiming_deferred() + set waitfor = 0 + sleep(0) + update_aiming() + +/obj/aiming_overlay/proc/update_aiming() + + if(!owner) + qdel(src) + return + + if(!aiming_at) + cancel_aiming() + return + + if(!locked && lock_time >= world.time) + locked = 1 + update_icon() + + var/cancel_aim = 1 + if(!(aiming_with in owner) || (owner.l_hand != aiming_with && owner.r_hand != aiming_with)) + owner << "You must keep hold of your weapon!" + else if(!aiming_at || !istype(aiming_at.loc, /turf)) + owner << "You have lost sight of your target!" + else if(owner.incapacitated() || owner.lying || owner.restrained()) + owner << "You must be conscious and standing to keep track of your target!" + else if(aiming_at.alpha == 0 || (aiming_at.invisibility > owner.see_invisible)) + owner << "Your target has become invisible!" + else if(get_dist(get_turf(owner), get_turf(aiming_at)) > 7) // !(owner in viewers(aiming_at, 7)) + owner << "Your target is too far away to track!" + else + cancel_aim = 0 + + forceMove(get_turf(aiming_at)) + + if(cancel_aim) + cancel_aiming() + return + + if(!owner.incapacitated() && owner.client) + spawn(0) + owner.set_dir(get_dir(get_turf(owner), get_turf(src))) + +/obj/aiming_overlay/proc/aim_at(var/mob/target, var/obj/thing) + + if(!owner) + return + + if(owner.incapacitated()) + owner << "You cannot aim a gun in your current state." + return + if(owner.lying) + owner << "You cannot aim a gun while prone." + return + if(owner.restrained()) + owner << "You cannot aim a gun while handcuffed." + return + + if(aiming_at) + if(aiming_at == target) + return + aiming_at.aimed -= src + owner.visible_message("\The [owner] turns \the [thing] on \the [target]!") + else + owner.visible_message("\The [owner] aims \the [thing] at \the [target]!") + + if(owner.client) + owner.client.add_gun_icons() + target << "You now have a gun pointed at you. No sudden moves!" + aiming_with = thing + aiming_at = target + if(istype(aiming_with, /obj/item/weapon/gun)) + playsound(get_turf(owner), 'sound/weapons/TargetOn.ogg', 50,1) + forceMove(get_turf(target)) + processing_objects |= src + + aiming_at.aimed |= src + toggle_active(1) + locked = 0 + update_icon() + lock_time = world.time + 35 + +/obj/aiming_overlay/update_icon() + if(locked) + icon_state = "locked" + else + icon_state = "locking" + +/obj/aiming_overlay/proc/toggle_active(var/force_state = null) + if(!isnull(force_state)) + if(active == force_state) + return + active = force_state + else + active = !active + + if(!active) + cancel_aiming() + + if(owner.client) + if(active) + owner << "You will now aim rather than fire." + owner.client.add_gun_icons() + else + owner << "You will no longer aim rather than fire." + owner.client.remove_gun_icons() + +/obj/aiming_overlay/proc/cancel_aiming(var/no_message = 0) + if(!aiming_with || !aiming_at) + return + if(istype(aiming_with, /obj/item/weapon/gun)) + playsound(get_turf(owner), 'sound/weapons/TargetOff.ogg', 50,1) + if(!no_message) + owner.visible_message("\The [owner] lowers \the [aiming_with].") + + aiming_with = null + aiming_at.aimed -= src + aiming_at = null + loc = null + processing_objects -= src + diff --git a/code/modules/projectiles/targeting/targeting_triggers.dm b/code/modules/projectiles/targeting/targeting_triggers.dm new file mode 100644 index 00000000000..ea18fc3a708 --- /dev/null +++ b/code/modules/projectiles/targeting/targeting_triggers.dm @@ -0,0 +1,29 @@ +/mob/living/proc/trigger_aiming(var/trigger_type) + if(!aimed.len) + return + for(var/obj/aiming_overlay/AO in aimed) + if(AO.aiming_at == src) + AO.update_aiming() + if(AO.aiming_at == src) + AO.trigger(trigger_type) + AO.update_aiming_deferred() + +/obj/aiming_overlay/proc/trigger(var/perm) + if(!owner || !aiming_with || !aiming_at || !locked) + return + if(perm && (target_permissions & perm)) + return + if(!owner.canClick()) + return + owner.setClickCooldown(5) // Spam prevention, essentially. + if(owner.a_intent == I_HELP) + owner << "You refrain from firing \the [aiming_with] as your intent is set to help." + return + owner.visible_message("\The [owner] pulls the trigger reflexively!") + var/obj/item/weapon/gun/G = aiming_with + if(istype(G)) + G.Fire(aiming_at, owner) + +/mob/living/ClickOn(var/atom/A, var/params) + . = ..() + trigger_aiming(TARGET_CAN_CLICK) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index a11bf15a248..800482df64e 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -116,7 +116,7 @@ if (GM.client) GM.client.perspective = EYE_PERSPECTIVE GM.client.eye = src - GM.loc = src + GM.forceMove(src) for (var/mob/C in viewers(src)) C.show_message("\red [GM.name] has been placed in the [src] by [user].", 3) qdel(G) @@ -132,7 +132,7 @@ user.drop_item() if(I) - I.loc = src + I.forceMove(src) user << "You place \the [I] into the [src]." for(var/mob/M in viewers(src)) @@ -177,7 +177,8 @@ if (target.client) target.client.perspective = EYE_PERSPECTIVE target.client.eye = src - target.loc = src + + target.forceMove(src) for (var/mob/C in viewers(src)) if(C == user) @@ -201,7 +202,7 @@ if (user.client) user.client.eye = user.client.mob user.client.perspective = MOB_PERSPECTIVE - user.loc = src.loc + user.forceMove(src.loc) update() return @@ -310,7 +311,7 @@ // eject the contents of the disposal unit /obj/machinery/disposal/proc/eject() for(var/atom/movable/AM in src) - AM.loc = src.loc + AM.forceMove(src.loc) AM.pipe_eject(0) update() @@ -443,7 +444,7 @@ for(var/atom/movable/AM in H) target = get_offset_target_turf(src.loc, rand(5)-rand(5), rand(5)-rand(5)) - AM.loc = src.loc + AM.forceMove(src.loc) AM.pipe_eject(0) if(!istype(AM,/mob/living/silicon/robot/drone)) //Poor drones kept smashing windows and taking system damage being fired out of disposals. ~Z spawn(1) @@ -459,7 +460,7 @@ if(istype(I, /obj/item/projectile)) return if(prob(75)) - I.loc = src + I.forceMove(src) for(var/mob/M in viewers(src)) M.show_message("\The [I] lands in \the [src].", 3) else @@ -508,7 +509,7 @@ // now everything inside the disposal gets put into the holder // note AM since can contain mobs or objs for(var/atom/movable/AM in D) - AM.loc = src + AM.forceMove(src) if(istype(AM, /obj/structure/bigDelivery) && !hasmob) var/obj/structure/bigDelivery/T = AM src.destinationTag = T.sortTag @@ -528,7 +529,7 @@ D.expel(src) // no trunk connected, so expel immediately return - loc = D.trunk + forceMove(D.trunk) active = 1 set_dir(DOWN) spawn(1) @@ -585,7 +586,7 @@ // used when a a holder meets a stuck holder proc/merge(var/obj/structure/disposalholder/other) for(var/atom/movable/AM in other) - AM.loc = src // move everything in other holder to this one + AM.forceMove(src) // move everything in other holder to this one if(ismob(AM)) var/mob/M = AM if(M.client) // if a client mob, update eye to follow this holder @@ -671,7 +672,7 @@ // this is unlikely, but just dump out everything into the turf in case for(var/atom/movable/AM in H) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(0) qdel(H) ..() @@ -702,9 +703,9 @@ if(H2 && !H2.active) H.merge(H2) - H.loc = P + H.forceMove(P) else // if wasn't a pipe, then set loc to turf - H.loc = T + H.forceMove(T) return null return P @@ -746,6 +747,7 @@ H.active = 0 H.loc = src return + if(!T.is_plating() && istype(T,/turf/simulated/floor)) //intact floor, pop the tile var/turf/simulated/floor/F = T F.break_tile() @@ -760,7 +762,7 @@ playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0) if(H) for(var/atom/movable/AM in H) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(direction) spawn(1) if(AM) @@ -775,7 +777,7 @@ for(var/atom/movable/AM in H) target = get_offset_target_turf(T, rand(5)-rand(5), rand(5)-rand(5)) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(0) spawn(1) if(AM) @@ -808,7 +810,7 @@ // this is unlikely, but just dump out everything into the turf in case for(var/atom/movable/AM in H) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(0) qdel(H) return @@ -929,7 +931,7 @@ // this is unlikely, but just dump out everything into the turf in case for(var/atom/movable/AM in H) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(0) qdel(H) ..() @@ -990,7 +992,7 @@ if(nextdir == 12) T = GetAbove(src) if(!T) - H.loc = loc + H.forceMove(loc) return else for(var/obj/structure/disposalpipe/down/F in T) @@ -1006,9 +1008,9 @@ if(H2 && !H2.active) H.merge(H2) - H.loc = P + H.forceMove(P) else // if wasn't a pipe, then set loc to turf - H.loc = T + H.forceMove(T) return null return P @@ -1040,7 +1042,7 @@ if(nextdir == 11) T = GetBelow(src) if(!T) - H.loc = src.loc + H.forceMove(src.loc) return else for(var/obj/structure/disposalpipe/up/F in T) @@ -1056,9 +1058,9 @@ if(H2 && !H2.active) H.merge(H2) - H.loc = P + H.forceMove(P) else // if wasn't a pipe, then set loc to turf - H.loc = T + H.forceMove(T) return null return P @@ -1249,9 +1251,9 @@ if(H2 && !H2.active) H.merge(H2) - H.loc = P + H.forceMove(P) else // if wasn't a pipe, then set loc to turf - H.loc = T + H.forceMove(T) return null return P @@ -1439,7 +1441,7 @@ if(H) for(var/atom/movable/AM in H) - AM.loc = src.loc + AM.forceMove(src.loc) AM.pipe_eject(dir) if(!istype(AM,/mob/living/silicon/robot/drone)) //Drones keep smashing windows from being fired out of chutes. Bad for the station. ~Z spawn(5) diff --git a/html/changelogs/Zuhayr-aiming.yml b/html/changelogs/Zuhayr-aiming.yml new file mode 100644 index 00000000000..88b4b7f3d54 --- /dev/null +++ b/html/changelogs/Zuhayr-aiming.yml @@ -0,0 +1,4 @@ +author: Zuhayr +delete-after: True +changes: + - tweak: "Aiming has been rewritten, keep an eye out for weird behavior." diff --git a/polaris.dme b/polaris.dme index 2acbed414ca..d337865505d 100644 --- a/polaris.dme +++ b/polaris.dme @@ -31,6 +31,7 @@ #include "code\__defines\mobs.dm" #include "code\__defines\research.dm" #include "code\__defines\species_languages.dm" +#include "code\__defines\targeting.dm" #include "code\__defines\turfs.dm" #include "code\_helpers\atmospherics.dm" #include "code\_helpers\datum_pool.dm" @@ -64,9 +65,9 @@ #include "code\_onclick\hud\_defines.dm" #include "code\_onclick\hud\action.dm" #include "code\_onclick\hud\alien_larva.dm" +#include "code\_onclick\hud\gun_mode.dm" #include "code\_onclick\hud\hud.dm" #include "code\_onclick\hud\human.dm" -#include "code\_onclick\hud\monkey.dm" #include "code\_onclick\hud\movable_screen_objects.dm" #include "code\_onclick\hud\other_mobs.dm" #include "code\_onclick\hud\robot.dm" @@ -1610,7 +1611,6 @@ #include "code\modules\projectiles\effects.dm" #include "code\modules\projectiles\gun.dm" #include "code\modules\projectiles\projectile.dm" -#include "code\modules\projectiles\targeting.dm" #include "code\modules\projectiles\ammunition\boxes.dm" #include "code\modules\projectiles\ammunition\bullets.dm" #include "code\modules\projectiles\guns\alien.dm" @@ -1641,6 +1641,11 @@ #include "code\modules\projectiles\projectile\energy.dm" #include "code\modules\projectiles\projectile\force.dm" #include "code\modules\projectiles\projectile\special.dm" +#include "code\modules\projectiles\targeting\targeting_client.dm" +#include "code\modules\projectiles\targeting\targeting_gun.dm" +#include "code\modules\projectiles\targeting\targeting_mob.dm" +#include "code\modules\projectiles\targeting\targeting_overlay.dm" +#include "code\modules\projectiles\targeting\targeting_triggers.dm" #include "code\modules\random_map\_random_map_setup.dm" #include "code\modules\random_map\random_map.dm" #include "code\modules\random_map\random_map_verbs.dm"