ID:162484
 
Ok, so I want to create an attack which checks to see if anyone in a specific area either exist already in that area or if someone enters the area.

Basically, I am trying to make a machine gun that can do suppressing fire: IE continually attack an area in front of the user.

Here is the proc I have made so far:

        Suppressing(T as text)
usr.dir = get_dir(usr,src)
if (usr.dir == SOUTH)
if(src.loc==usr.x&usr.y-1)
T = "Yes"
else if(src.loc==usr.x-1&usr.y-1)
T = "Yes"
else if(src.loc==usr.x+1&usr.y-1)
T = "Yes"
else if(src.loc==usr.x&usr.y-2)
T = "Yes"
else if(src.loc==usr.x-1&usr.y-2)
T = "Yes"
else if(src.loc==usr.x+1&usr.y-2)
T = "Yes"
else if(src.loc==usr.x&usr.y-3)
T = "Yes"
else if(src.loc==usr.x-1&usr.y-3)
T = "Yes"
else if(src.loc==usr.x+1&usr.y-3)
T = "Yes"
else if(src.loc==usr.x&usr.y-4)
T = "Yes"
else if(src.loc==usr.x-1&usr.y-4)
T = "Yes"
else if(src.loc==usr.x+1&usr.y-4)
T = "Yes"
else if(src.loc==usr.x&usr.y-5)
T = "Yes"
else if(src.loc==usr.x-1&usr.y-5)
T = "Yes"
else if(src.loc==usr.x+1&usr.y-5)
T = "Yes"
else if(src.loc==usr.x&usr.y-6)
T = "Yes"
else if(src.loc==usr.x-1&usr.y-6)
T = "Yes"
else if(src.loc==usr.x+1&usr.y-6)
T = "Yes"
else if(src.loc==usr.x&usr.y-7)
T = "Yes"
else if(src.loc==usr.x-1&usr.y-7)
T = "Yes"
else if(src.loc==usr.x+1&usr.y-7)
T = "Yes"
else if(src.loc==usr.x&usr.y-8)
T = "Yes"
else if(src.loc==usr.x-1&usr.y-8)
T = "Yes"
else if(src.loc==usr.x+1&usr.y-8)
T = "Yes"
else
T = "No"


So, now I want to make the gun that has a suppressing fire option. When used, it will check src.Suppressing() to see if it is yes or no.

My questions are this:

First, will this code work as written so far?
Second, how should I write the code for the gun? I don't want it to create a target list. I just want it to hit anyone which Suppressing() returns a yes for.

And third, am I doing this the hard way?
No, it won't work. loc is a turf, you're comparing it to a number (& is a binary operator).

Question two, depends on a lot of things.

Question three, yes, yes you are doing it the hard way.

proc/Suppressing(atom/fire, range) //Returns all mobs within 'range' squares of 'fire', in the direction fire is facing. Dense objects provide cover
var/turf/current = fire.loc
var/list/ret = list()
while(range>0)
range--
current = get_step(current, fire.dir)
for(var/mob/m in current)
ret+=m

if(current.density) break

return ret


I'll leave expanding the procedure to effect a 3 (or n) tile-wide strip up to you. Although I will give you a hint - try looping through all the turfs within 1 tiles of 'current', and adding any mobs in them to the return list. Being careful not to include the atom 'fire', and adjusting the range the gun shoots to accordingly.
In response to Jp
What you posted is going to give an error if the gun is pointing off the map, at the if(current.density) break line. The easiest way to fix that is to change the if() to if(!current || current.density).

I would also like to add that you suggestion for how to make the suppressing fire affect a 3 (or n) tile-wide strip would result in each mob being counted up to 3 (or n) times, tripling (or ning) the damage caused. A combination of get_step() and turn() would be a better idea. In fact, wider paths would make this proc an excellent candidate for recursion.
In response to Garthor
What you posted is going to give an error if the gun is pointing off the map, at the if(current.density) break line. The easiest way to fix that is to change the if() to if(!current || current.density).


Whoops, forgot to take that case into account

