Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Claymores & Mine Tweaks #2988

Merged
merged 24 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b6d0ab6
la bomba
Sun-Soaked May 13, 2024
db41fdd
fixes create & destroy test (I think)
Sun-Soaked May 13, 2024
872235f
Merge branch 'master' into claymores
Sun-Soaked May 15, 2024
ec9c747
plasma claymores
Sun-Soaked May 22, 2024
38629df
oops
Sun-Soaked May 22, 2024
eaff52b
Merge remote-tracking branch 'upstream/master' into claymores
Sun-Soaked May 23, 2024
2bfe2a8
cargo claymores
Sun-Soaked May 23, 2024
56ab18e
oops again
Sun-Soaked May 23, 2024
cbb2131
Merge remote-tracking branch 'upstream/master' into claymores
Sun-Soaked Jun 2, 2024
4e35bce
violent thought...
Sun-Soaked Jun 4, 2024
941f2ec
Merge branch 'master' into claymores
Sun-Soaked Jun 4, 2024
3ba3ff4
this is gonna be hilarious
Sun-Soaked Jun 4, 2024
0fc172a
Merge branch 'master' into claymores
Sun-Soaked Jun 4, 2024
16259b3
Merge remote-tracking branch 'upstream/master' into claymores
Sun-Soaked Jun 6, 2024
8750c47
Merge remote-tracking branch 'upstream/master' into claymores
Sun-Soaked Jul 12, 2024
c18e1e8
it's minover
Sun-Soaked Jul 25, 2024
8583930
Merge branch 'master' into claymores
Sun-Soaked Aug 28, 2024
b9314ae
Merge branch 'master' into claymores
Sun-Soaked Sep 6, 2024
e4afbbc
Merge remote-tracking branch 'upstream/master' into claymores
Sun-Soaked Sep 29, 2024
4e73025
sanity check
Sun-Soaked Sep 29, 2024
82b9857
Merge branch 'master' into claymores
Sun-Soaked Sep 29, 2024
f29a6ed
another pr sterilized
Sun-Soaked Oct 22, 2024
b1030b4
Merge branch 'master' into claymores
Sun-Soaked Oct 22, 2024
cf5fc3c
Merge branch 'master' into claymores
Sun-Soaked Oct 22, 2024
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
13 changes: 10 additions & 3 deletions code/datums/components/pellet_cloud.dm
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@


/datum/component/pellet_cloud/proc/create_casing_pellets(obj/item/ammo_casing/shell, atom/target, mob/living/user, fired_from, randomspread, spread, zone_override, params, distro)
shooter = user
if(user)
shooter = user
else
shooter = fired_from
var/targloc = get_turf(target)
if(!zone_override)
zone_override = shooter.zone_selected
Expand All @@ -106,8 +109,12 @@
RegisterSignal(shell.BB, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(pellet_hit))
RegisterSignal(shell.BB, list(COMSIG_PROJECTILE_RANGE_OUT, COMSIG_PARENT_QDELETING), PROC_REF(pellet_range))
pellets += shell.BB
if(!shell.throw_proj(target, targloc, shooter, params, spread))
return
if(user)
if(!shell.throw_proj(target, targloc, shooter, params, spread))
return
else
if(!shell.throw_proj(target, targloc, null, params, spread, shooter))
return
if(i != num_pellets)
shell.newshot()

Expand Down
190 changes: 186 additions & 4 deletions code/game/objects/items/devices/mines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,14 @@
//using an unarmed mine inhand deploys it.
/obj/item/mine/attack_self(mob/user)
if(!armed)
if(!loccheck(user))
to_chat(user, span_warning("There's already a mine at this position!"))
return
user.visible_message(span_danger("[user] deploys the [src]."), span_notice("You deploy the [src]."))

user.dropItemToGround(src)
anchored = TRUE
dir = user.dir
playsound(src, 'sound/machines/click.ogg', 60, TRUE)

if(arm_delay)
Expand All @@ -82,6 +86,12 @@
armed = TRUE
message_admins("[key_name(user)] has placed \a [src] at ([x],[y],[z]).")

/obj/item/mine/proc/loccheck(mob/user)
for(var/obj/item/mine/alreadymined in user.loc)
if(alreadymined.anchored)
return FALSE
return TRUE

