Tio Akima 74 Posted September 11, 2016 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 ^^ Quote Share this post Link to post Share on other sites
0 Nerual 0 Posted September 11, 2016 (edited) Maybe check out Arrow Shower? Only skill I can think of that's not point and click on enemy. Edited September 11, 2016 by Wahahahaha Quote Share this post Link to post Share on other sites
0 Tio Akima 74 Posted September 12, 2016 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 Quote Share this post Link to post Share on other sites
0 Nardoth 4 Posted September 13, 2016 (edited) 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 September 13, 2016 by Nardoth Quote Share this post Link to post Share on other sites
0 Tio Akima 74 Posted September 13, 2016 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: I'm trying to edit these skills that I cited, to be able to do this. yet without success. =/ Quote Share this post Link to post Share on other sites
0 Nardoth 4 Posted September 14, 2016 (edited) 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 September 14, 2016 by Nardoth 1 Tio Akima reacted to this Quote Share this post Link to post Share on other sites
0 Tio Akima 74 Posted September 15, 2016 (edited) 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: 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 September 15, 2016 by Tio Akima Quote Share this post Link to post Share on other sites
0 Nardoth 4 Posted September 15, 2016 (edited) 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 September 15, 2016 by Nardoth 1 Tio Akima reacted to this Quote Share this post Link to post Share on other sites
0 Tio Akima 74 Posted September 15, 2016 (edited) 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 September 15, 2016 by Tio Akima Quote Share this post Link to post Share on other sites
0 Nardoth 4 Posted September 15, 2016 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. Quote Share this post Link to post Share on other sites
0 Tio Akima 74 Posted September 15, 2016 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 ??? Quote Share this post Link to post Share on other sites
0 Nardoth 4 Posted September 16, 2016 (edited) 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 September 16, 2016 by Nardoth Quote Share this post Link to post Share on other sites
0 Tio Akima 74 Posted September 16, 2016 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 ^^ Quote Share this post Link to post Share on other sites
Share this post
Link to post
Share on other sites