diff --git a/code/__DEFINES/guns.dm b/code/__DEFINES/guns.dm
index 664b6a31c2bb..63de2f695df8 100644
--- a/code/__DEFINES/guns.dm
+++ b/code/__DEFINES/guns.dm
@@ -68,3 +68,8 @@
#define CO_GUN_2006MB_COUNCIL "Colonel's golden 2006M black handle"
#define CO_GUN_2006MS_COUNCIL "Colonel's silver 2006M"
#define CO_GUN_DEAGLE_COUNCIL "Colonel's golden Desert Eagle"
+
+//SHARP modes
+#define SHARP_DANGER_MODE "DANGER"
+#define SHARP_DIRECTED_MODE "DIRECTED"
+#define SHARP_SAFE_MODE "SAFE"
diff --git a/code/game/objects/items/explosives/mine.dm b/code/game/objects/items/explosives/mine.dm
index bf718cadf122..5fbb8ecf1500 100644
--- a/code/game/objects/items/explosives/mine.dm
+++ b/code/game/objects/items/explosives/mine.dm
@@ -397,19 +397,29 @@
layer = ABOVE_OBJ_LAYER
shrapnel_spread = 360
health = 50
+ ignore_small_xeno = TRUE
var/disarmed = FALSE
- var/explosion_size = 100
- var/explosion_falloff = 50
+ var/explosion_strength = 100
+ var/explosion_falloff = 30
+ var/explosion_falloff_shape = EXPLOSION_FALLOFF_SHAPE_EXPONENTIAL
+
var/mine_level = 1
var/deploy_time = 0
var/mine_state = ""
- var/timer_id
+ var/mine_mode = ""
+
+ var/setup_timer // initialized in sharp.dm drop_dart
+ var/upgrade_timer // used here
+ var/disarm_timer // initialized in sharp.dm drop_dart
/obj/item/explosive/mine/sharp/proc/upgrade_mine()
mine_level++
icon_state = mine_state + "_[mine_level]"
if(mine_level < 4)
- timer_id = addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, upgrade_mine)), 30 SECONDS, TIMER_DELETE_ME | TIMER_STOPPABLE)
+ upgrade_timer = addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, upgrade_mine)), 30 SECONDS, TIMER_DELETE_ME | TIMER_STOPPABLE)
+
+/obj/item/explosive/mine/sharp/proc/set_mine_mode(mode)
+ mine_mode = mode
/obj/item/explosive/mine/sharp/check_for_obstacles(mob/living/user)
return FALSE
@@ -417,46 +427,86 @@
/obj/item/explosive/mine/sharp/attackby(obj/item/W, mob/user)
if(user.action_busy)
return
- else if(HAS_TRAIT(W, TRAIT_TOOL_MULTITOOL))
- user.visible_message(SPAN_NOTICE("[user] starts disarming [src]."), \
- SPAN_NOTICE("You start disarming [src]."))
- if(!do_after(user, 30, INTERRUPT_NO_NEEDHAND, BUSY_ICON_FRIENDLY))
- user.visible_message(SPAN_WARNING("[user] stops disarming [src]."), \
- SPAN_WARNING("You stop disarming [src]."))
- return
- if(!active)//someone beat us to it
- return
- user.visible_message(SPAN_NOTICE("[user] finishes disarming [src]."), \
- SPAN_NOTICE("You finish disarming [src]."))
- disarm()
+ if(!disarmed)
+ if(HAS_TRAIT(W, TRAIT_TOOL_MULTITOOL))
+ user.visible_message(SPAN_NOTICE("[user] starts disarming [src]."), \
+ SPAN_NOTICE("You start disarming [src]."))
+ if(!do_after(user, 3 SECONDS, INTERRUPT_NO_NEEDHAND, BUSY_ICON_FRIENDLY))
+ user.visible_message(SPAN_WARNING("[user] stops disarming [src]."), \
+ SPAN_WARNING("You stop disarming [src]."))
+ return
+ if(!active)//someone beat us to it
+ return
+ user.visible_message(SPAN_NOTICE("[user] finishes disarming [src]."), \
+ SPAN_NOTICE("You finish disarming [src]."))
+ disarm()
+ else
+ if(HAS_TRAIT(W, TRAIT_TOOL_MULTITOOL))
+ if(!skillcheck(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_ALL) && user.skills.get_skill_level(SKILL_SPEC_WEAPONS) != SKILL_SPEC_GRENADIER)
+ to_chat(user, SPAN_WARNING("You don't seem to know how to rearm \the [src]..."))
+ return
+ var/turf = get_turf(src)
+ for(var/obj/item/explosive/mine/existing_mine in turf)
+ if(existing_mine != src)
+ to_chat(user, SPAN_WARNING("There is already a mine deployed here!"))
+ return
+ user.visible_message(SPAN_NOTICE("[user] starts rearming [src]."), \
+ SPAN_NOTICE("You start rearming [src]."))
+ if(!do_after(user, 1 SECONDS, INTERRUPT_NO_NEEDHAND, BUSY_ICON_FRIENDLY))
+ user.visible_message(SPAN_WARNING("[user] stops rearming [src]."), \
+ SPAN_WARNING("You stop rearming [src]."))
+ return
+ if(active)//someone beat us to it
+ return
+ user.visible_message(SPAN_NOTICE("[user] finishes rearming [src]."), \
+ SPAN_NOTICE("You finish rearming [src]."))
+ rearm(user)
return
/obj/item/explosive/mine/sharp/set_tripwire()
if(!active && !tripwire)
- for(var/direction in CARDINAL_ALL_DIRS)
- var/tripwire_loc = get_turf(get_step(loc,direction))
- tripwire = new(tripwire_loc)
+ if (mine_mode == SHARP_DIRECTED_MODE)
+ tripwire = new(src)
tripwire.linked_claymore = src
active = TRUE
+ else
+ for(var/direction in CARDINAL_ALL_DIRS)
+ var/tripwire_loc = get_turf(get_step(loc,direction))
+ tripwire = new(tripwire_loc)
+ tripwire.linked_claymore = src
+ active = TRUE
/obj/item/explosive/mine/sharp/prime(mob/user)
set waitfor = FALSE
+ if (disarmed)
+ qdel(src)
+ return
if(!cause_data)
cause_data = create_cause_data(initial(name), user, src)
else if(user)
cause_data.weak_mob = WEAKREF(user)
+
if(mine_level == 1)
- explosion_size = 100
+ explosion_strength = 100 // 100, (70), 10, 0
else if(mine_level == 2)
- explosion_size = 100
- explosion_falloff = 25
+ explosion_strength = 110 // 110, (80), 20, 0
else if(mine_level == 3)
- explosion_size = 125
- explosion_falloff = 30
+ explosion_strength = 120 // 120, (90), 30, 0
else
- explosion_size = 125
- explosion_falloff = 25
- cell_explosion(loc, explosion_size, explosion_falloff, EXPLOSION_FALLOFF_SHAPE_LINEAR, CARDINAL_ALL_DIRS, cause_data, enviro=map_deployed)
+ explosion_strength = 130 // 130, (100), 40, 0
+
+ switch(mine_mode)
+ if(SHARP_DIRECTED_MODE)
+ explosion_falloff = explosion_strength
+ if(SHARP_SAFE_MODE)
+ var/iff_range = mine_level == 1 ? 1 : 2
+ for(var/mob/living/carbon/human in range(iff_range, src))
+ if (human.get_target_lock(iff_signal))
+ disarm()
+ return
+ if(SHARP_DANGER_MODE)
+ explosion_falloff_shape = EXPLOSION_FALLOFF_SHAPE_LINEAR
+ cell_explosion(loc, explosion_strength, explosion_falloff, explosion_falloff_shape, CARDINAL_ALL_DIRS, cause_data, enviro=map_deployed)
playsound(loc, 'sound/weapons/gun_sharp_explode.ogg', 100)
qdel(src)
@@ -465,12 +515,19 @@
active = FALSE
triggered = FALSE
icon_state = "sharp_mine_disarmed"
- desc = "A disarmed P9 SHARP rifle dart, useless now."
+ desc = "A disarmed P9 SHARP rifle dart. With the right training, it can potentially be rearmed with a security access tuner."
QDEL_NULL(tripwire)
disarmed = TRUE
- deltimer(timer_id)
- add_to_garbage(src)
+ deltimer(upgrade_timer)
+ deltimer(disarm_timer)
+ playsound(src, 'sound/weapons/smartgun_fail.ogg', src, 25)
+/obj/item/explosive/mine/sharp/proc/rearm(mob/user)
+ disarmed = FALSE
+ mine_level = 1
+ desc = "An experimental P9 SHARP proximity triggered explosive dart designed by Armat Systems for use by the United States Colonial Marines. This one has full 360 detection range."
+ deploy_mine(user)
+ disarm_timer = addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, disarm)), 5 MINUTES, TIMER_DELETE_ME | TIMER_STOPPABLE)
/obj/item/explosive/mine/sharp/attack_self(mob/living/user)
if(disarmed)
@@ -482,18 +539,17 @@
return
if(!hard_iff_lock && user)
iff_signal = user.faction
+ if(user && src.loc == user)
+ user.drop_inv_item_on_ground(src)
cause_data = create_cause_data(initial(name), user, src)
- if(user)
- user.drop_inv_item_on_ground(src)
setDir(user ? user.dir : dir) //The direction it is planted in is the direction the user faces at that time
activate_sensors()
update_icon()
deploy_time = world.time
mine_state = icon_state
- timer_id = addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, upgrade_mine)), 30 SECONDS, TIMER_DELETE_ME | TIMER_STOPPABLE)
- for(var/mob/living/carbon/mob in range(1, src))
- try_to_prime(mob)
+ upgrade_timer = addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, upgrade_mine)), 30 SECONDS, TIMER_DELETE_ME | TIMER_STOPPABLE)
+ anchored = TRUE
/obj/item/explosive/mine/sharp/attack_alien()
if(disarmed)
@@ -518,6 +574,32 @@
if(health <= 0)
prime()
+/obj/item/explosive/mine/sharp/get_examine_text(mob/user)
+ . = ..()
+ var/extended_description = ""
+ if(!ishuman(user))
+ switch (mine_mode)
+ if (SHARP_DANGER_MODE, SHARP_SAFE_MODE)
+ extended_description = "one comes near it"
+ if (SHARP_DIRECTED_MODE)
+ extended_description = "directly stepped on"
+ . += SPAN_INFO("Your heightened senses allow you to discern how this sharp stick triggers: This will blow up when [extended_description].")
+ else if(skillcheck(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_GRENADIER))
+ switch (mine_mode)
+ if (SHARP_DANGER_MODE)
+ extended_description = "DANGER"
+ if (SHARP_DIRECTED_MODE)
+ extended_description = "DIRECTED"
+ if (SHARP_SAFE_MODE)
+ extended_description = "SAFE"
+ . += SPAN_INFO("Your training allows you to discern what mode this mine was fired in: it appears to be set to [extended_description] mode.")
+ if(disarmed)
+ . += SPAN_INFO("The dart's internal timer has already expired, but you are trained in resetting the clock with a multitool.")
+ else if(deploy_time)
+ var/remaining_ds = max(0, (deploy_time + 5 MINUTES) - world.time)
+ var/remaining_mins = round(remaining_ds / 600, 1)
+ . += SPAN_INFO("Your training allows you to determine how much time is approximately left on the mine: ~[remaining_mins] [remaining_mins == 1 ? "minute" : "minutes"] remaining before auto-disarm.")
+
/obj/item/explosive/mine/sharp/incendiary
name = "\improper P9 SHARP incendiary dart"
desc = "An experimental P9 SHARP proximity triggered explosive dart designed by Armat Systems for use by the United States Colonial Marines. This one has full 360 detection range."
@@ -525,26 +607,39 @@
/obj/item/explosive/mine/sharp/incendiary/prime(mob/user)
set waitfor = FALSE
+ if (disarmed)
+ qdel(src)
+ return
if(!cause_data)
cause_data = create_cause_data(initial(name), user, src)
else if(user)
cause_data.weak_mob = WEAKREF(user)
+
+ var/datum/reagent
+ var/flame_radius = 1
+ var/flame_duration_modifier
+
if(mine_level == 1)
- var/datum/effect_system/smoke_spread/phosphorus/smoke = new /datum/effect_system/smoke_spread/phosphorus/sharp
- var/smoke_radius = 2
- smoke.set_up(smoke_radius, 0, loc)
- smoke.start()
- playsound(loc, 'sound/weapons/gun_sharp_explode.ogg', 100)
+ reagent = new /datum/reagent/napalm/green()
+ flame_duration_modifier = 1
else if(mine_level == 2)
- var/datum/reagent/napalm/green/reagent = new()
- new /obj/flamer_fire(loc, cause_data, reagent, 2)
- playsound(loc, 'sound/weapons/gun_flamethrower3.ogg', 45)
+ reagent = new /datum/reagent/napalm/green()
+ flame_duration_modifier = 1.5
else if(mine_level == 3)
- var/datum/reagent/napalm/ut/reagent = new()
- new /obj/flamer_fire(loc, cause_data, reagent, 2)
- playsound(loc, 'sound/weapons/gun_flamethrower3.ogg', 45)
+ reagent = new /datum/reagent/napalm/ut()
+ flame_duration_modifier = 2
else
- var/datum/reagent/napalm/ut/reagent = new()
- new /obj/flamer_fire(loc, cause_data, reagent, 3)
- playsound(loc, 'sound/weapons/gun_flamethrower3.ogg', 45)
+ reagent = new /datum/reagent/napalm/ut()
+ flame_duration_modifier = 3
+ switch(mine_mode)
+ if (SHARP_DIRECTED_MODE)
+ flame_radius = 0
+ if (SHARP_SAFE_MODE)
+ for(var/mob/living/carbon/human in range(flame_radius, src))
+ if (human.get_target_lock(iff_signal))
+ disarm()
+ return
+
+ playsound(loc, 'sound/weapons/gun_flamethrower3.ogg', 45)
+ new /obj/flamer_fire(loc, cause_data, reagent, flame_radius, null, FLAMESHAPE_STAR, null, null, flame_duration_modifier)
qdel(src)
diff --git a/code/modules/cm_marines/equipment/kit_boxes.dm b/code/modules/cm_marines/equipment/kit_boxes.dm
index 5093c68a490f..1d3e7b320da6 100644
--- a/code/modules/cm_marines/equipment/kit_boxes.dm
+++ b/code/modules/cm_marines/equipment/kit_boxes.dm
@@ -225,6 +225,7 @@
new /obj/item/ammo_magazine/pistol/vp78(src)
new /obj/item/ammo_magazine/pistol/vp78(src)
new /obj/item/device/binoculars(src)
+ new /obj/item/device/multitool(src)
//maybe put in req for later use?
diff --git a/code/modules/projectiles/guns/specialist/sharp.dm b/code/modules/projectiles/guns/specialist/sharp.dm
index 270674e4b597..5e29acfed0cc 100644
--- a/code/modules/projectiles/guns/specialist/sharp.dm
+++ b/code/modules/projectiles/guns/specialist/sharp.dm
@@ -20,20 +20,21 @@
aim_slowdown = SLOWDOWN_ADS_SPECIALIST
wield_delay = WEAPON_DELAY_VERY_SLOW
- flags_gun_features = GUN_SPECIALIST|GUN_WIELDED_FIRING_ONLY|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
+ flags_gun_features = GUN_SPECIALIST|GUN_WIELDED_FIRING_ONLY|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER|GUN_AUTO_EJECTOR
flags_item = TWOHANDED|NO_CRYO_STORE
map_specific_decoration = TRUE
- var/explosion_delay_sharp = TRUE
+ var/current_mine_mode = SHARP_SAFE_MODE
/obj/item/weapon/gun/rifle/sharp/Initialize()
- . = ..()
AddElement(/datum/element/corp_label/armat)
+ LAZYADD(actions_types, list(/datum/action/item_action/specialist/sharp_firemode_ability))
+ return ..()
/obj/item/weapon/gun/rifle/sharp/get_examine_text(mob/user)
. = ..()
- . += SPAN_INFO("Switching firemodes will toggle the explosion delay timer between 1 second and 5 seconds.")
+ . += SPAN_INFO("Switching firemodes will toggle the mode of operation of fired mines. DANGER mode sets mines with regular functionality. DIRECTED mode sets mines with concentrated intensity. SAFE mode sets mines with greater IFF which NEVER detonate when allies are nearby.")
/obj/item/weapon/gun/rifle/sharp/set_bullet_traits()
LAZYADD(traits_to_give, list(
@@ -52,7 +53,6 @@
damage_mult = BASE_BULLET_DAMAGE_MULT
recoil = RECOIL_OFF
-
/obj/item/weapon/gun/rifle/sharp/unload_chamber(mob/user)
if(!in_chamber)
return
@@ -74,16 +74,63 @@
to_chat(user, SPAN_WARNING("You don't seem to know how to use \the [src]..."))
return FALSE
-//code for changing explosion delay on direct hits
+// Sharp "switch firemode" ability
+/datum/action/item_action/specialist/sharp_firemode_ability
+ ability_primacy = SPEC_PRIMARY_ACTION_1
+
+/datum/action/item_action/specialist/sharp_firemode_ability/New(mob/living/user, obj/item/holder)
+ . = ..()
+ name = "Toggle SHARP Firemode"
+ button.name = name
+ update_button_icon()
+ update_ability_icon()
+
+/datum/action/item_action/specialist/sharp_firemode_ability/proc/update_ability_icon()
+ var/obj/item/weapon/gun/rifle/sharp/sharp_rifle = holder_item
+ var/icon = 'icons/mob/hud/actions.dmi'
+ var/icon_state
+ switch(sharp_rifle.current_mine_mode)
+ if (SHARP_DANGER_MODE)
+ icon_state = "sharp_danger"
+ if (SHARP_DIRECTED_MODE)
+ icon_state = "sharp_direct"
+ if (SHARP_SAFE_MODE)
+ icon_state = "sharp_safe"
+ button.overlays.Cut()
+ var/image/IMG = image(icon, button, icon_state)
+ button.overlays += IMG
+
+/datum/action/item_action/specialist/sharp_firemode_ability/can_use_action()
+ if(owner.is_mob_incapacitated())
+ return FALSE
+ return TRUE
+
+/datum/action/item_action/specialist/sharp_firemode_ability/action_activate()
+ . = ..()
+ var/obj/item/weapon/gun/rifle/sharp/sharp_rifle = holder_item
+ if(!ishuman(owner))
+ return
+ sharp_rifle.do_toggle_firemode(owner)
/obj/item/weapon/gun/rifle/sharp/do_toggle_firemode(mob/user)
. = ..()
- explosion_delay_sharp = !explosion_delay_sharp
playsound(user, 'sound/weapons/handling/gun_burst_toggle.ogg', 15, 1)
- to_chat(user, SPAN_NOTICE("[icon2html(src, user)] You [explosion_delay_sharp ? SPAN_BOLD("enable") : SPAN_BOLD("disable")] [src]'s delayed fire mode. Explosive ammo will blow up in [explosion_delay_sharp ? SPAN_BOLD("5 seconds") : SPAN_BOLD("2.5 seconds")]."))
- user.balloon_alert(user, "explosion delay [explosion_delay_sharp ? "5 seconds" : "2.5 seconds"].")
-
-
+ var/mine_mode_notice = ""
+ switch (current_mine_mode)
+ if (SHARP_DANGER_MODE)
+ current_mine_mode = SHARP_SAFE_MODE
+ mine_mode_notice += "[icon2html(src, user)] You set [src]'s mine mode to [current_mine_mode]. Explosive ammo will not blow up near detected IFF targets."
+ if (SHARP_DIRECTED_MODE)
+ current_mine_mode = SHARP_DANGER_MODE
+ mine_mode_notice += "[icon2html(src, user)] You set [src]'s mine mode to [current_mine_mode]. Explosive ammo will blow up regularly."
+ if (SHARP_SAFE_MODE)
+ current_mine_mode = SHARP_DIRECTED_MODE
+ mine_mode_notice += "[icon2html(src, user)] You set [src]'s mine mode to [current_mine_mode]. Explosive ammo will concentrate the explosion on the target."
+ user.balloon_alert(user, "[current_mine_mode] mode activated")
+ to_chat(user, SPAN_NOTICE(mine_mode_notice))
+
+ var/datum/action/item_action/specialist/sharp_firemode_ability/SFA = locate(/datum/action/item_action/specialist/sharp_firemode_ability) in actions
+ SFA.update_ability_icon()
/*
//========
@@ -108,6 +155,7 @@
shell_speed = AMMO_SPEED_TIER_2
var/embed_object = /obj/item/sharp/explosive
var/mine_level = 0
+ var/mine_mode = SHARP_DANGER_MODE
/datum/ammo/rifle/sharp/on_embed(mob/embedded_mob, obj/limb/target_organ)
if(!ishuman(embedded_mob))
@@ -138,15 +186,14 @@
return
var/mob/shooter = shot_dart.firer
+ var/obj/item/weapon/gun/rifle/sharp/weapon = shot_dart.shot_from
shake_camera(target, 2, 1)
if(shooter && ismob(shooter))
target.balloon_alert(target, "you have been hit by an explosive dart!", text_color = "#ce1e1e")
if(!target.get_target_lock(shooter.faction_group))
- var/obj/item/weapon/gun/rifle/sharp/weapon = shot_dart.shot_from
playsound(get_turf(target), 'sound/weapons/gun_sharp_explode.ogg', 100)
- if(weapon && weapon.explosion_delay_sharp)
- addtimer(CALLBACK(src, PROC_REF(delayed_explosion), shot_dart, target, shooter), 5 SECONDS)
- else
+ if(weapon)
+ mine_mode = weapon.current_mine_mode
addtimer(CALLBACK(src, PROC_REF(delayed_explosion), shot_dart, target, shooter), 2.5 SECONDS)
/datum/ammo/rifle/sharp/explosive/drop_dart(loc, obj/projectile/shot_dart, mob/shooter)
@@ -154,20 +201,39 @@
if(locate(/obj/item/explosive/mine) in get_turf(loc))
signal_explosion = TRUE
var/obj/item/explosive/mine/sharp/dart = new /obj/item/explosive/mine/sharp(loc)
+ var/obj/item/weapon/gun/rifle/sharp/weapon = shot_dart.shot_from
+ if(weapon)
+ dart.set_mine_mode(weapon.current_mine_mode)
// if no darts on tile, don't arm, explode instead.
if(signal_explosion)
INVOKE_ASYNC(dart, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, prime), shooter)
else
dart.anchored = TRUE
- addtimer(CALLBACK(dart, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, deploy_mine), shooter), 3 SECONDS, TIMER_DELETE_ME)
- addtimer(CALLBACK(dart, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, disarm)), 5 MINUTES, TIMER_DELETE_ME)
+ dart.setup_timer = addtimer(CALLBACK(dart, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, deploy_mine), shooter, weapon), 3 SECONDS, TIMER_DELETE_ME | TIMER_STOPPABLE)
+ dart.disarm_timer = addtimer(CALLBACK(dart, TYPE_PROC_REF(/obj/item/explosive/mine/sharp, disarm)), 5 MINUTES, TIMER_DELETE_ME | TIMER_STOPPABLE)
/datum/ammo/rifle/sharp/explosive/proc/delayed_explosion(obj/projectile/shot_dart, mob/target, mob/shooter)
if(ismob(target))
- var/explosion_size = 60
- var/falloff_size = 35
+ var/explosion_strength = 60
+ var/explosion_falloff = 20
+ var/explosion_falloff_shape = EXPLOSION_FALLOFF_SHAPE_EXPONENTIAL
var/cause_data = create_cause_data("P9 SHARP Rifle", shooter)
- cell_explosion(get_turf(target), explosion_size, falloff_size, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, cause_data)
+
+ switch(mine_mode)
+ if(SHARP_DIRECTED_MODE)
+ explosion_strength = 90
+ explosion_falloff = explosion_strength
+ if(SHARP_SAFE_MODE)
+ for(var/mob/living/carbon/human in range(1, target))
+ if (human.get_target_lock(shooter.faction_group))
+ playsound(target, 'sound/weapons/smartgun_fail.ogg', target, 25)
+ to_chat(target, SPAN_WARNING("[shot_dart] releases itself from you!"))
+ target.balloon_alert(target, "an attached explosive dart releases itself from you!")
+ to_chat(shooter, SPAN_WARNING("[shot_dart] recognized an IFF marked target and did not detonate!"))
+ return
+ if(SHARP_DANGER_MODE)
+ explosion_falloff_shape = EXPLOSION_FALLOFF_SHAPE_LINEAR
+ cell_explosion(get_turf(target), explosion_strength, explosion_falloff, explosion_falloff_shape, CARDINAL_ALL_DIRS, cause_data)
/datum/ammo/rifle/sharp/incendiary
@@ -180,15 +246,14 @@
if(!target || target == shot_dart.firer)
return
var/mob/shooter = shot_dart.firer
+ var/obj/item/weapon/gun/rifle/sharp/weapon = shot_dart.shot_from
shake_camera(target, 2, 1)
if(shooter && ismob(shooter))
- target.balloon_alert(target, "you have been hit by an incendiary dart!", text_color = "#ce1e1e")
+ target.balloon_alert(target, "you have been hit by an incendiary dart!", text_color = "#ce7c1e")
if(!target.get_target_lock(shooter.faction_group))
- var/obj/item/weapon/gun/rifle/sharp/weapon = shot_dart.shot_from
playsound(get_turf(target), 'sound/weapons/gun_sharp_explode.ogg', 100)
- if(weapon && weapon.explosion_delay_sharp)
- addtimer(CALLBACK(src, PROC_REF(delayed_fire), shot_dart, target, shooter), 5 SECONDS)
- else
+ if(weapon)
+ mine_mode = weapon.current_mine_mode
addtimer(CALLBACK(src, PROC_REF(delayed_fire), shot_dart, target, shooter), 2.5 SECONDS)
/datum/ammo/rifle/sharp/incendiary/drop_dart(loc, obj/projectile/shot_dart, mob/shooter)
@@ -196,6 +261,9 @@
if(locate(/obj/item/explosive/mine) in get_turf(loc))
signal_explosion = TRUE
var/obj/item/explosive/mine/sharp/incendiary/dart = new /obj/item/explosive/mine/sharp/incendiary(loc)
+ var/obj/item/weapon/gun/rifle/sharp/weapon = shot_dart.shot_from
+ if(weapon)
+ dart.set_mine_mode(weapon.current_mine_mode)
// if no darts on tile, don't arm, explode instead.
if(signal_explosion)
INVOKE_ASYNC(dart, TYPE_PROC_REF(/obj/item/explosive/mine/sharp/incendiary, prime), shooter)
@@ -208,6 +276,20 @@
if(ismob(target))
var/datum/effect_system/smoke_spread/phosphorus/smoke = new /datum/effect_system/smoke_spread/phosphorus/sharp
var/smoke_radius = 2
+ switch(mine_mode)
+ if(SHARP_DIRECTED_MODE)
+ var/datum/reagent/napalm/gel/reagent = new()
+ var/flame_radius = 0
+ new /obj/flamer_fire(get_turf(target), WEAKREF(shooter), reagent, flame_radius)
+ return
+ if(SHARP_SAFE_MODE)
+ for(var/mob/living/carbon/human in range(smoke_radius, target))
+ if (human.get_target_lock(shooter.faction_group))
+ playsound(target, 'sound/weapons/smartgun_fail.ogg', target, 25)
+ to_chat(target, SPAN_WARNING("[shot_dart] releases itself from you!"))
+ target.balloon_alert(target, "an attached incendiary dart releases itself from you!")
+ to_chat(shooter, SPAN_WARNING("[shot_dart] recognized an IFF marked target and did not detonate!"))
+ return
smoke.set_up(smoke_radius, 0, get_turf(target))
smoke.start()
diff --git a/code/modules/projectiles/magazines/rifles.dm b/code/modules/projectiles/magazines/rifles.dm
index 0a03c799f7f8..9a61d79173d4 100644
--- a/code/modules/projectiles/magazines/rifles.dm
+++ b/code/modules/projectiles/magazines/rifles.dm
@@ -734,17 +734,17 @@
/obj/item/ammo_magazine/rifle/sharp/explosive
name = "\improper 9X-E sticky explosive dart magazine"
- desc = "A specialized explosive sticky dart magazine for the SHARP rifle."
+ desc = "A specialized explosive dart magazine for the P9 SHARP rifle. Darts either embed into targets and detonate after a short delay, or stay behind as proximity-triggered explosive mines."
/obj/item/ammo_magazine/rifle/sharp/incendiary
name = "\improper 9X-T sticky incendiary dart magazine"
- desc = "A specialized incendiary dart magazine for the SHARP rifle."
+ desc = "A specialized incendiary dart magazine for the P9 SHARP rifle. Darts either embed into targets and release an incendiary concoction after a short delay, or stay behind as proximity-triggered incendiary mines."
icon_state = "sharp_incendiary_mag"
default_ammo = /datum/ammo/rifle/sharp/incendiary
/obj/item/ammo_magazine/rifle/sharp/flechette
name = "\improper 9X-F flechette dart magazine"
- desc = "A specialized flechette dart magazine for the SHARP rifle."
+ desc = "A specialized flechette dart magazine for the P9 SHARP rifle. Unlike their explosive and incendiary counterparts, the darts detonate on contact without delay, dispersing a concentrated cone of metal shards that shred anything in their path."
icon_state = "sharp_flechette_mag"
default_ammo = /datum/ammo/rifle/sharp/flechette
diff --git a/icons/mob/hud/actions.dmi b/icons/mob/hud/actions.dmi
index 4a754815243b..c6eb78c931cc 100644
Binary files a/icons/mob/hud/actions.dmi and b/icons/mob/hud/actions.dmi differ