Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
156a102
initial testing commit
MPhonks Feb 10, 2026
e4cee15
direct-hit logic
MPhonks Feb 10, 2026
2df6dcb
on_hit changes
MPhonks Feb 10, 2026
fa24a3f
mines logic, definitions in guns.dm, rearming logic
MPhonks Feb 10, 2026
b6ab19c
rearm disarm timer
MPhonks Feb 10, 2026
e2a6d1e
mine_level rearm fix
MPhonks Feb 10, 2026
fa1bcce
updates kit to include multitool
MPhonks Feb 10, 2026
0521a15
oops, NOW includes multitool
MPhonks Feb 10, 2026
6fe203b
disarmed fix
MPhonks Feb 10, 2026
e1c1a9e
directed on-hits now have the correct range
MPhonks Feb 10, 2026
186d4d5
simpler falloff logic
MPhonks Feb 10, 2026
6259aba
fixes rearming
MPhonks Feb 10, 2026
12a6116
sound fix
MPhonks Feb 10, 2026
dd7eede
balloon_alert changes
MPhonks Feb 10, 2026
ba4061e
adjusts iff radius, fixes sound
MPhonks Feb 10, 2026
5a84d00
adjusts iff range for mines
MPhonks Feb 10, 2026
badad80
adjusts iff radius... again. fixes incendiary logic, reverts healthch…
MPhonks Feb 10, 2026
7d43458
iff adjustment: electric boogaloo
MPhonks Feb 10, 2026
bbc141b
adjusts falloff of explosions (due to cardinal_all_dirs now being set)
MPhonks Feb 10, 2026
e121cfb
Merge branch 'master' into sharp-resharpening
MPhonks Feb 10, 2026
2ffbe04
2.5s instead of 5s
MPhonks Feb 15, 2026
b7b68b6
Merge branch 'sharp-resharpening' of https://github.com/MPhonks/cmss1…
MPhonks Feb 15, 2026
89d2bd4
comments adressed
MPhonks Feb 23, 2026
916e1b5
comments adressed v2
MPhonks Feb 23, 2026
24c3086
removes is_smoke check, replaced with simple mine_level check
MPhonks Feb 23, 2026
82b558a
defaults sharp to safe mode
MPhonks Feb 23, 2026
4473f52
changes mode order to safe -> directed -> danger -> safe
MPhonks Feb 23, 2026
d7a1373
fixes flames not burning targets
MPhonks Feb 23, 2026
fb1716a
Merge branch 'master' into sharp-resharpening
MPhonks Feb 23, 2026
235b5b3
Merge branch 'master' into sharp-resharpening
MPhonks Feb 24, 2026
0b0127a
Merge branch 'master' into sharp-resharpening
MPhonks Feb 24, 2026
b469e1c
Merge branch 'cmss13-devs:master' into sharp-resharpening
MPhonks Feb 25, 2026
42c54ff
Merge branch 'cmss13-devs:master' into sharp-resharpening
MPhonks Feb 26, 2026
c5f664f
rearm now drops mines, can't rearm on other mines
MPhonks Mar 15, 2026
3afad4e
Merge branch 'master' into sharp-resharpening
MPhonks Apr 16, 2026
72e7c83
Merge branch 'master' into sharp-resharpening
MPhonks Jun 27, 2026
ee868f8
fixes disarmed mines not updating description, removes unnecessary pr…
maximow-mark-commits Jun 27, 2026
ab09d07
fixes disarmed mines not updating description, removes unnecessary pr…
MPhonks Jun 27, 2026
19fc265
Merge branch 'sharp-resharpening' of https://github.com/MPhonks/cmss1…
MPhonks Jun 27, 2026
bcc5836
Merge branch 'master' into sharp-resharpening
MPhonks Jun 28, 2026
1048eb5
adds hud modes and specialist_activation_one as alternatives to switc…
MPhonks Jun 28, 2026
b5bb299
adds extended descriptions to magazines and mines - alongside timer a…
MPhonks Jun 28, 2026
ec74865
adds the disarmed check to disarmed incendiary mines
MPhonks Jun 28, 2026
b27c190
actions.dmi fix?
MPhonks Jun 29, 2026
082274c
test
MPhonks Jun 29, 2026
697e67a
Merge branch 'master' into sharp-resharpening
MPhonks Jun 29, 2026
e01d120
readds the icons (fix?)
MPhonks Jun 29, 2026
3360abc
Merge branch 'sharp-resharpening' of https://github.com/MPhonks/cmss1…
MPhonks Jun 29, 2026
a9a894d
adds the auto_ejector flag
MPhonks Jun 29, 2026
bf06a3e
removes strict "in_hand" requirement from firemode toggling
MPhonks Jun 29, 2026
040357d
cleans unused var
MPhonks Jun 29, 2026
aeafa5a
fixes timers not resetting when disarmed/rearmed
MPhonks Jun 29, 2026
0dae32c
incendiary mine changes; level 1 is no longer phoshporus smoke, level…
MPhonks Jun 29, 2026
ae2e303
examine: typo fix, removal of redundant check, different description …
MPhonks Jun 30, 2026
552ff08
explosive mines: switch from falloff_shape_linear to falloff_shape_ex…
MPhonks Jun 30, 2026
ecd26ee
Merge branch 'master' into sharp-resharpening
MPhonks Jun 30, 2026
7314e5f
qol: rearming takes 1 second instead of 3 seconds
MPhonks Jul 15, 2026
7dffa32
Merge branch 'master' into sharp-resharpening
MPhonks Jul 15, 2026
3a1908c
removes try_to_prime check from initial deployment, small xeno no lon…
MPhonks Jul 18, 2026
f9e0fb3
Merge branch 'master' into sharp-resharpening
MPhonks Jul 18, 2026
574bd9d
fixes dart-hit explosive shape, danger mode uses previous linear expl…
MPhonks Jul 24, 2026
35ee2cf
Merge branch 'master' into sharp-resharpening
MPhonks Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions code/__DEFINES/guns.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
193 changes: 144 additions & 49 deletions code/game/objects/items/explosives/mine.dm
Original file line number Diff line number Diff line change
Expand Up @@ -397,66 +397,116 @@
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

/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)

Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -518,33 +574,72 @@
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 <b>when [extended_description]</b>.")
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 <b>[extended_description]</b> 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: <b>~[remaining_mins] [remaining_mins == 1 ? "minute" : "minutes"]</b> 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."
icon_state = "sharp_incendiary_mine"

/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)
Comment thread
MPhonks marked this conversation as resolved.
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)
1 change: 1 addition & 0 deletions code/modules/cm_marines/equipment/kit_boxes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
Loading