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:
akinari1087 2013-04-28 02:49:48 +00:00
parent 69508a5ffc
commit 1b5e1a8f8f
6 changed files with 239 additions and 277 deletions

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);