Merge branch 'master' into upstream-merge-30862
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
var/list/beakers = list()
|
||||
var/list/allowed_containers = list(/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle)
|
||||
var/affected_area = 3
|
||||
var/obj/item/device/assembly_holder/nadeassembly = null
|
||||
var/obj/item/assembly_holder/nadeassembly = null
|
||||
var/assemblyattacher
|
||||
var/ignition_temp = 10 // The amount of heat added to the reagents when this grenade goes off.
|
||||
var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy.
|
||||
@@ -27,26 +27,26 @@
|
||||
/obj/item/grenade/chem_grenade/examine(mob/user)
|
||||
display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state
|
||||
..()
|
||||
if(user.can_see_reagents())
|
||||
var/count = 0
|
||||
if(beakers.len)
|
||||
to_chat(user, "<span class='notice'>You scan the grenade and detect the following reagents:</span>")
|
||||
for(var/obj/item/reagent_containers/glass/G in beakers)
|
||||
var/textcount = thtotext(++count)
|
||||
for(var/datum/reagent/R in G.reagents.reagent_list)
|
||||
to_chat(user, "<span class='notice'>[R.volume] units of [R.name] in the [textcount] beaker.</span>")
|
||||
if(beakers.len == 1)
|
||||
to_chat(user, "<span class='notice'>You detect no second beaker in the grenade.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You scan the grenade, but detect nothing.</span>")
|
||||
|
||||
|
||||
/obj/item/grenade/chem_grenade/attack_self(mob/user)
|
||||
if(stage == READY && !active)
|
||||
if(stage == READY && !active)
|
||||
if(nadeassembly)
|
||||
nadeassembly.attack_self(user)
|
||||
else if(clown_check(user))
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] has primed a [name] for detonation at [A.name][ADMIN_JMP(bombturf)].")
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
|
||||
to_chat(user, "<span class='warning'>You prime the [name]! [det_time / 10] second\s!</span>")
|
||||
playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
|
||||
active = 1
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.throw_mode_on()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/grenade/chem_grenade/attackby(obj/item/I, mob/user, params)
|
||||
@@ -55,12 +55,12 @@
|
||||
if(beakers.len)
|
||||
stage_change(READY)
|
||||
to_chat(user, "<span class='notice'>You lock the [initial(name)] assembly.</span>")
|
||||
playsound(loc, I.usesound, 25, -3)
|
||||
I.play_tool_sound(src, 25)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to add at least one beaker before locking the [initial(name)] assembly!</span>")
|
||||
else if(stage == READY && !nadeassembly)
|
||||
det_time = det_time == 50 ? 30 : 50 //toggle between 30 and 50
|
||||
to_chat(user, "<span class='notice'>You modify the time delay. It's set for [det_time / 10] second\s.</span>")
|
||||
to_chat(user, "<span class='notice'>You modify the time delay. It's set for [DisplayTimeText(det_time)].</span>")
|
||||
else if(stage == EMPTY)
|
||||
to_chat(user, "<span class='warning'>You need to add an activation mechanism!</span>")
|
||||
|
||||
@@ -78,9 +78,9 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[I] is empty!</span>")
|
||||
|
||||
else if(stage == EMPTY && istype(I, /obj/item/device/assembly_holder))
|
||||
else if(stage == EMPTY && istype(I, /obj/item/assembly_holder))
|
||||
. = 1 // no afterattack
|
||||
var/obj/item/device/assembly_holder/A = I
|
||||
var/obj/item/assembly_holder/A = I
|
||||
if(isigniter(A.a_left) == isigniter(A.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
|
||||
return
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
@@ -110,12 +110,12 @@
|
||||
else if(stage == WIRED && istype(I, /obj/item/wrench))
|
||||
if(beakers.len)
|
||||
for(var/obj/O in beakers)
|
||||
O.loc = get_turf(src)
|
||||
O.forceMove(drop_location())
|
||||
beakers = list()
|
||||
to_chat(user, "<span class='notice'>You open the [initial(name)] assembly and remove the payload.</span>")
|
||||
return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
|
||||
if(nadeassembly)
|
||||
nadeassembly.loc = get_turf(src)
|
||||
nadeassembly.forceMove(drop_location())
|
||||
nadeassembly.master = null
|
||||
nadeassembly = null
|
||||
else // If "nadeassembly = null && stage == WIRED", then it most have been cable_coil that was used.
|
||||
@@ -163,11 +163,13 @@
|
||||
for(var/obj/item/reagent_containers/glass/G in beakers)
|
||||
reactants += G.reagents
|
||||
|
||||
if(!chem_splash(get_turf(src), affected_area, reactants, ignition_temp, threatscale) && !no_splash)
|
||||
playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
var/turf/detonation_turf = get_turf(src)
|
||||
|
||||
if(!chem_splash(detonation_turf, affected_area, reactants, ignition_temp, threatscale) && !no_splash)
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(beakers.len)
|
||||
for(var/obj/O in beakers)
|
||||
O.loc = get_turf(src)
|
||||
O.forceMove(drop_location())
|
||||
beakers = list()
|
||||
stage_change(EMPTY)
|
||||
return
|
||||
@@ -175,14 +177,10 @@
|
||||
if(nadeassembly)
|
||||
var/mob/M = get_mob_by_ckey(assemblyattacher)
|
||||
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/A = get_area(T)
|
||||
message_admins("grenade primed by an assembly, attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [ADMIN_JMP(T)]</a>.")
|
||||
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [COORD(T)]")
|
||||
message_admins("grenade primed by an assembly, attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [ADMIN_VERBOSEJMP(detonation_turf)]</a>.")
|
||||
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [AREACOORD(detonation_turf)]")
|
||||
|
||||
var/turf/DT = get_turf(src)
|
||||
var/area/DA = get_area(DT)
|
||||
log_game("A grenade detonated at [DA.name] [COORD(DT)]")
|
||||
log_game("A grenade detonated at [AREACOORD(detonation_turf)]")
|
||||
|
||||
update_mob()
|
||||
|
||||
@@ -195,7 +193,6 @@
|
||||
icon_state = "large_grenade"
|
||||
allowed_containers = list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/condiment,
|
||||
/obj/item/reagent_containers/food/drinks)
|
||||
origin_tech = "combat=3;engineering=3"
|
||||
affected_area = 5
|
||||
ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades.
|
||||
threatscale = 1.1 // 10% more effective.
|
||||
@@ -245,7 +242,6 @@
|
||||
name = "pyro grenade"
|
||||
desc = "A custom made pyrotechnical grenade. It heats up and ignites its contents upon detonation."
|
||||
icon_state = "pyrog"
|
||||
origin_tech = "combat=4;engineering=4"
|
||||
affected_area = 3
|
||||
ignition_temp = 500 // This is enough to expose a hotspot.
|
||||
|
||||
@@ -253,11 +249,10 @@
|
||||
name = "advanced release grenade"
|
||||
desc = "A custom made advanced release grenade. It is able to be detonated more than once. Can be configured using a multitool."
|
||||
icon_state = "timeg"
|
||||
origin_tech = "combat=3;engineering=4"
|
||||
var/unit_spread = 10 // Amount of units per repeat. Can be altered with a multitool.
|
||||
|
||||
/obj/item/grenade/chem_grenade/adv_release/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/device/multitool))
|
||||
if(istype(I, /obj/item/multitool))
|
||||
switch(unit_spread)
|
||||
if(0 to 24)
|
||||
unit_spread += 5
|
||||
@@ -287,18 +282,15 @@
|
||||
RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, threatscale, 1, 1)
|
||||
chem_splash(get_turf(src), affected_area, list(reactants), ignition_temp, threatscale)
|
||||
|
||||
var/turf/DT = get_turf(src)
|
||||
if(nadeassembly)
|
||||
var/mob/M = get_mob_by_ckey(assemblyattacher)
|
||||
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/A = get_area(T)
|
||||
message_admins("grenade primed by an assembly, attached by [key_name_admin(M)]<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>(?)</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</A>) and last touched by [key_name_admin(last)]<A HREF='?_src_=holder;adminmoreinfo=\ref[last]'>(?)</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[last]'>FLW</A>) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>.")
|
||||
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
|
||||
message_admins("grenade primed by an assembly at [AREACOORD(DT)], attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name])</a>.")
|
||||
log_game("grenade primed by an assembly at [AREACOORD(DT)], attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name])")
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time)
|
||||
var/turf/DT = get_turf(src)
|
||||
var/area/DA = get_area(DT)
|
||||
log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])")
|
||||
log_game("A grenade detonated at [AREACOORD(DT)]")
|
||||
|
||||
|
||||
|
||||
@@ -529,7 +521,7 @@
|
||||
|
||||
/obj/item/grenade/chem_grenade/bioterrorfoam
|
||||
name = "Bio terror foam grenade"
|
||||
desc = "Tiger Cooperative chemical foam grenade. Causes temporary irration, blindness, confusion, mutism, and mutations to carbon based life forms. Contains additional spore toxin"
|
||||
desc = "Tiger Cooperative chemical foam grenade. Causes temporary irration, blindness, confusion, mutism, and mutations to carbon based life forms. Contains additional spore toxin."
|
||||
stage = READY
|
||||
|
||||
/obj/item/grenade/chem_grenade/bioterrorfoam/Initialize()
|
||||
@@ -565,3 +557,24 @@
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
|
||||
/obj/item/grenade/chem_grenade/holy
|
||||
name = "holy hand grenade"
|
||||
desc = "A vessel of concentrated religious might."
|
||||
icon_state = "holy_grenade"
|
||||
stage = READY
|
||||
|
||||
/obj/item/grenade/chem_grenade/holy/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("potassium", 100)
|
||||
B2.reagents.add_reagent("holywater", 100)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
|
||||
#undef READY
|
||||
#undef WIRED
|
||||
#undef EMPTY
|
||||
|
||||
@@ -6,28 +6,31 @@
|
||||
name = "clusterbang"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "clusterbang"
|
||||
var/base_state = "clusterbang"
|
||||
var/payload = /obj/item/grenade/flashbang/cluster
|
||||
var/payload_spawner = /obj/effect/payload_spawner
|
||||
var/prime_sound = 'sound/weapons/armbomb.ogg'
|
||||
var/min_spawned = 4
|
||||
var/max_spawned = 8
|
||||
var/segment_chance = 35
|
||||
|
||||
/obj/item/grenade/clusterbuster/prime()
|
||||
update_mob()
|
||||
var/numspawned = rand(4,8)
|
||||
var/numspawned = rand(min_spawned,max_spawned)
|
||||
var/again = 0
|
||||
|
||||
for(var/more = numspawned,more > 0,more--)
|
||||
if(prob(35))
|
||||
if(prob(segment_chance))
|
||||
again++
|
||||
numspawned--
|
||||
|
||||
for(var/loop = again ,loop > 0, loop--)
|
||||
new /obj/item/grenade/clusterbuster/segment(loc, payload)//Creates 'segments' that launches a few more payloads
|
||||
|
||||
new /obj/effect/payload_spawner(loc, payload, numspawned)//Launches payload
|
||||
|
||||
playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
|
||||
for(var/loop in 1 to again)
|
||||
new /obj/item/grenade/clusterbuster/segment(drop_location(), src)//Creates 'segments' that launches a few more payloads
|
||||
|
||||
new payload_spawner(drop_location(), payload, numspawned)//Launches payload
|
||||
playsound(src, prime_sound, 75, 1, -3)
|
||||
qdel(src)
|
||||
|
||||
|
||||
//////////////////////
|
||||
//Clusterbang segment
|
||||
//////////////////////
|
||||
@@ -36,38 +39,77 @@
|
||||
name = "clusterbang segment"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "clusterbang_segment"
|
||||
base_state = "clusterbang_segment"
|
||||
|
||||
/obj/item/grenade/clusterbuster/segment/New(var/loc, var/payload_type = /obj/item/grenade/flashbang/cluster)
|
||||
..()
|
||||
icon_state = "clusterbang_segment_active"
|
||||
payload = payload_type
|
||||
active = 1
|
||||
walk_away(src,loc,rand(1,4))
|
||||
/obj/item/grenade/clusterbuster/segment/Initialize(mapload, obj/item/grenade/clusterbuster/base)
|
||||
. = ..()
|
||||
if(base)
|
||||
name = "[base.name] segment"
|
||||
base_state = "[base.base_state]_segment"
|
||||
icon_state = base_state
|
||||
payload_spawner = base.payload_spawner
|
||||
payload = base.payload
|
||||
prime_sound = base.prime_sound
|
||||
min_spawned = base.min_spawned
|
||||
max_spawned = base.max_spawned
|
||||
icon_state = "[base_state]_active"
|
||||
active = TRUE
|
||||
var/steps = rand(1,4)
|
||||
for(var/i in 1 to steps)
|
||||
step_away(src,loc)
|
||||
addtimer(CALLBACK(src, .proc/prime), rand(15,60))
|
||||
|
||||
/obj/item/grenade/clusterbuster/segment/prime()
|
||||
|
||||
new /obj/effect/payload_spawner(loc, payload, rand(4,8))
|
||||
|
||||
playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
|
||||
|
||||
new payload_spawner(drop_location(), payload, rand(min_spawned,max_spawned))
|
||||
playsound(src, prime_sound, 75, 1, -3)
|
||||
qdel(src)
|
||||
|
||||
//////////////////////////////////
|
||||
//The payload spawner effect
|
||||
/////////////////////////////////
|
||||
/obj/effect/payload_spawner/New(var/turf/newloc,var/type, var/numspawned as num)
|
||||
/obj/effect/payload_spawner/Initialize(mapload, type, numspawned)
|
||||
..()
|
||||
spawn_payload(type, numspawned)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
for(var/loop = numspawned ,loop > 0, loop--)
|
||||
/obj/effect/payload_spawner/proc/spawn_payload(type, numspawned)
|
||||
for(var/loop in 1 to numspawned)
|
||||
var/obj/item/grenade/P = new type(loc)
|
||||
P.active = 1
|
||||
walk_away(P,loc,rand(1,4))
|
||||
if(istype(P))
|
||||
P.active = TRUE
|
||||
addtimer(CALLBACK(P, /obj/item/grenade/proc/prime), rand(15,60))
|
||||
var/steps = rand(1,4)
|
||||
for(var/i in 1 to steps)
|
||||
step_away(src,loc)
|
||||
|
||||
spawn(rand(15,60))
|
||||
if(P && !QDELETED(P))
|
||||
P.prime()
|
||||
qdel(src)
|
||||
/obj/effect/payload_spawner/random_slime
|
||||
var/volatile = FALSE
|
||||
|
||||
/obj/effect/payload_spawner/random_slime/volatile
|
||||
volatile = TRUE
|
||||
|
||||
/obj/item/slime_extract/proc/activate_slime()
|
||||
var/list/slime_chems = src.activate_reagents
|
||||
if(!QDELETED(src))
|
||||
var/chem = pick(slime_chems)
|
||||
var/amount = 5
|
||||
if(chem == "lesser plasma") //In the rare case we get another rainbow.
|
||||
chem = "plasma"
|
||||
amount = 4
|
||||
if(chem == "holy water and uranium")
|
||||
chem = "uranium"
|
||||
reagents.add_reagent("holywater")
|
||||
reagents.add_reagent(chem,amount)
|
||||
|
||||
/obj/effect/payload_spawner/random_slime/spawn_payload(type, numspawned)
|
||||
for(var/loop = numspawned ,loop > 0, loop--)
|
||||
var/chosen = pick(subtypesof(/obj/item/slime_extract))
|
||||
var/obj/item/slime_extract/P = new chosen(loc)
|
||||
if(volatile)
|
||||
addtimer(CALLBACK(P, /obj/item/slime_extract/proc/activate_slime), rand(15,60))
|
||||
var/steps = rand(1,4)
|
||||
for(var/i in 1 to steps)
|
||||
step_away(src,loc)
|
||||
|
||||
//////////////////////////////////
|
||||
//Custom payload clusterbusters
|
||||
@@ -127,9 +169,22 @@
|
||||
name = "WELCOME TO HELL"
|
||||
payload = /obj/item/grenade/chem_grenade/clf3
|
||||
|
||||
|
||||
//random clusterbuster spawner
|
||||
/obj/item/grenade/clusterbuster/random
|
||||
icon_state = "random_clusterbang"
|
||||
|
||||
/obj/item/grenade/clusterbuster/random/New()
|
||||
var/real_type = pick(subtypesof(/obj/item/grenade/clusterbuster))
|
||||
new real_type(loc)
|
||||
qdel(src)
|
||||
|
||||
//rainbow slime effect
|
||||
/obj/item/grenade/clusterbuster/slime
|
||||
name = "Blorble Blorble"
|
||||
icon_state = "slimebang"
|
||||
base_state = "slimebang"
|
||||
payload_spawner = /obj/effect/payload_spawner/random_slime
|
||||
prime_sound = 'sound/effects/bubbles.ogg'
|
||||
|
||||
/obj/item/grenade/clusterbuster/slime/volatile
|
||||
payload_spawner = /obj/effect/payload_spawner/random_slime/volatile
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
desc = "It is designed to wreak havoc on electronic systems."
|
||||
icon_state = "emp"
|
||||
item_state = "emp"
|
||||
origin_tech = "magnets=3;combat=2"
|
||||
|
||||
/obj/item/grenade/empgrenade/prime()
|
||||
update_mob()
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
item_state = "flashbang"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
origin_tech = "materials=2;combat=3"
|
||||
|
||||
/obj/item/grenade/flashbang/prime()
|
||||
update_mob()
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
//improvised explosives//
|
||||
|
||||
/obj/item/grenade/iedcasing
|
||||
name = "improvised firebomb"
|
||||
desc = "A weak, improvised incendiary device."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "improvised_grenade"
|
||||
item_state = "flashbang"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = SLOT_BELT
|
||||
active = 0
|
||||
det_time = 50
|
||||
display_timer = 0
|
||||
var/range = 3
|
||||
var/list/times
|
||||
|
||||
/obj/item/grenade/iedcasing/Initialize()
|
||||
. = ..()
|
||||
add_overlay("improvised_grenade_filled")
|
||||
add_overlay("improvised_grenade_wired")
|
||||
times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value]
|
||||
det_time = text2num(pickweight(times))
|
||||
if(det_time < 0) //checking for 'duds'
|
||||
range = 1
|
||||
det_time = rand(30,80)
|
||||
else
|
||||
range = pick(2,2,2,3,3,3,4)
|
||||
|
||||
/obj/item/grenade/iedcasing/CheckParts(list/parts_list)
|
||||
..()
|
||||
var/obj/item/reagent_containers/food/drinks/soda_cans/can = locate() in contents
|
||||
if(can)
|
||||
can.pixel_x = 0 //Reset the sprite's position to make it consistent with the rest of the IED
|
||||
can.pixel_y = 0
|
||||
var/mutable_appearance/can_underlay = new(can)
|
||||
can_underlay.layer = FLOAT_LAYER
|
||||
can_underlay.plane = FLOAT_PLANE
|
||||
underlays += can_underlay
|
||||
|
||||
|
||||
/obj/item/grenade/iedcasing/attack_self(mob/user) //
|
||||
if(!active)
|
||||
if(clown_check(user))
|
||||
to_chat(user, "<span class='warning'>You light the [name]!</span>")
|
||||
cut_overlay("improvised_grenade_filled")
|
||||
//improvised explosives//
|
||||
|
||||
/obj/item/grenade/iedcasing
|
||||
name = "improvised firebomb"
|
||||
desc = "A weak, improvised incendiary device."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "improvised_grenade"
|
||||
item_state = "flashbang"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
active = 0
|
||||
det_time = 50
|
||||
display_timer = 0
|
||||
var/range = 3
|
||||
var/list/times
|
||||
|
||||
/obj/item/grenade/iedcasing/Initialize()
|
||||
. = ..()
|
||||
add_overlay("improvised_grenade_filled")
|
||||
add_overlay("improvised_grenade_wired")
|
||||
times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value]
|
||||
det_time = text2num(pickweight(times))
|
||||
if(det_time < 0) //checking for 'duds'
|
||||
range = 1
|
||||
det_time = rand(30,80)
|
||||
else
|
||||
range = pick(2,2,2,3,3,3,4)
|
||||
|
||||
/obj/item/grenade/iedcasing/CheckParts(list/parts_list)
|
||||
..()
|
||||
var/obj/item/reagent_containers/food/drinks/soda_cans/can = locate() in contents
|
||||
if(can)
|
||||
can.pixel_x = 0 //Reset the sprite's position to make it consistent with the rest of the IED
|
||||
can.pixel_y = 0
|
||||
var/mutable_appearance/can_underlay = new(can)
|
||||
can_underlay.layer = FLOAT_LAYER
|
||||
can_underlay.plane = FLOAT_PLANE
|
||||
underlays += can_underlay
|
||||
|
||||
|
||||
/obj/item/grenade/iedcasing/attack_self(mob/user) //
|
||||
if(!active)
|
||||
if(clown_check(user))
|
||||
to_chat(user, "<span class='warning'>You light the [name]!</span>")
|
||||
cut_overlay("improvised_grenade_filled")
|
||||
preprime(user, null, FALSE)
|
||||
|
||||
/obj/item/grenade/iedcasing/prime() //Blowing that can up
|
||||
update_mob()
|
||||
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/iedcasing/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "You can't tell when it will explode!")
|
||||
|
||||
/obj/item/grenade/iedcasing/prime() //Blowing that can up
|
||||
update_mob()
|
||||
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/iedcasing/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "You can't tell when it will explode!")
|
||||
|
||||
@@ -1,108 +1,119 @@
|
||||
/obj/item/grenade
|
||||
name = "grenade"
|
||||
desc = "It has an adjustable timer."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "grenade"
|
||||
item_state = "flashbang"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = SLOT_BELT
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 40
|
||||
var/active = 0
|
||||
var/det_time = 50
|
||||
var/display_timer = 1
|
||||
|
||||
/obj/item/grenade/deconstruct(disassembled = TRUE)
|
||||
if(!disassembled)
|
||||
prime()
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
|
||||
if(user.disabilities & CLUMSY && prob(50))
|
||||
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
|
||||
/obj/item/grenade
|
||||
name = "grenade"
|
||||
desc = "It has an adjustable timer."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "grenade"
|
||||
item_state = "flashbang"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 40
|
||||
var/active = 0
|
||||
var/det_time = 50
|
||||
var/display_timer = 1
|
||||
var/clumsy_check = GRENADE_CLUMSY_FUMBLE
|
||||
|
||||
/obj/item/grenade/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] primes [src], then eats it! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/items/eatfood.ogg', 50, 1)
|
||||
preprime(user, det_time)
|
||||
user.transferItemToLoc(src, user, TRUE)//>eat a grenade set to 5 seconds >rush captain
|
||||
sleep(det_time)//so you dont die instantly
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/grenade/deconstruct(disassembled = TRUE)
|
||||
if(!disassembled)
|
||||
prime()
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
|
||||
var/clumsy = user.has_trait(TRAIT_CLUMSY)
|
||||
if(clumsy && (clumsy_check == GRENADE_CLUMSY_FUMBLE))
|
||||
if(prob(50))
|
||||
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
|
||||
preprime(user, 5, FALSE)
|
||||
return FALSE
|
||||
else if(!clumsy && (clumsy_check == GRENADE_NONCLUMSY_FUMBLE))
|
||||
to_chat(user, "<span class='warning'>You pull the pin on [src]. Attached to it is a pink ribbon that says, \"<span class='clown'>HONK</span>\"</span>")
|
||||
preprime(user, 5, FALSE)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/grenade/examine(mob/user)
|
||||
..()
|
||||
if(display_timer)
|
||||
if(det_time > 1)
|
||||
to_chat(user, "The timer is set to [det_time/10] second\s.")
|
||||
else
|
||||
to_chat(user, "\The [src] is set for instant detonation.")
|
||||
|
||||
|
||||
/obj/item/grenade/attack_self(mob/user)
|
||||
if(!active)
|
||||
if(clown_check(user))
|
||||
preprime(user)
|
||||
|
||||
|
||||
|
||||
/obj/item/grenade/examine(mob/user)
|
||||
..()
|
||||
if(display_timer)
|
||||
if(det_time > 1)
|
||||
to_chat(user, "The timer is set to [DisplayTimeText(det_time)].")
|
||||
else
|
||||
to_chat(user, "\The [src] is set for instant detonation.")
|
||||
|
||||
|
||||
/obj/item/grenade/attack_self(mob/user)
|
||||
if(!active)
|
||||
if(clown_check(user))
|
||||
preprime(user)
|
||||
|
||||
/obj/item/grenade/proc/log_grenade(mob/user, turf/T)
|
||||
var/area/A = get_area(T)
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed \a [src] for detonation at [ADMIN_COORDJMP(T)]"
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed \a [src] for detonation at [ADMIN_VERBOSEJMP(T)]"
|
||||
GLOB.bombers += message
|
||||
message_admins(message)
|
||||
log_game("[key_name(user)] has primed \a [src] for detonation at [A.name] [COORD(T)].")
|
||||
log_game("[key_name(user)] has primed \a [src] for detonation at [AREACOORD(T)].")
|
||||
|
||||
/obj/item/grenade/proc/preprime(mob/user, delayoverride, msg = TRUE)
|
||||
/obj/item/grenade/proc/preprime(mob/user, delayoverride, msg = TRUE, volume = 60)
|
||||
var/turf/T = get_turf(src)
|
||||
log_grenade(user, T)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.throw_mode_on()
|
||||
if(msg)
|
||||
to_chat(user, "<span class='warning'>You prime \the [src]! [det_time/10] seconds!</span>")
|
||||
playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1)
|
||||
active = TRUE
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
add_fingerprint(user)
|
||||
log_grenade(user, T) //Inbuilt admin procs already handle null users
|
||||
if(user)
|
||||
add_fingerprint(user)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.throw_mode_on()
|
||||
if(msg)
|
||||
to_chat(user, "<span class='warning'>You prime [src]! [DisplayTimeText(det_time)]!</span>")
|
||||
playsound(src, 'sound/weapons/armbomb.ogg', volume, 1)
|
||||
active = TRUE
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
addtimer(CALLBACK(src, .proc/prime), isnull(delayoverride)? det_time : delayoverride)
|
||||
|
||||
/obj/item/grenade/proc/prime()
|
||||
|
||||
/obj/item/grenade/proc/update_mob()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.dropItemToGround(src)
|
||||
|
||||
|
||||
/obj/item/grenade/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
switch(det_time)
|
||||
if ("1")
|
||||
det_time = 10
|
||||
to_chat(user, "<span class='notice'>You set the [name] for 1 second detonation time.</span>")
|
||||
if ("10")
|
||||
det_time = 30
|
||||
to_chat(user, "<span class='notice'>You set the [name] for 3 second detonation time.</span>")
|
||||
if ("30")
|
||||
det_time = 50
|
||||
to_chat(user, "<span class='notice'>You set the [name] for 5 second detonation time.</span>")
|
||||
if ("50")
|
||||
det_time = 1
|
||||
to_chat(user, "<span class='notice'>You set the [name] for instant detonation.</span>")
|
||||
add_fingerprint(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/attack_hand()
|
||||
walk(src, null, null)
|
||||
..()
|
||||
|
||||
/obj/item/grenade/attack_paw(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/item/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
var/obj/item/projectile/P = hitby
|
||||
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
|
||||
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
|
||||
prime()
|
||||
|
||||
/obj/item/grenade/proc/prime()
|
||||
|
||||
/obj/item/grenade/proc/update_mob()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.dropItemToGround(src)
|
||||
|
||||
|
||||
/obj/item/grenade/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
switch(det_time)
|
||||
if ("1")
|
||||
det_time = 10
|
||||
to_chat(user, "<span class='notice'>You set the [name] for 1 second detonation time.</span>")
|
||||
if ("10")
|
||||
det_time = 30
|
||||
to_chat(user, "<span class='notice'>You set the [name] for 3 second detonation time.</span>")
|
||||
if ("30")
|
||||
det_time = 50
|
||||
to_chat(user, "<span class='notice'>You set the [name] for 5 second detonation time.</span>")
|
||||
if ("50")
|
||||
det_time = 1
|
||||
to_chat(user, "<span class='notice'>You set the [name] for instant detonation.</span>")
|
||||
add_fingerprint(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/attack_paw(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/item/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
var/obj/item/projectile/P = hitby
|
||||
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
|
||||
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
|
||||
prime()
|
||||
return TRUE //It hit the grenade, not them
|
||||
|
||||
@@ -2,22 +2,30 @@
|
||||
name = "plastic explosive"
|
||||
desc = "Used to put holes in specific areas without too much extra hole."
|
||||
icon_state = "plastic-explosive0"
|
||||
item_state = "plasticx"
|
||||
item_state = "plastic-explosive"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/bombs_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/bombs_righthand.dmi'
|
||||
flags_1 = NOBLUDGEON_1
|
||||
flags_2 = NO_EMP_WIRES_2
|
||||
det_time = 10
|
||||
display_timer = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/atom/target = null
|
||||
var/mutable_appearance/plastic_overlay
|
||||
var/obj/item/device/assembly_holder/nadeassembly = null
|
||||
var/obj/item/assembly_holder/nadeassembly = null
|
||||
var/assemblyattacher
|
||||
var/directional = FALSE
|
||||
var/aim_dir = NORTH
|
||||
var/boom_sizes = list(0, 0, 3)
|
||||
var/can_attach_mob = FALSE
|
||||
var/full_damage_on_mobs = FALSE
|
||||
|
||||
/obj/item/grenade/plastic/New()
|
||||
plastic_overlay = mutable_appearance(icon, "[item_state]2")
|
||||
..()
|
||||
/obj/item/grenade/plastic/Initialize()
|
||||
. = ..()
|
||||
plastic_overlay = mutable_appearance(icon, "[item_state]2", HIGH_OBJ_LAYER)
|
||||
|
||||
/obj/item/grenade/plastic/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/item/grenade/plastic/Destroy()
|
||||
qdel(nadeassembly)
|
||||
@@ -26,8 +34,8 @@
|
||||
..()
|
||||
|
||||
/obj/item/grenade/plastic/attackby(obj/item/I, mob/user, params)
|
||||
if(!nadeassembly && istype(I, /obj/item/device/assembly_holder))
|
||||
var/obj/item/device/assembly_holder/A = I
|
||||
if(!nadeassembly && istype(I, /obj/item/assembly_holder))
|
||||
var/obj/item/assembly_holder/A = I
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
return ..()
|
||||
nadeassembly = A
|
||||
@@ -38,7 +46,7 @@
|
||||
update_icon()
|
||||
return
|
||||
if(nadeassembly && istype(I, /obj/item/wirecutters))
|
||||
playsound(src, I.usesound, 20, 1)
|
||||
I.play_tool_sound(src, 20)
|
||||
nadeassembly.forceMove(get_turf(src))
|
||||
nadeassembly.master = null
|
||||
nadeassembly = null
|
||||
@@ -52,6 +60,8 @@
|
||||
if(!QDELETED(target))
|
||||
location = get_turf(target)
|
||||
target.cut_overlay(plastic_overlay, TRUE)
|
||||
if(!ismob(target) || full_damage_on_mobs)
|
||||
target.ex_act(2, target)
|
||||
else
|
||||
location = get_turf(src)
|
||||
if(location)
|
||||
@@ -60,7 +70,6 @@
|
||||
explosion(get_step(T, aim_dir), boom_sizes[1], boom_sizes[2], boom_sizes[3])
|
||||
else
|
||||
explosion(location, boom_sizes[1], boom_sizes[2], boom_sizes[3])
|
||||
location.ex_act(2, target)
|
||||
if(ismob(target))
|
||||
var/mob/M = target
|
||||
M.gib()
|
||||
@@ -84,7 +93,7 @@
|
||||
return
|
||||
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
|
||||
if(user.get_active_held_item() == src)
|
||||
newtime = Clamp(newtime, 10, 60000)
|
||||
newtime = CLAMP(newtime, 10, 60000)
|
||||
det_time = newtime
|
||||
to_chat(user, "Timer set for [det_time] seconds.")
|
||||
|
||||
@@ -92,50 +101,57 @@
|
||||
aim_dir = get_dir(user,AM)
|
||||
if(!flag)
|
||||
return
|
||||
if(ismob(AM))
|
||||
if(ismob(AM) && !can_attach_mob)
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You start planting the [src]. The timer is set to [det_time]...</span>")
|
||||
to_chat(user, "<span class='notice'>You start planting [src]. The timer is set to [det_time]...</span>")
|
||||
|
||||
if(do_after(user, 30, target = AM))
|
||||
if(!user.temporarilyRemoveItemFromInventory(src))
|
||||
return
|
||||
src.target = AM
|
||||
forceMove(null) //Yep
|
||||
target = AM
|
||||
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at [ADMIN_VERBOSEJMP(target)] with [det_time] second fuse")
|
||||
log_game("[key_name(user)] planted [name] on [target.name] at [AREACOORD(user)] with [det_time] second fuse")
|
||||
|
||||
moveToNullspace() //Yep
|
||||
|
||||
if(istype(AM, /obj/item)) //your crappy throwing star can't fly so good with a giant brick of c4 on it.
|
||||
var/obj/item/I = AM
|
||||
I.throw_speed = max(1, (I.throw_speed - 3))
|
||||
I.throw_range = max(1, (I.throw_range - 3))
|
||||
I.embed_chance = 0
|
||||
I.embedding = I.embedding.setRating(embed_chance = 0)
|
||||
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at [ADMIN_COORDJMP(target)] with [det_time] second fuse",0,1)
|
||||
log_game("[key_name(user)] planted [name] on [target.name] at [COORD(src)] with [det_time] second fuse")
|
||||
|
||||
target.add_overlay(plastic_overlay, 1)
|
||||
target.add_overlay(plastic_overlay, TRUE)
|
||||
if(!nadeassembly)
|
||||
to_chat(user, "<span class='notice'>You plant the bomb. Timer counting down from [det_time].</span>")
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time*10)
|
||||
else
|
||||
qdel(src) //How?
|
||||
|
||||
/obj/item/grenade/plastic/suicide_act(mob/user)
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [src] at [ADMIN_COORDJMP(user)]",0,1)
|
||||
log_game("[key_name(user)] suicided with [src] at [COORD(user)]")
|
||||
user.visible_message("<span class='suicide'>[user] activates the [src] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!</span>")
|
||||
/obj/item/grenade/plastic/proc/shout_syndicate_crap(mob/M)
|
||||
if(!M)
|
||||
return
|
||||
var/message_say = "FOR NO RAISIN!"
|
||||
if(user.mind)
|
||||
if(user.mind.special_role)
|
||||
var/role = lowertext(user.mind.special_role)
|
||||
if(role == "traitor" || role == "syndicate")
|
||||
message_say = "FOR THE SYNDICATE!"
|
||||
else if(role == "changeling")
|
||||
message_say = "FOR THE HIVE!"
|
||||
else if(role == "cultist")
|
||||
message_say = "FOR NAR-SIE!"
|
||||
else if(role == "revolutionary" || role == "head revolutionary")
|
||||
message_say = "VIVA LA REVOLUTION!"
|
||||
user.say(message_say)
|
||||
if(M.mind)
|
||||
var/datum/mind/UM = M
|
||||
if(UM.has_antag_datum(/datum/antagonist/nukeop) || UM.has_antag_datum(/datum/antagonist/traitor))
|
||||
message_say = "FOR THE SYNDICATE!"
|
||||
else if(UM.has_antag_datum(/datum/antagonist/changeling))
|
||||
message_say = "FOR THE HIVE!"
|
||||
else if(UM.has_antag_datum(/datum/antagonist/cult))
|
||||
message_say = "FOR NAR-SIE!"
|
||||
else if(UM.has_antag_datum(/datum/antagonist/clockcult))
|
||||
message_say = "FOR RATVAR!"
|
||||
else if(UM.has_antag_datum(/datum/antagonist/rev))
|
||||
message_say = "VIVA LA REVOLUTION!"
|
||||
M.say(message_say)
|
||||
|
||||
/obj/item/grenade/plastic/suicide_act(mob/user)
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [src] at [ADMIN_VERBOSEJMP(user)]")
|
||||
log_game("[key_name(user)] suicided with [src] at [AREACOORD(user)]")
|
||||
user.visible_message("<span class='suicide'>[user] activates [src] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!</span>")
|
||||
shout_syndicate_crap(user)
|
||||
explosion(user,0,2,0) //Cheap explosion imitation because putting prime() here causes runtimes
|
||||
user.gib(1, 1)
|
||||
qdel(src)
|
||||
@@ -154,21 +170,13 @@
|
||||
name = "C4"
|
||||
desc = "Used to put holes in specific areas without too much extra hole. A saboteur's favorite."
|
||||
gender = PLURAL
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "plastic-explosive0"
|
||||
item_state = "plasticx"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/bombs_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/bombs_righthand.dmi'
|
||||
flags_1 = NOBLUDGEON_1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "syndicate=1"
|
||||
var/timer = 10
|
||||
var/open_panel = 0
|
||||
can_attach_mob = TRUE
|
||||
|
||||
/obj/item/grenade/plastic/c4/New()
|
||||
wires = new /datum/wires/explosive/c4(src)
|
||||
..()
|
||||
plastic_overlay = mutable_appearance(icon, "plastic-explosive2")
|
||||
|
||||
/obj/item/grenade/plastic/c4/Destroy()
|
||||
qdel(wires)
|
||||
@@ -178,22 +186,10 @@
|
||||
|
||||
/obj/item/grenade/plastic/c4/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] activates the [src.name] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!</span>")
|
||||
var/message_say = "FOR NO RAISIN!"
|
||||
if(user.mind)
|
||||
if(user.mind.special_role)
|
||||
var/role = lowertext(user.mind.special_role)
|
||||
if(role == "traitor" || role == "syndicate")
|
||||
message_say = "FOR THE SYNDICATE!"
|
||||
else if(role == "changeling")
|
||||
message_say = "FOR THE HIVE!"
|
||||
else if(role == "cultist")
|
||||
message_say = "FOR NAR-SIE!"
|
||||
else if(role == "revolutionary" || role == "head revolutionary")
|
||||
message_say = "VIVA LA REVOLUTION!"
|
||||
user.say(message_say)
|
||||
shout_syndicate_crap(user)
|
||||
target = user
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [name] at [ADMIN_COORDJMP(src)]",0,1)
|
||||
message_admins("[key_name(user)] suicided with [name] at ([x],[y],[z])")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [name] at [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("[key_name(user)] suicided with [name] at [AREACOORD(user)]")
|
||||
sleep(10)
|
||||
explode(get_turf(user))
|
||||
user.gib(1, 1)
|
||||
@@ -210,23 +206,19 @@
|
||||
/obj/item/grenade/plastic/c4/attack_self(mob/user)
|
||||
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
|
||||
if(user.get_active_held_item() == src)
|
||||
newtime = Clamp(newtime, 10, 60000)
|
||||
newtime = CLAMP(newtime, 10, 60000)
|
||||
timer = newtime
|
||||
to_chat(user, "Timer set for [timer] seconds.")
|
||||
|
||||
/obj/item/grenade/plastic/c4/afterattack(atom/movable/AM, mob/user, flag)
|
||||
if (!flag)
|
||||
return
|
||||
if (ismob(AM))
|
||||
if(ismob(AM) && !can_attach_mob)
|
||||
return
|
||||
if(loc == AM)
|
||||
return
|
||||
if((istype(AM, /obj/item/storage/)) && !((istype(AM, /obj/item/storage/secure)) || (istype(AM, /obj/item/storage/lockbox)))) //If its storage but not secure storage OR a lockbox, then place it inside.
|
||||
if(AM.SendSignal(COMSIG_CONTAINS_STORAGE) && !AM.SendSignal(COMSIG_IS_STORAGE_LOCKED))
|
||||
return
|
||||
if((istype(AM, /obj/item/storage/secure)) || (istype(AM, /obj/item/storage/lockbox)))
|
||||
var/obj/item/storage/secure/S = AM
|
||||
if(!S.locked) //Literal hacks, this works for lockboxes despite incorrect type casting, because they both share the locked var. But if its unlocked, place it inside, otherwise PLANTING C4!
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You start planting the bomb...</span>")
|
||||
|
||||
@@ -234,14 +226,14 @@
|
||||
if(!user.temporarilyRemoveItemFromInventory(src))
|
||||
return
|
||||
src.target = AM
|
||||
forceMove(null)
|
||||
moveToNullspace()
|
||||
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at [ADMIN_COORDJMP(target)] with [timer] second fuse"
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at [ADMIN_VERBOSEJMP(target)] with [timer] second fuse"
|
||||
GLOB.bombers += message
|
||||
message_admins(message,0,1)
|
||||
log_game("[key_name(user)] planted [name] on [target.name] at [COORD(target)] with [timer] second fuse")
|
||||
log_game("[key_name(user)] planted [name] on [target.name] at [AREACOORD(target)] with [timer] second fuse")
|
||||
|
||||
target.add_overlay(plastic_overlay, 1)
|
||||
target.add_overlay(plastic_overlay, TRUE)
|
||||
to_chat(user, "<span class='notice'>You plant the bomb. Timer counting down from [timer].</span>")
|
||||
addtimer(CALLBACK(src, .proc/explode), timer * 10)
|
||||
|
||||
@@ -253,10 +245,11 @@
|
||||
if(!QDELETED(target))
|
||||
location = get_turf(target)
|
||||
target.cut_overlay(plastic_overlay, TRUE)
|
||||
if(!ismob(target) || full_damage_on_mobs)
|
||||
target.ex_act(2, target)
|
||||
else
|
||||
location = get_turf(src)
|
||||
if(location)
|
||||
location.ex_act(2, target)
|
||||
explosion(location,0,0,3)
|
||||
qdel(src)
|
||||
|
||||
@@ -272,5 +265,6 @@
|
||||
desc = "A shaped high-explosive breaching charge. Designed to ensure user safety and wall nonsafety."
|
||||
icon_state = "plasticx40"
|
||||
item_state = "plasticx4"
|
||||
gender = PLURAL
|
||||
directional = TRUE
|
||||
boom_sizes = list(0, 2, 5)
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
/obj/item/grenade/smokebomb
|
||||
name = "smoke grenade"
|
||||
desc = "The word 'Dank' is scribbled on it in crayon."
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "smokewhite"
|
||||
det_time = 20
|
||||
item_state = "flashbang"
|
||||
slot_flags = SLOT_BELT
|
||||
var/datum/effect_system/smoke_spread/bad/smoke
|
||||
|
||||
/obj/item/grenade/smokebomb/New()
|
||||
..()
|
||||
src.smoke = new /datum/effect_system/smoke_spread/bad
|
||||
src.smoke.attach(src)
|
||||
|
||||
/obj/item/grenade/smokebomb/Destroy()
|
||||
qdel(smoke)
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/smokebomb/prime()
|
||||
update_mob()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.set_up(4, src)
|
||||
smoke.start()
|
||||
|
||||
|
||||
for(var/obj/structure/blob/B in view(8,src))
|
||||
var/damage = round(30/(get_dist(B,src)+1))
|
||||
B.take_damage(damage, BURN, "melee", 0)
|
||||
sleep(80)
|
||||
qdel(src)
|
||||
/obj/item/grenade/smokebomb
|
||||
name = "smoke grenade"
|
||||
desc = "The word 'Dank' is scribbled on it in crayon."
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "smokewhite"
|
||||
det_time = 20
|
||||
item_state = "flashbang"
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
var/datum/effect_system/smoke_spread/bad/smoke
|
||||
|
||||
/obj/item/grenade/smokebomb/New()
|
||||
..()
|
||||
src.smoke = new /datum/effect_system/smoke_spread/bad
|
||||
src.smoke.attach(src)
|
||||
|
||||
/obj/item/grenade/smokebomb/Destroy()
|
||||
qdel(smoke)
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/smokebomb/prime()
|
||||
update_mob()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.set_up(4, src)
|
||||
smoke.start()
|
||||
|
||||
|
||||
for(var/obj/structure/blob/B in view(8,src))
|
||||
var/damage = round(30/(get_dist(B,src)+1))
|
||||
B.take_damage(damage, BURN, "melee", 0)
|
||||
sleep(80)
|
||||
qdel(src)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "delivery"
|
||||
item_state = "flashbang"
|
||||
origin_tech = "materials=3;magnets=4"
|
||||
var/spawner_type = null // must be an object path
|
||||
var/deliveryamt = 1 // amount of type to deliver
|
||||
|
||||
@@ -18,7 +17,7 @@
|
||||
C.flash_act()
|
||||
|
||||
// Spawn some hostile syndicate critters and spread them out
|
||||
spawn_and_random_walk(spawner_type, T, deliveryamt, walk_chance=50, admin_spawn=admin_spawned)
|
||||
spawn_and_random_walk(spawner_type, T, deliveryamt, walk_chance=50, admin_spawn=((flags_1 & ADMIN_SPAWNED_1) ? TRUE : FALSE))
|
||||
|
||||
qdel(src)
|
||||
|
||||
@@ -26,13 +25,11 @@
|
||||
name = "viscerator delivery grenade"
|
||||
spawner_type = /mob/living/simple_animal/hostile/viscerator
|
||||
deliveryamt = 10
|
||||
origin_tech = "materials=3;magnets=4;syndicate=3"
|
||||
|
||||
/obj/item/grenade/spawnergrenade/spesscarp
|
||||
name = "carp delivery grenade"
|
||||
spawner_type = /mob/living/simple_animal/hostile/carp
|
||||
deliveryamt = 5
|
||||
origin_tech = "materials=3;magnets=4;syndicate=3"
|
||||
|
||||
/obj/item/grenade/spawnergrenade/syndiesoap
|
||||
name = "Mister Scrubby"
|
||||
|
||||
@@ -1,53 +1,50 @@
|
||||
/obj/item/grenade/syndieminibomb
|
||||
desc = "A syndicate manufactured explosive used to sow destruction and chaos"
|
||||
name = "syndicate minibomb"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "syndicate"
|
||||
item_state = "flashbang"
|
||||
origin_tech = "materials=3;magnets=4;syndicate=3"
|
||||
|
||||
|
||||
/obj/item/grenade/syndieminibomb/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,1,2,4,flame_range = 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion
|
||||
name = "HE Grenade"
|
||||
desc = "A compact shrapnel grenade meant to devestate nearby organisms and cause some damage in the process. Pull pin and throw opposite direction."
|
||||
icon_state = "concussion"
|
||||
origin_tech = "materials=3;magnets=4;syndicate=2"
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,0,2,3,flame_range = 3)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion/frag
|
||||
name = "frag grenade"
|
||||
desc = "Fire in the hole."
|
||||
icon_state = "frag"
|
||||
|
||||
/obj/item/grenade/gluon
|
||||
desc = "An advanced grenade that releases a harmful stream of gluons inducing radiation in those nearby. These gluon streams will also make victims feel exhausted, and induce shivering. This extreme coldness will also likely wet any nearby floors."
|
||||
name = "gluon frag grenade"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "bluefrag"
|
||||
item_state = "flashbang"
|
||||
var/freeze_range = 4
|
||||
var/rad_damage = 35
|
||||
var/stamina_damage = 30
|
||||
|
||||
/obj/item/grenade/gluon/prime()
|
||||
update_mob()
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
|
||||
radiation_pulse(loc,freeze_range,freeze_range+1,rad_damage)
|
||||
for(var/turf/T in view(freeze_range,loc))
|
||||
if(isfloorturf(T))
|
||||
var/turf/open/floor/F = T
|
||||
F.wet = TURF_WET_PERMAFROST
|
||||
addtimer(CALLBACK(F, /turf/open/floor.proc/MakeDry, TURF_WET_PERMAFROST), rand(3000, 3100))
|
||||
for(var/mob/living/carbon/L in T)
|
||||
L.adjustStaminaLoss(stamina_damage)
|
||||
L.bodytemperature -= 230
|
||||
qdel(src)
|
||||
/obj/item/grenade/syndieminibomb
|
||||
desc = "A syndicate manufactured explosive used to sow destruction and chaos."
|
||||
name = "syndicate minibomb"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "syndicate"
|
||||
item_state = "flashbang"
|
||||
|
||||
|
||||
/obj/item/grenade/syndieminibomb/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,1,2,4,flame_range = 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion
|
||||
name = "HE Grenade"
|
||||
desc = "A compact shrapnel grenade meant to devestate nearby organisms and cause some damage in the process. Pull pin and throw opposite direction."
|
||||
icon_state = "concussion"
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,0,2,3,flame_range = 3)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion/frag
|
||||
name = "frag grenade"
|
||||
desc = "Fire in the hole."
|
||||
icon_state = "frag"
|
||||
|
||||
/obj/item/grenade/gluon
|
||||
desc = "An advanced grenade that releases a harmful stream of gluons inducing radiation in those nearby. These gluon streams will also make victims feel exhausted, and induce shivering. This extreme coldness will also likely wet any nearby floors."
|
||||
name = "gluon frag grenade"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "bluefrag"
|
||||
item_state = "flashbang"
|
||||
var/freeze_range = 4
|
||||
var/rad_damage = 350
|
||||
var/stamina_damage = 30
|
||||
|
||||
/obj/item/grenade/gluon/prime()
|
||||
update_mob()
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
|
||||
radiation_pulse(src, rad_damage)
|
||||
for(var/turf/T in view(freeze_range,loc))
|
||||
if(isfloorturf(T))
|
||||
var/turf/open/floor/F = T
|
||||
F.MakeSlippery(TURF_WET_PERMAFROST, 6 MINUTES)
|
||||
for(var/mob/living/carbon/L in T)
|
||||
L.adjustStaminaLoss(stamina_damage)
|
||||
L.adjust_bodytemperature(-230)
|
||||
qdel(src)
|
||||
|
||||
Reference in New Issue
Block a user