Merge branch 'master' into upstream-merge-31737

This commit is contained in:
Poojawa
2017-10-21 07:18:14 -05:00
committed by GitHub
591 changed files with 181531 additions and 178280 deletions

View File

@@ -170,7 +170,7 @@
/obj/item/ammo_casing/mm195x129/incen
name = "1.95x129mm incendiary bullet casing"
desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames. "
desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames."
projectile_type = /obj/item/projectile/bullet/incendiary/mm195x129
// Shotgun

View File

@@ -1,6 +1,6 @@
/obj/item/ammo_casing/energy
name = "energy weapon lens"
desc = "The part of the gun that makes the laser go pew"
desc = "The part of the gun that makes the laser go pew."
caliber = "energy"
projectile_type = /obj/item/projectile/energy
var/e_cost = 100 //The amount of energy a cell needs to expend to create this shot.

View File

@@ -42,7 +42,7 @@
/obj/item/ammo_box/magazine/m10mm/ap
name = "pistol magazine (10mm AP)"
icon_state = "9x19pA"
desc= "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets"
desc= "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets."
ammo_type = /obj/item/ammo_casing/c10mm/ap
/obj/item/ammo_box/magazine/m45

View File

@@ -1,62 +1,62 @@
/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread)
distro += variance
for (var/i = max(1, pellets), i > 0, i--)
var/targloc = get_turf(target)
ready_proj(target, user, quiet, zone_override)
if(distro) //We have to spread a pixel-precision bullet. throw_proj was called before so angles should exist by now...
if(randomspread)
spread = round((rand() - 0.5) * distro)
else //Smart spread
spread = round((i / pellets - 0.5) * distro)
if(!throw_proj(target, targloc, user, params, spread))
return 0
if(i > 1)
newshot()
if(click_cooldown_override)
user.changeNext_move(click_cooldown_override)
else
user.changeNext_move(CLICK_CD_RANGE)
user.newtonian_move(get_dir(target, user))
update_icon()
return 1
/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override)
if (!BB)
return
BB.original = target
BB.firer = user
if (zone_override)
BB.def_zone = zone_override
else
BB.def_zone = user.zone_selected
BB.suppressed = quiet
if(reagents && BB.reagents)
reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets
qdel(reagents)
/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread)
var/turf/curloc = get_turf(user)
if (!istype(targloc) || !istype(curloc) || !BB)
return 0
var/firing_dir
if(BB.firer)
firing_dir = BB.firer.dir
if(!BB.suppressed && firing_effect_type)
new firing_effect_type(get_turf(src), firing_dir)
var/direct_target
if(targloc == curloc)
if(target) //if the target is right on our location we'll skip the travelling code in the proj's fire()
direct_target = target
if(!direct_target)
BB.preparePixelProjectile(target, targloc, user, params, spread)
BB.fire(null, direct_target)
BB = null
return 1
/obj/item/ammo_casing/proc/spread(turf/target, turf/current, distro)
var/dx = abs(target.x - current.x)
var/dy = abs(target.y - current.y)
return locate(target.x + round(gaussian(0, distro) * (dy+2)/8, 1), target.y + round(gaussian(0, distro) * (dx+2)/8, 1), target.z)
/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread)
distro += variance
for (var/i = max(1, pellets), i > 0, i--)
var/targloc = get_turf(target)
ready_proj(target, user, quiet, zone_override)
if(distro) //We have to spread a pixel-precision bullet. throw_proj was called before so angles should exist by now...
if(randomspread)
spread = round((rand() - 0.5) * distro)
else //Smart spread
spread = round((i / pellets - 0.5) * distro)
if(!throw_proj(target, targloc, user, params, spread))
return 0
if(i > 1)
newshot()
if(click_cooldown_override)
user.changeNext_move(click_cooldown_override)
else
user.changeNext_move(CLICK_CD_RANGE)
user.newtonian_move(get_dir(target, user))
update_icon()
return 1
/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override)
if (!BB)
return
BB.original = target
BB.firer = user
if (zone_override)
BB.def_zone = zone_override
else
BB.def_zone = user.zone_selected
BB.suppressed = quiet
if(reagents && BB.reagents)
reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets
qdel(reagents)
/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread)
var/turf/curloc = get_turf(user)
if (!istype(targloc) || !istype(curloc) || !BB)
return 0
var/firing_dir
if(BB.firer)
firing_dir = BB.firer.dir
if(!BB.suppressed && firing_effect_type)
new firing_effect_type(get_turf(src), firing_dir)
var/direct_target
if(targloc == curloc)
if(target) //if the target is right on our location we'll skip the travelling code in the proj's fire()
direct_target = target
if(!direct_target)
BB.preparePixelProjectile(target, user, params, spread)
BB.fire(null, direct_target)
BB = null
return 1
/obj/item/ammo_casing/proc/spread(turf/target, turf/current, distro)
var/dx = abs(target.x - current.x)
var/dy = abs(target.y - current.y)
return locate(target.x + round(gaussian(0, distro) * (dy+2)/8, 1), target.y + round(gaussian(0, distro) * (dx+2)/8, 1), target.z)

