ID:146285
 
Code:
obj
magic
WingBlade
name = "Wing Blade"
icon = 'Skills.dmi'
icon_state = "wingblade"
suffix = "Attack all monsters in 3 tiles infront of you with 80% ATK."
Click()
if(usr.InUseWingBlade == 0)
if(usr.LVL <15)
usr << "You're to weak to use this skill."
else
var/Target
if(usr.attackdelay == 0)
if(usr.dir == NORTH)
for(var/mob/A in usr.x,usr.y+1,usr.z)
Target += A
for(var/mob/B in usr.x-1,usr.y+1,usr.z)
Target += B
for(var/mob/C in usr.x+1,usr.y+1,usr.z)
Target += C
if(usr.dir == SOUTH)
for(var/mob/A in usr.x,usr.y-1,usr.z)
Target += A
for(var/mob/B in usr.x-1,usr.y-1,usr.z)
Target += B
for(var/mob/C in usr.x+1,usr.y-1,usr.z)
Target += C
if(usr.dir == EAST)
for(var/mob/A in usr.x+1,usr.y,usr.z)
Target += A
for(var/mob/B in usr.x+1,usr.y-1,usr.z)
Target += B
for(var/mob/C in usr.x+1,usr.y+1,usr.z)
Target += C
if(usr.dir == WEST)
for(var/mob/A in usr.x-1,usr.y,usr.z)
Target += A
for(var/mob/B in usr.x-1,usr.y-1,usr.z)
Target += B
for(var/mob/C in usr.x-1,usr.y+1,usr.z)
Target += C
usr.attackdelay = 1
var/BaseDam = rand((usr.STR/2), (usr.STR))
var/WeapDam = rand((usr.WeaponSTR/2 + usr.STRSkillBoost)*0.8, (usr.WeaponSTR + usr.STRSkillBoost)*0.8)
var/BaseDef = rand((Target:BaseDef/4), (Target:BaseDef / 2))
var/WeapDef = rand((Target:WeapDef/4), (Target:WeapDef / 2))
var/Dam = (WeapDam + BaseDam) - (BaseDef + WeapDef)
if(Dam <= 0)
Dam = 0
var/colour = "white"
s_damage(Target,Dam,colour)
if(Dam > 0)
var/colour = "white"
s_damage(Target,Dam,colour)
Target:HP -= Dam
Target:Death(Target,usr)
sleep(usr.equipweapdelay - usr.attackdelaybonus + usr.attackspeedpenalty)
usr.attackdelay = 0
else
return


Problem description:
I want it to select the 3 monsters infront of me, and attack those, but it crashes the game when i use it
You may want to use locate(usr.x,usr.y,usr.z) in your for statements, when checking for mobs in a specific area.
You can condense your three for() statments into one using the block() proc. Also, you could cut down on some cpu time by changing the four if() statments into one switch() statment. (usr.dir is only evaluated once in a switch statment, instead of four times in the if statments... not a big deal, but a good habit to pick up.)
switch(usr.dir)
if(NORTH)
for(var/mob/M in block(locate(usr.x-1,usr.y+1,usr.z),locate(usr.x+1,usr.y+1,usr.z)))
Target += M
if(SOUTH)
... etc.
In response to Igmolicious
Ill try it out and edit this post if it works
PS: I was really looking for a way to shorten it ;)

Ok, now the skill does NOTHING

