Jump to content
  • 0
Tio Akima

Check Collision in Skill

Question

Hello guys.

 

I'm trying to make a skill shot, that is ... a skill it is possible to enemy dodge.

 

And I see that the Ragnarok most skills are Point click, It makes things a little without thanks.

 

So if anyone knows and want to share information about.

 

 

I want to make skill where the player can launch the area. And also a check of collision, for the ability to stop at first that she hit. 

Enemy or monster.

 

ANOTHER DOUBT:  be possible a skill hit something the map? Launch the skill and she hit a wall, a mountain, or some object ???

 

Well that's it .. Complicated not?

 

thanks ^^

Share this post


Link to post
Share on other sites

12 answers to this question

Recommended Posts

  • 0

Maybe check out Arrow Shower? Only skill I can think of that's not point and click on enemy.

 

I tested the Skill to see how it works, but it did not work in my emuador. Weird

Share this post


Link to post
Share on other sites
  • 0

I think your best bet would be to check on ninja's Kamaitachi (NJ_KAMAITACHI) and make it cast on ground, but also it bypasses through every enemy so you should make it stop as soon as it hits 1 target.

Edited by Nardoth

Share this post


Link to post
Share on other sites
  • 0

I think your best bet would be to check on ninja's Kamaitachi (NJ_KAMAITACHI) and make it cast on ground, but also it bypasses through every enemy so you should make it stop as soon as it hits 1 target.

 

hi Nardoth

 

I looked at the Skill "Kamaitachi"
I believe she also served even my purpose.
In fact, I'm trying to do the following, let me explain:
 
When selecting an area, the skill takes my position (x, y character) and the selected position (x, y of the selected area) and launches the damage, starting from my position until selected position.
 
you see?
 
I will demonstrate the logic in this drawing:
 
skill_ilustrate.jpg
 

I'm trying to edit these skills that I cited, to be able to do this.

 

yet without success.

=/

Share this post


Link to post
Share on other sites
  • 0

I know what you are trying to do, what I said was about that. You need to study how kamaitachi works. It uses the map->foreachinpath function to attack to everyone in it's path. That function returns the total amount of damage done in the area, so you may use that to know if it already hit something in a convenient loop (i.e. looping at every cell in the path).
To set kamaitachi as a ground skill you go to your skill_db.conf and replace Enemy: true to Place: true, but after you do that the skill will stop calling skill->castend_damage_id to use skill->castend_pos2 (and because of that it will stop calling map->foreachinpath unless you set it to do that in castend_pos2).
 
To loop at everycell in it's range you will have to get the direction the src is facing and calculate the next coordinate it should be heading. 
Check the available functions in unit.c (or by typing unit-> ).

It seems to me that this is a very inefficient way to do it but I bet it will do the trick and is the best thing I know to do with the tools we have.

 

The only problem with this method is that the skill animation wont show up if the skill fails to find an target. The animation is called by clif->skill_damage but it needs a block_list as a target and you only have the coordinates x,y of the targeted cell. In the other hand, using the caster's block_list (src) as a target will make the animation head always to east, which is an issue.

 

I don't know about you but I never learn C, or C++, or whatever this language is (actually the only language I'm not afraid to say I know a bit is fortran), but after learning I can use printf("string") or printf("%d",int i) my understanding speed of this code increased greatly. It may be helpful to you. The output will be print in the map-server console and to write a new line use printf("\n") to make it readable.

It helps to find bugs in your code about what it is doing or where it's crashing. Trial and error will help you a lot.

Edited by Nardoth

Share this post


Link to post
Share on other sites
  • 0

I know what you are trying to do, what I said was about that. You need to study how kamaitachi works. It uses the map->foreachinpath function to attack to everyone in it's path. That function returns the total amount of damage done in the area, so you may use that to know if it already hit something in a convenient loop (i.e. looping at every cell in the path).

To set kamaitachi as a ground skill you go to your skill_db.conf and replace Enemy: true to Place: true, but after you do that the skill will stop calling skill->castend_damage_id to use skill->castend_pos2 (and because of that it will stop calling map->foreachinpath unless you set it to do that in castend_pos2).

 

To loop at everycell in it's range you will have to get the direction the src is facing and calculate the next coordinate it should be heading. 

Check the available functions in unit.c (or by typing unit-> ).

It seems to me that this is a very inefficient way to do it but I bet it will do the trick and is the best thing I know to do with the tools we have.

 

The only problem with this method is that the skill animation wont show up if the skill fails to find an target. The animation is called by clif->skill_damage but it needs a block_list as a target and you only have the coordinates x,y of the targeted cell. In the other hand, using the caster's block_list (src) as a target will make the animation head always to east, which is an issue.

 