I would also like to add that you suggestion for how to make the suppressing fire affect a 3 (or n) tile-wide strip would result in each mob being counted up to 3 (or n) times, tripling (or ning) the damage caused. A combination of get_step() and turn() would be a better idea. In fact, wider paths would make this proc an excellent candidate for recursion.

Only if you don't check whether they're already in the list before adding them, but recursion probably would be a better idea.
In response to Jp
Because I liked the sound of this, I decided to actually write the whole thing out:

proc/areafire(var/atom/loc, var/dir, var/range, var/leftwidth, var/rightwidth = leftwidth)
if(range == 0 || !loc || loc.density) return list()
. = list()
. += loc
. += loc.contents
var/list/left = .(get_step(loc, turn(dir, 90)), turn(dir,90), leftwidth, 0)
var/list/right = .(get_step(loc, turn(dir,-90)), turn(dir,-90), rightwidth, 0)
. += left
. += right
. += .(get_step(loc, dir), dir, range-1, left.len, right.len)


The recursion obfuscates the whole thing (not helped at all by the arcane notation I decided to use for the hell of it) but hooray recursion anyway!
In response to Garthor
You don't check for density - if you did, using left.len and right.len would make a lot more sense, because you would then 'slim down' the beam when passing through narrow passages.

I didn't actually know you could use . like that. I'll have to use that some time.
In response to Jp
I did check for density. Right at the start.

And I don't think ANYBODY'S used . like that, which is why I did.
In response to Garthor
Take a look at some of Dan's libraries. He does that and far weirder stuff in there. :-)
In response to Garthor
So, I think I understand how this works. My question is, if I used this proc (provided I got your permission, of course) is this how I would call it?

obj/item
heavyspecial
Minigun
name = "GAU-17 Minigun"
icon = 'shopicons.dmi'
icon_state = "HeavySpecial"
layer = 1
var/ammo = 0
var/reloading = 0
verb
equip()
if(usr.guneqed != null)
usr <<"You already have a gun equiped."
else if(usr.meleeeqed != null)
usr <<"You already have something in your hands."
else
usr.guneqed = name
usr.wepbon = 100
unequip()
set src in view(0)
if (usr.guneqed == null)
usr <<"You do not have a gun equiped."
else
usr.guneqed = null
usr.wepbon = 0
suppressing_fire()
if(reloading ==1)
usr << "You have to finish reloading first!"
else if(ammo < 500)
usr << "You have to finish reloading first!"
else
ammo = 0
for(var/mob/M in areafire(usr,usr.dir,7,3))
spawn()M.HitCheckGun()
drop()
if (usr.guneqed == name)
usr << "You need to unequip it first."
else
set src in usr
Move(usr.loc)
reload()
if(ammo >= 500)
usr << "Your gun is already fully loaded."
else if (usr.clip == 0)
usr << "You need a clip to reload!"
else
reloading = 1
usr.Delay(90)
reloading = 0
ammo = 500
usr.clip -= 1
usr << "You have reloaded your gun."
ammo_count()
usr << "Your gun has [ammo] shots left."
In response to Zuglilth
Actually, you have to call suppressing_fire from the tile in front of usr. It's somewhat silly like that because it makes it easier for the whole thing to be recursive.

Well, not really. An easy change could've made it work the way you're using it, but it was too late for me to realize it at the time.

You'll also probably want to set up a while() loop (to continue until the ammo is expended) so that it fires more than one big burst.

Also: setting width to 3 actually results in a 7-wide area. A 3-wide lane just has width set to 1.
In response to Garthor
So, it should look this this?
            suppressing_fire()
if(reloading)
usr << "You have to finish reloading first!"
else if(ammo < 500)
usr << "You do not have enough bullets for that!"
else if(suppressing)
usr << "You are already laying down a suppressing fire!"
else
ammo = 0
usr.movement_locked = 1
suppressing = 1
for(var/mob/M in areafire(1,usr.dir,1,3))
while(suppressing)
spawn()M.HitCheckGun()
check_fire()
if(suppressing == FALSE)
usr << "You have no fire to check!"
else
suppressing = TRUE


Because I am trying that, and when I suppress it doesn't proc damage.
In response to Zuglilth
I'd do something like this:

while(suppressing && ammo > 0)
ammo -= 10
for(var/mob/M in areafire(get_step(usr,usr.dir), usr.dir, 7, 1))
spawn() M.whatever hurts them
sleep(10)
suppressing = 0
if(ammo < 0) ammo = 0


So that, every second, you use up 10 ammo and shoot everybody in a 7x3 path in front of the gun.
In response to Garthor
I don't know, this isn't working.

proc/areafire(var/atom/loc, var/dir, var/range, var/leftwidth, var/rightwidth = leftwidth)
if(range == 0 || !loc || loc.density) return list()
. = list()
. += loc
. += loc.contents
var/list/left = .(get_step(loc, turn(dir, 90)), turn(dir,90), leftwidth, 0)
var/list/right = .(get_step(loc, turn(dir,-90)), turn(dir,-90), rightwidth, 0)
. += left
. += right
. += .(get_step(loc, dir), dir, range-1, left.len, right.len)

The proc is unchanged from what you originally posted (mostly because I do not understand it.)

Here is the code on the gun.

obj/item
heavyspecial
Minigun
name = "GAU-17 Minigun"
icon = 'shopicons.dmi'
icon_state = "HeavySpecial"
layer = 1
var/ammo = 0
var/reloading = FALSE
var/suppressing = 0
verb
equip()
if(usr.guneqed != null)
usr <<"You already have a gun equiped."
else if(usr.meleeeqed != null)
usr <<"You already have something in your hands."
else
usr.guneqed = name
usr.wepbon = 100
unequip()
set src in view(0)
if(reloading)
usr <<"You are still reloading it."
else if(suppressing = 1)
usr <<"You are still laying down a suppressing fire."
else if (usr.guneqed == null)
usr <<"You do not have a gun equiped."
else
usr.guneqed = null
usr.wepbon = 0
suppressing_fire()
while(suppressing && ammo > 0)
ammo -= 10
for(var/mob/M in areafire(get_step(usr,usr.dir), usr.dir, 7, 1))
spawn() M.HitCheckGun()
sleep(10)
suppressing = 0
if(ammo < 0) ammo = 0
check_fire()
if(suppressing == 0)
usr << "You have no fire to check!"
else
suppressing = 0
drop()
if (usr.guneqed == name)
usr << "You need to unequip it first."
else
set src in usr
Move(usr.loc)
reload()
if(ammo >= 500)
usr << "Your gun is already fully loaded."
else if (usr.clip == 0)
usr << "You need a clip to reload!"
else
reloading = 1
usr.Delay(90)
reloading = 0
ammo = 500
usr.clip -= 1
usr << "You have reloaded your gun."
ammo_count()
usr << "Your gun has [ammo] shots left."


And just for completeness sake, here is the HitCheck proc:

        HitCheckGun()
