Selaa lähdekoodia

Song/Dance timers cannot be updated by self without Soul Link - Fixes bugreport:7155
Updated Magic Crasher for Renewal - Fixes bugreport:6340
Attempt to fix walking dead by modifying death function sequence - Fixes bugreport:7607 (but blame aleos if it breaks something - he helped me)
Some code cleanup

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17301 54d463be-8e91-2dee-dedb-b68131a5f0ec

akinari1087 12 vuotta sitten
vanhempi
commit
1b5e1a8f8f
6 muutettua tiedostoa jossa 237 lisäystä ja 275 poistoa
  1. 21 35
      src/map/battle.c
  2. 3 4
      src/map/clif.c
  3. 96 105
      src/map/mob.c
  4. 54 65
      src/map/pc.c
  5. 55 53
      src/map/skill.c
  6. 8 13
      src/map/status.c

+ 21 - 35
src/map/battle.c

@@ -1423,8 +1423,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
 		weapon = sd->weapontype1;
 	else
 		weapon = sd->weapontype2;
-	switch(weapon)
-	{
+	switch(weapon) {
 		case W_1HSWORD:
 			#ifdef RENEWAL
 				if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0)
@@ -1516,10 +1515,8 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
 	short type = 0;
 	int damage = 0;
 
-	if (!sd)
-	{	//Mobs/Pets
-		if(flag&4)
-		{
+	if (!sd) { //Mobs/Pets
+		if(flag&4) {
 			atkmin = status->matk_min;
 			atkmax = status->matk_max;
 		} else {
@@ -1528,12 +1525,11 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
 		}
 		if (atkmin > atkmax)
 			atkmin = atkmax;
-	} else {	//PCs
+	} else { //PCs
 		atkmax = wa->atk;
 		type = (wa == &status->lhw)?EQI_HAND_L:EQI_HAND_R;
 
-		if (!(flag&1) || (flag&2))
-		{	//Normal attacks
+		if (!(flag&1) || (flag&2)) { //Normal attacks
 			atkmin = status->dex;
 
 			if (sd->equip_index[type] >= 0 && sd->inventory_data[sd->equip_index[type]])
@@ -1542,8 +1538,7 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
 			if (atkmin > atkmax)
 				atkmin = atkmax;
 
-			if(flag&2 && !(flag&16))
-			{	//Bows
+			if(flag&2 && !(flag&16)) { //Bows
 				atkmin = atkmin*atkmax/100;
 				if (atkmin > atkmax)
 					atkmax = atkmin;
@@ -1560,8 +1555,7 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
 	else
 		damage = atkmax;
 
-	if (sd)
-	{
+	if (sd) {
 		//rodatazone says the range is 0~arrow_atk-1 for non crit
 		if (flag&2 && sd->bonus.arrow_atk)
 			damage += ( (flag&1) ? sd->bonus.arrow_atk : rnd()%sd->bonus.arrow_atk );
@@ -1576,6 +1570,10 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
 	//Finally, add baseatk
 	if(flag&4)
 		damage += status->matk_min;
+#ifdef RENEWAL
+	else if(flag&32)
+		damage += status->matk_min + status->batk;
+#endif
 	else
 		damage += status->batk;
 
@@ -1879,30 +1877,14 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 		}
 		else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW
 			&& (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1){
-				int chance = rand()%100;
+				int chance = rnd()%100;
 				wd.type = 0x08;
-				switch(sc->data[SC_FEARBREEZE]->val1){
-					case 5:
-						if( chance < 3){// 3 % chance to attack 5 times.
-							wd.div_ = 5;
-							break;
-						}
-					case 4:
-						if( chance < 7){// 6 % chance to attack 4 times.
-							wd.div_ = 4;
-							break;
-						}
-					case 3:
-						if( chance < 10){// 9 % chance to attack 3 times.
-							wd.div_ = 3;
-							break;
-						}
+				switch(sc->data[SC_FEARBREEZE]->val1) {
+					case 5: if( chance < 4) { wd.div_ = 5; break; } // 3 % chance to attack 5 times.
+					case 4: if( chance < 7) { wd.div_ = 4; break; } // 6 % chance to attack 4 times.
+					case 3: if( chance < 10) { wd.div_ = 3; break; } // 9 % chance to attack 3 times.
 					case 2:
-					case 1:
-						if( chance < 13){// 12 % chance to attack 2 times.
-							wd.div_ = 2;
-							break;
-						}
+					case 1: if( chance < 13) { wd.div_ = 2; break; } // 12 % chance to attack 2 times.
 				}
 				wd.div_ = min(wd.div_,sd->status.inventory[i].amount);
 				sc->data[SC_FEARBREEZE]->val4 = wd.div_-1;
@@ -2161,7 +2143,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 			{
 				i = (flag.cri?1:0)|
 					(flag.arrow?2:0)|
+#ifndef RENEWAL
 					(skill_id == HW_MAGICCRASHER?4:0)|
+#else
+					(skill_id == HW_MAGICCRASHER?32:0)|
+#endif
 					(!skill_id && sc && sc->data[SC_CHANGE]?4:0)|
 					(skill_id == MO_EXTREMITYFIST?8:0)|
 					(sc && sc->data[SC_WEAPONPERFECTION]?8:0);

+ 3 - 4
src/map/clif.c

@@ -12066,11 +12066,10 @@ void clif_parse_GuildChangeNotice(int fd, struct map_session_data* sd)
 }
 
 // Helper function for guild invite functions
-int
-clif_sub_guild_invite(int fd, struct map_session_data *sd, struct map_session_data *t_sd) {
-	if (t_sd == NULL) {// not online or does not exist
+int clif_sub_guild_invite(int fd, struct map_session_data *sd, struct map_session_data *t_sd)
+{
+	if (t_sd == NULL) // not online or does not exist
 		return 1;
-	}
 
 	if (map[sd->bl.m].flag.guildlock) {//Guild locked.
 		clif_displaymessage(fd, msg_txt(sd,228));

+ 96 - 105
src/map/mob.c

@@ -2109,8 +2109,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	status = &md->status;
 	sc = &md->sc;
 
-	if( src && src->type == BL_PC )
-	{
+	if( src && src->type == BL_PC ) {
 		sd = (struct map_session_data *)src;
 		mvp_sd = sd;
 	}
@@ -2118,10 +2117,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	if( md->guardian_data && md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS )
 		guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
 
-	if( src )
-	{ // Use Dead skill only if not killed by Script or Command
+	if( src ) { // Use Dead skill only if not killed by Script or Command
+		md->status.hp = 1;
 		md->state.skillstate = MSS_DEAD;
 		mobskill_use(md,tick,-1);
+		md->status.hp = 0;
 	}
 
 	map_freeblock_lock();
@@ -2133,8 +2133,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 	// filter out entries not eligible for exp distribution
 	memset(tmpsd,0,sizeof(tmpsd));
-	for(i = 0, count = 0, mvp_damage = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++)
-	{
+	for(i = 0, count = 0, mvp_damage = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++) {
 		struct map_session_data* tsd = map_charid2sd(md->dmglog[i].id);
 
 		if(tsd == NULL)
@@ -2168,8 +2167,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	// determines, if the monster was killed by homunculus' damage only
 	homkillonly = (bool)( ( dmgbltypes&BL_HOM ) && !( dmgbltypes&~BL_HOM ) );
 
-	if(!battle_config.exp_calc_type && count > 1)
-	{	//Apply first-attacker 200% exp share bonus
+	if(!battle_config.exp_calc_type && count > 1) {	//Apply first-attacker 200% exp share bonus
 		//TODO: Determine if this should go before calculating the MVP player instead of after.
 		if (UINT_MAX - md->dmglog[0].dmg > md->tdmg) {
 			md->tdmg += md->dmglog[0].dmg;
@@ -2200,111 +2198,110 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 		if(battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris]
 			bonus += (md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate;
 
-	for(i = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++) {
-		int flag=1,zeny=0;
-		unsigned int base_exp, job_exp;
-		double per; //Your share of the mob's exp
+		for(i = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++) {
+			int flag=1,zeny=0;
+			unsigned int base_exp, job_exp;
+			double per; //Your share of the mob's exp
 
-		if (!tmpsd[i]) continue;
+			if (!tmpsd[i]) continue;
 
-		if (!battle_config.exp_calc_type && md->tdmg)
-			//jAthena's exp formula based on total damage.
-			per = (double)md->dmglog[i].dmg/(double)md->tdmg;
-		else {
-			//eAthena's exp formula based on max hp.
-			per = (double)md->dmglog[i].dmg/(double)status->max_hp;
-			if (per > 2) per = 2; // prevents unlimited exp gain
-		}
+			if (!battle_config.exp_calc_type && md->tdmg)
+				//jAthena's exp formula based on total damage.
+				per = (double)md->dmglog[i].dmg/(double)md->tdmg;
+			else {
+				//eAthena's exp formula based on max hp.
+				per = (double)md->dmglog[i].dmg/(double)status->max_hp;
+				if (per > 2) per = 2; // prevents unlimited exp gain
+			}
 
-		if (count>1 && battle_config.exp_bonus_attacker) {
-			//Exp bonus per additional attacker.
-			if (count > battle_config.exp_bonus_max_attacker)
-				count = battle_config.exp_bonus_max_attacker;
-			per += per*((count-1)*battle_config.exp_bonus_attacker)/100.;
-		}
+			if (count>1 && battle_config.exp_bonus_attacker) {
+				//Exp bonus per additional attacker.
+				if (count > battle_config.exp_bonus_max_attacker)
+					count = battle_config.exp_bonus_max_attacker;
+				per += per*((count-1)*battle_config.exp_bonus_attacker)/100.;
+			}
 
-		// change experience for different sized monsters [Valaris]
-		if (battle_config.mob_size_influence) {
-			switch( md->special_state.size ) {
-				case SZ_MEDIUM:
-					per /= 2.;
-					break;
-				case SZ_BIG:
-					per *= 2.;
-					break;
+			// change experience for different sized monsters [Valaris]
+			if (battle_config.mob_size_influence) {
+				switch( md->special_state.size ) {
+					case SZ_MEDIUM:
+						per /= 2.;
+						break;
+					case SZ_BIG:
+						per *= 2.;
+						break;
+				}
 			}
-		}
 
-		if( md->dmglog[i].flag == MDLF_PET )
-			per *= battle_config.pet_attack_exp_rate/100.;
+			if( md->dmglog[i].flag == MDLF_PET )
+				per *= battle_config.pet_attack_exp_rate/100.;
 
-		if(battle_config.zeny_from_mobs && md->level) {
-			 // zeny calculation moblv + random moblv [Valaris]
-			zeny=(int) ((md->level+rnd()%md->level)*per*bonus/100.);
-			if(md->db->mexp > 0)
-				zeny*=rnd()%250;
-		}
+			if(battle_config.zeny_from_mobs && md->level) {
+				 // zeny calculation moblv + random moblv [Valaris]
+				zeny=(int) ((md->level+rnd()%md->level)*per*bonus/100.);
+				if(md->db->mexp > 0)
+					zeny*=rnd()%250;
+			}
 
-		if (map[m].flag.nobaseexp || !md->db->base_exp)
-			base_exp = 0;
-		else
-			base_exp = (unsigned int)cap_value(md->db->base_exp * per * bonus/100. * map[m].bexp/100., 1, UINT_MAX);
+			if (map[m].flag.nobaseexp || !md->db->base_exp)
+				base_exp = 0;
+			else
+				base_exp = (unsigned int)cap_value(md->db->base_exp * per * bonus/100. * map[m].bexp/100., 1, UINT_MAX);
 
-		if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost.
-			job_exp = 0;
-		else
-			job_exp = (unsigned int)cap_value(md->db->job_exp * per * bonus/100. * map[m].jexp/100., 1, UINT_MAX);
-
-		if ( ( temp = tmpsd[i]->status.party_id)>0 ) {
-			int j;
-			for( j = 0; j < pnum && pt[j].id != temp; j++ ); //Locate party.
-
-			if( j == pnum ) { //Possibly add party.
-				pt[pnum].p = party_search(temp);
-				if(pt[pnum].p && pt[pnum].p->party.exp) {
-					pt[pnum].id = temp;
-					pt[pnum].base_exp = base_exp;
-					pt[pnum].job_exp = job_exp;
-					pt[pnum].zeny = zeny; // zeny share [Valaris]
-					pnum++;
-					flag = 0;
-				}
-			} else {	//Add to total
-				if (pt[j].base_exp > UINT_MAX - base_exp)
-					pt[j].base_exp = UINT_MAX;
-				else
-					pt[j].base_exp += base_exp;
+			if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost.
+				job_exp = 0;
+			else
+				job_exp = (unsigned int)cap_value(md->db->job_exp * per * bonus/100. * map[m].jexp/100., 1, UINT_MAX);
+
+			if ( ( temp = tmpsd[i]->status.party_id)>0 ) {
+				int j;
+				for( j = 0; j < pnum && pt[j].id != temp; j++ ); //Locate party.
+
+				if( j == pnum ) { //Possibly add party.
+					pt[pnum].p = party_search(temp);
+					if(pt[pnum].p && pt[pnum].p->party.exp) {
+						pt[pnum].id = temp;
+						pt[pnum].base_exp = base_exp;
+						pt[pnum].job_exp = job_exp;
+						pt[pnum].zeny = zeny; // zeny share [Valaris]
+						pnum++;
+						flag = 0;
+					}
+				} else {	//Add to total
+					if (pt[j].base_exp > UINT_MAX - base_exp)
+						pt[j].base_exp = UINT_MAX;
+					else
+						pt[j].base_exp += base_exp;
 
-				if (pt[j].job_exp > UINT_MAX - job_exp)
-					pt[j].job_exp = UINT_MAX;
-				else
-					pt[j].job_exp += job_exp;
+					if (pt[j].job_exp > UINT_MAX - job_exp)
+						pt[j].job_exp = UINT_MAX;
+					else
+						pt[j].job_exp += job_exp;
 
-				pt[j].zeny += zeny;  // zeny share [Valaris]
-				flag = 0;
+					pt[j].zeny += zeny;  // zeny share [Valaris]
+					flag = 0;
+				}
 			}
-		}
-		if(base_exp && md->dmglog[i].flag == MDLF_HOMUN) //tmpsd[i] is null if it has no homunc.
-			merc_hom_gainexp(tmpsd[i]->hd, base_exp);
-		if(flag) {
-			if(base_exp || job_exp)
-			{
-				if( md->dmglog[i].flag != MDLF_PET || battle_config.pet_attack_exp_to_master ) {
+			if(base_exp && md->dmglog[i].flag == MDLF_HOMUN) //tmpsd[i] is null if it has no homunc.
+				merc_hom_gainexp(tmpsd[i]->hd, base_exp);
+			if(flag) {
+				if(base_exp || job_exp) {
+					if( md->dmglog[i].flag != MDLF_PET || battle_config.pet_attack_exp_to_master ) {
 #ifdef RENEWAL_EXP
-					int rate = pc_level_penalty_mod(tmpsd[i], md->level, md->status.race, md->status.mode, 1);
-					base_exp = (unsigned int)cap_value(base_exp * rate / 100, 1, UINT_MAX);
-					job_exp = (unsigned int)cap_value(job_exp * rate / 100, 1, UINT_MAX);
+						int rate = pc_level_penalty_mod(tmpsd[i], md->level, md->status.race, md->status.mode, 1);
+						base_exp = (unsigned int)cap_value(base_exp * rate / 100, 1, UINT_MAX);
+						job_exp = (unsigned int)cap_value(job_exp * rate / 100, 1, UINT_MAX);
 #endif
-					pc_gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false);
+						pc_gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false);
+					}
 				}
+				if(zeny) // zeny from mobs [Valaris]
+					pc_getzeny(tmpsd[i], zeny, LOG_TYPE_PICKDROP_MONSTER, NULL);
 			}
-			if(zeny) // zeny from mobs [Valaris]
-				pc_getzeny(tmpsd[i], zeny, LOG_TYPE_PICKDROP_MONSTER, NULL);
 		}
-	}
 
-	for( i = 0; i < pnum; i++ ) //Party share.
-		party_exp_share(pt[i].p, &md->bl, pt[i].base_exp,pt[i].job_exp,pt[i].zeny);
+		for( i = 0; i < pnum; i++ ) //Party share.
+			party_exp_share(pt[i].p, &md->bl, pt[i].base_exp,pt[i].job_exp,pt[i].zeny);
 
 	} //End EXP giving.
 
@@ -2332,8 +2329,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 		dlist->third_charid = (third_sd ? third_sd->status.char_id : 0);
 		dlist->item = NULL;
 
-		for (i = 0; i < MAX_MOB_DROP; i++)
-		{
+		for (i = 0; i < MAX_MOB_DROP; i++) {
 			if (md->db->dropitem[i].nameid <= 0)
 				continue;
 			if ( !(it = itemdb_exists(md->db->dropitem[i].nameid)) )
@@ -2346,8 +2342,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 			}
 
 			// change drops depending on monsters size [Valaris]
-			if (battle_config.mob_size_influence)
-			{
+			if (battle_config.mob_size_influence) {
 				if (md->special_state.size == SZ_MEDIUM && drop_rate >= 2)
 					drop_rate /= 2;
 				else if( md->special_state.size == SZ_BIG)
@@ -2408,8 +2403,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 		if(sd) {
 			// process script-granted extra drop bonuses
 			int itemid = 0;
-			for (i = 0; i < ARRAYLENGTH(sd->add_drop) && (sd->add_drop[i].id || sd->add_drop[i].group); i++)
-			{
+			for (i = 0; i < ARRAYLENGTH(sd->add_drop) && (sd->add_drop[i].id || sd->add_drop[i].group); i++) {
 				if ( sd->add_drop[i].race == -md->class_ ||
 					( sd->add_drop[i].race > 0 && (
 						sd->add_drop[i].race & (1<<status->race) ||
@@ -2554,7 +2548,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 	rebirth =  ( md->sc.data[SC_KAIZEL] || (md->sc.data[SC_REBIRTH] && !md->state.rebirth) );
 	if( !rebirth ) { // Only trigger event on final kill
-		md->status.hp = 0; //So that npc_event invoked functions KNOW that mob is dead
 		if( src ) {
 			switch( src->type ) { //allowed type
 				case BL_PET:
@@ -2600,8 +2593,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 			pc_setparam(mvp_sd, SP_KILLEDRID, md->class_);
 			npc_script_event(mvp_sd, NPCE_KILLNPC); // PCKillNPC [Lance]
 		}
-
-		md->status.hp = 1;
 	}
 
 	if(md->deletetimer != INVALID_TIMER) {
@@ -2639,7 +2630,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 		mvptomb_create(md, mvp_sd ? mvp_sd->status.name : NULL, time(NULL));
 
 	// Remove all status changes before creating a respawn
-	if( sc ){
+	if( sc ) {
 		for(i=0; i<SC_MAX; i++){
 			if(sc->data[i] && (sc->data[i]->timer != INVALID_TIMER))
 				delete_timer(sc->data[i]->timer, status_change_timer);

+ 54 - 65
src/map/pc.c

@@ -6584,7 +6584,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 				status_change_end(&devsd->bl, SC_DEVOTION, INVALID_TIMER);
 			sd->devotion[k] = 0;
 		}
-	if(sd->shadowform_id){ //if we were target of shadowform
+	if(sd->shadowform_id) { //if we were target of shadowform
 		status_change_end(map_id2bl(sd->shadowform_id), SC__SHADOWFORM, INVALID_TIMER);
 		sd->shadowform_id = 0; //should be remove on status end anyway
 	}
@@ -6601,7 +6601,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 			pet_unlocktarget(sd->pd);
 	}
 
-	if (sd->status.hom_id > 0){
+	if (sd->status.hom_id > 0) {
 		if(battle_config.homunculus_auto_vapor && sd->hd && !sd->hd->sc.data[SC_LIGHT_OF_REGENE])
 			merc_hom_vaporize(sd, HOM_ST_ACTIVE);
 	}
@@ -6620,18 +6620,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 			duel_reject(sd->duel_invite, sd);
 	}
 
-	pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1);
-	pc_setparam(sd, SP_KILLERRID, src?src->id:0);
-
-	if( sd->bg_id ) {
-		struct battleground_data *bg;
-		if( (bg = bg_team_search(sd->bg_id)) != NULL && bg->die_event[0] )
-			npc_event(sd, bg->die_event, 0);
-	}
-
 	// Clear anything NPC-related when you die and was interacting with one.
-	if (sd->npc_id)
-	{
+	if (sd->npc_id) {
 		if (sd->state.using_fake_npc) {
 			clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
 			sd->state.using_fake_npc = 0;
@@ -6646,14 +6636,24 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 			sd->st->state = END;
 	}
 
-	npc_script_event(sd,NPCE_DIE);
-
 	/* e.g. not killed thru pc_damage */
 	if( pc_issit(sd) ) {
 		clif_status_load(&sd->bl,SI_SIT,0);
 	}
 
 	pc_setdead(sd);
+
+	pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1);
+	pc_setparam(sd, SP_KILLERRID, src?src->id:0);
+
+	if( sd->bg_id ) {
+		struct battleground_data *bg;
+		if( (bg = bg_team_search(sd->bg_id)) != NULL && bg->die_event[0] )
+			npc_event(sd, bg->die_event, 0);
+	}
+
+	npc_script_event(sd,NPCE_DIE);
+
 	//Reset menu skills/item skills
 	if (sd->skillitem)
 		sd->skillitem = sd->skillitemlv = 0;
@@ -6670,37 +6670,36 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 
 	if (src)
 	switch (src->type) {
-	case BL_MOB:
-	{
-		struct mob_data *md=(struct mob_data *)src;
-		if(md->target_id==sd->bl.id)
-			mob_unlocktarget(md,tick);
-		if(battle_config.mobs_level_up && md->status.hp &&
-			(unsigned int)md->level < pc_maxbaselv(sd) &&
-			!md->guardian_data && !md->special_state.ai// Guardians/summons should not level. [Skotlex]
-		) { 	// monster level up [Valaris]
-			clif_misceffect(&md->bl,0);
-			md->level++;
-			status_calc_mob(md, 0);
-			status_percent_heal(src,10,0);
-
-			if( battle_config.show_mob_info&4 )
-			{// update name with new level
-				clif_charnameack(0, &md->bl);
+		case BL_MOB:
+		{
+			struct mob_data *md=(struct mob_data *)src;
+			if(md->target_id==sd->bl.id)
+				mob_unlocktarget(md,tick);
+			if(battle_config.mobs_level_up && md->status.hp &&
+				(unsigned int)md->level < pc_maxbaselv(sd) &&
+				!md->guardian_data && !md->special_state.ai// Guardians/summons should not level. [Skotlex]
+			) { 	// monster level up [Valaris]
+				clif_misceffect(&md->bl,0);
+				md->level++;
+				status_calc_mob(md, 0);
+				status_percent_heal(src,10,0);
+
+				if( battle_config.show_mob_info&4 )
+				{// update name with new level
+					clif_charnameack(0, &md->bl);
+				}
 			}
+			src = battle_get_master(src); // Maybe Player Summon
 		}
-		src = battle_get_master(src); // Maybe Player Summon
-	}
-	break;
-	case BL_PET: //Pass on to master...
-	case BL_HOM:
-	case BL_MER:
-		src = battle_get_master(src);
-		break;
+			break;
+		case BL_PET: //Pass on to master...
+		case BL_HOM:
+		case BL_MER:
+			src = battle_get_master(src);
+			break;
 	}
 
-	if (src && src->type == BL_PC)
-	{
+	if (src && src->type == BL_PC) {
 		struct map_session_data *ssd = (struct map_session_data *)src;
 		pc_setparam(ssd, SP_KILLEDRID, sd->bl.id);
 		npc_script_event(ssd, NPCE_KILLPC);
@@ -6750,8 +6749,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 	}
 
 	// activate Steel body if a super novice dies at 99+% exp [celest]
-	if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && !sd->state.snovice_dead_flag)
-	{
+	if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && !sd->state.snovice_dead_flag) {
 		unsigned int next = pc_nextbaseexp(sd);
 		if( next == 0 ) next = pc_thisbaseexp(sd);
 		if( get_percentage(sd->status.base_exp,next) >= 99 ) {
@@ -6791,8 +6789,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 				clif_updatestatus(sd,SP_BASEEXP);
 			}
 		}
-		if(battle_config.death_penalty_job > 0)
-		{
+		if(battle_config.death_penalty_job > 0) {
 			base_penalty = 0;
 			switch (battle_config.death_penalty_type) {
 				case 1:
@@ -6809,16 +6806,14 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 				clif_updatestatus(sd,SP_JOBEXP);
 			}
 		}
-		if(battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty)
-		{
+		if(battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty) {
 			base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
 			if(base_penalty)
 				pc_payzeny(sd, base_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL);
 		}
 	}
 
-	if(map[sd->bl.m].flag.pvp_nightmaredrop)
-	{ // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker]
+	if(map[sd->bl.m].flag.pvp_nightmaredrop) { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker]
 		for(j=0;j<MAX_DROP_PER_MAP;j++){
 			int id = map[sd->bl.m].drop_list[j].drop_id;
 			int type = map[sd->bl.m].drop_list[j].drop_type;
@@ -6828,7 +6823,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 			if(id == -1){
 				int eq_num=0,eq_n[MAX_INVENTORY];
 				memset(eq_n,0,sizeof(eq_n));
-				for(i=0;i<MAX_INVENTORY;i++){
+				for(i=0;i<MAX_INVENTORY;i++) {
 					if( (type == 1 && !sd->status.inventory[i].equip)
 						|| (type == 2 && sd->status.inventory[i].equip)
 						||  type == 3)
@@ -6843,14 +6838,14 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 				}
 				if(eq_num > 0){
 					int n = eq_n[rnd()%eq_num];
-					if(rnd()%10000 < per){
+					if(rnd()%10000 < per) {
 						if(sd->status.inventory[n].equip)
 							pc_unequipitem(sd,n,3);
 						pc_dropitem(sd,n,1);
 					}
 				}
 			}
-			else if(id > 0){
+			else if(id > 0) {
 				for(i=0;i<MAX_INVENTORY;i++){
 					if(sd->status.inventory[i].nameid == id
 						&& rnd()%10000 < per
@@ -6868,33 +6863,27 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 	}
 	// pvp
 	// disable certain pvp functions on pk_mode [Valaris]
-	if( map[sd->bl.m].flag.pvp && !battle_config.pk_mode && !map[sd->bl.m].flag.pvp_nocalcrank )
-	{
+	if( map[sd->bl.m].flag.pvp && !battle_config.pk_mode && !map[sd->bl.m].flag.pvp_nocalcrank ) {
 		sd->pvp_point -= 5;
 		sd->pvp_lost++;
-		if( src && src->type == BL_PC )
-		{
+		if( src && src->type == BL_PC ) {
 			struct map_session_data *ssd = (struct map_session_data *)src;
 			ssd->pvp_point++;
 			ssd->pvp_won++;
 		}
-		if( sd->pvp_point < 0 )
-		{
+		if( sd->pvp_point < 0 ) {
 			add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0);
 			return 1|8;
 		}
 	}
 	//GvG
-	if( map_flag_gvg(sd->bl.m) )
-	{
+	if( map_flag_gvg(sd->bl.m) ) {
 		add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0);
 		return 1|8;
 	}
-	else if( sd->bg_id )
-	{
+	else if( sd->bg_id ) {
 		struct battleground_data *bg = bg_team_search(sd->bg_id);
-		if( bg && bg->mapindex > 0 )
-		{ // Respawn by BG
+		if( bg && bg->mapindex > 0 ) { // Respawn by BG
 			add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0);
 			return 1|8;
 		}

+ 55 - 53
src/map/skill.c

@@ -12222,48 +12222,57 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
 		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;
+		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 -1;
 	}
 	return sg->skill_id;
 }
@@ -12430,14 +12439,15 @@ static int skill_unit_effect (struct block_list* bl, va_list ap)
 	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) == -1 )
+				return 0; // Don't let a Bard/Dancer update their own song timer
+		}
 
 		if( flag&4 )
 			skill_unit_onleft(skill_id, bl, tick);
-	}else if( !isTarget && flag&4 && ( group->state.song_dance&0x1 || ( group->src_id == bl->id && group->state.song_dance&0x2 ) ) ){
+	} else if( !isTarget && flag&4 && ( group->state.song_dance&0x1 || ( group->src_id == bl->id && group->state.song_dance&0x2 ) ) )
 		skill_unit_onleft(skill_id, bl, tick);//Ensemble check to terminate it.
-	}
 
 	if( dissonance ) {
 		skill_dance_switch(unit, 1);
@@ -15959,7 +15969,6 @@ int skill_unit_move_sub (struct block_list* bl, va_list ap) {
 					else
 						ShowError("skill_unit_move_sub: Reached limit of unit objects per cell!\n");
 				}
-
 			}
 
 			if( flag&4 )
@@ -15969,24 +15978,17 @@ int skill_unit_move_sub (struct block_list* bl, va_list ap) {
 		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;

+ 8 - 13
src/map/status.c

@@ -1255,14 +1255,13 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 		unit_stop_walking( target, 1 );
 	}
 
-	if( status->hp || (flag&8) )
-	{	//Still lives or has been dead before this damage.
+	if( status->hp || (flag&8) ) { //Still lives or has been dead before this damage.
 		if (walkdelay)
 			unit_set_walkdelay(target, gettick(), walkdelay, 0);
 		return hp+sp;
 	}
 
-	status->hp = 1; //To let the dead function cast skills and all that.
+	status->hp = 0;
 	//NOTE: These dead functions should return: [Skotlex]
 	//0: Death cancelled, auto-revived.
 	//Non-zero: Standard death. Clear status, cancel move/attack, etc
@@ -1283,13 +1282,11 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 		return hp+sp;
 
 	//Normal death
-	status->hp = 0;
 	if (battle_config.clear_unit_ondeath &&
 		battle_config.clear_unit_ondeath&target->type)
 		skill_clear_unitgroup(target);
 
-	if(target->type&BL_REGEN)
-	{	//Reset regen ticks.
+	if(target->type&BL_REGEN) { //Reset regen ticks.
 		struct regen_data *regen = status_get_regen_data(target);
 		if (regen) {
 			memset(&regen->tick, 0, sizeof(regen->tick));
@@ -1300,8 +1297,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 		}
 	}
 
-	if( sc && sc->data[SC_KAIZEL] && !map_flag_gvg(target->m) )
-	{ //flag&8 = disable Kaizel
+	if( sc && sc->data[SC_KAIZEL] && !map_flag_gvg(target->m) ) { //flag&8 = disable Kaizel
 		int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
 		//Look for Osiris Card's bonus effect on the character and revive 100% or revive normally
 		if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover )
@@ -1317,10 +1313,10 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 
 		return hp+sp;
 	}
-	if(target->type == BL_PC){
+	if(target->type == BL_PC) {
 		TBL_PC *sd = BL_CAST(BL_PC,target);
 		TBL_HOM *hd = sd->hd;
-		if(hd && hd->sc.data[SC_LIGHT_OF_REGENE]){
+		if(hd && hd->sc.data[SC_LIGHT_OF_REGENE]) {
 			status_change_clear(target,0);
 			clif_skillcasting(&hd->bl, hd->bl.id, target->id, 0,0, MH_LIGHT_OF_REGENE, skill_get_ele(MH_LIGHT_OF_REGENE, 1), 10); //just to display usage
 			clif_skill_nodamage(&sd->bl, target, ALL_RESURRECTION, 1, status_revive(&sd->bl,hd->sc.data[SC_LIGHT_OF_REGENE]->val2,0));
@@ -1328,7 +1324,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 			return hp + sp;
 		}
 	}
-	if (target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB*) target)->state.rebirth) {// Ensure the monster has not already rebirthed before doing so.
+	if (target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB*) target)->state.rebirth) { // Ensure the monster has not already rebirthed before doing so.
 		status_revive(target, sc->data[SC_REBIRTH]->val2, 0);
 		status_change_clear(target,0);
 		((TBL_MOB*)target)->state.rebirth = 1;
@@ -1343,8 +1339,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 	else
 	if(flag&2) //remove from map
 		unit_remove_map(target,CLR_DEAD);
-	else
-	{ //Some death states that would normally be handled by unit_remove_map
+	else { //Some death states that would normally be handled by unit_remove_map
 		unit_stop_attack(target);
 		unit_stop_walking(target,1);
 		unit_skillcastcancel(target,0);