//let them know the mine's done cooking
/obj/item/mine/proc/now_armed()
armed = TRUE
Expand Down Expand Up @@ -142,7 +152,7 @@
user.visible_message(span_warning("[user] extends their hand towards \the [src]!"), span_userdanger("You extend your arms to pick up \the [src], knowing that it will likely blow up when you touch it!"))
if(do_after(user, 5 SECONDS, target = src))//SO SO generous. You can still step back from the edge.
if(prob(10))
user.visible_message(span_notice("[user] picks up \the [src], which miraculously doesn't explode!"), span_notice("You pick up \the [src], which miraculously doesn't explode!"))
user.visible_message(span_notice("[user] picks up \the [src], which miraculously doesn't go off!"), span_notice("You pick up \the [src], which miraculously doesn't go off!"))
disarm()
else
user.visible_message(span_danger("[user] attempts to pick up \the [src] only to hear a beep as it activates in their hand!"), span_danger("You attempt to pick up \the [src] only to hear a beep as it activates in your hands!"))
Expand Down Expand Up @@ -285,7 +295,7 @@
arm_delay = 10 SECONDS//clear the area
///needed for the proximity checks.
var/datum/proximity_monitor/proximity_monitor
var/proximity_range = 2
var/proximity_range = 3

/obj/item/mine/proximity/Initialize(mapload)
. = ..()
Expand All @@ -306,7 +316,6 @@
light_range = 1

/obj/item/mine/proximity/disarm()
. = ..()
QDEL_NULL(proximity_monitor)

/obj/item/mine/proximity/Destroy()
Expand All @@ -315,7 +324,11 @@
. = ..()

/obj/item/mine/proximity/HasProximity(atom/movable/triggerer)
if(!iscarbon(triggerer))//let's keep these on player movements for now.
//let's keep these on player movements for now.
if(!iscarbon(triggerer))
return
//Quick and dirty solution for preventing activations behind walls.
if(!(triggerer in view(proximity_range, src)))
return
if(!can_trigger(triggerer))
return
Expand All @@ -325,6 +338,90 @@
QDEL_NULL(proximity_monitor)
return

//
//DIRECTIONAL MINES
//Once deployed, keeps an eye on a line of turfs in the faced direction. If something moves in them, explode.
//
/obj/item/mine/directional
name = "directional mine"
desc = "An anti-personnel device that activates when an object moves in front of it. This one does nothing and is for testing purposes only."

blast_delay = 1 DECISECONDS
arm_delay = 5 SECONDS

//range of tripwire
var/trigger_range = 4

//projectile casing to fire in the selected direction when the mine is triggered.
//null prevents a projectile from being fired.
var/obj/item/ammo_casing/casingtype = null

//cache of turfs for detection area
var/list/tripwire_turfs

//for aiming the resulting projectiles
var/turf/target_turf

//kills any existing tripwires
/obj/item/mine/directional/proc/remove_tripwires()
if(tripwire_turfs)
for(var/turf/affected_turf in tripwire_turfs)
UnregisterSignal(affected_turf, COMSIG_ATOM_ENTERED)
tripwire_turfs = null
if(target_turf)
target_turf = null
return

//sets up tripwires(or recreates them, if already present)
/obj/item/mine/directional/proc/draw_tripwires()
if(tripwire_turfs)
remove_tripwires()
//we'll also use this to set up the pew
target_turf = get_ranged_target_turf(src, dir, trigger_range)
var/turf/starting_turf = get_turf(src)
tripwire_turfs = get_line(starting_turf, target_turf)

for(var/turf/affected_turf in tripwire_turfs)
RegisterSignal(affected_turf, COMSIG_ATOM_ENTERED, PROC_REF(on_entered))

/obj/item/mine/directional/now_armed()
draw_tripwires()
. = ..()

/obj/item/mine/directional/proc/on_entered(datum/source, atom/movable/arrived)
SIGNAL_HANDLER
if(!(arrived in view(trigger_range, src)))
return
if(!can_trigger(arrived))
return

if(ismob(arrived))
var/mob/living/fool = arrived
fool.do_alert_animation(fool)

visible_message(span_danger("[icon2html(src, viewers(src))] *click*"))
playsound(src, 'sound/machines/click.ogg', 100, TRUE)
INVOKE_ASYNC(src, PROC_REF(trigger_mine), arrived)