obj
magic
WingBlade
name = "Wing Blade"
icon = 'Skills.dmi'
icon_state = "wingblade"
suffix = "Attack all monsters in 3 tiles infront of you with 80% ATK."
Click()
if(usr.InUseWingBlade == 0)
if(usr.LVL <15)
usr << "You're to weak to use this skill."
else
var/Target = list()
switch(usr.dir)
if(NORTH)
for(var/mob/M in block(locate(usr.x-1,usr.y+1,usr.z),locate(usr.x+1,usr.y+1,usr.z)))
Target += M
if(SOUTH)
for(var/mob/M in block(locate(usr.x-1,usr.y-1,usr.z),locate(usr.x+1,usr.y-1,usr.z)))
Target += M
if(WEST)
for(var/mob/M in block(locate(usr.x-1,usr.y+1,usr.z),locate(usr.x-1,usr.y-1,usr.z)))
Target += M
if(EAST)
for(var/mob/M in block(locate(usr.x+1,usr.y+1,usr.z),locate(usr.x+1,usr.y-1,usr.z)))
Target += M
var/BaseDam
var/WeapDam
var/Def
var/WeaponDef
var/Dam
for(var/mob/M in Target)
BaseDam = rand((usr.STR/2), (usr.STR))*0.8
WeapDam = rand((usr.WeaponSTR/2 + usr.STRSkillBoost)*0.8, (usr.WeaponSTR + usr.STRSkillBoost)*0.8)
Def = rand((M.BaseDef/4), (M.BaseDef / 2))
WeaponDef = rand((M.WeapDef/4), (M.WeapDef / 2))
Dam = (WeapDam + BaseDam) - (Def + WeaponDef)
usr << "[Dam]"
if(Dam <= 0)
Dam = 0
var/colour = "white"
for(var/mob/monster/M in Target)
s_damage(M,Dam,colour)
if(Dam > 0)
var/colour = "white"
for(var/mob/monster/M in Target)
s_damage(M,Dam,colour)
M.HP -= Dam
M.Death(Target,usr)
sleep(usr.equipweapdelay - usr.attackdelaybonus + usr.attackspeedpenalty)
usr.InUseWingBlade = 0
else
return
In response to Xeronage
Eh, I assumed you wanted something like the following code. It targets the three mobs dead-ahead of you, and attacks them.
obj/magic/WingBlade
name = "Wing Blade"
icon = 'Skills.dmi'
icon_state = "wingblade"
suffix = "Attack all monsters in 3 tiles infront of you with 80% ATK."
Click()
if(!usr.InUseWingBlade)
if(usr.LVL <15) {usr<<"You're to weak to use this skill.";return}
var/Target[0]
for(var/mob/monster/M in oview(3))
if(get_dir(usr,M)==usr.dir) Target.Add(M)
var/BaseDam
var/WeapDam
var/BaseDef
var/WeapDef
var/Dam
for(var/mob/M in Target)
BaseDam = rand((usr.STR/2),(usr.STR))
WeapDam = rand((usr.WeaponSTR/2+usr.STRSkillBoost)*0.8,(usr.WeaponSTR+usr.STRSkillBoost)*0.8)
BaseDef = rand((M:BaseDef/4),(M:BaseDef/2))
WeapDef = rand((M:WeapDef/4),(M:WeapDef/2))
Dam = (WeapDam+BaseDam)-(BaseDef+WeapDef)
var/colour = "white"
if(Dam<=0)
Dam = 0
for(var/mob/M in Target)
s_damage(M,Dam,colour)
if(Dam>0)
for(var/mob/M in Target)
s_damage(M,Dam,colour)
M.HP -= Dam
M.Death(Target,usr)
sleep(usr.equipweapdelay-usr.attackdelaybonus+usr.attackspeedpenalty)
usr.InUseWingBlade = 0
In response to CaptFalcon33035
I dont want em to hit the ones 3 tiles AWAY, just the 3 tiles INFRONT of you(2 diagonals + forward)
Bump
In response to CaptFalcon33035
There's a couple things that may be causing the proc to not do what you want it to, but still run without crashing:
  • 'if(!usr.InUseWingBlade)': Check to make sure that this variable starts as 0.
  • This will target any mob directly in front of you and up to three steps away; not exactly what you where looking for.
    for(var/mob/monster/M in oview(3))
    if(get_dir(usr,M)==usr.dir) Target.Add(M)
  • for(var/mob/M in Target)
    ...
    Dam = (WeapDam+BaseDam)-(BaseDef+WeapDef)
    //Check if Dam is actually a number
    if(Dam<=0)
    for(var/mob/M in Target)
    ...
    if(Dam>0)
    for(var/mob/M in Target)
    ...
    Here your looping through all mobs and making 'Dam' equal to some value. However, only the last mobs is really effecting the value of Dam, be cause it overrides what Dam was set to by all the other mobs. Because all three of your for() statements loop through the same mobs in the same container, combine them into one and your Dam code will actually do something.
    for(var/mob/M in Target)
    ...
    Dam = (WeapDam+BaseDam)-(BaseDef+WeapDef)
    if(!isnum(Dam))
    world<< "[Dam] is not a number!"
    CRASH()
    if(Dam>0)
    ...
    else
    ...
  • Dam = 0
    for(var/mob/M in Target)
    s_damage(M,Dam,colour)
    Does your s_damage proc allow 'Dam' to equal 0? Perhaps your proc is working, but Dam is 0 so nothing is happening.
In response to IainPeregrine
I did some check up using this

                usr << "works if u can read this"
for(var/mob/monster/M in Target)
usr << "works if u can read this"


Conclusion: The message PAST for() doesnt work.. so the problem has to be there

and if i use
for(var/mob/monster/M)

It attacks ALL monsters in the world so it does work though.. so the problem is with the Mobs being ADDED to Target
In response to Xeronage
Okay. Good job narrowing down our search area, that's always a good idea when you're having code problems. Isolate and investigate.