I don't know about you but I never learn C, or C++, or whatever this language is (actually the only language I'm not afraid to say I know a bit is fortran), but after learning I can use printf("string") or printf("%d",int i) my understanding speed of this code increased greatly. It may be helpful to you. The output will be print in the map-server console and to write a new line use printf("\n") to make it readable.

It helps to find bugs in your code about what it is doing or where it's crashing. Trial and error will help you a lot.

 

hello Nardoth

 
Thanks for answering, that our conversation is clarifying me some things.
 
good, I was all day today studying and testing things.
 
sorry, it's hard to speak English to me.
 
Come on.
 
To use the function map-> foreachinpath () in castend_pos2, as you said, it needs to be configured.
 
This is the part  the code map->foreachinpath ()

 

map->foreachinpath(skill->attack_area,src->m,src->x,src->y,bl->x,bl->y,
                               skill->get_splash(skill_id, skill_lv),skill->get_maxcount(skill_id,skill_lv), skill->splash_target(src),
                               skill->get_type(skill_id),src,src,skill_id,skill_lv,tick,flag,BCT_ENEMY);
 

 

The part that needs to be set is part of setting the selected area:

bl->x
bl->y
You can not really use "bl-> x" and "bl-> y"
you need to define somehow

 

I tried to do is create a function in map.c and Map.h
this function:
int map_getbl( struct block_list *bl, int16 dx, int16 dy) {
    int16 dx, dy;
    
    dx = bl->x;
    dy =bl->y;

    return dx, dy;
} 

So I could replace the map->foreachinpath ():

