Index: src/map/pc.c =================================================================== --- src/map/pc.c (revision 17299) +++ src/map/pc.c (working copy) @@ -4724,10 +4724,11 @@ return 1; } - if( pc_isdead(sd) ) - { //Revive dead people before warping them - pc_setstand(sd); - pc_setrestartvalue(sd,1); + if( pc_isdead(sd) ) { //Revive dead people before warping them + if( !sd->status.hp == 1 ) { // Occurs when character is warped before setting HP to 0 + pc_setstand(sd); + pc_setrestartvalue(sd,1); + } } m = map_mapindex2mapid(mapindex); Index: src/map/skill.c =================================================================== --- src/map/skill.c (revision 17299) +++ src/map/skill.c (working copy) @@ -12221,49 +12221,59 @@ (status_isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB) ) //Need to delete the trap if the source died. return 0; - switch(sg->unit_id){ - case UNT_SAFETYWALL: - case UNT_PNEUMA: - case UNT_EPICLESIS://Arch Bishop - case UNT_NEUTRALBARRIER: - case UNT_STEALTHFIELD: - if (sce) - status_change_end(bl, type, INVALID_TIMER); - break; + switch(sg->unit_id) { + case UNT_SAFETYWALL: + case UNT_PNEUMA: + case UNT_EPICLESIS://Arch Bishop + case UNT_NEUTRALBARRIER: + case UNT_STEALTHFIELD: + if (sce) + status_change_end(bl, type, INVALID_TIMER); + break; - case UNT_BASILICA: - if( sce && sce->val4 == src->bl.id ) - status_change_end(bl, type, INVALID_TIMER); - break; - case UNT_HERMODE: //Clear Hermode if the owner moved. - if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id) - status_change_end(bl, type, INVALID_TIMER); - break; + case UNT_BASILICA: + if( sce && sce->val4 == src->bl.id ) + status_change_end(bl, type, INVALID_TIMER); + break; + case UNT_HERMODE: //Clear Hermode if the owner moved. + if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id) + status_change_end(bl, type, INVALID_TIMER); + break; - case UNT_SPIDERWEB: - { - struct block_list *target = map_id2bl(sg->val2); - if (target && target==bl) + case UNT_SPIDERWEB: { - if (sce && sce->val3 == sg->group_id) - status_change_end(bl, type, INVALID_TIMER); - sg->limit = DIFF_TICK(tick,sg->tick)+1000; + struct block_list *target = map_id2bl(sg->val2); + if (target && target==bl) + { + if (sce && sce->val3 == sg->group_id) + status_change_end(bl, type, INVALID_TIMER); + sg->limit = DIFF_TICK(tick,sg->tick)+1000; + } + break; } - break; - } - case UNT_DISSONANCE: - case UNT_UGLYDANCE: //Used for updating timers in song overlap instances - { - short i; - for(i = BA_WHISTLE; i <= DC_SERVICEFORYOU; i++){ - if(skill_get_inf2(i)&(INF2_SONG_DANCE)){ - type = status_skill2sc(i); - sce = (sc && type != -1)?sc->data[type]:NULL; - if(sce) - return i; + case UNT_DISSONANCE: + case UNT_UGLYDANCE: //Used for updating timers in song overlap instances + { + short i; + for(i = BA_WHISTLE; i <= DC_SERVICEFORYOU; i++){ + if(skill_get_inf2(i)&(INF2_SONG_DANCE)){ + type = status_skill2sc(i); + sce = (sc && type != -1)?sc->data[type]:NULL; + if(sce) + return i; + } } } - } + case UNT_WHISTLE: + case UNT_ASSASSINCROSS: + case UNT_POEMBRAGI: + case UNT_APPLEIDUN: + case UNT_HUMMING: + case UNT_DONTFORGETME: + case UNT_FORTUNEKISS: + case UNT_SERVICEFORYOU: + if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) + return 0; } return sg->skill_id; } @@ -12301,8 +12311,8 @@ case BD_ROKISWEIL: case BD_INTOABYSS: case BD_SIEGFRIED: - if(sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == skill_id) - { //Check if you just stepped out of your ensemble skill to cancel dancing. [Skotlex] + if(sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == skill_id) { + //Check if you just stepped out of your ensemble skill to cancel dancing. [Skotlex] //We don't check for SC_LONGING because someone could always have knocked you back and out of the song/dance. //FIXME: This code is not perfect, it doesn't checks for the real ensemble's owner, //it only checks if you are doing the same ensemble. So if there's two chars doing an ensemble @@ -12361,8 +12371,7 @@ case DC_DONTFORGETME: case DC_FORTUNEKISS: case DC_SERVICEFORYOU: - if (sce) - { + if (sce) { delete_timer(sce->timer, status_change_timer); //NOTE: It'd be nice if we could get the skill_lv for a more accurate extra time, but alas... //not possible on our current implementation. @@ -12371,8 +12380,7 @@ } break; case PF_FOGWALL: - if (sce) - { + if (sce) { status_change_end(bl, type, INVALID_TIMER); if ((sce=sc->data[SC_BLIND])) { @@ -12430,8 +12438,10 @@ if( isTarget ){ if( flag&1 ) skill_unit_onplace(unit,bl,tick); - else - skill_unit_onout(unit,bl,tick); + else { + if (!skill_unit_onout(unit,bl,tick)) // When a player attempts to update their own timer, we stop them + return 0; + } if( flag&4 ) skill_unit_onleft(skill_id, bl, tick); @@ -15929,12 +15939,11 @@ return 0; // Fiberlock is never supposed to trigger on skill_unit_move. [Inkfish] dissonance = skill_dance_switch(unit, 0); - //Necessary in case the group is deleted after calling on_place/on_out [Skotlex] skill_id = unit->group->skill_id; - if( unit->group->interval != -1 && !(skill_get_unit_flag(skill_id)&UF_DUALMODE) && skill_id != BD_LULLABY ) //Lullaby is the exception, bugreport:411 - { //Non-dualmode unit skills with a timer don't trigger when walking, so just return + if( unit->group->interval != -1 && !(skill_get_unit_flag(skill_id)&UF_DUALMODE) && skill_id != BD_LULLABY ) { //Lullaby is the exception, bugreport:411 + //Non-dualmode unit skills with a timer don't trigger when walking, so just return if( dissonance ) { skill_dance_switch(unit, 1); skill_unit_onleft(skill_unit_onout(unit,target,tick),target,tick); //we placed a dissonance, let's update @@ -15969,24 +15978,17 @@ if( dissonance ) skill_dance_switch(unit, 1); return 0; - } - else - { - if( flag&1 ) - { + } else { + if( flag&1 ) { int result = skill_unit_onplace(unit,target,tick); - if( flag&2 && result ) - { //Clear skill ids we have stored in onout. + 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; } - } - else - { + } else { int result = skill_unit_onout(unit,target,tick); - if( flag&2 && result ) - { //Store this unit id. + 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;