From fc872dda5d274936217a9674c016ab18a7ed6ba4 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 25 Jan 2015 00:58:51 -0500 Subject: [PATCH 1/3] PACMAN update Cleans up parts of pacman code, simplifies and improves temperature and overheating mechanics. Temperature now gravitates to some set temperature based on the power output, and if left above a max temp for too long, the generator explodes as before. Rebalances all of the various generator types. --- code/modules/power/port_gen.dm | 279 +++++++++++++++++++-------------- 1 file changed, 161 insertions(+), 118 deletions(-) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 0799900909..e5a2a9f6a8 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -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) @@ -93,17 +53,54 @@ 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) + //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 = "" + 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." + + var/sheet_name = "solid plasma sheet" 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/time_per_sheet = 40 - var/heat = 0 + + /* + 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() ..() @@ -129,76 +126,104 @@ 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 outputing [power_gen*power_output] W." + user << "There are [sheets] [sheet_name]\s left in the hopper." + if(IsBroken()) user << "\The [src] seems to have broken down." + if(overheating) user << "\The [src] is overheating!" /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 + var/lower_limit = 56 + power_output * temperature_gain + var/upper_limit = 76 + power_output * temperature_gain + var/average = (upper_limit + lower_limit)/2 + + //calculate the temperature increase + var/bias = 0 + if (temperature < lower_limit) + bias = round((average - temperature)/40, 1) + else if (temperature > upper_limit) + bias = round((temperature - average)/40, 1) + + 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) + if (temperature > 0) + var/temp_loss = max(2, temperature/50 + rand(-2,2)) + temperature = max(temperature - temp_loss, 0) 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)) @@ -207,16 +232,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) @@ -239,18 +264,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" @@ -260,7 +276,6 @@ display round(lastgen) and phorontank amount ..() if (!anchored) return - interact(user) /obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob) @@ -283,9 +298,11 @@ display round(lastgen) and phorontank amount dat += text("[capitalize(sheet_name)]: [sheets] - Eject
") var/stack_percent = round(sheet_left * 100, 1) dat += text("Current stack: [stack_percent]%
") - dat += text("Power output: - [power_gen * power_output] +
") + dat += text("Power output: - [power_gen * power_output] Watts+
") dat += text("Power current: [(powernet == null ? "Unconnected" : "[avail()]")]
") - dat += text("Heat: [heat]
") + + var/tempstr = "Temperature: [temperature]°C
" + dat += (overheating)? "[tempstr]" : tempstr dat += "
Close" user << browse("[dat]", "window=port_gen") onclose(user, "port_gen") @@ -297,7 +314,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() @@ -315,7 +332,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") @@ -324,20 +341,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 - power_gen = 15000 - time_per_sheet = 65 + 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" - overheat() - explosion(src.loc, 3, 3, 3, -1) + +/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) + + 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 - power_gen = 40000 - time_per_sheet = 80 + + //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" - 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) From bbd541308c1442c92eac1dbf812f0b1c633a07cb Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 25 Jan 2015 13:51:46 -0500 Subject: [PATCH 2/3] Generator temperature now affected by ambient air Gives traitors more opportunities to sabotage the generator or allows engineers to build additional cooling. Also fixes typo. --- code/modules/power/port_gen.dm | 38 ++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index e5a2a9f6a8..985ad214f8 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -75,6 +75,9 @@ 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 = "\improper P.A.C.M.A.N.-type Portable Generator" @@ -143,7 +146,7 @@ /obj/machinery/power/port_gen/pacman/examine(mob/user) ..(user) - user << "\The [src] appears to be outputing [power_gen*power_output] W." + 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 << "\The [src] seems to have broken down." if(overheating) user << "\The [src] is overheating!" @@ -183,16 +186,31 @@ sheet_left -= needed_sheets //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 = round((average - temperature)/40, 1) + bias = min(round((average - temperature)/TEMPERATURE_DIVISOR, 1), TEMPERATURE_CHANGE_MAX) else if (temperature > upper_limit) - bias = round((temperature - average)/40, 1) + bias = max(round((temperature - average)/TEMPERATURE_DIVISOR, 1), -TEMPERATURE_CHANGE_MAX) temperature += rand(-7 + bias, 7 + bias) @@ -202,9 +220,17 @@ overheating-- /obj/machinery/power/port_gen/pacman/handleInactive() - if (temperature > 0) - var/temp_loss = max(2, temperature/50 + rand(-2,2)) - temperature = max(temperature - temp_loss, 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() From 7cc440aecc62b0e32054ee56ed1aeb653e0d83f9 Mon Sep 17 00:00:00 2001 From: Loganbacca Date: Sat, 7 Feb 2015 13:37:12 +1300 Subject: [PATCH 3/3] Absolute paths - Cleaned up projectile.dm and beams.dm --- code/modules/projectiles/projectile.dm | 256 +++++++++---------- code/modules/projectiles/projectile/beams.dm | 142 +++++----- 2 files changed, 197 insertions(+), 201 deletions(-) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 3b5ed8bd53..705492c00a 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -50,115 +50,113 @@ var/agony = 0 var/embed = 0 // whether or not the projectile can embed itself in the mob - proc/on_hit(var/atom/target, var/blocked = 0) - 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 +/obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0) + 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 - 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! +/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! - Bump(atom/A as mob|obj|turf|area) - if(A == firer) +/obj/item/projectile/Bump(atom/A as mob|obj|turf|area) + if(A == firer) + loc = A.loc + return 0 //cannot shoot yourself + + if(bumped) return 0 + var/forcedodge = 0 // force the projectile to pass + + bumped = 1 + if(firer && istype(A, /mob)) + var/mob/M = A + if(!istype(A, /mob/living)) loc = A.loc - return 0 //cannot shoot yourself + return 0// nope.avi - if(bumped) return 0 - var/forcedodge = 0 // force the projectile to pass + var/distance = get_dist(starting,loc) + var/miss_modifier = -30 - bumped = 1 - if(firer && istype(A, /mob)) - var/mob/M = A - if(!istype(A, /mob/living)) - loc = A.loc - return 0// nope.avi + 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 + def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 15*distance) - var/distance = get_dist(starting,loc) - var/miss_modifier = -30 - - 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 - def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 15*distance) - - if(!def_zone) - visible_message("\blue \The [src] misses [M] narrowly!") - forcedodge = -1 + if(!def_zone) + visible_message("\blue \The [src] misses [M] narrowly!") + forcedodge = -1 + else + if(silenced) + M << "\red You've been shot in the [parse_zone(def_zone)] by the [src.name]!" else - if(silenced) - M << "\red You've been shot in the [parse_zone(def_zone)] by the [src.name]!" - else - visible_message("\red [A.name] is hit by the [src.name] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter - if(istype(firer, /mob)) - M.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type]" - firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type]" - msg_admin_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]" - msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG + visible_message("\red [A.name] is hit by the [src.name] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter + if(istype(firer, /mob)) + M.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type]" + firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type]" + msg_admin_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG + else + M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]" + msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG - if(A) - if (!forcedodge) - forcedodge = A.bullet_act(src, def_zone) // searches for return value - if(forcedodge == -1) // the bullet passes through a dense object! - bumped = 0 // reset bumped variable! - if(istype(A, /turf)) - loc = A - else - loc = A.loc - permutated.Add(A) - return 0 - if(istype(A,/turf)) - for(var/obj/O in A) - O.bullet_act(src) - for(var/mob/M in A) - M.bullet_act(src, def_zone) - density = 0 - invisibility = 101 - del(src) + if(A) + if (!forcedodge) + forcedodge = A.bullet_act(src, def_zone) // searches for return value + if(forcedodge == -1) // the bullet passes through a dense object! + bumped = 0 // reset bumped variable! + if(istype(A, /turf)) + loc = A + else + loc = A.loc + permutated.Add(A) + return 0 + if(istype(A,/turf)) + for(var/obj/O in A) + O.bullet_act(src) + for(var/mob/M in A) + M.bullet_act(src, def_zone) + density = 0 + invisibility = 101 + del(src) + return 1 + +/obj/item/projectile/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) + 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) - else - return 1 - - - process() - if(kill_count < 1) +/obj/item/projectile/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) - 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) - return + return + step_towards(src, current) + sleep(1) + if(!bumped && !isturf(original)) + if(loc == get_turf(original)) + if(!(original in permutated)) + Bump(original) + sleep(1) + return /obj/item/projectile/test //Used to see if you can hit them. invisibility = 101 //Nope! Can't see me! @@ -167,36 +165,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 diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index b811eb9281..1aaefb060d 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -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" @@ -105,13 +105,11 @@ var/list/beam_master = list() icon_state = "u_laser" damage = 50 - /obj/item/projectile/beam/emitter name = "emitter beam" icon_state = "emitter" damage = 30 - /obj/item/projectile/beam/lastertag/blue name = "lasertag beam" icon_state = "bluelaser" @@ -120,12 +118,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" @@ -135,12 +133,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" @@ -150,12 +148,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"