mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Merge remote-tracking branch 'upstream/dev' into boolit
Conflicts: code/modules/projectiles/projectile.dm code/modules/projectiles/projectile/beams.dm
This commit is contained in:
@@ -1,45 +1,3 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
|
||||
/* new portable generator - work in progress
|
||||
|
||||
/obj/machinery/power/port_gen
|
||||
name = "portable generator"
|
||||
desc = "A portable generator used for emergency backup power."
|
||||
icon = 'generator.dmi'
|
||||
icon_state = "off"
|
||||
density = 1
|
||||
anchored = 0
|
||||
directwired = 0
|
||||
var/t_status = 0
|
||||
var/t_per = 5000
|
||||
var/filter = 1
|
||||
var/tank = null
|
||||
var/turf/inturf
|
||||
var/starter = 0
|
||||
var/rpm = 0
|
||||
var/rpmtarget = 0
|
||||
var/capacity = 1e6
|
||||
var/turf/outturf
|
||||
var/lastgen
|
||||
|
||||
|
||||
/obj/machinery/power/port_gen/process()
|
||||
ideally we're looking to generate 5000
|
||||
|
||||
/obj/machinery/power/port_gen/attackby(obj/item/weapon/W, mob/user)
|
||||
tank [un]loading stuff
|
||||
|
||||
/obj/machinery/power/port_gen/attack_hand(mob/user)
|
||||
turn on/off
|
||||
|
||||
/obj/machinery/power/port_gen/examine(mob/user)
|
||||
display round(lastgen) and phorontank amount
|
||||
|
||||
*/
|
||||
|
||||
//Previous code been here forever, adding new framework for portable generators
|
||||
|
||||
|
||||
//Baseline portable generator. Has all the default handling. Not intended to be used on it's own (since it generates unlimited power).
|
||||
/obj/machinery/power/port_gen
|
||||
name = "Placeholder Generator" //seriously, don't use this. It can't be anchored without VV magic.
|
||||
@@ -56,6 +14,9 @@ display round(lastgen) and phorontank amount
|
||||
var/recent_fault = 0
|
||||
var/power_output = 1
|
||||
|
||||
/obj/machinery/power/port_gen/proc/IsBroken()
|
||||
return (crit_fail || (stat & BROKEN|EMPED))
|
||||
|
||||
/obj/machinery/power/port_gen/proc/HasFuel() //Placeholder for fuel check.
|
||||
return 1
|
||||
|
||||
@@ -69,11 +30,10 @@ display round(lastgen) and phorontank amount
|
||||
return
|
||||
|
||||
/obj/machinery/power/port_gen/process()
|
||||
if(active && HasFuel() && !crit_fail && anchored && powernet)
|
||||
if(active && HasFuel() && !IsBroken() && anchored && powernet)
|
||||
add_avail(power_gen * power_output)
|
||||
UseFuel()
|
||||
src.updateDialog()
|
||||
|
||||
else
|
||||
active = 0
|
||||
icon_state = initial(icon_state)
|
||||
@@ -96,20 +56,57 @@ display round(lastgen) and phorontank amount
|
||||
else
|
||||
usr << "\blue The generator is off."
|
||||
|
||||
/obj/machinery/power/port_gen/emp_act(severity)
|
||||
var/duration = 6000 //ten minutes
|
||||
switch(severity)
|
||||
if(1)
|
||||
stat &= BROKEN
|
||||
if(prob(75)) explode()
|
||||
if(2)
|
||||
if(prob(25)) stat &= BROKEN
|
||||
if(prob(10)) explode()
|
||||
if(3)
|
||||
if(prob(10)) stat &= BROKEN
|
||||
duration = 300
|
||||
|
||||
stat |= EMPED
|
||||
if(duration)
|
||||
spawn(duration)
|
||||
stat &= ~EMPED
|
||||
|
||||
/obj/machinery/power/port_gen/proc/explode()
|
||||
explosion(src.loc, -1, 3, 5, -1)
|
||||
del(src)
|
||||
|
||||
#define TEMPERATURE_DIVISOR 40
|
||||
#define TEMPERATURE_CHANGE_MAX 20
|
||||
|
||||
//A power generator that runs on solid plasma sheets.
|
||||
/obj/machinery/power/port_gen/pacman
|
||||
name = "P.A.C.M.A.N.-type Portable Generator"
|
||||
var/sheets = 0
|
||||
var/max_sheets = 100
|
||||
var/sheet_name = ""
|
||||
var/sheet_path = /obj/item/stack/sheet/mineral/phoron
|
||||
var/board_path = "/obj/item/weapon/circuitboard/pacman"
|
||||
var/sheet_left = 0 // How much is left of the sheet
|
||||
var/heat = 0
|
||||
name = "\improper P.A.C.M.A.N.-type Portable Generator"
|
||||
desc = "A power generator that runs on solid plasma sheets. Rated for 80 kW max safe output."
|
||||
|
||||
//produces up to 80 kW and lasts for 20 minutes with 50 sheets
|
||||
var/time_per_sheet = 96
|
||||
power_gen = 20000
|
||||
var/sheet_name = "solid plasma sheet"
|
||||
var/sheet_path = /obj/item/stack/sheet/mineral/phoron
|
||||
var/board_path = "/obj/item/weapon/circuitboard/pacman"
|
||||
|
||||
/*
|
||||
These values were chosen so that the generator can run safely up to 80 kW
|
||||
A full 50 phoron sheet stack should last 20 minutes at power_output = 4
|
||||
temperature_gain and max_temperature are set so that the max safe power level is 4.
|
||||
Setting to 5 or higher can only be done temporarily before the generator overheats.
|
||||
*/
|
||||
power_gen = 20000 //Watts output per power_output level
|
||||
var/max_power_output = 5 //The maximum power setting without emagging.
|
||||
var/time_per_sheet = 96 //fuel efficiency - how long 1 sheet lasts at power level 1
|
||||
var/max_sheets = 100 //max capacity of the hopper
|
||||
var/max_temperature = 300 //max temperature before overheating increases
|
||||
var/temperature_gain = 50 //how much the temperature increases per power output level, in degrees per level
|
||||
|
||||
var/sheets = 0 //How many sheets of material are loaded in the generator
|
||||
var/sheet_left = 0 //How much is left of the current sheet
|
||||
var/temperature = 0 //The current temperature
|
||||
var/overheating = 0 //if this gets high enough the generator explodes
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/initialize()
|
||||
..()
|
||||
@@ -135,76 +132,127 @@ display round(lastgen) and phorontank amount
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/RefreshParts()
|
||||
var/temp_rating = 0
|
||||
var/temp_reliability = 0
|
||||
for(var/obj/item/weapon/stock_parts/SP in component_parts)
|
||||
if(istype(SP, /obj/item/weapon/stock_parts/matter_bin))
|
||||
max_sheets = SP.rating * SP.rating * 50
|
||||
else if(istype(SP, /obj/item/weapon/stock_parts/micro_laser) || istype(SP, /obj/item/weapon/stock_parts/capacitor))
|
||||
temp_rating += SP.rating
|
||||
|
||||
var/temp_reliability = 0
|
||||
var/part_count = 0
|
||||
for(var/obj/item/weapon/CP in component_parts)
|
||||
temp_reliability += CP.reliability
|
||||
reliability = min(round(temp_reliability / 4), 100)
|
||||
part_count++
|
||||
|
||||
reliability = min(round(temp_reliability / part_count), 100)
|
||||
power_gen = round(initial(power_gen) * (max(2, temp_rating) / 2))
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/examine(mob/user)
|
||||
..(user)
|
||||
user << "\blue The generator has [sheets] units of [sheet_name] fuel left, producing [power_gen] per cycle."
|
||||
if(crit_fail) user << "\red The generator seems to have broken down."
|
||||
user << "\The [src] appears to be producing [power_gen*power_output] W."
|
||||
user << "There are [sheets] [sheet_name]\s left in the hopper."
|
||||
if(IsBroken()) user << "<span class='warning'>\The [src] seems to have broken down.</span>"
|
||||
if(overheating) user << "<span class='danger'>\The [src] is overheating!</span>"
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/HasFuel()
|
||||
if(sheets >= 1 / (time_per_sheet / power_output) - sheet_left)
|
||||
var/needed_sheets = power_output / time_per_sheet
|
||||
if(sheets >= needed_sheets - sheet_left)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Removes one stack's worth of material from the generator.
|
||||
/obj/machinery/power/port_gen/pacman/DropFuel()
|
||||
if(sheets)
|
||||
var/fail_safe = 0
|
||||
while(sheets > 0 && fail_safe < 100)
|
||||
fail_safe += 1
|
||||
var/obj/item/stack/sheet/S = new sheet_path(loc)
|
||||
var/amount = min(sheets, S.max_amount)
|
||||
S.amount = amount
|
||||
sheets -= amount
|
||||
var/obj/item/stack/sheet/S = new sheet_path(loc)
|
||||
var/amount = min(sheets, S.max_amount)
|
||||
S.amount = amount
|
||||
sheets -= amount
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/UseFuel()
|
||||
var/needed_sheets = 1 / (time_per_sheet / power_output)
|
||||
var/temp = min(needed_sheets, sheet_left)
|
||||
needed_sheets -= temp
|
||||
sheet_left -= temp
|
||||
sheets -= round(needed_sheets)
|
||||
needed_sheets -= round(needed_sheets)
|
||||
if (sheet_left <= 0 && sheets > 0)
|
||||
sheet_left = 1 - needed_sheets
|
||||
//break down sometimes
|
||||
if (reliability < 100)
|
||||
if (prob(1) && prob(1) && prob(100 - reliability))
|
||||
stat |= BROKEN
|
||||
crit_fail = 1
|
||||
if (prob(100 - reliability))
|
||||
explode()
|
||||
|
||||
//how much material are we using this iteration?
|
||||
var/needed_sheets = power_output / time_per_sheet
|
||||
|
||||
//HasFuel() should guarantee us that there is enough fuel left, so no need to check that
|
||||
//the only thing we need to worry about is if we are going to rollover to the next sheet
|
||||
if (needed_sheets > sheet_left)
|
||||
sheets--
|
||||
|
||||
var/lower_limit = 56 + power_output * 10
|
||||
var/upper_limit = 76 + power_output * 10
|
||||
var/bias = 0
|
||||
if (power_output > 4)
|
||||
upper_limit = 400
|
||||
bias = power_output * 3
|
||||
if (heat < lower_limit)
|
||||
heat += 3
|
||||
sheet_left = (1 + sheet_left) - needed_sheets
|
||||
else
|
||||
heat += rand(-7 + bias, 7 + bias)
|
||||
if (heat < lower_limit)
|
||||
heat = lower_limit
|
||||
if (heat > upper_limit)
|
||||
heat = upper_limit
|
||||
sheet_left -= needed_sheets
|
||||
|
||||
if (heat > 300)
|
||||
//calculate the "target" temperature range
|
||||
//This should probably depend on the external temperature somehow, but whatever.
|
||||
var/lower_limit = 56 + power_output * temperature_gain
|
||||
var/upper_limit = 76 + power_output * temperature_gain
|
||||
|
||||
/*
|
||||
Hot or cold environments can affect the equilibrium temperature
|
||||
The lower the pressure the less effect it has. I guess it cools using a radiator or something when in vacuum.
|
||||
Gives traitors more opportunities to sabotage the generator or allows enterprising engineers to build additional
|
||||
cooling in order to get more power out.
|
||||
*/
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if (environment)
|
||||
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
|
||||
var/ambient = environment.temperature - T20C
|
||||
lower_limit += ambient*ratio
|
||||
upper_limit += ambient*ratio
|
||||
|
||||
var/average = (upper_limit + lower_limit)/2
|
||||
|
||||
//calculate the temperature increase
|
||||
var/bias = 0
|
||||
if (temperature < lower_limit)
|
||||
bias = min(round((average - temperature)/TEMPERATURE_DIVISOR, 1), TEMPERATURE_CHANGE_MAX)
|
||||
else if (temperature > upper_limit)
|
||||
bias = max(round((temperature - average)/TEMPERATURE_DIVISOR, 1), -TEMPERATURE_CHANGE_MAX)
|
||||
|
||||
temperature += rand(-7 + bias, 7 + bias)
|
||||
|
||||
if (temperature > max_temperature)
|
||||
overheat()
|
||||
del(src)
|
||||
return
|
||||
else if (overheating > 0)
|
||||
overheating--
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/handleInactive()
|
||||
|
||||
if (heat > 0)
|
||||
heat = max(heat - 2, 0)
|
||||
var/cooling_temperature = 20
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if (environment)
|
||||
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
|
||||
var/ambient = environment.temperature - T20C
|
||||
cooling_temperature += ambient*ratio
|
||||
|
||||
if (temperature > cooling_temperature)
|
||||
var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR
|
||||
temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX)
|
||||
temperature = max(temperature - temp_loss, cooling_temperature)
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/proc/overheat()
|
||||
explosion(src.loc, 2, 5, 2, -1)
|
||||
overheating++
|
||||
if (overheating > 60)
|
||||
explode()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/explode()
|
||||
//Vapourize all the phoron
|
||||
//When ground up in a grinder, 1 sheet produces 20 u of phoron -- Chemistry-Machinery.dm
|
||||
//1 mol = 10 u? I dunno. 1 mol of carbon is definitely bigger than a pill
|
||||
var/phoron = (sheets+sheet_left)*20
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if (environment)
|
||||
environment.adjust_gas_temp("phoron", phoron/10, temperature + T0C)
|
||||
|
||||
sheets = 0
|
||||
sheet_left = 0
|
||||
..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(istype(O, sheet_path))
|
||||
@@ -213,16 +261,16 @@ display round(lastgen) and phorontank amount
|
||||
if(amount < 1)
|
||||
user << "\blue The [src.name] is full!"
|
||||
return
|
||||
user << "\blue You add [amount] sheets to the [src.name]."
|
||||
user << "\blue You add [amount] [addstack.singular_name]\s to the [src.name]."
|
||||
sheets += amount
|
||||
addstack.use(amount)
|
||||
updateUsrDialog()
|
||||
return
|
||||
else if (istype(O, /obj/item/weapon/card/emag))
|
||||
emagged = 1
|
||||
emp_act(1)
|
||||
if (active && prob(25))
|
||||
explode() //if they're foolish enough to emag while it's running
|
||||
else if(!active)
|
||||
|
||||
if(istype(O, /obj/item/weapon/wrench))
|
||||
|
||||
if(!anchored)
|
||||
@@ -245,18 +293,9 @@ display round(lastgen) and phorontank amount
|
||||
else if(istype(O, /obj/item/weapon/crowbar) && open)
|
||||
var/obj/machinery/constructable_frame/machine_frame/new_frame = new /obj/machinery/constructable_frame/machine_frame(src.loc)
|
||||
for(var/obj/item/I in component_parts)
|
||||
if(I.reliability < 100)
|
||||
I.crit_fail = 1
|
||||
I.loc = src.loc
|
||||
while ( sheets > 0 )
|
||||
var/obj/item/stack/sheet/G = new sheet_path(src.loc)
|
||||
|
||||
if ( sheets > 50 )
|
||||
G.amount = 50
|
||||
else
|
||||
G.amount = sheets
|
||||
|
||||
sheets -= G.amount
|
||||
DropFuel()
|
||||
|
||||
new_frame.state = 2
|
||||
new_frame.icon_state = "box_1"
|
||||
@@ -266,7 +305,6 @@ display round(lastgen) and phorontank amount
|
||||
..()
|
||||
if (!anchored)
|
||||
return
|
||||
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob)
|
||||
@@ -289,9 +327,11 @@ display round(lastgen) and phorontank amount
|
||||
dat += text("[capitalize(sheet_name)]: [sheets] - <A href='?src=\ref[src];action=eject'>Eject</A><br>")
|
||||
var/stack_percent = round(sheet_left * 100, 1)
|
||||
dat += text("Current stack: [stack_percent]% <br>")
|
||||
dat += text("Power output: <A href='?src=\ref[src];action=lower_power'>-</A> [power_gen * power_output] <A href='?src=\ref[src];action=higher_power'>+</A><br>")
|
||||
dat += text("Power output: <A href='?src=\ref[src];action=lower_power'>-</A> [power_gen * power_output] Watts<A href='?src=\ref[src];action=higher_power'>+</A><br>")
|
||||
dat += text("Power current: [(powernet == null ? "Unconnected" : "[avail()]")]<br>")
|
||||
dat += text("Heat: [heat]<br>")
|
||||
|
||||
var/tempstr = "Temperature: [temperature]°C<br>"
|
||||
dat += (overheating)? "<span class='danger'>[tempstr]</span>" : tempstr
|
||||
dat += "<br><A href='?src=\ref[src];action=close'>Close</A>"
|
||||
user << browse("[dat]", "window=port_gen")
|
||||
onclose(user, "port_gen")
|
||||
@@ -303,7 +343,7 @@ display round(lastgen) and phorontank amount
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["action"])
|
||||
if(href_list["action"] == "enable")
|
||||
if(!active && HasFuel() && !crit_fail)
|
||||
if(!active && HasFuel() && !IsBroken())
|
||||
active = 1
|
||||
icon_state = "portgen1"
|
||||
src.updateUsrDialog()
|
||||
@@ -321,7 +361,7 @@ display round(lastgen) and phorontank amount
|
||||
power_output--
|
||||
src.updateUsrDialog()
|
||||
if (href_list["action"] == "higher_power")
|
||||
if (power_output < 4 || emagged)
|
||||
if (power_output < max_power_output || (emagged && power_output < round(max_power_output*2.5)))
|
||||
power_output++
|
||||
src.updateUsrDialog()
|
||||
if (href_list["action"] == "close")
|
||||
@@ -330,26 +370,46 @@ display round(lastgen) and phorontank amount
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super
|
||||
name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator"
|
||||
desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard PACMAN type generators. Rated for 80 kW max safe output."
|
||||
icon_state = "portgen1"
|
||||
sheet_path = /obj/item/stack/sheet/mineral/uranium
|
||||
time_per_sheet = 576 //same power output, but a 50 sheet stack will last 2 hours at max safe power
|
||||
board_path = "/obj/item/weapon/circuitboard/pacman/super"
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super/UseFuel()
|
||||
//produces a tiny amount of radiation when in use
|
||||
if (prob(2*power_output))
|
||||
for (var/mob/living/L in range(src, 5))
|
||||
L.apply_effect(1, IRRADIATE) //should amount to ~5 rads per minute at max safe power
|
||||
..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super/explode()
|
||||
//a nice burst of radiation
|
||||
var/rads = 50 + (sheets + sheet_left)*1.5
|
||||
for (var/mob/living/L in range(src, 10))
|
||||
//should really fall with the square of the distance, but that makes the rads value drop too fast
|
||||
//I dunno, maybe physics works different when you live in 2D -- SM radiation also works like this, apparently
|
||||
L.apply_effect(max(20, round(rads/get_dist(L,src))), IRRADIATE)
|
||||
|
||||
//produces 80 kW like the PACMAN but 50 sheets will last for 2 hours
|
||||
power_gen = 20000
|
||||
time_per_sheet = 576
|
||||
|
||||
overheat()
|
||||
explosion(src.loc, 3, 3, 3, -1)
|
||||
explosion(src.loc, 3, 3, 5, 3)
|
||||
del(src)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/mrs
|
||||
name = "M.R.S.P.A.C.M.A.N.-type Portable Generator"
|
||||
desc = "An advanced power generator that runs on tritium. Rated for 200 kW maximum safe output!"
|
||||
icon_state = "portgen2"
|
||||
sheet_path = /obj/item/stack/sheet/mineral/tritium
|
||||
sheet_path = /obj/item/stack/sheet/mineral/tritium
|
||||
|
||||
//I don't think tritium has any other use, so we might as well make this rewarding for players
|
||||
//max safe power output (power level = 8) is 200 kW and lasts for 1 hour - 3 or 4 of these could power the station
|
||||
power_gen = 25000 //watts
|
||||
max_power_output = 10
|
||||
time_per_sheet = 576
|
||||
max_temperature = 800
|
||||
temperature_gain = 90
|
||||
board_path = "/obj/item/weapon/circuitboard/pacman/mrs"
|
||||
|
||||
//produces 200 kW and lasts for 1 hour with 50 sheets
|
||||
power_gen = 50000
|
||||
time_per_sheet = 288
|
||||
|
||||
overheat()
|
||||
explosion(src.loc, 4, 4, 4, -1)
|
||||
/obj/machinery/power/port_gen/pacman/mrs/explode()
|
||||
//no special effects, but the explosion is pretty big (same as a supermatter shard).
|
||||
explosion(src.loc, 3, 6, 12, 16, 1)
|
||||
del(src)
|
||||
|
||||
@@ -52,200 +52,194 @@
|
||||
var/agony = 0
|
||||
var/embed = 0 // whether or not the projectile can embed itself in the mob
|
||||
|
||||
//TODO: make it so this is called more reliably, instead of sometimes by bullet_act() and sometimes not
|
||||
proc/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
|
||||
if(blocked >= 2) return 0//Full block
|
||||
if(!isliving(target)) return 0
|
||||
if(isanimal(target)) return 0
|
||||
var/mob/living/L = target
|
||||
L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked) // add in AGONY!
|
||||
//TODO: make it so this is called more reliably, instead of sometimes by bullet_act() and sometimes not
|
||||
/obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
|
||||
if(blocked >= 2) return 0//Full block
|
||||
if(!isliving(target)) return 0
|
||||
if(isanimal(target)) return 0
|
||||
var/mob/living/L = target
|
||||
L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked) // add in AGONY!
|
||||
return 1
|
||||
|
||||
//called when the projectile stops flying because it collided with something
|
||||
/obj/item/projectile/proc/on_impact(var/atom/A)
|
||||
return
|
||||
|
||||
//return 1 if the projectile should be allowed to pass through after all, 0 if not.
|
||||
/obj/item/projectile/proc/on_penetrate(var/atom/A)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not.
|
||||
if(!istype(target) || !istype(user))
|
||||
return 0
|
||||
var/obj/item/projectile/test/in_chamber = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test....
|
||||
in_chamber.target = target
|
||||
in_chamber.flags = flags //Set the flags...
|
||||
in_chamber.pass_flags = pass_flags //And the pass flags to that of the real projectile...
|
||||
in_chamber.firer = user
|
||||
var/output = in_chamber.process() //Test it!
|
||||
del(in_chamber) //No need for it anymore
|
||||
return output //Send it back to the gun!
|
||||
|
||||
//called to launch a projectile from a gun
|
||||
/obj/item/projectile/proc/launch(atom/target, mob/user, obj/item/weapon/gun/launcher, var/target_zone, var/x_offset=0, var/y_offset=0, var/px=null, var/py=null)
|
||||
var/turf/curloc = get_turf(user)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if (!istype(targloc) || !istype(curloc))
|
||||
return 1
|
||||
|
||||
//called when the projectile stops flying because it collided with something
|
||||
proc/on_impact(var/atom/A)
|
||||
return
|
||||
|
||||
//return 1 if the projectile should be allowed to pass through after all, 0 if not.
|
||||
proc/on_penetrate(var/atom/A)
|
||||
return 1
|
||||
|
||||
proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not.
|
||||
if(!istype(target) || !istype(user))
|
||||
return 0
|
||||
var/obj/item/projectile/test/in_chamber = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test....
|
||||
in_chamber.target = target
|
||||
in_chamber.flags = flags //Set the flags...
|
||||
in_chamber.pass_flags = pass_flags //And the pass flags to that of the real projectile...
|
||||
in_chamber.firer = user
|
||||
var/output = in_chamber.process() //Test it!
|
||||
del(in_chamber) //No need for it anymore
|
||||
return output //Send it back to the gun!
|
||||
|
||||
//called to launch a projectile from a gun
|
||||
proc/launch(atom/target, mob/user, obj/item/weapon/gun/launcher, var/target_zone, var/x_offset=0, var/y_offset=0, var/px=null, var/py=null)
|
||||
var/turf/curloc = get_turf(user)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if (!istype(targloc) || !istype(curloc))
|
||||
return 1
|
||||
|
||||
firer = user
|
||||
def_zone = user.zone_sel.selecting
|
||||
|
||||
if(user == target) //Shooting yourself
|
||||
user.bullet_act(src, target_zone)
|
||||
del(src)
|
||||
return 0
|
||||
if(targloc == curloc) //Shooting the ground
|
||||
targloc.bullet_act(src, target_zone)
|
||||
del(src)
|
||||
return 0
|
||||
|
||||
original = target
|
||||
loc = curloc
|
||||
starting = curloc
|
||||
current = curloc
|
||||
yo = targloc.y - curloc.y + y_offset
|
||||
xo = targloc.x - curloc.x + x_offset
|
||||
if(!isnull(py)) p_y = py
|
||||
if(!isnull(px)) p_x = px
|
||||
|
||||
shot_from = launcher
|
||||
silenced = launcher.silenced
|
||||
|
||||
spawn()
|
||||
process()
|
||||
firer = user
|
||||
def_zone = user.zone_sel.selecting
|
||||
|
||||
if(user == target) //Shooting yourself
|
||||
user.bullet_act(src, target_zone)
|
||||
del(src)
|
||||
return 0
|
||||
if(targloc == curloc) //Shooting the ground
|
||||
targloc.bullet_act(src, target_zone)
|
||||
del(src)
|
||||
return 0
|
||||
|
||||
//Used to change the direction of the projectile in flight.
|
||||
proc/redirect(var/new_x, var/new_y, var/atom/starting_loc, var/mob/new_firer=null)
|
||||
original = locate(new_x, new_y, src.z)
|
||||
starting = starting_loc
|
||||
current = starting_loc
|
||||
if(new_firer)
|
||||
firer = src
|
||||
original = target
|
||||
loc = curloc
|
||||
starting = curloc
|
||||
current = curloc
|
||||
yo = targloc.y - curloc.y + y_offset
|
||||
xo = targloc.x - curloc.x + x_offset
|
||||
if(!isnull(py)) p_y = py
|
||||
if(!isnull(px)) p_x = px
|
||||
|
||||
yo = new_y - starting_loc.y
|
||||
xo = new_x - starting_loc.x
|
||||
shot_from = launcher
|
||||
silenced = launcher.silenced
|
||||
|
||||
//Called when the projectile intercepts a mob. Returns 1 if the projectile hit the mob, 0 if it missed and should keep flying.
|
||||
proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier = -30)
|
||||
//accuracy bonus from aiming
|
||||
if (istype(shot_from, /obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often.
|
||||
var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim
|
||||
if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew
|
||||
miss_modifier += -30
|
||||
spawn()
|
||||
process()
|
||||
|
||||
//roll to-hit
|
||||
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, max(miss_modifier + 15*distance, 0))
|
||||
if(!hit_zone)
|
||||
visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
|
||||
return 0
|
||||
return 0
|
||||
|
||||
//set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part
|
||||
def_zone = hit_zone
|
||||
//Used to change the direction of the projectile in flight.
|
||||
/obj/item/projectile/proc/redirect(var/new_x, var/new_y, var/atom/starting_loc, var/mob/new_firer=null)
|
||||
original = locate(new_x, new_y, src.z)
|
||||
starting = starting_loc
|
||||
current = starting_loc
|
||||
if(new_firer)
|
||||
firer = src
|
||||
|
||||
//hit messages
|
||||
if(silenced)
|
||||
target_mob << "<span class='danger'>You've been hit in the [parse_zone(def_zone)] by \the [src]!</span>"
|
||||
yo = new_y - starting_loc.y
|
||||
xo = new_x - starting_loc.x
|
||||
|
||||
//Called when the projectile intercepts a mob. Returns 1 if the projectile hit the mob, 0 if it missed and should keep flying.
|
||||
/obj/item/projectile/proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier = -30)
|
||||
//accuracy bonus from aiming
|
||||
if (istype(shot_from, /obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often.
|
||||
var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim
|
||||
if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew
|
||||
miss_modifier += -30
|
||||
|
||||
//roll to-hit
|
||||
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, max(miss_modifier + 15*distance, 0))
|
||||
if(!hit_zone)
|
||||
visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
|
||||
return 0
|
||||
|
||||
//set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part
|
||||
def_zone = hit_zone
|
||||
|
||||
//hit messages
|
||||
if(silenced)
|
||||
target_mob << "<span class='danger'>You've been hit in the [parse_zone(def_zone)] by \the [src]!</span>"
|
||||
else
|
||||
visible_message("<span class='danger'>\The [target_mob] is hit by \the [src] in the [parse_zone(def_zone)]!</span>")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
|
||||
|
||||
//admin logs
|
||||
if(istype(firer, /mob))
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src.type]</b>"
|
||||
firer.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src.type]</b>"
|
||||
msg_admin_attack("[firer] ([firer.ckey]) shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
else
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src]</b>"
|
||||
msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
|
||||
//sometimes bullet_act() will want the projectile to continue flying
|
||||
if (target_mob.bullet_act(src, def_zone) == -1)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == src)
|
||||
return 0 //no
|
||||
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return 0 //cannot shoot yourself
|
||||
|
||||
if(bumped)
|
||||
return 0
|
||||
|
||||
var/passthrough = 0 //if the projectile should continue flying
|
||||
var/distance = get_dist(starting,loc)
|
||||
|
||||
bumped = 1
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(istype(A, /mob/living))
|
||||
passthrough = !attack_mob(M, distance)
|
||||
else
|
||||
visible_message("<span class='danger'>\The [target_mob] is hit by \the [src] in the [parse_zone(def_zone)]!</span>")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
|
||||
passthrough = 1 //so ghosts don't stop bullets
|
||||
else
|
||||
passthrough = (A.bullet_act(src, def_zone) == -1) //backwards compatibility
|
||||
if(isturf(A))
|
||||
for(var/obj/O in A)
|
||||
O.bullet_act(src)
|
||||
for(var/mob/M in A)
|
||||
attack_mob(M, distance)
|
||||
|
||||
//admin logs
|
||||
if(istype(firer, /mob))
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src.type]</b>"
|
||||
firer.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src.type]</b>"
|
||||
msg_admin_attack("[firer] ([firer.ckey]) shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
//penetrating projectiles can pass through things that otherwise would not let them
|
||||
if(penetrating > 0)
|
||||
if(on_penetrate(A))
|
||||
passthrough = 1
|
||||
penetrating--
|
||||
|
||||
//the bullet passes through a dense object!
|
||||
if(passthrough)
|
||||
bumped = 0 //reset bumped variable!
|
||||
if(istype(A, /turf))
|
||||
loc = A
|
||||
else
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src]</b>"
|
||||
msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
|
||||
//sometimes bullet_act() will want the projectile to continue flying
|
||||
if (target_mob.bullet_act(src, def_zone) == -1)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == src)
|
||||
return 0 //no
|
||||
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return 0 //cannot shoot yourself
|
||||
permutated.Add(A)
|
||||
return 0
|
||||
|
||||
if(bumped)
|
||||
return 0
|
||||
//stop flying
|
||||
on_impact(A)
|
||||
|
||||
density = 0
|
||||
invisibility = 101
|
||||
del(src)
|
||||
return 1
|
||||
|
||||
var/passthrough = 0 //if the projectile should continue flying
|
||||
var/distance = get_dist(starting,loc)
|
||||
/obj/item/projectile/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0)) return 1
|
||||
|
||||
bumped = 1
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(istype(A, /mob/living))
|
||||
passthrough = !attack_mob(M, distance)
|
||||
else
|
||||
passthrough = 1 //so ghosts don't stop bullets
|
||||
else
|
||||
passthrough = (A.bullet_act(src, def_zone) == -1) //backwards compatibility
|
||||
if(isturf(A))
|
||||
for(var/obj/O in A)
|
||||
O.bullet_act(src)
|
||||
for(var/mob/M in A)
|
||||
attack_mob(M, distance)
|
||||
|
||||
//penetrating projectiles can pass through things that otherwise would not let them
|
||||
if(penetrating > 0)
|
||||
if(on_penetrate(A))
|
||||
passthrough = 1
|
||||
penetrating--
|
||||
|
||||
//the bullet passes through a dense object!
|
||||
if(passthrough)
|
||||
bumped = 0 //reset bumped variable!
|
||||
if(istype(A, /turf))
|
||||
loc = A
|
||||
else
|
||||
loc = A.loc
|
||||
permutated.Add(A)
|
||||
return 0
|
||||
|
||||
//stop flying
|
||||
on_impact(A)
|
||||
|
||||
density = 0
|
||||
invisibility = 101
|
||||
del(src)
|
||||
if(istype(mover, /obj/item/projectile))
|
||||
return prob(95) //ha
|
||||
else
|
||||
return 1
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0)) return 1
|
||||
|
||||
if(istype(mover, /obj/item/projectile))
|
||||
return prob(95) //ha
|
||||
else
|
||||
return 1
|
||||
|
||||
process()
|
||||
if(kill_count < 1)
|
||||
del(src)
|
||||
kill_count--
|
||||
spawn while(src)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
|
||||
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
|
||||
del(src)
|
||||
return
|
||||
step_towards(src, current)
|
||||
sleep(1)
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
sleep(1)
|
||||
/obj/item/projectile/process()
|
||||
if(kill_count < 1)
|
||||
del(src)
|
||||
return
|
||||
step_towards(src, current)
|
||||
sleep(1)
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
sleep(1)
|
||||
|
||||
//"Tracing" projectile
|
||||
/obj/item/projectile/test //Used to see if you can hit them.
|
||||
invisibility = 101 //Nope! Can't see me!
|
||||
yo = null
|
||||
@@ -253,36 +247,36 @@
|
||||
var/target = null
|
||||
var/result = 0 //To pass the message back to the gun.
|
||||
|
||||
Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return //cannot shoot yourself
|
||||
if(istype(A, /obj/item/projectile))
|
||||
return
|
||||
if(istype(A, /mob/living))
|
||||
result = 2 //We hit someone, return 1!
|
||||
return
|
||||
result = 1
|
||||
/obj/item/projectile/test/Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return //cannot shoot yourself
|
||||
if(istype(A, /obj/item/projectile))
|
||||
return
|
||||
if(istype(A, /mob/living))
|
||||
result = 2 //We hit someone, return 1!
|
||||
return
|
||||
result = 1
|
||||
return
|
||||
|
||||
process()
|
||||
var/turf/curloc = get_turf(src)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if(!curloc || !targloc)
|
||||
return 0
|
||||
yo = targloc.y - curloc.y
|
||||
xo = targloc.x - curloc.x
|
||||
target = targloc
|
||||
while(src) //Loop on through!
|
||||
if(result)
|
||||
return (result - 1)
|
||||
if((!( target ) || loc == target))
|
||||
target = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge
|
||||
step_towards(src, target)
|
||||
var/mob/living/M = locate() in get_turf(src)
|
||||
if(istype(M)) //If there is someting living...
|
||||
return 1 //Return 1
|
||||
else
|
||||
M = locate() in get_step(src,target)
|
||||
if(istype(M))
|
||||
return 1
|
||||
/obj/item/projectile/test/process()
|
||||
var/turf/curloc = get_turf(src)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if(!curloc || !targloc)
|
||||
return 0
|
||||
yo = targloc.y - curloc.y
|
||||
xo = targloc.x - curloc.x
|
||||
target = targloc
|
||||
while(src) //Loop on through!
|
||||
if(result)
|
||||
return (result - 1)
|
||||
if((!( target ) || loc == target))
|
||||
target = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge
|
||||
step_towards(src, target)
|
||||
var/mob/living/M = locate() in get_turf(src)
|
||||
if(istype(M)) //If there is someting living...
|
||||
return 1 //Return 1
|
||||
else
|
||||
M = locate() in get_step(src,target)
|
||||
if(istype(M))
|
||||
return 1
|
||||
|
||||
@@ -17,68 +17,69 @@ var/list/beam_master = list()
|
||||
flag = "laser"
|
||||
eyeblur = 4
|
||||
var/frequency = 1
|
||||
process()
|
||||
var/reference = "\ref[src]" //So we do not have to recalculate it a ton
|
||||
var/first = 1 //So we don't make the overlay in the same tile as the firer
|
||||
spawn while(src) //Move until we hit something
|
||||
|
||||
if((!( current ) || loc == current)) //If we pass our target
|
||||
current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
|
||||
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
|
||||
del(src) //Delete if it passes the world edge
|
||||
return
|
||||
step_towards(src, current) //Move~
|
||||
/obj/item/projectile/beam/process()
|
||||
var/reference = "\ref[src]" //So we do not have to recalculate it a ton
|
||||
var/first = 1 //So we don't make the overlay in the same tile as the firer
|
||||
spawn while(src) //Move until we hit something
|
||||
|
||||
if(kill_count < 1)
|
||||
del(src)
|
||||
kill_count--
|
||||
if((!( current ) || loc == current)) //If we pass our target
|
||||
current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
|
||||
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
|
||||
del(src) //Delete if it passes the world edge
|
||||
return
|
||||
step_towards(src, current) //Move~
|
||||
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
if(kill_count < 1)
|
||||
del(src)
|
||||
kill_count--
|
||||
|
||||
if(!first) //Add the overlay as we pass over tiles
|
||||
var/target_dir = get_dir(src, current) //So we don't call this too much
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
|
||||
//If the icon has not been added yet
|
||||
if( !("[icon_state][target_dir]" in beam_master) )
|
||||
var/image/I = image(icon,icon_state,10,target_dir) //Generate it.
|
||||
beam_master["[icon_state][target_dir]"] = I //And cache it!
|
||||
if(!first) //Add the overlay as we pass over tiles
|
||||
var/target_dir = get_dir(src, current) //So we don't call this too much
|
||||
|
||||
//Finally add the overlay
|
||||
src.loc.overlays += beam_master["[icon_state][target_dir]"]
|
||||
//If the icon has not been added yet
|
||||
if( !("[icon_state][target_dir]" in beam_master) )
|
||||
var/image/I = image(icon,icon_state,10,target_dir) //Generate it.
|
||||
beam_master["[icon_state][target_dir]"] = I //And cache it!
|
||||
|
||||
//Add the turf to a list in the beam master so they can be cleaned up easily.
|
||||
if(reference in beam_master)
|
||||
var/list/turf_master = beam_master[reference]
|
||||
if("[icon_state][target_dir]" in turf_master)
|
||||
var/list/turfs = turf_master["[icon_state][target_dir]"]
|
||||
turfs += loc
|
||||
else
|
||||
turf_master["[icon_state][target_dir]"] = list(loc)
|
||||
//Finally add the overlay
|
||||
src.loc.overlays += beam_master["[icon_state][target_dir]"]
|
||||
|
||||
//Add the turf to a list in the beam master so they can be cleaned up easily.
|
||||
if(reference in beam_master)
|
||||
var/list/turf_master = beam_master[reference]
|
||||
if("[icon_state][target_dir]" in turf_master)
|
||||
var/list/turfs = turf_master["[icon_state][target_dir]"]
|
||||
turfs += loc
|
||||
else
|
||||
var/list/turfs = list()
|
||||
turfs["[icon_state][target_dir]"] = list(loc)
|
||||
beam_master[reference] = turfs
|
||||
turf_master["[icon_state][target_dir]"] = list(loc)
|
||||
else
|
||||
first = 0
|
||||
cleanup(reference)
|
||||
return
|
||||
var/list/turfs = list()
|
||||
turfs["[icon_state][target_dir]"] = list(loc)
|
||||
beam_master[reference] = turfs
|
||||
else
|
||||
first = 0
|
||||
cleanup(reference)
|
||||
return
|
||||
|
||||
Del()
|
||||
cleanup("\ref[src]")
|
||||
..()
|
||||
/obj/item/projectile/beam/Del()
|
||||
cleanup("\ref[src]")
|
||||
..()
|
||||
|
||||
proc/cleanup(reference) //Waits .3 seconds then removes the overlay.
|
||||
src = null //we're getting deleted! this will keep the code running
|
||||
spawn(3)
|
||||
var/list/turf_master = beam_master[reference]
|
||||
for(var/laser_state in turf_master)
|
||||
var/list/turfs = turf_master[laser_state]
|
||||
for(var/turf/T in turfs)
|
||||
T.overlays -= beam_master[laser_state]
|
||||
return
|
||||
/obj/item/projectile/beam/proc/cleanup(reference) //Waits .3 seconds then removes the overlay.
|
||||
src = null //we're getting deleted! this will keep the code running
|
||||
spawn(3)
|
||||
var/list/turf_master = beam_master[reference]
|
||||
for(var/laser_state in turf_master)
|
||||
var/list/turfs = turf_master[laser_state]
|
||||
for(var/turf/T in turfs)
|
||||
T.overlays -= beam_master[laser_state]
|
||||
return
|
||||
|
||||
/obj/item/projectile/beam/practice
|
||||
name = "laser"
|
||||
@@ -89,7 +90,6 @@ var/list/beam_master = list()
|
||||
flag = "laser"
|
||||
eyeblur = 2
|
||||
|
||||
|
||||
/obj/item/projectile/beam/heavylaser
|
||||
name = "heavy laser"
|
||||
icon_state = "heavylaser"
|
||||
@@ -115,7 +115,6 @@ var/list/beam_master = list()
|
||||
icon_state = "emitter"
|
||||
damage = 30
|
||||
|
||||
|
||||
/obj/item/projectile/beam/lastertag/blue
|
||||
name = "lasertag beam"
|
||||
icon_state = "bluelaser"
|
||||
@@ -124,12 +123,12 @@ var/list/beam_master = list()
|
||||
damage_type = BURN
|
||||
flag = "laser"
|
||||
|
||||
on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = target
|
||||
if(istype(M.wear_suit, /obj/item/clothing/suit/redtag))
|
||||
M.Weaken(5)
|
||||
return 1
|
||||
/obj/item/projectile/beam/lastertag/blue/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = target
|
||||
if(istype(M.wear_suit, /obj/item/clothing/suit/redtag))
|
||||
M.Weaken(5)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/beam/lastertag/red
|
||||
name = "lasertag beam"
|
||||
@@ -139,12 +138,12 @@ var/list/beam_master = list()
|
||||
damage_type = BURN
|
||||
flag = "laser"
|
||||
|
||||
on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = target
|
||||
if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag))
|
||||
M.Weaken(5)
|
||||
return 1
|
||||
/obj/item/projectile/beam/lastertag/red/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = target
|
||||
if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag))
|
||||
M.Weaken(5)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/beam/lastertag/omni//A laser tag bolt that stuns EVERYONE
|
||||
name = "lasertag beam"
|
||||
@@ -154,12 +153,12 @@ var/list/beam_master = list()
|
||||
damage_type = BURN
|
||||
flag = "laser"
|
||||
|
||||
on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = target
|
||||
if((istype(M.wear_suit, /obj/item/clothing/suit/bluetag))||(istype(M.wear_suit, /obj/item/clothing/suit/redtag)))
|
||||
M.Weaken(5)
|
||||
return 1
|
||||
/obj/item/projectile/beam/lastertag/omni/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = target
|
||||
if((istype(M.wear_suit, /obj/item/clothing/suit/bluetag))||(istype(M.wear_suit, /obj/item/clothing/suit/redtag)))
|
||||
M.Weaken(5)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/beam/sniper
|
||||
name = "sniper beam"
|
||||
|
||||
Reference in New Issue
Block a user