usr.CheckStat()
src.CheckStat()
usr.dir = get_dir(usr,src)
flick ("shoot",usr)
var/hitprob = rand(usr.quickness1,usr.quickness2)+usr.cyberhitbon+usr.bonus+usr.wephit
var/missprob = rand(src.quickness1,src.quickness2)+src.cybermissbon+src.bonus
if (hitprob > missprob)
if (prob(70))
DamageCheckGun()
else
view(5,src) << "[src] barely dodges [usr]'s bullets."
else if (hitprob < missprob)
if (prob(30))
DamageCheckGun()
else
view(5,src) << "[src] deftly dodges [usr]'s sloppy shooting."
else
if (prob(50))
DamageCheckGun()
else
view(5,src) << "[src] dodges [usr]'s attack."
In response to Zuglilth
You should not be using usr in that HitCheckGun() proc. Or any proc, in fact. You should be passing an argument, and using that instead.
In response to Garthor
I read through this link you gave me (http://www.byondscape.com/ascape.dmb/LummoxJR.2002-1104/).

It says that as long as the proc is called by a verb (in which case, it is) that using usr should be fine. The way the code works, this proc will always be called by a verb.
In response to Zuglilth
Unless if you, at any point, want to have an AI of any sort that shoots people. Like a bot, or a turret.
In response to Garthor
Which I do, and I will fix it. However, that tells me that this is not the problem I am having currently.
In response to Zuglilth
Yeah, I just got finished changing all the procs to no longer use usr.

I however get the same problem. This is the code currently:

obj/item
heavyspecial
Minigun
name = "GAU-17 Minigun"
icon = 'shopicons.dmi'
icon_state = "HeavySpecial"
layer = 1
var/ammo = 0
var/reloading = FALSE
var/suppressing = 0
verb
equip()
if(usr.guneqed != null)
usr <<"You already have a gun equiped."
else if(usr.meleeeqed != null)
usr <<"You already have something in your hands."
else
usr.guneqed = name
usr.wepbon = 100
unequip()
set src in view(0)
if(reloading)
usr <<"You are still reloading it."
else if(suppressing)
usr <<"You are still laying down a suppressing fire."
else if (usr.guneqed == null)
usr <<"You do not have a gun equiped."
else
usr.guneqed = null
usr.wepbon = 0
suppressing_fire()
while(suppressing && ammo > 0)
ammo -= 10
for(var/mob/M in areafire(get_step(usr,usr.dir), usr.dir, 7, 1))
spawn() M.HitCheckGun(M)
sleep(10)
suppressing = 0
if(ammo < 0) ammo = 0
check_fire()
if(suppressing == 0)
usr << "You have no fire to check!"
else
suppressing = 0

drop()
if (usr.guneqed == name)
usr << "You need to unequip it first."
else
set src in usr
Move(usr.loc)
reload()
if(ammo >= 500)
usr << "Your gun is already fully loaded."
else if (usr.clip == 0)
usr << "You need a clip to reload!"
else
reloading = 1
usr.Delay(90)
reloading = 0
ammo = 500
usr.clip -= 1
usr << "You have reloaded your gun."
ammo_count()
usr << "Your gun has [ammo] shots left."


        HitCheckGun(A)
var/mob/M =A
M.CheckStat()
src.CheckStat()
M.dir = get_dir(M,src)
flick ("shoot",M)
var/hitprob = rand(M.quickness1,M.quickness2)+M.cyberhitbon+M.bonus+M.wephit
var/missprob = rand(src.quickness1,src.quickness2)+src.cybermissbon+src.bonus
if (hitprob > missprob)
if (prob(70))
DamageCheckGun(M)
else
view(5,src) << "[src] barely dodges [M]'s bullets."
else if (hitprob < missprob)
if (prob(30))
DamageCheckGun(M)
else
view(5,src) << "[src] deftly dodges [M]'s sloppy shooting."
else
if (prob(50))
DamageCheckGun(M)
else
view(5,src) << "[src] dodges [M]'s attack."


        DamageCheckGun(A)
var/mob/M =A
RangedIsHit()
M << "[M] attacks [src]!"
oview(5,src) << "[M] attacks [src]!"
M.CheckStat()
src.CheckStat()
var/damage = rand(M.quickness1,M.quickness2) + rand(M.firearms1,M.firearms2) + M.wepbon + M.bonus+M.wepdam
var/soak = rand(src.toughness1,src.toughness2) + rand(src.armor1,src.armor2) + src.bonus + src.cybersoakbon
var/difference = damage - soak
if (difference < 0)
difference = 0
view(5,src) << "[M] strikes for [damage]!"
view(5,src) << "[src] soaks for [soak]!"
view(5,src) << "[src] takes [difference]!"
src.HP -= difference
src.DeathCheckMelee(M) //check for death with a proc


proc/areafire(var/atom/loc, var/dir, var/range, var/leftwidth, var/rightwidth = leftwidth)
if(range == 0 || !loc || loc.density) return list()
. = list()
. += loc
. += loc.contents
var/list/left = .(get_step(loc, turn(dir, 90)), turn(dir,90), leftwidth, 0)
var/list/right = .(get_step(loc, turn(dir,-90)), turn(dir,-90), rightwidth, 0)
. += left
. += right
. += .(get_step(loc, dir), dir, range-1, left.len, right.len)
In response to Zuglilth
But not working how?
In response to Garthor
Ok, I will press suppressing fire... and literally nothing happens. I expect to see the icon flick to the shooting state, that doesnt happen. That tells me it never calls the HitCheckGun() proc.

It doesn't even -10 ammo.
Page: 1 2