diff --git a/code/modules/projectiles/guns/ballistic/assault.dm b/code/modules/projectiles/guns/ballistic/assault.dm index f6da18d86254..2c59adaaa2d0 100644 --- a/code/modules/projectiles/guns/ballistic/assault.dm +++ b/code/modules/projectiles/guns/ballistic/assault.dm @@ -180,6 +180,9 @@ /obj/item/gun/ballistic/automatic/assault/e40/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) var/current_firemode = gun_firemodes[firemode_index] if(current_firemode != FIREMODE_OTHER) + if(!secondary.latch_closed && prob(65)) + to_chat(user, span_warning("[src]'s cell falls out!")) + secondary.eject_cell() return ..() return secondary.process_fire(target, user, message, params, zone_override, bonus_spread) @@ -198,10 +201,42 @@ /obj/item/gun/ballistic/automatic/assault/e40/attackby(obj/item/attack_obj, mob/user, params) if(istype(attack_obj, /obj/item/stock_parts/cell/gun)) return secondary.attackby(attack_obj, user, params) - if(istype(attack_obj, /obj/item/screwdriver)) - return secondary.screwdriver_act(user, attack_obj,) return ..() +/obj/item/gun/ballistic/automatic/assault/e40/attack_hand(mob/user) + var/current_firemode = gun_firemodes[firemode_index] + if(current_firemode == FIREMODE_OTHER && loc == user && user.is_holding(src) && secondary.cell && !secondary.latch_closed) + secondary.eject_cell(user) + return + if(current_firemode == FIREMODE_OTHER && loc == user && user.is_holding(src) && secondary.cell && secondary.latch_closed) + to_chat(user, span_warning("The cell retainment clip is latched!")) + return + return ..() + +/obj/item/gun/ballistic/automatic/assault/e40/AltClick(mob/living/user) + var/current_firemode = gun_firemodes[firemode_index] + if(current_firemode == FIREMODE_OTHER) + if(secondary.latch_closed) + to_chat(user, span_notice("You start to unlatch the [src]'s power cell retainment clip...")) + if(do_after(user, secondary.latch_toggle_delay, src, IGNORE_USER_LOC_CHANGE)) + to_chat(user, span_notice("You unlatch [src]'s power cell retainment clip " + "OPEN" + ".")) + playsound(src, 'sound/items/taperecorder/taperecorder_play.ogg', 50, FALSE) + secondary.tac_reloads = TRUE + secondary.latch_closed = FALSE + update_appearance() + return + else + to_chat(user, span_warning("You start to latch the [src]'s power cell retainment clip...")) + if (do_after(user, secondary.latch_toggle_delay, src, IGNORE_USER_LOC_CHANGE)) + to_chat(user, span_notice("You latch [src]'s power cell retainment clip " + "CLOSED" + ".")) + playsound(src, 'sound/items/taperecorder/taperecorder_close.ogg', 50, FALSE) + secondary.tac_reloads = FALSE + secondary.latch_closed = TRUE + update_appearance() + return + else + return ..() + /obj/item/gun/ballistic/automatic/assault/e40/on_wield(obj/item/source, mob/user) wielded = TRUE secondary.wielded = TRUE @@ -241,6 +276,20 @@ . += "[icon_state]_charge[ratio]" if(secondary.cell) . += "[icon_state]_cell" + if(ismob(loc)) + var/mutable_appearance/latch_overlay + latch_overlay = mutable_appearance('icons/obj/guns/cell_latch.dmi') + if(secondary.latch_closed) + if(secondary.cell) + latch_overlay.icon_state = "latch-on-full" + else + latch_overlay.icon_state = "latch-on-empty" + else + if(secondary.cell) + latch_overlay.icon_state = "latch-off-full" + else + latch_overlay.icon_state = "latch-off-empty" + . += latch_overlay /obj/item/gun/ballistic/automatic/assault/e40/toggle_safety(mob/user, silent=FALSE) @@ -257,6 +306,17 @@ SEND_SIGNAL(src, COMSIG_GUN_SET_AUTOFIRE_SPEED, fire_delay) SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD) +/obj/item/gun/ballistic/automatic/assault/e40/examine(mob/user) + . = ..() + if(!secondary.internal_magazine) + . += "The cell retainment latch is [secondary.latch_closed ? "CLOSED" : "OPEN"]. Alt-Click to toggle the latch." + var/obj/item/ammo_casing/energy/shot = secondary.ammo_type[select] + if(secondary.cell) + . += "\The [name]'s cell has [secondary.cell.percent()]% charge remaining." + . += "\The [name] has [round(secondary.cell.charge/shot.e_cost)] shots remaining on [shot.select_name] mode." + else + . += span_notice("\The [name] doesn't seem to have a cell!") + //laser /obj/item/gun/energy/laser/e40_laser_secondary @@ -268,5 +328,6 @@ fire_delay = 0.2 SECONDS gun_firemodes = list(FIREMODE_FULLAUTO) default_firemode = FIREMODE_FULLAUTO + latch_toggle_delay = 1.2 SECONDS spread_unwielded = 20 diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 1f595e994902..41147c0e0452 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -30,6 +30,9 @@ tac_reloads = FALSE tactical_reload_delay = 1.2 SECONDS + var/latch_closed = TRUE + var/latch_toggle_delay = 1.0 SECONDS + valid_attachments = list( /obj/item/attachment/laser_sight, /obj/item/attachment/rail_light, @@ -128,7 +131,7 @@ if (!internal_magazine && (A.type in (allowed_ammo_types - blacklisted_ammo_types))) var/obj/item/stock_parts/cell/gun/C = A if (!cell) - insert_cell(user, C) + return insert_cell(user, C) else if (tac_reloads) eject_cell(user, C) @@ -136,14 +139,18 @@ return ..() /obj/item/gun/energy/proc/insert_cell(mob/user, obj/item/stock_parts/cell/gun/C) - if(user.transferItemToLoc(C, src)) - cell = C - to_chat(user, span_notice("You load the [C] into \the [src].")) - playsound(src, load_sound, load_sound_volume, load_sound_vary) - update_appearance() - return TRUE + if(!latch_closed) + if(user.transferItemToLoc(C, src)) + cell = C + to_chat(user, span_notice("You load the [C] into \the [src].")) + playsound(src, load_sound, load_sound_volume, load_sound_vary) + update_appearance() + return TRUE + else + to_chat(user, span_warning("You cannot seem to get \the [src] out of your hands!")) + return FALSE else - to_chat(user, span_warning("You cannot seem to get \the [src] out of your hands!")) + to_chat(user, span_warning("The [src]'s cell retainment clip is latched!")) return FALSE /obj/item/gun/energy/proc/eject_cell(mob/user, obj/item/stock_parts/cell/gun/tac_load = null) @@ -167,13 +174,33 @@ user.put_in_hands(old_cell) update_appearance() -/obj/item/gun/energy/screwdriver_act(mob/living/user, obj/item/I) - if(cell && !internal_magazine) - to_chat(user, span_notice("You begin unscrewing and pulling out the cell...")) - if(I.use_tool(src, user, unscrewing_time, volume = 100)) - to_chat(user, span_notice("You remove the power cell.")) - eject_cell(user) - return ..() +//special is_type_in_list method to counteract problem with current method +/obj/item/gun/energy/proc/is_attachment_in_contents_list() + for(var/content_item in contents) + if(istype(content_item, /obj/item/attachment/)) + return TRUE + return FALSE + +/obj/item/gun/energy/AltClick(mob/living/user) + if(!internal_magazine && latch_closed) + to_chat(user, span_notice("You start to unlatch the [src]'s power cell retainment clip...")) + if(do_after(user, latch_toggle_delay, src, IGNORE_USER_LOC_CHANGE)) + to_chat(user, span_notice("You unlatch the [src]'s power cell retainment clip " + "OPEN" + ".")) + playsound(src, 'sound/items/taperecorder/taperecorder_play.ogg', 50, FALSE) + tac_reloads = TRUE + latch_closed = FALSE + update_appearance() + else if(!internal_magazine && !latch_closed) + if(!cell && is_attachment_in_contents_list()) + return ..() //should bring up the attachment menu if attachments are added. If none are added, it just does leaves the latch open + to_chat(user, span_warning("You start to latch the [src]'s power cell retainment clip...")) + if (do_after(user, latch_toggle_delay, src, IGNORE_USER_LOC_CHANGE)) + to_chat(user, span_notice("You latch the [src]'s power cell retainment clip " + "CLOSED" + ".")) + playsound(src, 'sound/items/taperecorder/taperecorder_close.ogg', 50, FALSE) + tac_reloads = FALSE + latch_closed = TRUE + update_appearance() + return /obj/item/gun/energy/can_shoot(visuals) if(safety && !visuals) @@ -213,7 +240,12 @@ /obj/item/gun/energy/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) if(!chambered && can_shoot()) process_chamber() // If the gun was drained and then recharged, load a new shot. - return ..() + ..() //process the gunshot as normal + if(!latch_closed && prob(65)) //make the cell slide out if it's fired while the retainment clip is unlatched, with a 65% probability + to_chat(user, span_warning("The [src]'s cell falls out!")) + eject_cell() + return + /obj/item/gun/energy/proc/select_fire(mob/living/user) select++ @@ -252,6 +284,20 @@ var/overlay_icon_state = "[icon_state]_charge" var/obj/item/ammo_casing/energy/shot = ammo_type[modifystate ? select : 1] var/ratio = get_charge_ratio() + if(ismob(loc) && !internal_magazine) + var/mutable_appearance/latch_overlay + latch_overlay = mutable_appearance('icons/obj/guns/cell_latch.dmi') + if(latch_closed) + if(cell) + latch_overlay.icon_state = "latch-on-full" + else + latch_overlay.icon_state = "latch-on-empty" + else + if(cell) + latch_overlay.icon_state = "latch-off-full" + else + latch_overlay.icon_state = "latch-off-empty" + . += latch_overlay if(cell) . += "[icon_state]_cell" if(ratio == 0) @@ -322,6 +368,8 @@ /obj/item/gun/energy/examine(mob/user) . = ..() + if(!internal_magazine) + . += "The cell retainment latch is [latch_closed ? "CLOSED" : "OPEN"]. Alt-Click to toggle the latch." var/obj/item/ammo_casing/energy/shot = ammo_type[select] if(ammo_type.len > 1) . += "You can switch firemodes by pressing the unique action key. By default, this is space" diff --git a/icons/obj/guns/cell_latch.dmi b/icons/obj/guns/cell_latch.dmi new file mode 100644 index 000000000000..6372df688776 Binary files /dev/null and b/icons/obj/guns/cell_latch.dmi differ