What I would do next is to test what areas I'm actually checking for mobs in. Here is the mob location code I gave you earlier. It seems I forgot that block() returns a list of turfs, and searching for mobs in that list will result in nothing. This error on my part may be what's causing you problems... sorry :/
switch(usr.dir)
if(NORTH)
for(var/mob/M in block(locate(usr.x-1,usr.y+1,usr.z),locate(usr.x+1,usr.y+1,usr.z)))
Target += M
if(SOUTH)
for(var/mob/M in block(locate(usr.x-1,usr.y-1,usr.z),locate(usr.x+1,usr.y-1,usr.z)))
Target += M
if(WEST)
for(var/mob/M in block(locate(usr.x-1,usr.y+1,usr.z),locate(usr.x-1,usr.y-1,usr.z)))
Target += M
if(EAST)
for(var/mob/M in block(locate(usr.x+1,usr.y+1,usr.z),locate(usr.x+1,usr.y-1,usr.z)))
Target += M

Before we test the turfs, I'm going to condense those four for() loops into one.
var/list/test_turfs
switch(usr.dir)
if(NORTH)
test_turfs = block(locate(usr.x-1,usr.y+1,usr.z),locate(usr.x+1,usr.y+1,usr.z)))
if(SOUTH)
test_turfs = block(locate(usr.x-1,usr.y-1,usr.z),locate(usr.x+1,usr.y-1,usr.z)))
if(WEST)
test_turfs = block(locate(usr.x-1,usr.y+1,usr.z),locate(usr.x-1,usr.y-1,usr.z)))
if(EAST)
test_turfs = block(locate(usr.x+1,usr.y+1,usr.z),locate(usr.x+1,usr.y-1,usr.z)))
for(var/turf/T in test_turfs)
for(var/mob/M in T.contents)
Target.Add(M)

There we loop through all the turfs, and then loop through each of those looking for mobs.

If that still doesn't work, we can loop through test_turfs to see exactly which turfs we are searching in for mobs. For this test, I'll ask you to make an icon file called 'diagnostic.dmi' with an icon_state named "black_square". Then add this code directly after the code in comments:
/*for(var/turf/T in test_turfs)
for(var/mob/M in T.contents)
Target.Add(M)*/

for(var/turf/T in test_turfs)
T.icon = 'diagnostic.dmi'
T.icon_state="black_square"

This will turn the turfs we looked for in the switch() statement into a black square, letting us know without a doubt if we are using the block() correctly.
In response to IainPeregrine
Ok, problem solved >.> made Target and List_turfs empty the wrong way
----------
Ok, now I get

runtime error: type mismatch
proc name: Click (/obj/magic/WingBlade/Click)
usr: Xeronage (/mob/player)
src: Wing Blade (/obj/magic/WingBlade)
call stack:
Wing Blade (/obj/magic/WingBlade): Click("Magic")

when i click it sometimes
obj
magic
WingBlade
name = "Wing Blade"
icon = 'Skills.dmi'
icon_state = "wingblade"
suffix = "Attack all monsters in 3 tiles infront of you with 80% ATK."
Click()
if(usr.InUseWingBlade == 0)
if(usr.LVL <15)
usr << "You're to weak to use this skill."
else
var/Target
if(usr.attackdelay == 0)
for(var/mob/M in oview(1))
switch(dir)
if(NORTH)
switch(get_dir(usr,M))
if(NORTHWEST)
Target += M
if(NORTH)
Target += M
if(NORTHEAST)
Target += M
if(SOUTH)
switch(get_dir(usr,M))
if(SOUTHWEST)
Target += M
if(SOUTH)
Target += M
if(SOUTHEAST)
Target += M
if(EAST)
switch(get_dir(usr,M))
if(NORTHEAST)
Target += M
if(EAST)
Target += M
if(SOUTHEAST)
Target += M
if(WEST)
switch(get_dir(usr,M))
if(NORTHWEST)
Target += M
if(WEST)
Target += M
if(SOUTHWEST)
Target += M
usr.attackdelay = 1
var/BaseDam = rand((usr.STR/2), (usr.STR))
var/WeapDam = rand((usr.WeaponSTR/2 + usr.STRSkillBoost)*0.8, (usr.WeaponSTR + usr.STRSkillBoost)*0.8)
var/BaseDef = rand((Target:BaseDef/4), (Target:BaseDef / 2))
var/WeapDef = rand((Target:WeapDef/4), (Target:WeapDef / 2))
var/Dam = (WeapDam + BaseDam) - (BaseDef + WeapDef)
if(Dam <= 0)
Dam = 0
var/colour = "white"
s_damage(Target,Dam,colour)
if(Dam > 0)
var/colour = "white"
s_damage(Target,Dam,colour)
Target:HP -= Dam
Target:Death(Target,usr)
sleep(usr.equipweapdelay - usr.attackdelaybonus + usr.attackspeedpenalty)
usr.attackdelay = 0
else
return

try that on for size...its longer but it sure is a heck of a lot easier to understand
In response to Peckerwd
I can understand the rest too =\ and problem is solved already