mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
436 lines
13 KiB
Plaintext
436 lines
13 KiB
Plaintext
/obj/effect/mine
|
|
name = "land mine" //The name and description are deliberately NOT modified, so you can't game the mines you find.
|
|
desc = "A small explosive land mine."
|
|
density = FALSE
|
|
anchored = TRUE
|
|
icon = 'icons/obj/weapons.dmi'
|
|
icon_state = "landmine"
|
|
var/triggered = FALSE
|
|
var/smoke_strength = 3
|
|
var/obj/item/mine/mineitemtype = /obj/item/mine
|
|
var/panel_open = FALSE
|
|
var/datum/wires/mines/wires = null
|
|
var/camo_net = FALSE // Will the mine 'cloak' on deployment?
|
|
|
|
// The trap item will be triggered in some manner when detonating. Default only checks for grenades.
|
|
var/obj/item/trap = null
|
|
|
|
/obj/effect/mine/Initialize()
|
|
icon_state = "landmine_armed"
|
|
wires = new(src)
|
|
. = ..()
|
|
if(ispath(trap))
|
|
trap = new trap(src)
|
|
register_dangerous_to_step()
|
|
if(camo_net)
|
|
alpha = 50
|
|
|
|
/obj/effect/mine/Destroy()
|
|
unregister_dangerous_to_step()
|
|
if(trap)
|
|
QDEL_NULL(trap)
|
|
qdel_null(wires)
|
|
return ..()
|
|
|
|
/obj/effect/mine/Moved(atom/oldloc)
|
|
. = ..()
|
|
if(.)
|
|
var/turf/old_turf = get_turf(oldloc)
|
|
var/turf/new_turf = get_turf(src)
|
|
if(old_turf != new_turf)
|
|
old_turf.unregister_dangerous_object(src)
|
|
new_turf.register_dangerous_object(src)
|
|
|
|
/obj/effect/mine/proc/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
|
triggered = TRUE
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
|
|
if(trap)
|
|
trigger_trap(M)
|
|
visible_message("\The [src.name] flashes as it is triggered!")
|
|
|
|
else
|
|
explosion(loc, 0, 2, 3, 4) //land mines are dangerous, folks.
|
|
visible_message("\The [src.name] detonates!")
|
|
|
|
qdel(s)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/proc/trigger_trap(var/mob/living/victim)
|
|
if(istype(trap, /obj/item/grenade))
|
|
var/obj/item/grenade/G = trap
|
|
trap = null
|
|
G.forceMove(get_turf(src))
|
|
if(victim.ckey)
|
|
msg_admin_attack("[key_name_admin(victim)] stepped on \a [src.name], triggering [trap]")
|
|
G.activate()
|
|
|
|
if(istype(trap, /obj/item/transfer_valve))
|
|
var/obj/item/transfer_valve/TV = trap
|
|
trap = null
|
|
TV.forceMove(get_turf(src))
|
|
TV.toggle_valve()
|
|
|
|
/obj/effect/mine/bullet_act()
|
|
if(prob(50))
|
|
explode()
|
|
|
|
/obj/effect/mine/ex_act(severity)
|
|
if(severity <= 2 || prob(50))
|
|
explode()
|
|
..()
|
|
|
|
/obj/effect/mine/Crossed(atom/movable/AM as mob|obj)
|
|
if(AM.is_incorporeal())
|
|
return
|
|
Bumped(AM)
|
|
|
|
/obj/effect/mine/Bumped(mob/M as mob|obj)
|
|
|
|
if(triggered)
|
|
return
|
|
|
|
if(istype(M, /obj/mecha))
|
|
explode(M)
|
|
|
|
if(istype(M, /mob/living/))
|
|
if(!M.hovering) //CHOMPedit: let's not make wings ignore mines because we use those here.
|
|
explode(M)
|
|
|
|
/obj/effect/mine/attackby(obj/item/W as obj, mob/living/user as mob)
|
|
if(W.has_tool_quality(TOOL_SCREWDRIVER))
|
|
panel_open = !panel_open
|
|
user.visible_message(span_warning("[user] very carefully screws the mine's panel [panel_open ? "open" : "closed"]."),
|
|
span_notice("You very carefully screw the mine's panel [panel_open ? "open" : "closed"]."))
|
|
playsound(src, W.usesound, 50, 1)
|
|
|
|
// Panel open, stay uncloaked, or uncloak if already cloaked. If you don't cloak on place, ignore it and just be normal alpha.
|
|
alpha = camo_net ? (panel_open ? 255 : 50) : 255
|
|
|
|
else if((W.has_tool_quality(TOOL_WIRECUTTER) || istype(W, /obj/item/multitool)) && panel_open)
|
|
interact(user)
|
|
else
|
|
..()
|
|
|
|
/obj/effect/mine/interact(mob/living/user as mob)
|
|
if(!panel_open || isAI(user))
|
|
return
|
|
user.set_machine(src)
|
|
wires.Interact(user)
|
|
|
|
/obj/effect/mine/camo
|
|
camo_net = TRUE
|
|
|
|
/obj/effect/mine/dnascramble
|
|
mineitemtype = /obj/item/mine/dnascramble
|
|
|
|
/obj/effect/mine/dnascramble/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
|
triggered = TRUE
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
if(istype(M))
|
|
M.radiation += 50
|
|
randmutb(M)
|
|
domutcheck(M,null)
|
|
M.UpdateAppearance()
|
|
visible_message("\The [src.name] flashes violently before disintegrating!")
|
|
SSmotiontracker.ping(src,100)
|
|
spawn(0)
|
|
qdel(s)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/stun
|
|
mineitemtype = /obj/item/mine/stun
|
|
|
|
/obj/effect/mine/stun/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
triggered = TRUE
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
if(istype(M))
|
|
M.Stun(30)
|
|
visible_message("\The [src.name] flashes violently before disintegrating!")
|
|
SSmotiontracker.ping(src,100)
|
|
spawn(0)
|
|
qdel(s)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/n2o
|
|
mineitemtype = /obj/item/mine/n2o
|
|
|
|
/obj/effect/mine/n2o/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
triggered = TRUE
|
|
for (var/turf/simulated/floor/target in range(1,src))
|
|
if(!target.blocks_air)
|
|
target.assume_gas(GAS_N2O, 30)
|
|
visible_message("\The [src.name] detonates!")
|
|
SSmotiontracker.ping(src,100)
|
|
spawn(0)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/phoron
|
|
mineitemtype = /obj/item/mine/phoron
|
|
|
|
/obj/effect/mine/phoron/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
triggered = TRUE
|
|
for (var/turf/simulated/floor/target in range(1,src))
|
|
if(!target.blocks_air)
|
|
target.assume_gas(GAS_PHORON, 30)
|
|
target.hotspot_expose(1000, CELL_VOLUME)
|
|
visible_message("\The [src.name] detonates!")
|
|
SSmotiontracker.ping(src,100)
|
|
spawn(0)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/kick
|
|
mineitemtype = /obj/item/mine/kick
|
|
|
|
/obj/effect/mine/kick/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
|
triggered = TRUE
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
if(istype(M, /obj/mecha))
|
|
var/obj/mecha/E = M
|
|
M = E.occupant
|
|
if(istype(M))
|
|
qdel(M.client)
|
|
spawn(0)
|
|
qdel(s)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/frag
|
|
mineitemtype = /obj/item/mine/frag
|
|
var/fragment_types = list(/obj/item/projectile/bullet/pellet/fragment)
|
|
var/num_fragments = 20 //total number of fragments produced by the grenade
|
|
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
|
|
var/spread_range = 7
|
|
|
|
/obj/effect/mine/frag/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
|
triggered = TRUE
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
var/turf/O = get_turf(src)
|
|
if(!O)
|
|
return
|
|
src.fragmentate(O, 20, 7, list(/obj/item/projectile/bullet/pellet/fragment)) //only 20 weak fragments because you're stepping directly on it
|
|
visible_message("\The [src.name] detonates!")
|
|
SSmotiontracker.ping(src,100)
|
|
spawn(0)
|
|
qdel(s)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/training //Name and Desc commented out so it's possible to trick people with the training mines
|
|
// name = "training mine"
|
|
// desc = "A mine with its payload removed, for EOD training and demonstrations."
|
|
mineitemtype = /obj/item/mine/training
|
|
|
|
/obj/effect/mine/training/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
triggered = TRUE
|
|
visible_message("\The [src.name]'s light flashes rapidly as it 'explodes'.")
|
|
new src.mineitemtype(get_turf(src))
|
|
spawn(0)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/emp
|
|
mineitemtype = /obj/item/mine/emp
|
|
|
|
/obj/effect/mine/emp/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
triggered = TRUE
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
visible_message("\The [src.name] flashes violently before disintegrating!")
|
|
SSmotiontracker.ping(src,100)
|
|
empulse(loc, 2, 4, 7, 10, 1) // As strong as an EMP grenade
|
|
spawn(0)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/emp/camo
|
|
camo_net = TRUE
|
|
|
|
/obj/effect/mine/incendiary
|
|
mineitemtype = /obj/item/mine/incendiary
|
|
|
|
/obj/effect/mine/incendiary/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
triggered = TRUE
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
if(istype(M))
|
|
M.adjust_fire_stacks(5)
|
|
M.fire_act()
|
|
visible_message("\The [src.name] bursts into flames!")
|
|
SSmotiontracker.ping(src,100)
|
|
spawn(0)
|
|
qdel(src)
|
|
|
|
/obj/effect/mine/gadget
|
|
mineitemtype = /obj/item/mine/gadget
|
|
|
|
/obj/effect/mine/gadget/explode(var/mob/living/M)
|
|
if(triggered) // Prevents circular mine explosions from two mines detonating eachother
|
|
return
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
|
triggered = TRUE
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
|
|
if(trap)
|
|
trigger_trap(M)
|
|
visible_message("\The [src.name] flashes as it is triggered!")
|
|
|
|
else
|
|
explosion(loc, 0, 0, 2, 2)
|
|
visible_message("\The [src.name] detonates!")
|
|
SSmotiontracker.ping(src,100)
|
|
|
|
qdel(s)
|
|
qdel(src)
|
|
|
|
/////////////////////////////////////////////
|
|
// The held item version of the above mines
|
|
/////////////////////////////////////////////
|
|
/obj/item/mine
|
|
name = "mine"
|
|
desc = "A small explosive mine with 'HE' and a grenade symbol on the side."
|
|
icon = 'icons/obj/weapons.dmi'
|
|
icon_state = "landmine"
|
|
var/countdown = 10
|
|
var/minetype = /obj/effect/mine //This MUST be an /obj/effect/mine type, or it'll runtime.
|
|
|
|
var/obj/item/trap = null
|
|
|
|
var/list/allowed_gadgets = null
|
|
|
|
/obj/item/mine/attack_self(mob/user as mob) // You do not want to move or throw a land mine while priming it... Explosives + Sudden Movement = Bad Times
|
|
add_fingerprint(user)
|
|
msg_admin_attack("[key_name_admin(user)] primed \a [src]")
|
|
user.visible_message("[user] starts priming \the [src.name].", "You start priming \the [src.name]. Hold still!")
|
|
if(do_after(user, 10 SECONDS))
|
|
playsound(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
|
|
prime(user)
|
|
else
|
|
visible_message("[user] triggers \the [src.name]!", "You accidentally trigger \the [src.name]!")
|
|
prime(user, TRUE)
|
|
return
|
|
|
|
/obj/item/mine/attackby(obj/item/W as obj, mob/living/user as mob)
|
|
if(W.has_tool_quality(TOOL_SCREWDRIVER) && trap)
|
|
to_chat(user, span_notice("You begin removing \the [trap]."))
|
|
if(do_after(user, 10 SECONDS))
|
|
to_chat(user, span_notice("You finish disconnecting the mine's trigger."))
|
|
trap.forceMove(get_turf(src))
|
|
trap = null
|
|
return
|
|
|
|
if(LAZYLEN(allowed_gadgets) && !trap)
|
|
var/allowed = FALSE
|
|
|
|
for(var/path in allowed_gadgets)
|
|
if(istype(W, path))
|
|
allowed = TRUE
|
|
break
|
|
|
|
if(allowed)
|
|
user.drop_from_inventory(W)
|
|
W.forceMove(src)
|
|
trap = W
|
|
|
|
..()
|
|
|
|
/obj/item/mine/proc/prime(mob/user as mob, var/explode_now = FALSE)
|
|
visible_message("\The [src.name] beeps as the priming sequence completes.")
|
|
var/obj/effect/mine/R = new minetype(get_turf(src))
|
|
src.transfer_fingerprints_to(R)
|
|
R.add_fingerprint(user)
|
|
if(trap)
|
|
R.trap = trap
|
|
trap = null
|
|
R.trap.forceMove(R)
|
|
if(explode_now)
|
|
R.explode(user)
|
|
spawn(0)
|
|
qdel(src)
|
|
|
|
/obj/item/mine/dnascramble
|
|
name = "radiation mine"
|
|
desc = "A small explosive mine with a radiation symbol on the side."
|
|
minetype = /obj/effect/mine/dnascramble
|
|
|
|
/obj/item/mine/phoron
|
|
name = "incendiary mine"
|
|
desc = "A small explosive mine with a fire symbol on the side."
|
|
minetype = /obj/effect/mine/phoron
|
|
|
|
/obj/item/mine/kick
|
|
name = "kick mine"
|
|
desc = "Concentrated war crimes. Handle with care."
|
|
minetype = /obj/effect/mine/kick
|
|
|
|
/obj/item/mine/n2o
|
|
name = "nitrous oxide mine"
|
|
desc = "A small explosive mine with three Z's on the side."
|
|
minetype = /obj/effect/mine/n2o
|
|
|
|
/obj/item/mine/stun
|
|
name = "stun mine"
|
|
desc = "A small explosive mine with a lightning bolt symbol on the side."
|
|
minetype = /obj/effect/mine/stun
|
|
|
|
/obj/item/mine/frag
|
|
name = "fragmentation mine"
|
|
desc = "A small explosive mine with 'FRAG' and a grenade symbol on the side."
|
|
minetype = /obj/effect/mine/frag
|
|
|
|
/obj/item/mine/training
|
|
name = "training mine"
|
|
desc = "A mine with its payload removed, for EOD training and demonstrations."
|
|
minetype = /obj/effect/mine/training
|
|
|
|
/obj/item/mine/emp
|
|
name = "emp mine"
|
|
desc = "A small explosive mine with a lightning bolt symbol on the side."
|
|
minetype = /obj/effect/mine/emp
|
|
|
|
/obj/item/mine/incendiary
|
|
name = "incendiary mine"
|
|
desc = "A small explosive mine with a fire symbol on the side."
|
|
minetype = /obj/effect/mine/incendiary
|
|
|
|
/obj/item/mine/gadget
|
|
name = "gadget mine"
|
|
desc = "A small pressure-triggered device. If no component is added, the internal release bolts will detonate in unison when triggered."
|
|
|
|
allowed_gadgets = list(/obj/item/grenade, /obj/item/transfer_valve)
|
|
|
|
// This tells AI mobs to not be dumb and step on mines willingly.
|
|
/obj/item/mine/is_safe_to_step(mob/living/L)
|
|
if(!L.hovering) //CHOMPedit: Let's not trivialize mines.
|
|
return FALSE
|
|
return ..()
|