Index: src/map/unit.c =================================================================== --- src/map/unit.c (revision 17247) +++ src/map/unit.c (working copy) @@ -161,7 +161,7 @@ x += dx; y += dy; - map_moveblock(bl, x, y, tick); + map_moveblock(bl, x, y, tick); //move bl to new x y ud->walk_count++; //walked cell counter, to be used for walk-triggered skills. [Skotlex] status_change_end(bl, SC_ROLLINGCUTTER, INVALID_TIMER); //If you move, you lose your counters. [malufett] @@ -211,7 +211,7 @@ if(tid != INVALID_TIMER && !(ud->walk_count%WALK_SKILL_INTERVAL) && mobskill_use(md, tick, -1)) - { + { if (!(ud->skill_id == NPC_SELFDESTRUCTION && ud->skilltimer != INVALID_TIMER)) { //Skill used, abort walking clif_fixpos(bl); //Fix position as walk has been cancelled. @@ -397,8 +397,8 @@ // if flag&2, start attacking upon arrival within range, otherwise just walk to that character. int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int flag) { - struct unit_data *ud = NULL; - struct status_change *sc = NULL; + struct unit_data *ud = NULL; + struct status_change *sc = NULL; nullpo_ret(bl); nullpo_ret(tbl); Index: src/map/status.c =================================================================== --- src/map/status.c (revision 17247) +++ src/map/status.c (working copy) @@ -338,8 +338,8 @@ add_sc( BA_FROSTJOKER , SC_FREEZE ); set_sc( BA_WHISTLE , SC_WHISTLE , SI_BLANK , SCB_FLEE|SCB_FLEE2 ); set_sc( BA_ASSASSINCROSS , SC_ASSNCROS , SI_BLANK , SCB_ASPD ); - add_sc( BA_POEMBRAGI , SC_POEMBRAGI ); - set_sc( BA_APPLEIDUN , SC_APPLEIDUN , SI_BLANK , SCB_MAXHP ); + set_sc( BA_POEMBRAGI , SC_POEMBRAGI ,SI_FIREWEAPON ,SCB_NONE); + set_sc( BA_APPLEIDUN , SC_APPLEIDUN , SI_WATERWEAPON , SCB_MAXHP ); add_sc( DC_SCREAM , SC_STUN ); set_sc( DC_HUMMING , SC_HUMMING , SI_BLANK , SCB_HIT ); set_sc( DC_DONTFORGETME , SC_DONTFORGETME , SI_BLANK , SCB_SPEED|SCB_ASPD ); Index: src/map/skill.c =================================================================== --- src/map/skill.c (revision 17247) +++ src/map/skill.c (working copy) @@ -2413,7 +2413,7 @@ //Spirit of Wizard blocks Kaite's reflection if( type == 2 && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD ) { //Consume one Fragment per hit of the casted skill? [Skotlex] - type = tsd?pc_search_inventory (tsd, 7321):0; + type = tsd?pc_search_inventory (tsd, 7321):0; if (type >= 0) { if ( tsd ) pc_delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME); dmg.damage = dmg.damage2 = 0; @@ -2614,7 +2614,7 @@ if(damage > 0 && dmg.flag&BF_SKILL && tsd && pc_checkskill(tsd,RG_PLAGIARISM) - && (!sc || !sc->data[SC_PRESERVE]) + && (!sc || !sc->data[SC_PRESERVE]) && damage < tsd->battle_status.hp) { //Updated to not be able to copy skills if the blow will kill you. [Skotlex] int copy_skill = skill_id; @@ -11226,6 +11226,7 @@ type = status_skill2sc(sg->skill_id); sce = (sc && type != -1)?sc->data[type]:NULL; skill_id = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still. + ShowDebug("skill_unit_onplace, skill_id=%d, unit_id=%d\n",skill_id,sg->unit_id); switch (sg->unit_id) { case UNT_SPIDERWEB: if( sc && sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1 > 0 ) { @@ -11348,6 +11349,7 @@ case UNT_DONTFORGETME: case UNT_FORTUNEKISS: case UNT_SERVICEFORYOU: + ShowDebug("skill_unit_onplace, skill_id=%d, unit_id=%d\n",skill_id,sg->unit_id); if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) return 0; @@ -12146,6 +12148,8 @@ type = status_skill2sc(sg->skill_id); sce = (sc && type != -1)?sc->data[type]:NULL; + ShowDebug("skill_unit_onout skill_id=%d\n",sg->skill_id); + if( bl->prev==NULL || (status_isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB) ) //Need to delete the trap if the source died. return 0; @@ -12193,6 +12197,8 @@ struct status_change_entry *sce; enum sc_type type; + ShowDebug("skill_unit_onleft skill_id=%d\n",skill_id); + sc = status_get_sc(bl); if (sc && !sc->count) sc = NULL; @@ -12323,6 +12329,7 @@ //Necessary in case the group is deleted after calling on_place/on_out [Skotlex] skill_id = group->skill_id; //Target-type check. + ShowDebug("skill_unit_effect, skill_id=%d, flag=%d\n",skill_id,flag); isTarget = group->bl_flag & bl->type && battle_check_target( &unit->bl, bl, group->target_flag ) > 0; if( isTarget ){ if( flag&1 ) @@ -15791,7 +15798,7 @@ } } - if( dissonance ) skill_dance_switch(unit, 1); + if( dissonance ) skill_dance_switch(unit, 1); return 0; } @@ -15809,11 +15816,33 @@ } static int skill_unit_temp[20]; // temporary storage for tracking skill unit skill ids as players move in/out of them +// temporary storage for tracking skill unit skill ids as players move in/out of them + +//flag&2 store skillid +//flag=1 remove skillid +void skill_unit_move_sub2(uint16 skill_id, int flag){ + int i=0; + if(flag==1){ //Clear skill ids we have stored in onout. + ShowDebug("remove skillid from skillunittmp\n",skill_id,flag); + ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == skill_id ); + if( i < ARRAYLENGTH(skill_unit_temp) ) + skill_unit_temp[i] = 0; + } + if(flag&2) { //store the skill we have step into + ShowDebug("add skillid from skillunittmp\n",skill_id,flag); + //check if already here or empty place + ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == skill_id || skill_unit_temp[i] == 0 ); + if( i < ARRAYLENGTH(skill_unit_temp) ) + skill_unit_temp[i] = skill_id; + } +} + /*========================================== * flag : - * 1 : store that skill_unit in array - * 2 : clear that skill_unit - * 4 : call_on_left + * 1 : call_on_place - rm skillid in sk_unit_tmp + * 2 : call_on_out - add skillid from sk_unit_tmp + * 3 : call_on_left - place then out + * 4 : force on left *------------------------------------------*/ int skill_unit_move_sub (struct block_list* bl, va_list ap) { struct skill_unit* unit = (struct skill_unit *)bl; @@ -15845,68 +15874,28 @@ if( dissonance ) skill_dance_switch(unit, 1); return 0; } - //Target-type check. if( !(group->bl_flag&target->type && battle_check_target(&unit->bl,target,group->target_flag) > 0) ) { if( group->src_id == target->id && group->state.song_dance&0x2 ) { //Ensemble check to see if they went out/in of the area [Skotlex] - if( flag&1 ) { - if( flag&2 ) { //Clear this skill id. - ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == skill_id ); - if( i < ARRAYLENGTH(skill_unit_temp) ) - skill_unit_temp[i] = 0; - } - } else { - if( flag&2 ) { //Store this skill id. - ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == 0 ); - if( i < ARRAYLENGTH(skill_unit_temp) ) - skill_unit_temp[i] = skill_id; - else - ShowError("skill_unit_move_sub: Reached limit of unit objects per cell!\n"); - } - - } - - if( flag&4 ) - skill_unit_onleft(skill_id,target,tick); + ShowDebug("skill_unit_move_sub1, ensemble check\n",skill_id,flag); + if( dissonance ) skill_dance_switch(unit, 1); } - - if( dissonance ) skill_dance_switch(unit, 1); - return 0; } - else + else //unit correspond to target { - if( flag&1 ) - { - int result = skill_unit_onplace(unit,target,tick); - if( flag&2 && result ) - { //Clear skill ids we have stored in onout. - ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == result ); - if( i < ARRAYLENGTH(skill_unit_temp) ) - skill_unit_temp[i] = 0; - } + uint16 skid_tmp=-1; + ShowDebug("skill_unit_move_sub2, normal call skill_id=%d flag=%d\n",skill_id,flag); + if(flag&(1|2)){ //1 or 2 or 3 + if(flag&1) skid_tmp=skill_unit_onplace(unit,target,tick); + if(flag&2) skid_tmp=skill_unit_onout(unit,target,tick); + skill_unit_move_sub2(skill_id, flag); + ShowDebug("skill_tmp = %d\n",skid_tmp); } - else - { - int result = skill_unit_onout(unit,target,tick); - if( flag&2 && result ) - { //Store this unit id. - ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == 0 ); - if( i < ARRAYLENGTH(skill_unit_temp) ) - skill_unit_temp[i] = skill_id; - else - ShowError("skill_unit_move_sub: Reached limit of unit objects per cell!\n"); - } - } - - //TODO: Normally, this is dangerous since the unit and group could be freed - //inside the onout/onplace functions. Currently it is safe because we know song/dance - //cells do not get deleted within them. [Skotlex] - if( dissonance ) skill_dance_switch(unit, 1); - - if( flag&4 ) + if(flag&4 || skid_tmp==0) {//force onleft or (out+in = 0 (mean we left) ) + ShowDebug("skill_unit_move_sub2 call onleft\n",skill_id,flag); skill_unit_onleft(skill_id,target,tick); - + } return 1; } } @@ -15914,10 +15903,10 @@ /*========================================== * Invoked when a char has moved and unit cells must be invoked (onplace, onout, onleft) * Flag values: - * flag&1: invoke skill_unit_onplace (otherwise invoke skill_unit_onout) - * flag&2: this function is being invoked twice as a bl moves, store in memory the affected - * units to figure out when they have left a group. - * flag&4: Force a onleft event (triggered when the bl is killed, for example) + * flag&1: on place + * flag&2: on out + * flag&3: on left (yes that will do onout+onplace) + * flag&4: force onleft *------------------------------------------*/ int skill_unit_move (struct block_list *bl, unsigned int tick, int flag) { nullpo_ret(bl); @@ -15925,18 +15914,18 @@ if( bl->prev == NULL ) return 0; - if( flag&2 && !(flag&1) ) { //Onout, clear data - memset(skill_unit_temp, 0, sizeof(skill_unit_temp)); - } map_foreachincell(skill_unit_move_sub,bl->m,bl->x,bl->y,BL_SKILL,bl,tick,flag); - if( flag&2 && flag&1 ) { //Onplace, check any skill units you have left. + if(flag&4) { //Onleft, check any skill units you have left. int i; for( i = 0; i < ARRAYLENGTH(skill_unit_temp); i++ ) - if( skill_unit_temp[i] ) + if( skill_unit_temp[i] ) { + ShowDebug("skill_unit_move, callonleft with skill_id=%d\n",skill_unit_temp[i]); skill_unit_onleft(skill_unit_temp[i], bl, tick); } + memset(skill_unit_temp, 0, sizeof(skill_unit_temp)); // clear data + } return 0; } Index: src/map/map.c =================================================================== --- src/map/map.c (revision 17247) +++ src/map/map.c (working copy) @@ -380,7 +380,7 @@ if (bl->type&BL_CHAR) { sc = status_get_sc(bl); - skill_unit_move(bl,tick,2); + skill_unit_move(bl,tick,2); // check onout status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER); status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER); status_change_end(bl, SC_TINDER_BREAKER, INVALID_TIMER); @@ -408,7 +408,7 @@ if (bl->type&BL_CHAR) { - skill_unit_move(bl,tick,3); + skill_unit_move(bl,tick,3); //check on left (place+out)) if( bl->type == BL_PC && ((TBL_PC*)bl)->shadowform_id ) {//Shadow Form Target Moving struct block_list *d_bl; @@ -1699,7 +1699,7 @@ elemental_clean_effect(sd->ed); unit_remove_map(&sd->ed->bl,CLR_TELEPORT); } - + unit_remove_map_pc(sd,CLR_TELEPORT); if( map[sd->bl.m].instance_id ) { // Avoid map conflicts and warnings on next login Index: conf/char_athena.conf =================================================================== --- conf/char_athena.conf (revision 17247) +++ conf/char_athena.conf (working copy) @@ -165,7 +165,7 @@ // NOTE: Requires client 2011-03-09aragexeRE or newer. // A window is opened before you can select your character and you will have to enter a pincode by using only your mouse. // Default: yes -pincode_enabled: yes +pincode_enabled: no // How often does a user have to change his pincode? // 0: never (default)