//pew pew
/obj/item/mine/directional/mine_effect(mob/victim)
if(casingtype && target_turf && src.loc != victim.loc)
var/obj/item/ammo_casing/casing = new casingtype(src)
casing.fire_casing(target_turf, null, null, null, 30, ran_zone(), 60, src)
. = ..()

/obj/item/mine/directional/disarm()
remove_tripwires()
visible_message(span_danger("With a soft clunk, the [src]'s securing bolts retract."))
. = ..()

//handles weird cases like ship movement or teleporting
/obj/item/mine/directional/Moved()
. = ..()
if(armed & !triggered & loc)
draw_tripwires()

//
//LANDMINE TYPES
//Rylie please help me make these more immersive
Expand Down Expand Up @@ -525,6 +622,89 @@
desc = "An anti-infantry device produced during the corporate wars. The explosive payload has been swapped out for 'viscerator'-type antipersonnel drones."
spawn_type = /mob/living/simple_animal/hostile/viscerator


//
//Claymores
//shrapnel based dir explosive, extreme short range
//FRONT TOWARDS ENEMY
//

/obj/item/mine/directional/claymore
name = "C-10 Claymore"
desc = "A compact anti-personnel device with a directional trigger that responds to movement. A faded sticker on the back reads \"FRONT TOWARDS ENEMY\"."

icon_state = "mine_claymore"
base_icon_state = "mine_claymore"

trigger_range = 2

//customize explosive power
var/range_devastation = -1
var/range_heavy = 1
var/range_light = 2
var/range_flame = 0

//using this to indicate pb
var/range_flash = 1

//shim for ground icons till world icons get in
var/planted = FALSE

//a second run of shrapnel, intended for maiming especially pb targets
var/obj/item/ammo_casing/shredtype = /obj/item/ammo_casing/caseless/shrapnel/shred
casingtype = /obj/item/ammo_casing/caseless/shrapnel

manufacturer = MANUFACTURER_SCARBOROUGH

//world icons would save like 20 lines here
/obj/item/mine/directional/claymore/update_icon_state()
if(planted)
base_icon_state = "mine_claymore_planted"
icon_state = "mine_claymore_planted"
else
icon_state = "mine_claymore"
base_icon_state = "mine_claymore"
. = ..()

/obj/item/mine/directional/claymore/disarm()
. = ..()
planted = FALSE
update_appearance(UPDATE_ICON_STATE)

/obj/item/mine/directional/claymore/attack_self(mob/user)
if(!armed && loccheck(user))
planted = TRUE
. = ..()

/obj/item/mine/directional/claymore/attackby(obj/item/I, mob/user)
if (I.tool_behaviour == TOOL_SCREWDRIVER && armed)
to_chat(user, "<span class='notice'>You begin unscrewing \the [src]'s arming pin...</span>")
I.play_tool_sound(src, 50)
if(do_after(user, 10 SECONDS, target = src))
to_chat(user, "<span class='notice'>You unscrew \the [src]'s arming pin, disarming it.</span>")
disarm()
else
. = ..()

/obj/item/mine/directional/claymore/mine_effect(mob/victim)
. = ..()
//if you somehow explode it while on the same tile, you win bonus shrapnel
//also spews stuff everywhere if it's triggered while not set up
if(!target_turf || victim.loc == src.loc)
explosion(src, range_devastation, range_heavy, range_light, range_flash, 1, 0, range_flame, 0, 1)
var/casingammo = casingtype.projectile_type
var/shredammo = shredtype.projectile_type
if(casingtype)
AddComponent(/datum/component/pellet_cloud, projectile_type = casingammo, magnitude = 1)
if(shredtype)
AddComponent(/datum/component/pellet_cloud, projectile_type = shredammo, magnitude = 2)
else
var/blastloc = get_step_towards(src, target_turf)
explosion(blastloc, range_devastation, range_heavy, range_light, range_flash, 1, 0, range_flame, 0, 1)
if(shredtype)
var/obj/item/ammo_casing/shredcasing = new shredtype(src)
shredcasing.fire_casing(target_turf, null, null, null, 30, ran_zone(), 50, src)

