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
This commit is contained in:
parent
69508a5ffc
commit
1b5e1a8f8f
@ -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);
|
||||
|
@ -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));
|
||||
|
201
src/map/mob.c
201
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 (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;
|
||||
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( md->dmglog[i].flag == MDLF_PET )
|
||||
per *= battle_config.pet_attack_exp_rate/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.;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// 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 (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( md->dmglog[i].flag == MDLF_PET )
|
||||
per *= battle_config.pet_attack_exp_rate/100.;
|
||||
|
||||
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(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 ( ( temp = tmpsd[i]->status.party_id)>0 ) {
|
||||
int j;
|
||||
for( j = 0; j < pnum && pt[j].id != temp; j++ ); //Locate party.
|
||||
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( 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++;
|
||||
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;
|
||||
|
||||
pt[j].zeny += zeny; // zeny share [Valaris]
|
||||
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;
|
||||
|
||||
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);
|
||||
|
117
src/map/pc.c
117
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
114
src/map/skill.c
114
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_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)
|
||||
{
|
||||
if (sce && sce->val3 == sg->group_id)
|
||||
status_change_end(bl, type, INVALID_TIMER);
|
||||
sg->limit = DIFF_TICK(tick,sg->tick)+1000;
|
||||
}
|
||||
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_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_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) {
|
||||
if (sce && sce->val3 == sg->group_id)
|
||||
status_change_end(bl, type, INVALID_TIMER);
|
||||
sg->limit = DIFF_TICK(tick,sg->tick)+1000;
|
||||
}
|
||||
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_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;
|
||||
|
@ -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(®en->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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user