View File

@@ -212,7 +212,7 @@
firing_burst = FALSE
return FALSE
if(!issilicon(user))
if( iteration > 1 && !(user.is_holding(src))) //for burst firing
if(iteration > 1 && !(user.is_holding(src))) //for burst firing
firing_burst = FALSE
return FALSE
if(chambered && chambered.BB)
@@ -230,6 +230,8 @@
shoot_live_shot(user, 1, target, message)
else
shoot_live_shot(user, 0, target, message)
if (iteration >= burst_size)
firing_burst = FALSE
else
shoot_with_empty_chamber(user)
firing_burst = FALSE
@@ -254,8 +256,7 @@
if(burst_size > 1)
firing_burst = TRUE
for(var/i = 1 to burst_size)
addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), min(fire_delay * (i - 1), 0))
firing_burst = FALSE
addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), fire_delay * (i - 1))
else
if(chambered)
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))

View File

@@ -1,5 +1,5 @@
/obj/item/gun/ballistic
desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason"
desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason."
name = "projectile gun"
icon_state = "pistol"
origin_tech = "combat=2;materials=2"

View File

@@ -3,7 +3,7 @@
//The ammo/gun is stored in a back slot item
/obj/item/minigunpack
name = "backpack power source"
desc = "The massive external power source for the laser gatling gun"
desc = "The massive external power source for the laser gatling gun."
icon = 'icons/obj/guns/minigun.dmi'
icon_state = "holstered"
item_state = "backpack"

View File

@@ -341,7 +341,7 @@
/obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawn
name = "sawn-off improvised shotgun"
desc = "A single-shot shotgun, better not miss"
desc = "A single-shot shotgun. Better not miss."
icon_state = "ishotgun"
item_state = "gun"
w_class = WEIGHT_CLASS_NORMAL

View File

@@ -137,7 +137,7 @@
/obj/item/gun/ballistic/shotgun/boltaction/enchanted/arcane_barrage
name = "arcane barrage"
desc = "Pew Pew Pew"
desc = "Pew Pew Pew."
fire_sound = 'sound/weapons/emitter.ogg'
pin = /obj/item/device/firing_pin/magic
icon_state = "arcane_barrage"

View File