map->foreachinpath(skill->attack_area,src->m,src->x,src->y,map->getbl,bl->y... etc

But I'm still confused how to do this.

If you can auxilar me, I'm grateful.

 

------------------------------------------------------------------------------------------------------

 
Now, let the other doubts
 
I want do a ''For()'' in the skill FirePillar - WZ_FIREPILLAR
 
The idea is to launch the skill, and go repeating along the way until you reach the selected area.
 
Like this:
 
essa_aqi_screen_skill.png

I have not done this for () to test, but I'm including in the conversation.

It is also the function skill_castend_pos2

I will also need to get the coordinates of the selected area and go running skill to get it

Edited by Tio Akima

Share this post


Link to post
Share on other sites
  • 0

In castend_pos2 there are already variables x and y that are set as parameters of the function, these are the coordinates of the cell the player casted the skill on, so you just have to replace bl->x and bl->y for just x and y respectively. But then again, in NJ_KAMAITACHI the animation does not show up when there are no enemies in the area.

 

The loop should advance from the last cell the animation showed up to the next one, until it hit's a target or reach the range of the skill, and then continue. I will let you do the math about how to calculate which cell it should go, probably you will have to mess with some conditions about the direction where the target cell is from your point of view.

 

It would look something like this:

for(i=0;i<range;i++){
     if (0<map->foreachinpath(skill->attack_area,src->m,previous_cellx(i),previous_celly(i),next_cellx(i),next_celly(i),
                               skill->get_splash(skill_id, skill_lv),skill->get_maxcount(skill_id,skill_lv), skill-  >splash_target(src),skill->get_type(skill_id),src,src,skill_id,skill_lv,tick,flag,BCT_ENEMY))
     continue;
}
 

Using the firepillar will be more tricky, since what it does is place a unit on the cell with skill->unitsetting if I guess correctly.

If that's the case, maybe it will help you to set a variable of the struct skill_unit_group to that unit of firepillar, and set it's alive parameter to a lower number so it does not persist after the skill is done casting and it disappears quickly.

 

 

PD: My main language is spanish, but I can understand you pretty well.

Edited by Nardoth

Share this post


Link to post
Share on other sites
  • 0
I understand.
I was going for the more complicated way then.
 
Now it's working. But still a little clumsy.
 
and do not need the BL, what put the "skill->area_temp [1] = BL> id;"  ?????
 
for now this way in castend_pos2:
 
ps: in skill->castend_damage_id, I removed the code that was it.

 

                               flag|=1;
                               skill->unitsetting(src, skill_id, skill_lv, x, y, flag);
            
//                            skill->area_temp[1] = bl->id;
            map->foreachinpath(skill->attack_area,src->m,src->x,src->y,x,y,
                               skill->get_splash(skill_id, skill_lv),skill->get_maxcount(skill_id,skill_lv), skill->splash_target(src),
                               skill->get_type(skill_id),src,src,skill_id,skill_lv,tick,flag,BCT_ENEMY);
 

 

And talking about the effect, he is not showing up, not with the enemy, and not without them. hahaha

 

about firepillar

sorry, I thought what using FirePillar, would be more easy.

already the loop just repeat the skill to reach the target.
But you are much more experienced than me. I follow your way.
 

I must calculate the range with get_unit_range?

skill->get_unit_range(skill_id, skill_lv);

thinking that the damage starts from the cell that was shot (in this case me)

so,

 

previous_cellx(i) and previous_celly(i)  here it will be changed to the cell that start?.

 

next_cellx(i) and next_cellxy(i) here it will be changed to the cell that start + i ?

 

and about the struct skill_unit_group,

 

you are talking about map->getcell()??

 

        case WZ_FIREPILLAR:
            if (map->getcell(src->m, src, x, y, CELL_CHKLANDPROTECTOR))
                return NULL;
            if((flag&1)!=0)
                limit=1000;
            val1=skill_lv+2;
            break;

sorry, I understand the logic, but I have difficulty in applying.

 

Edited by Tio Akima

Share this post


Link to post
Share on other sites
  • 0

As a comment in some function say: 

				// skill->area_temp[0] holds number of targets in area
				// skill->area_temp[1] holds the id of the original target
				// skill->area_temp[2] counts how many targets have already been processed

That's all I know about it.

 

We have to mess with the timer in order to get the skill to display properly, but I have made something that may help you wich is different from what we have done:

{
				int i=0;
				int64 delay=tick;
				int64 temp=tick;
				do{	
					if (timer->gettick()!=temp)
						temp=timer->gettick();
					else continue; //we need this because sometimes tick gets called too fast and it puts the same pillar over and over

					if (temp>=delay){
						struct skill_unit_group *su;						
						su=skill->unitsetting(src,WZ_FIREPILLAR,1,x+i,y+i,0);
						delay += 300; //Put a pillar of lvl 1 in the x+i,y+i diagonal (for testing purposes)
						su->limit = 400; //Pillar disappears after 0.4 seconds
						i++;
					}
				}while(temp<tick+2000); //Execute in 2 seconds
			}

The problem with this script is that it kind of stops everything until it ends the do loop, because it's not executing at every tick, but it may help as a start. You will also need a way to determine if it hits a target for it to stop placing more pillars. map->foreachinpath solved that problem in some way but can't be used here or the targets will be hit twice. 

Timed stuff and functions with va_args variables are my weak point and I can't help you with that but maybe you can flood your clif_delay_damage function with code that has nothing to do with what it does now to solve that problem. I used that function for that in some ocassion. That function is called at the tick it's set to in the variable.

Share this post


Link to post
Share on other sites
  • 0

As a comment in some function say: 

				// skill->area_temp[0] holds number of targets in area
				// skill->area_temp[1] holds the id of the original target
				// skill->area_temp[2] counts how many targets have already been processed

That's all I know about it.

 

We have to mess with the timer in order to get the skill to display properly, but I have made something that may help you wich is different from what we have done:

{
				int i=0;
				int64 delay=tick;
				int64 temp=tick;
				do{	
					if (timer->gettick()!=temp)
						temp=timer->gettick();
					else continue; //we need this because sometimes tick gets called too fast and it puts the same pillar over and over

					if (temp>=delay){
						struct skill_unit_group *su;						
						su=skill->unitsetting(src,WZ_FIREPILLAR,1,x+i,y+i,0);
						delay += 300; //Put a pillar of lvl 1 in the x+i,y+i diagonal (for testing purposes)
						su->limit = 400; //Pillar disappears after 0.4 seconds
						i++;
					}
				}while(temp<tick+2000); //Execute in 2 seconds
			}

The problem with this script is that it kind of stops everything until it ends the do loop, because it's not executing at every tick, but it may help as a start. You will also need a way to determine if it hits a target for it to stop placing more pillars. map->foreachinpath solved that problem in some way but can't be used here or the targets will be hit twice. 

Timed stuff and functions with va_args variables are my weak point and I can't help you with that but maybe you can flood your clif_delay_damage function with code that has nothing to do with what it does now to solve that problem. I used that function for that in some ocassion. That function is called at the tick it's set to in the variable.

 

 

understand, so I'll leave skill->area temp[0] commented.

 

I put  skill->area_temp [1] = SRC->id; to see what would happen and when using the skill I take damage along with the enemy. hahaha

how not to use the bl->id, I will leave this commented part //

 

About FirePillar
nice Thanks, I will test the code, but I'm with a doubt.
it goes in skill_castend_pos2 ??
Or goes in skill_unit_group ???

Share this post


Link to post
Share on other sites
  • 0

In skill_castend_pos2. But as I said it doesn't work properly because it's like it stops everything during those 2 seconds until the loop ends. Probably the best thing would be to call clif->delaydamage and adapt the code to that function.

Edited by Nardoth

Share this post


Link to post
Share on other sites
  • 0

In skill_castend_pos2. But as I said it doesn't work properly because it's like it stops everything during those 2 seconds until the loop ends. Probably the best thing would be to call clif->delaydamage and adapt the code to that function.

 

I certainly do not know adapt, hahaha
always I appreciate the help ^^

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.