//
//GIMMICK MINES//
//pretty much exclusively for adminbus & code dependencies
Expand Down Expand Up @@ -670,6 +850,8 @@ LIVE_MINE_HELPER(proximity/explosive/sting)
LIVE_MINE_HELPER(proximity/spawner/manhack)
LIVE_MINE_HELPER(proximity/explosive/plasma)

LIVE_MINE_HELPER(directional/claymore)

LIVE_MINE_HELPER(pressure/gas)
LIVE_MINE_HELPER(pressure/kickmine)
LIVE_MINE_HELPER(pressure/sound)
Expand Down
32 changes: 32 additions & 0 deletions code/game/objects/items/shrapnel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,35 @@

/obj/projectile/bullet/pellet/stingball/on_ricochet(atom/A)
hit_stunned_targets = TRUE // ducking will save you from the first wave, but not the rebounds


//claymore shrapnel stuff//
//2 small bursts- one that harasses people passing by a bit aways, one that absolutely brutalizes point-blank targets.
/obj/item/ammo_casing/caseless/shrapnel
name = "directional shrapnel burst :D"
desc = "I May Have Overreacted"
pellets = 4
variance = 70
projectile_type = /obj/projectile/bullet/shrapnel/claymore
randomspread = TRUE

/obj/item/ammo_casing/caseless/shrapnel/shred
name = "point blank directional shrapnel burst"
desc = "Claymores are lethal to armored infantry at point blank range."
pellets = 3
variance = 50
projectile_type = /obj/projectile/bullet/shrapnel/claymore/pointbl
randomspread = TRUE

/obj/projectile/bullet/shrapnel/claymore
name = "ceramic splinter"
range = 4
armour_penetration = -10

/obj/projectile/bullet/shrapnel/claymore/pointbl
name = "large ceramic shard"
range = 2
damage = 18
dismemberment = 30
armour_penetration = 0

2 changes: 1 addition & 1 deletion code/game/turfs/open/floor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
if(1)
ScrapeAway(2, flags = CHANGETURF_INHERIT_AIR)
if(2)
if(prob(60))
if(prob(50) && broken)
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
else
break_tile()
Expand Down
34 changes: 23 additions & 11 deletions code/modules/projectiles/ammunition/_firing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,21 @@
spread = round((rand() - 0.5) * distro)
else //Smart spread
spread = round(1 - 0.5) * distro
if(!throw_proj(target, targloc, user, params, spread))
if(!throw_proj(target, targloc, user, params, spread, fired_from))
return FALSE
else
if(isnull(BB))
return FALSE
AddComponent(/datum/component/pellet_cloud, projectile_type, pellets)
SEND_SIGNAL(src, COMSIG_PELLET_CLOUD_INIT, target, user, fired_from, randomspread, spread, zone_override, params, distro)

if(click_cooldown_override)
user.changeNext_move(click_cooldown_override)
else
user.changeNext_move(CLICK_CD_RANGE)
if(user)
if(click_cooldown_override)
user.changeNext_move(click_cooldown_override)
else
user.changeNext_move(CLICK_CD_RANGE)
user.newtonian_move(get_dir(target, user))

user.newtonian_move(get_dir(target, user))
update_appearance()
return TRUE

Expand All @@ -46,9 +47,16 @@
reagents.trans_to(BB, reagents.total_volume, transfered_by = user) //For chemical darts/bullets
qdel(reagents)

/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread)
var/turf/curloc = get_turf(user)
if (!istype(targloc) || !istype(curloc) || !BB)
/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread, atom/fired_from)
var/turf/curloc
if(user)
curloc = get_turf(user)
else
curloc = get_turf(fired_from)
if(!istype(curloc))
return FALSE

if (!istype(targloc) || !BB)
return FALSE

var/firing_dir
Expand All @@ -61,8 +69,12 @@
if(targloc == curloc)
if(target) //if the target is right on our location we'll skip the travelling code in the proj's fire()
direct_target = target
if(!direct_target)
BB.preparePixelProjectile(target, user, params, spread)
if (user)
if(!direct_target)
BB.preparePixelProjectile(target, user, params, spread)
else
if(!direct_target)
BB.preparePixelProjectile(target, fired_from, params, spread)
BB.fire(null, direct_target)
BB = null
return TRUE
Expand Down
Binary file modified icons/obj/landmine.dmi
Binary file not shown.
Loading