@@ -38,9 +38,10 @@
var/aiming_time = 12
var/aiming_time_fire_threshold = 5
var/aiming_time_left = 12
var/aiming_time_increase_user_movement = 6
var/aiming_time_increase_user_movement = 3
var/scoped_slow = 1
var/aiming_time_increase_angle_multiplier = 0.3
var/last_process = 0
var/lastangle = 0
var/aiming_lastangle = 0
@@ -204,7 +205,7 @@
/obj/item/gun/energy/beam_rifle/Initialize()
. = ..()
START_PROCESSING(SSfastprocess, src)
START_PROCESSING(SSprojectiles, src)
zoom_speed_action = new(src)
zoom_lock_action = new(src)
@@ -240,7 +241,7 @@
if(!istype(curloc))
return
targloc = get_turf_in_angle(lastangle, curloc, 10)
P.preparePixelProjectile(targloc, targloc, current_user, current_user.client.mouseParams, 0)
P.preparePixelProjectile(targloc, current_user, current_user.client.mouseParams, 0)
P.fire(lastangle)
/obj/item/gun/energy/beam_rifle/process()
@@ -248,9 +249,9 @@
return
check_user()
handle_zooming()
aiming_time_left = min(0, aiming_time_left - (world.time - lastprocess))
aiming_time_left = max(0, aiming_time_left - (world.time - last_process))
aiming_beam(TRUE)
lastprocess = world.time
last_process = world.time
/obj/item/gun/energy/beam_rifle/proc/check_user(automatic_cleanup = TRUE)
if(!istype(current_user) || !isturf(current_user.loc) || !(src in current_user.held_items) || current_user.incapacitated()) //Doesn't work if you're not holding it!
@@ -442,7 +443,7 @@
firing_dir = BB.firer.dir
if(!BB.suppressed && firing_effect_type)
new firing_effect_type(get_turf(src), firing_dir)
BB.preparePixelProjectile(target, targloc, user, params, spread)
BB.preparePixelProjectile(target, user, params, spread)
BB.fire(gun? gun.lastangle : null, null)
BB = null
return TRUE
@@ -508,7 +509,7 @@
if(wall_pierce++ < wall_pierce_amount)
loc = target
if(prob(wall_devastate))
if(istype(target, /turf/closed/wall))
if(iswallturf(target))
var/turf/closed/wall/W = target
W.dismantle_wall(TRUE, TRUE)
else
@@ -638,10 +639,6 @@
while(loc)
if(++safety > (range * 3)) //If it's looping for way, way too long...
return //Kill!
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
if(!Angle)
Angle=round(Get_Angle(src,current))
if(spread)
Angle += (rand() - 0.5) * spread
var/matrix/M = new

View File

@@ -75,7 +75,7 @@
/obj/item/gun/energy/e_gun/dragnet/snare
name = "Energy Snare Launcher"
desc = "Fires an energy snare that slows the target down"
desc = "Fires an energy snare that slows the target down."
ammo_type = list(/obj/item/ammo_casing/energy/trap)
/obj/item/gun/energy/e_gun/turret

View File

@@ -108,7 +108,7 @@
/obj/item/gun/energy/xray
name = "x-ray laser gun"
desc = "A high-power laser gun capable of expelling concentrated x-ray blasts that pass through multiple soft targets and heavier materials"
desc = "A high-power laser gun capable of expelling concentrated x-ray blasts that pass through multiple soft targets and heavier materials."
icon_state = "xray"
item_state = null
origin_tech = "combat=6;materials=4;magnets=4;syndicate=1"

View File

@@ -1,6 +1,6 @@
/obj/item/gun/grenadelauncher
name = "grenade launcher"
desc = "a terrible, terrible thing. it's really awful!"
desc = "A terrible, terrible thing. It's really awful!"
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "riotgun"
item_state = "riotgun"

View File

@@ -6,7 +6,7 @@
/obj/item/gun/magic/staff/change
name = "staff of change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
fire_sound = 'sound/magic/staff_change.ogg'
ammo_type = /obj/item/ammo_casing/magic/change
icon_state = "staffofchange"
@@ -62,7 +62,7 @@
/obj/item/gun/magic/staff/honk
name = "staff of the honkmother"
desc = "Honk"
desc = "Honk."
fire_sound = 'sound/items/airhorn.ogg'
ammo_type = /obj/item/ammo_casing/magic/honk
icon_state = "honker"

View File

@@ -41,7 +41,8 @@
var/obj/item/reagent_containers/syringe/S = syringes[syringes.len]
if(!S) return 0
if(!S)
return 0
S.loc = user.loc
syringes.Remove(S)
@@ -78,16 +79,16 @@
force = 2 //Also very weak because it's smaller
suppressed = TRUE //Softer fire sound
can_unsuppress = FALSE //Permanently silenced
/obj/item/gun/syringe/dna
name = "modified syringe gun"
desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes."
origin_tech = "combat=2;syndicate=2;biotech=3"
/obj/item/gun/syringe/dna/Initialize()
. = ..()
chambered = new /obj/item/ammo_casing/dnainjector(src)
/obj/item/gun/syringe/dna/attackby(obj/item/A, mob/user, params, show_msg = TRUE)
if(istype(A, /obj/item/dnainjector))
var/obj/item/dnainjector/D = A

View File

@@ -1,3 +1,6 @@
#define MOVES_HITSCAN -1 //Not actually hitscan but close as we get.
/obj/item/projectile
name = "projectile"
icon = 'icons/obj/projectiles.dmi'
@@ -16,18 +19,31 @@
var/suppressed = FALSE //Attack message
var/yo = null
var/xo = null
var/current = null
var/atom/original = null // the original target clicked
var/turf/starting = null // the projectile's starting turf
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
var/paused = FALSE //for suspending the projectile midair
var/p_x = 16
var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
//Fired processing vars
var/fired = FALSE //Have we been fired yet
var/paused = FALSE //for suspending the projectile midair
var/last_projectile_move = 0
var/last_process = 0
var/time_offset = 0
var/old_pixel_x = 0
var/old_pixel_y = 0
var/pixel_x_increment = 0
var/pixel_y_increment = 0
var/pixel_x_offset = 0
var/pixel_y_offset = 0
var/new_x = 0
var/new_y = 0
var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel
var/Angle = 0
var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle
var/spread = 0 //amount (in degrees) of projectile spread
var/legacy = 0 //legacy projectile system
animate_movement = 0 //Use SLIDE_STEPS in conjunction with legacy
var/ricochets = 0
var/ricochets_max = 2
@@ -85,7 +101,7 @@
/obj/item/projectile/proc/on_hit(atom/target, blocked = FALSE)
var/turf/target_loca = get_turf(target)
if(!nodamage && (damage_type == BRUTE || damage_type == BURN) && istype(target_loca, /turf/closed/wall) && prob(75))
if(!nodamage && (damage_type == BRUTE || damage_type == BURN) && iswallturf(target_loca) && prob(75))
var/turf/closed/wall/W = target_loca
var/mutable_appearance/decal = mutable_appearance('icons/effects/effects.dmi', "bullet_hole", TURF_DECAL_LAYER)
if(target == original)
@@ -146,7 +162,7 @@
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
/obj/item/projectile/Collide(atom/A)
if(check_ricochet() && check_ricochet_flag(A) && ricochets < ricochets_max)
if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
ricochets++
if(A.handle_ricochet(src))
ignore_source_check = TRUE
@@ -171,41 +187,42 @@
if(forcedodge)
loc = target_turf
return FALSE
var/permutation = select_target(A,target_turf) // searches for return value, could be deleted after run so check A isn't null
var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null
if(permutation == -1 || forcedodge)// the bullet passes through a dense object!
loc = target_turf
if(A)
permutated.Add(A)
return FALSE
else
var/atom/alt = select_target(A)
if(alt)
if(!prehit(alt))
return FALSE
alt.bullet_act(src, def_zone)
qdel(src)
return TRUE
/obj/item/projectile/proc/select_target(atom/A,target_turf)
if((A && A.density && !(A.flags_1 & ON_BORDER_1)) && (istype(A,/obj/machinery) || isturf(A))) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile.
var/list/mobs_list = list()
var/list/machine_list = list()
for(var/mob/living/L in target_turf)
mobs_list += L
for(var/obj/machinery/m in target_turf)
if(m.density)
machine_list += m
var/permutationbackup
if(isturf(A))
permutationbackup = A.bullet_act(src, def_zone) // Just in case the turf can deflect bullets
if(mobs_list.len || machine_list.len)
var/atom/movable/selected_target
if(mobs_list.Find(original) || machine_list.Find(original))
selected_target = original
else if(mobs_list.len)
selected_target = pick(mobs_list)
else
selected_target = pick(machine_list)
if(!prehit(selected_target))
return FALSE
return selected_target.bullet_act(src, def_zone)
return permutationbackup
else
return A.bullet_act(src, def_zone)
/obj/item/projectile/proc/select_target(atom/A) //Selects another target from a wall if we hit a wall.
if(!A || !A.density || (A.flags_1 & ON_BORDER_1) || ismob(A) || A == original) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs or machines/structures on that tile.
return
var/turf/T = get_turf(A)
if(original in T)
return original
var/list/mob/possible_mobs = typecache_filter_list(T, GLOB.typecache_mob) - A
var/list/mob/mobs = list()
for(var/i in possible_mobs)
var/mob/M = i
if(M.lying)
continue
mobs += M
var/mob/M = safepick(mobs)
if(M)
return M.lowest_buckled_mob()
var/obj/O = safepick(typecache_filter_list(T, GLOB.typecache_machine_or_structure)) - A
if(O)
return O
/obj/item/projectile/proc/check_ricochet()
if(prob(ricochet_chance))
@@ -218,94 +235,104 @@
return FALSE
/obj/item/projectile/Process_Spacemove(var/movement_dir = 0)
return 1 //Bullets don't drift in space
return TRUE //Bullets don't drift in space
/obj/item/projectile/proc/fire(setAngle, atom/direct_target)
/obj/item/projectile/process()
last_process = world.time
if(!loc || !fired)
fired = FALSE
return PROCESS_KILL
if(paused || !isturf(loc))
last_projectile_move += world.time - last_process //Compensates for pausing, so it doesn't become a hitscan projectile when unpaused from charged up ticks.
return
var/elapsed_time_deciseconds = (world.time - last_projectile_move) + time_offset
time_offset = 0
var/required_moves = speed > 0? Floor(elapsed_time_deciseconds / speed) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :<
if(required_moves == MOVES_HITSCAN)
required_moves = SSprojectiles.global_max_tick_moves
else
if(required_moves > SSprojectiles.global_max_tick_moves)
var/overrun = required_moves - SSprojectiles.global_max_tick_moves
required_moves = SSprojectiles.global_max_tick_moves
time_offset += overrun * speed
time_offset += Modulus(elapsed_time_deciseconds, speed)
for(var/i in 1 to required_moves)
pixel_move(required_moves)
/obj/item/projectile/proc/fire(angle, atom/direct_target)
//If no angle needs to resolve it from xo/yo!
if(!log_override && firer && original)
add_logs(firer, original, "fired at", src, " [get_area(src)]")
if(direct_target)
prehit(direct_target)
direct_target.bullet_act(src, def_zone)
qdel(src)
return
if(isnum(setAngle))
Angle = setAngle
var/old_pixel_x = pixel_x
var/old_pixel_y = pixel_y
if(!legacy) //new projectiles
set waitfor = 0
var/next_run = world.time
while(loc)
if(paused)
next_run = world.time
stoplag(1)
continue
if(prehit(direct_target))
direct_target.bullet_act(src, def_zone)
qdel(src)
return
if(isnum(angle))
setAngle(angle)
if(spread)
setAngle(Angle + ((rand() - 0.5) * spread))
if(isnull(Angle)) //Try to resolve through offsets if there's no angle set.
var/turf/starting = get_turf(src)
var/turf/target = locate(Clamp(starting + xo, 1, world.maxx), Clamp(starting + yo, 1, world.maxy), starting.z)
setAngle(Get_Angle(src, target))
if(!nondirectional_sprite)
var/matrix/M = new
M.Turn(Angle)
transform = M
old_pixel_x = pixel_x
old_pixel_y = pixel_y
last_projectile_move = world.time
fired = TRUE
if(!isprocessing)
START_PROCESSING(SSprojectiles, src)
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
/obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides.
Angle = new_angle
return TRUE
if(!Angle)
Angle=round(Get_Angle(src,current))
if(spread)
Angle += (rand() - 0.5) * spread
if(!nondirectional_sprite)
var/matrix/M = new
M.Turn(Angle)
transform = M
/obj/item/projectile/proc/pixel_move(moves)
if(!nondirectional_sprite)
var/matrix/M = new
M.Turn(Angle)
transform = M
var/Pixel_x=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
var/Pixel_y=round((cos(Angle)+16*cos(Angle)*2), 1)
var/pixel_x_offset = old_pixel_x + Pixel_x
var/pixel_y_offset = old_pixel_y + Pixel_y
var/new_x = x
var/new_y = y
pixel_x_increment=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
pixel_y_increment=round((cos(Angle)+16*cos(Angle)*2), 1)
pixel_x_offset = old_pixel_x + pixel_x_increment
pixel_y_offset = old_pixel_y + pixel_y_increment
new_x = x
new_y = y
while(pixel_x_offset > 16)
pixel_x_offset -= 32
old_pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
old_pixel_x += 32
new_x--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
old_pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
old_pixel_y += 32
new_y--
while(pixel_x_offset > 16)
pixel_x_offset -= 32
old_pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
old_pixel_x += 32
new_x--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
old_pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
old_pixel_y += 32
new_y--
pixel_x = old_pixel_x
pixel_y = old_pixel_y
step_towards(src, locate(new_x, new_y, z))
next_run += max(world.tick_lag, speed)
var/delay = next_run - world.time
if(delay <= world.tick_lag*2)
pixel_x = pixel_x_offset
pixel_y = pixel_y_offset
else
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW)
old_pixel_x = pixel_x_offset
old_pixel_y = pixel_y_offset
if(can_hit_target(original, permutated))
Collide(original)
Range()
if (delay > 0)
sleep(delay)
else //old projectile system
set waitfor = 0
while(loc)
if(!paused)
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
step_towards(src, current)
if(can_hit_target(original, permutated))
Collide(original)
Range()
sleep(CONFIG_GET(number/run_delay) * 0.9)
step_towards(src, locate(new_x, new_y, z))
pixel_x = old_pixel_x
pixel_y = old_pixel_y
//var/animation_time = ((SSprojectiles.flags & SS_TICKER? (SSprojectiles.wait * world.tick_lag) : SSprojectiles.wait) / moves)
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = 1, flags = ANIMATION_END_NOW)
old_pixel_x = pixel_x_offset
old_pixel_y = pixel_y_offset
if(can_hit_target(original, permutated))
Collide(original)
Range()
last_projectile_move = world.time
//Returns true if the target atom is on our current turf and above the right layer
/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough)
@@ -315,21 +342,26 @@
return TRUE
return FALSE
/obj/item/projectile/proc/preparePixelProjectile(atom/target, var/turf/targloc, mob/living/user, params, spread)
var/turf/curloc = get_turf(user)
forceMove(get_turf(user))
starting = get_turf(user)
current = curloc
/obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0)
var/turf/curloc = get_turf(source)
var/turf/targloc = get_turf(target)
forceMove(get_turf(source))
starting = get_turf(source)
original = target
yo = targloc.y - curloc.y
xo = targloc.x - curloc.x
var/list/calculated = calculate_projectile_angle_and_pixel_offsets(user, params)
Angle = calculated[1]
p_x = calculated[2]
p_y = calculated[3]
if(isliving(source) && params)
var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params)
p_x = calculated[2]
p_y = calculated[3]
if(spread)
src.Angle += spread
if(spread)
setAngle(calculated[1] + spread)
else
setAngle(calculated[1])
else
setAngle(Get_Angle(src, targloc))
/proc/calculate_projectile_angle_and_pixel_offsets(mob/user, params)
var/list/mouse_control = params2list(params)
@@ -362,10 +394,11 @@
/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it.
..()
if(isliving(AM) && AM.density && !checkpass(PASSMOB))
if(isliving(AM) && (AM.density || AM == original) && !checkpass(PASSMOB))
Collide(AM)
/obj/item/projectile/Destroy()
STOP_PROCESSING(SSprojectiles, src)
return ..()
/obj/item/projectile/experience_pressure_difference()

View File

@@ -95,8 +95,6 @@
name = "emitter beam"
icon_state = "emitter"
damage = 30
legacy = 1
animate_movement = SLIDE_STEPS
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
light_color = LIGHT_COLOR_GREEN

View File

@@ -8,12 +8,6 @@
hitsound_wall = "ricochet"
impact_effect_type = /obj/effect/temp_visual/impact_effect
/obj/item/projectile/bullet/pellet/shotgun_buckshot/Range()
..()
damage -= 0.75
if(damage < 0)
qdel(src)
/obj/item/projectile/bullet/incendiary
damage = 20
var/fire_stacks = 4
@@ -39,7 +33,7 @@
damage = 60
// 7.62 (Nagant Rifle)
/obj/item/projectile/bullet/a762
name = "7.62 bullet"
damage = 60
@@ -109,7 +103,7 @@
// 4.6x30mm (Autorifles)
/obj/item/projectile/bullet/c46x30mm
desc = "4.6x30mm bullet"
name = "4.6x30mm bullet"
damage = 20
/obj/item/projectile/bullet/c46x30mm_ap
@@ -156,7 +150,7 @@
/obj/item/projectile/bullet/p50
name =".50 bullet"
speed = 0 //360 alwaysscope.
speed = 0.4
damage = 70
knockdown = 100
dismemberment = 50
@@ -272,15 +266,30 @@
explosion(target, -1, 0, 1)
return TRUE
/obj/item/projectile/bullet/pellet
var/tile_dropoff = 0.75
var/tile_dropoff_s = 1.25
/obj/item/projectile/bullet/pellet/shotgun_buckshot
name = "buckshot pellet"
damage = 12.5
/obj/item/projectile/bullet/pellet/shotgun_rubbershot
name = "rubbershot pellet"
damage = 3
stamina = 25
/obj/item/projectile/bullet/pellet/Range()
..()
if(damage > 0)
damage -= tile_dropoff
if(stamina > 0)
stamina -= tile_dropoff_s
if(damage < 0 && stamina < 0)
qdel(src)
/obj/item/projectile/bullet/pellet/shotgun_improvised
tile_dropoff = 0.55 //Come on it does 6 damage don't be like that.
damage = 6
/obj/item/projectile/bullet/pellet/shotgun_improvised/Initialize()

View File

@@ -76,7 +76,7 @@
OpenDoor(target)
else
var/turf/T = get_turf(target)
if(isclosedturf(T) && !istype(T, /turf/closed/indestructible))
if(isclosedturf(T) && !isindestructiblewall(T))
CreateDoor(T)
/obj/item/projectile/magic/door/proc/CreateDoor(turf/T)

View File

@@ -55,7 +55,7 @@
/obj/item/projectile/bullet/srmrocket
name ="SRM-8 Rocket"
desc = "Boom"
desc = "Boom."
icon_state = "missile"
damage = 30
ricochets_max = 0 //it's a MISSILE