- Code rewrites in mob_damage and party_exp_even_share for correctly handling overflow issues. Now uses UINT_MAX for range comparisons, as it should be.
- Also modified the mob_db reading to use UINT_MAX for exp limits, changed their exp/job exp fields to unsigned int as well. - Modified multi_level_up behaviour to work as specified by Kyoki. - removed functions pc_next[base/job]after as they are no longer needed. - Modified the skill attack display of Meteor Assault and the Warm Skills (I think the caster should no longer do fancy animations now on each hit) - Added back water elemental targets being inmune to SC_FREEZE - Fixed the status_change_start line in charsave.c (I knew I was forgetting something) git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5235 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
4ade31e5ea
commit
2a9dbcf690
@ -6,8 +6,19 @@ GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALAR
|
|||||||
|
|
||||||
|
|
||||||
2006/02/09
|
2006/02/09
|
||||||
* SQL compile fix (Skotlex, check line 470 in charsave.c,
|
* Code rewrites in mob_damage and party_exp_even_share for correctly
|
||||||
I've added here rate value = 10000) [Komurka]
|
handling overflow issues. Now uses UINT_MAX for range comparisons, as it
|
||||||
|
should be. [Skotlex]
|
||||||
|
* Also modified the mob_db reading to use UINT_MAX for exp limits, changed
|
||||||
|
their exp/job exp fields to unsigned int as well. [Skotlex]
|
||||||
|
* Modified multi_level_up behaviour to work as specified by Kyoki. That is,
|
||||||
|
on a level up, the max carry-over exp is the exp needed for the previous
|
||||||
|
level -1. [Skotlex]
|
||||||
|
* Modified the skill attack display of Meteor Assault and the Warm Skills
|
||||||
|
(I think the caster should no longer do fancy animations now on each hit)
|
||||||
|
[Skotlex]
|
||||||
|
* Added back water elemental targets being inmune to SC_FREEZE [Skotlex]
|
||||||
|
* SQL compile fix [Komurka]
|
||||||
|
|
||||||
2006/02/08
|
2006/02/08
|
||||||
* Added battle config option skill_caster_check, which does a
|
* Added battle config option skill_caster_check, which does a
|
||||||
|
@ -149,7 +149,7 @@ mob_remove_delay: 300000
|
|||||||
mob_clear_delay: 0
|
mob_clear_delay: 0
|
||||||
|
|
||||||
// Defines on who the mob npc_event gets executed when a mob is killed.
|
// Defines on who the mob npc_event gets executed when a mob is killed.
|
||||||
// Type 1: On theplayer that killed the mob (if killed by a non-player, resorts to type 0)
|
// Type 1: On the player that killed the mob (if killed by a non-player, resorts to type 0)
|
||||||
// Type 0: On the player that did the most damage to the mob.
|
// Type 0: On the player that did the most damage to the mob.
|
||||||
// NOTE: This affects who gains the Castle when the Emperium is broken.
|
// NOTE: This affects who gains the Castle when the Emperium is broken.
|
||||||
mob_npc_event_type: 1
|
mob_npc_event_type: 1
|
||||||
|
@ -467,8 +467,8 @@ int charsave_load_scdata(int account_id, int char_id)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_change_start(&sd->bl, atoi(sql_row[0]), 10000, atoi(sql_row[2]), atoi(sql_row[3]),
|
status_change_start(&sd->bl, atoi(sql_row[0]), 100, atoi(sql_row[2]), atoi(sql_row[3]),
|
||||||
atoi(sql_row[4]), atoi(sql_row[5]), atoi(sql_row[1]), 7);
|
atoi(sql_row[4]), atoi(sql_row[5]), atoi(sql_row[1]), 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
|
|||||||
for (i = 0; i < fd_max; i++) {
|
for (i = 0; i < fd_max; i++) {
|
||||||
if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) != NULL && sd->state.auth) {
|
if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) != NULL && sd->state.auth) {
|
||||||
if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
||||||
WFIFOHEAD(i, len);
|
WFIFOHEAD(i, len);
|
||||||
memcpy(WFIFOP(i,0), buf, len);
|
memcpy(WFIFOP(i,0), buf, len);
|
||||||
WFIFOSET(i,len);
|
WFIFOSET(i,len);
|
||||||
}
|
}
|
||||||
@ -412,7 +412,7 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
|
|||||||
if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
||||||
if (cd->usersd[i]->fd >0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW]
|
if (cd->usersd[i]->fd >0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW]
|
||||||
{
|
{
|
||||||
WFIFOHEAD(cd->usersd[i]->fd,len);
|
WFIFOHEAD(cd->usersd[i]->fd,len);
|
||||||
memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len);
|
memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len);
|
||||||
WFIFOSET(cd->usersd[i]->fd,len);
|
WFIFOSET(cd->usersd[i]->fd,len);
|
||||||
}
|
}
|
||||||
@ -424,6 +424,7 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
|
|||||||
for(i=1; i<fd_max; i++) {
|
for(i=1; i<fd_max; i++) {
|
||||||
if(session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL &&
|
if(session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL &&
|
||||||
sd->state.mainchat && sd->fd) {
|
sd->state.mainchat && sd->fd) {
|
||||||
|
WFIFOHEAD(sd->fd, len);
|
||||||
memcpy(WFIFOP(sd->fd,0), buf, len);
|
memcpy(WFIFOP(sd->fd,0), buf, len);
|
||||||
WFIFOSET(sd->fd, len);
|
WFIFOSET(sd->fd, len);
|
||||||
}
|
}
|
||||||
@ -472,7 +473,7 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
|
|||||||
if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->fd && sd->partyspy) {
|
if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->fd && sd->partyspy) {
|
||||||
if (sd->partyspy == p->party_id) {
|
if (sd->partyspy == p->party_id) {
|
||||||
if (sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
if (sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
||||||
WFIFOHEAD(sd->fd,len);
|
WFIFOHEAD(sd->fd,len);
|
||||||
memcpy(WFIFOP(sd->fd,0), buf, len);
|
memcpy(WFIFOP(sd->fd,0), buf, len);
|
||||||
WFIFOSET(sd->fd,len);
|
WFIFOSET(sd->fd,len);
|
||||||
}
|
}
|
||||||
@ -483,7 +484,7 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
|
|||||||
break;
|
break;
|
||||||
case SELF:
|
case SELF:
|
||||||
if (sd && sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
if (sd && sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
||||||
WFIFOHEAD(sd->fd,len);
|
WFIFOHEAD(sd->fd,len);
|
||||||
memcpy(WFIFOP(sd->fd,0), buf, len);
|
memcpy(WFIFOP(sd->fd,0), buf, len);
|
||||||
WFIFOSET(sd->fd,len);
|
WFIFOSET(sd->fd,len);
|
||||||
}
|
}
|
||||||
@ -533,7 +534,7 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
|
|||||||
if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->fd && sd->guildspy) {
|
if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->fd && sd->guildspy) {
|
||||||
if (sd->guildspy == g->guild_id) {
|
if (sd->guildspy == g->guild_id) {
|
||||||
if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
|
||||||
WFIFOHEAD(sd->fd,len);
|
WFIFOHEAD(sd->fd,len);
|
||||||
memcpy(WFIFOP(sd->fd,0), buf, len);
|
memcpy(WFIFOP(sd->fd,0), buf, len);
|
||||||
WFIFOSET(sd->fd,len);
|
WFIFOSET(sd->fd,len);
|
||||||
}
|
}
|
||||||
@ -8809,7 +8810,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
|||||||
pc_checkskill(sd,SG_STAR_COMFORT))
|
pc_checkskill(sd,SG_STAR_COMFORT))
|
||||||
status_calc_pc(sd,0);
|
status_calc_pc(sd,0);
|
||||||
|
|
||||||
if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobafter(sd))
|
if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
|
||||||
clif_status_load(&sd->bl, SI_DEVIL, 1); //blindness [Komurka]
|
clif_status_load(&sd->bl, SI_DEVIL, 1); //blindness [Komurka]
|
||||||
|
|
||||||
map_foreachinarea(clif_getareachar,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,BL_ALL,sd);
|
map_foreachinarea(clif_getareachar,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,BL_ALL,sd);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
@ -2176,7 +2177,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
|
|||||||
struct map_session_data *sd = NULL,*tmpsd[DAMAGELOG_SIZE];
|
struct map_session_data *sd = NULL,*tmpsd[DAMAGELOG_SIZE];
|
||||||
struct {
|
struct {
|
||||||
struct party *p;
|
struct party *p;
|
||||||
int id,base_exp,job_exp,zeny;
|
int id,zeny;
|
||||||
|
unsigned int base_exp,job_exp;
|
||||||
} pt[DAMAGELOG_SIZE];
|
} pt[DAMAGELOG_SIZE];
|
||||||
int pnum=0;
|
int pnum=0;
|
||||||
int mvp_damage,max_hp;
|
int mvp_damage,max_hp;
|
||||||
@ -2422,7 +2424,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
|
|||||||
// 経験値の分配
|
// 経験値の分配
|
||||||
for(i=0;i<DAMAGELOG_SIZE;i++){
|
for(i=0;i<DAMAGELOG_SIZE;i++){
|
||||||
int pid,flag=1,zeny=0;
|
int pid,flag=1,zeny=0;
|
||||||
unsigned long base_exp,job_exp;
|
unsigned int base_exp,job_exp;
|
||||||
double per;
|
double per;
|
||||||
struct party *p;
|
struct party *p;
|
||||||
if(tmpsd[i]==NULL || tmpsd[i]->bl.m != md->bl.m || pc_isdead(tmpsd[i]))
|
if(tmpsd[i]==NULL || tmpsd[i]->bl.m != md->bl.m || pc_isdead(tmpsd[i]))
|
||||||
@ -2436,8 +2438,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
|
|||||||
if (count>1)
|
if (count>1)
|
||||||
per *= (9.+(double)((count > 6)? 6:count))/10.; //attackers count bonus.
|
per *= (9.+(double)((count > 6)? 6:count))/10.; //attackers count bonus.
|
||||||
|
|
||||||
base_exp = (unsigned long)md->db->base_exp;
|
base_exp = md->db->base_exp;
|
||||||
job_exp = (unsigned long)md->db->job_exp;
|
job_exp = md->db->job_exp;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
per += per*ret/100.; //SC_RICHMANKIM bonus. [Skotlex]
|
per += per*ret/100.; //SC_RICHMANKIM bonus. [Skotlex]
|
||||||
@ -2477,21 +2479,24 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
|
|||||||
else if(md->special_state.size==2 && zeny >1)
|
else if(md->special_state.size==2 && zeny >1)
|
||||||
zeny*=2;
|
zeny*=2;
|
||||||
}
|
}
|
||||||
if(battle_config.mobs_level_up && md->level > md->db->lv) { // [Valaris]
|
if(battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris]
|
||||||
base_exp+=(unsigned long) (((md->level-md->db->lv)*((md->db->base_exp))*(battle_config.mobs_level_up_exp_rate/100)));
|
per+= per*(md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate/100;
|
||||||
job_exp+=(unsigned long) (((md->level-md->db->lv)*((md->db->job_exp))*(battle_config.mobs_level_up_exp_rate/100)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (per > 4) per = 4; //Limit gained exp to quadro the mob's exp. [3->4 Komurka]
|
if (per > 4) per = 4; //Limit gained exp to quadro the mob's exp. [3->4 Komurka]
|
||||||
base_exp = (unsigned long)(base_exp*per);
|
|
||||||
job_exp = (unsigned long)(job_exp*per);
|
|
||||||
|
|
||||||
if (base_exp > 0x7fffffff) base_exp = 0x7fffffff;
|
|
||||||
else if (base_exp < 1) base_exp = 1;
|
|
||||||
|
|
||||||
if (job_exp > 0x7fffffff) job_exp = 0x7fffffff;
|
if (base_exp*per > UINT_MAX)
|
||||||
else if (job_exp < 1) job_exp = 1;
|
base_exp = UINT_MAX;
|
||||||
|
else
|
||||||
|
base_exp = (unsigned int)(base_exp*per);
|
||||||
|
|
||||||
|
if (job_exp*per > UINT_MAX)
|
||||||
|
job_exp = UINT_MAX;
|
||||||
|
else
|
||||||
|
job_exp = (unsigned int)(job_exp*per);
|
||||||
|
|
||||||
|
if (base_exp < 1) base_exp = 1;
|
||||||
|
if (job_exp < 1) job_exp = 1;
|
||||||
|
|
||||||
//mapflags: noexp check [Lorky]
|
//mapflags: noexp check [Lorky]
|
||||||
if (map[md->bl.m].flag.nobaseexp == 1) base_exp=0;
|
if (map[md->bl.m].flag.nobaseexp == 1) base_exp=0;
|
||||||
@ -2514,14 +2519,16 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
|
|||||||
flag=0;
|
flag=0;
|
||||||
}
|
}
|
||||||
}else{ // いるときは公平
|
}else{ // いるときは公平
|
||||||
if (pt[j].base_exp +base_exp < 0x7fffffff)
|
if (pt[j].base_exp > UINT_MAX - base_exp)
|
||||||
|
pt[j].base_exp=UINT_MAX;
|
||||||
|
else
|
||||||
pt[j].base_exp+=base_exp;
|
pt[j].base_exp+=base_exp;
|
||||||
|
|
||||||
|
if (pt[j].job_exp > UINT_MAX - job_exp)
|
||||||
|
pt[j].job_exp=UINT_MAX;
|
||||||
else
|
else
|
||||||
pt[j].base_exp = 0x7fffffff;
|
|
||||||
if (pt[j].job_exp +job_exp < 0x7fffffff)
|
|
||||||
pt[j].job_exp+=job_exp;
|
pt[j].job_exp+=job_exp;
|
||||||
else
|
|
||||||
pt[j].job_exp = 0x7fffffff;
|
|
||||||
if(battle_config.zeny_from_mobs)
|
if(battle_config.zeny_from_mobs)
|
||||||
pt[j].zeny+=zeny; // zeny share [Valaris]
|
pt[j].zeny+=zeny; // zeny share [Valaris]
|
||||||
flag=0;
|
flag=0;
|
||||||
@ -4241,14 +4248,20 @@ static int mob_readdb(void)
|
|||||||
mob_db_data[class_]->max_sp = atoi(str[5]);
|
mob_db_data[class_]->max_sp = atoi(str[5]);
|
||||||
|
|
||||||
exp = (double)atoi(str[6]) * (double)battle_config.base_exp_rate / 100.;
|
exp = (double)atoi(str[6]) * (double)battle_config.base_exp_rate / 100.;
|
||||||
if (exp < 0) exp = 0;
|
if (exp < 0)
|
||||||
else if (exp > 0x7fffffff) exp = 0x7fffffff;
|
mob_db_data[class_]->base_exp = 0;
|
||||||
mob_db_data[class_]->base_exp = (int)exp;
|
if (exp > UINT_MAX)
|
||||||
|
mob_db_data[class_]->base_exp = UINT_MAX;
|
||||||
|
else
|
||||||
|
mob_db_data[class_]->base_exp = (unsigned int)exp;
|
||||||
|
|
||||||
exp = (double)atoi(str[7]) * (double)battle_config.job_exp_rate / 100.;
|
exp = (double)atoi(str[7]) * (double)battle_config.job_exp_rate / 100.;
|
||||||
if (exp < 0) exp = 0;
|
if (exp < 0)
|
||||||
else if (exp > 0x7fffffff) exp = 0x7fffffff;
|
mob_db_data[class_]->job_exp = 0;
|
||||||
mob_db_data[class_]->job_exp = (int)exp;
|
else if (exp > UINT_MAX)
|
||||||
|
mob_db_data[class_]->job_exp = UINT_MAX;
|
||||||
|
else
|
||||||
|
mob_db_data[class_]->job_exp = (unsigned int)exp;
|
||||||
|
|
||||||
mob_db_data[class_]->range=atoi(str[8]);
|
mob_db_data[class_]->range=atoi(str[8]);
|
||||||
mob_db_data[class_]->atk1=atoi(str[9]);
|
mob_db_data[class_]->atk1=atoi(str[9]);
|
||||||
@ -4811,14 +4824,20 @@ static int mob_read_sqldb(void)
|
|||||||
mob_db_data[class_]->max_sp = TO_INT(5);
|
mob_db_data[class_]->max_sp = TO_INT(5);
|
||||||
|
|
||||||
exp = (double)TO_INT(6) * (double)battle_config.base_exp_rate / 100.;
|
exp = (double)TO_INT(6) * (double)battle_config.base_exp_rate / 100.;
|
||||||
if (exp < 0) exp = 0;
|
if (exp < 0)
|
||||||
else if (exp > 0x7fffffff) exp = 0x7fffffff;
|
mob_db_data[class_]->base_exp = 0;
|
||||||
mob_db_data[class_]->base_exp = (int)exp;
|
else if (exp > UINT_MAX)
|
||||||
|
mob_db_data[class_]->base_exp = UINT_MAX;
|
||||||
|
else
|
||||||
|
mob_db_data[class_]->base_exp = (unsigned int)exp;
|
||||||
|
|
||||||
exp = (double)TO_INT(7) * (double)battle_config.job_exp_rate / 100.;
|
exp = (double)TO_INT(7) * (double)battle_config.job_exp_rate / 100.;
|
||||||
if (exp < 0) exp = 0;
|
if (exp < 0)
|
||||||
else if (exp > 0x7fffffff) exp = 0x7fffffff;
|
mob_db_data[class_]->job_exp = 0;
|
||||||
mob_db_data[class_]->job_exp = (int)exp;
|
else if (exp > UINT_MAX)
|
||||||
|
mob_db_data[class_]->job_exp = UINT_MAX;
|
||||||
|
else
|
||||||
|
mob_db_data[class_]->job_exp = (unsigned int)exp;
|
||||||
|
|
||||||
mob_db_data[class_]->range = TO_INT(8);
|
mob_db_data[class_]->range = TO_INT(8);
|
||||||
mob_db_data[class_]->atk1 = TO_INT(9);
|
mob_db_data[class_]->atk1 = TO_INT(9);
|
||||||
|
@ -31,7 +31,7 @@ struct mob_db {
|
|||||||
char name[NAME_LENGTH],jname[NAME_LENGTH];
|
char name[NAME_LENGTH],jname[NAME_LENGTH];
|
||||||
short lv;
|
short lv;
|
||||||
int max_hp,max_sp;
|
int max_hp,max_sp;
|
||||||
int base_exp,job_exp;
|
unsigned int base_exp,job_exp;
|
||||||
int atk1,atk2;
|
int atk1,atk2;
|
||||||
int def,mdef;
|
int def,mdef;
|
||||||
int str,agi,vit,int_,dex,luk;
|
int str,agi,vit,int_,dex,luk;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "../common/timer.h"
|
#include "../common/timer.h"
|
||||||
#include "../common/socket.h"
|
#include "../common/socket.h"
|
||||||
@ -639,12 +640,11 @@ int party_send_xy_clear(struct party *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exp share and added zeny share [Valaris]
|
// exp share and added zeny share [Valaris]
|
||||||
int party_exp_share(struct party *p,int map,int base_exp,int job_exp,int zeny)
|
int party_exp_share(struct party *p,int map,unsigned int base_exp,unsigned int job_exp,int zeny)
|
||||||
{
|
{
|
||||||
struct map_session_data* sd[MAX_PARTY];
|
struct map_session_data* sd[MAX_PARTY];
|
||||||
int i;
|
int i;
|
||||||
short c, bonus =100; // modified [Valaris]
|
short c, bonus =100; // modified [Valaris]
|
||||||
unsigned long base, job;
|
|
||||||
|
|
||||||
nullpo_retr(0, p);
|
nullpo_retr(0, p);
|
||||||
|
|
||||||
@ -660,15 +660,22 @@ int party_exp_share(struct party *p,int map,int base_exp,int job_exp,int zeny)
|
|||||||
bonus += (battle_config.party_even_share_bonus*c*(c-1)/10); //Changed Valaris's bonus switch to an equation [Skotlex]
|
bonus += (battle_config.party_even_share_bonus*c*(c-1)/10); //Changed Valaris's bonus switch to an equation [Skotlex]
|
||||||
else //Official kRO/iRO sites state that the even share bonus is 10% per additional party member.
|
else //Official kRO/iRO sites state that the even share bonus is 10% per additional party member.
|
||||||
bonus += (c-1)*10;
|
bonus += (c-1)*10;
|
||||||
base = (unsigned long)(base_exp/c)*bonus/100;
|
|
||||||
job = (unsigned long)(job_exp/c)*bonus/100;
|
base_exp/=c;
|
||||||
if (base > 0x7fffffff)
|
job_exp/=c;
|
||||||
base = 0x7fffffff;
|
if (base_exp/100 > UINT_MAX/bonus)
|
||||||
if (job > 0x7fffffff)
|
base_exp= UINT_MAX; //Exp overflow
|
||||||
job = 0x7fffffff;
|
else
|
||||||
|
base_exp = base_exp*bonus/100;
|
||||||
|
|
||||||
|
if (job_exp/100 > UINT_MAX/bonus)
|
||||||
|
job_exp = UINT_MAX;
|
||||||
|
else
|
||||||
|
job_exp = job_exp*bonus/100;
|
||||||
|
|
||||||
for (i = 0; i < c; i++)
|
for (i = 0; i < c; i++)
|
||||||
{
|
{
|
||||||
pc_gainexp(sd[i], base, job);
|
pc_gainexp(sd[i], base_exp, job_exp);
|
||||||
if (battle_config.zeny_from_mobs) // zeny from mobs [Valaris]
|
if (battle_config.zeny_from_mobs) // zeny from mobs [Valaris]
|
||||||
pc_getzeny(sd[i],bonus*zeny/(c*100));
|
pc_getzeny(sd[i],bonus*zeny/(c*100));
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ int party_recv_message(int party_id,int account_id,char *mes,int len);
|
|||||||
int party_check_conflict(struct map_session_data *sd);
|
int party_check_conflict(struct map_session_data *sd);
|
||||||
int party_skill_check(struct map_session_data *sd, int party_id, int skillid, int skilllv);
|
int party_skill_check(struct map_session_data *sd, int party_id, int skillid, int skilllv);
|
||||||
int party_send_xy_clear(struct party *p);
|
int party_send_xy_clear(struct party *p);
|
||||||
int party_exp_share(struct party *p,int map,int base_exp,int job_exp,int zeny);
|
int party_exp_share(struct party *p,int map,unsigned int base_exp,unsigned int job_exp,int zeny);
|
||||||
int party_send_dot_remove(struct map_session_data *sd);
|
int party_send_dot_remove(struct map_session_data *sd);
|
||||||
int party_sub_count(struct block_list *bl, va_list ap);
|
int party_sub_count(struct block_list *bl, va_list ap);
|
||||||
void party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int type,...);
|
void party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int type,...);
|
||||||
|
85
src/map/pc.c
85
src/map/pc.c
@ -6,6 +6,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "socket.h" // [Valaris]
|
#include "socket.h" // [Valaris]
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@ -4597,11 +4598,13 @@ int pc_checkbaselevelup(struct map_session_data *sd)
|
|||||||
nullpo_retr(0, sd);
|
nullpo_retr(0, sd);
|
||||||
|
|
||||||
if(sd->status.base_exp >= next && next > 0){
|
if(sd->status.base_exp >= next && next > 0){
|
||||||
|
|
||||||
// base側レベルアップ?理
|
|
||||||
sd->status.base_exp -= next;
|
sd->status.base_exp -= next;
|
||||||
|
//Kyoki pointed out that the max overcarry exp is the exp needed for the previous level -1. [Skotlex]
|
||||||
|
if(!battle_config.multi_level_up && sd->status.base_exp > next-1)
|
||||||
|
sd->status.base_exp = next-1;
|
||||||
|
|
||||||
sd->status.base_level ++;
|
sd->status.base_level ++;
|
||||||
|
|
||||||
if (battle_config.pet_lv_rate && sd->pd) //<Skotlex> update pet's level
|
if (battle_config.pet_lv_rate && sd->pd) //<Skotlex> update pet's level
|
||||||
status_calc_pet(sd,0);
|
status_calc_pet(sd,0);
|
||||||
if (battle_config.use_statpoint_table)
|
if (battle_config.use_statpoint_table)
|
||||||
@ -4653,9 +4656,13 @@ int pc_checkjoblevelup(struct map_session_data *sd)
|
|||||||
nullpo_retr(0, sd);
|
nullpo_retr(0, sd);
|
||||||
|
|
||||||
if(sd->status.job_exp >= next && next > 0){
|
if(sd->status.job_exp >= next && next > 0){
|
||||||
// job側レベルアップ?理
|
|
||||||
sd->status.job_exp -= next;
|
sd->status.job_exp -= next;
|
||||||
|
//Kyoki pointed out that the max overcarry exp is the exp needed for the previous level -1. [Skotlex]
|
||||||
|
if(!battle_config.multi_level_up && sd->status.job_exp > next-1)
|
||||||
|
sd->status.job_exp = next-1;
|
||||||
|
|
||||||
sd->status.job_level ++;
|
sd->status.job_level ++;
|
||||||
|
|
||||||
clif_updatestatus(sd,SP_JOBLEVEL);
|
clif_updatestatus(sd,SP_JOBLEVEL);
|
||||||
clif_updatestatus(sd,SP_NEXTJOBEXP);
|
clif_updatestatus(sd,SP_NEXTJOBEXP);
|
||||||
sd->status.skill_point ++;
|
sd->status.skill_point ++;
|
||||||
@ -4663,7 +4670,7 @@ int pc_checkjoblevelup(struct map_session_data *sd)
|
|||||||
status_calc_pc(sd,0);
|
status_calc_pc(sd,0);
|
||||||
|
|
||||||
clif_misceffect(&sd->bl,1);
|
clif_misceffect(&sd->bl,1);
|
||||||
if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobafter(sd))
|
if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
|
||||||
clif_status_change(&sd->bl,SI_DEVIL, 1); //Permanent blind effect from SG_DEVIL.
|
clif_status_change(&sd->bl,SI_DEVIL, 1); //Permanent blind effect from SG_DEVIL.
|
||||||
|
|
||||||
if (script_config.event_script_type == 0) {
|
if (script_config.event_script_type == 0) {
|
||||||
@ -4697,34 +4704,41 @@ int pc_gainexp(struct map_session_data *sd,unsigned int base_exp,unsigned int jo
|
|||||||
if(sd->bl.prev == NULL || pc_isdead(sd))
|
if(sd->bl.prev == NULL || pc_isdead(sd))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if((battle_config.pvp_exp == 0) && map[sd->bl.m].flag.pvp) // [MouseJstr]
|
if(!battle_config.pvp_exp && map[sd->bl.m].flag.pvp) // [MouseJstr]
|
||||||
return 0; // no exp on pvp maps
|
return 0; // no exp on pvp maps
|
||||||
|
|
||||||
if(sd->status.guild_id>0){ // ギルドに上納
|
if(sd->status.guild_id>0){ // ギルドに上納
|
||||||
base_exp-=guild_payexp(sd,base_exp);
|
base_exp-=guild_payexp(sd,base_exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!battle_config.multi_level_up && pc_nextbaseafter(sd) && sd->status.base_exp+base_exp >= pc_nextbaseafter(sd)) {
|
if(sd->state.showexp){
|
||||||
base_exp = pc_nextbaseafter(sd) - sd->status.base_exp;
|
nextb = pc_nextbaseexp(sd);
|
||||||
|
nextj = pc_nextjobexp(sd);
|
||||||
|
if (nextb > 0)
|
||||||
|
nextbp = (float) base_exp / (float) nextb;
|
||||||
|
if (nextj > 0)
|
||||||
|
nextjp = (float) job_exp / (float) nextj;
|
||||||
}
|
}
|
||||||
nextb = pc_nextbaseexp(sd);
|
|
||||||
nextj = pc_nextjobexp(sd);
|
//Overflow checks... think we'll ever really need'em? [Skotlex]
|
||||||
if (nextb > 0)
|
if (base_exp > 0 && sd->status.base_exp > UINT_MAX - base_exp)
|
||||||
nextbp = (float) base_exp / (float) nextb;
|
sd->status.base_exp = UINT_MAX;
|
||||||
if (nextj > 0)
|
else if (base_exp < 0 && sd->status.base_exp > base_exp)
|
||||||
nextjp = (float) job_exp / (float) nextj;
|
sd->status.base_exp = 0;
|
||||||
|
else
|
||||||
sd->status.base_exp += base_exp;
|
sd->status.base_exp += base_exp;
|
||||||
|
|
||||||
while(pc_checkbaselevelup(sd)) ;
|
while(pc_checkbaselevelup(sd)) ;
|
||||||
|
|
||||||
clif_updatestatus(sd,SP_BASEEXP);
|
clif_updatestatus(sd,SP_BASEEXP);
|
||||||
|
|
||||||
if(!battle_config.multi_level_up && pc_nextjobafter(sd) && sd->status.job_exp+job_exp >= pc_nextjobafter(sd)) {
|
//Overflow checks... think we'll ever really need'em? [Skotlex]
|
||||||
job_exp = pc_nextjobafter(sd) - sd->status.job_exp;
|
if (job_exp > 0 && sd->status.job_exp > UINT_MAX - job_exp)
|
||||||
}
|
sd->status.job_exp = UINT_MAX;
|
||||||
|
else if (job_exp < 0 && sd->status.job_exp > job_exp)
|
||||||
sd->status.job_exp += job_exp;
|
sd->status.job_exp = 0;
|
||||||
|
else
|
||||||
|
sd->status.job_exp += job_exp;
|
||||||
|
|
||||||
while(pc_checkjoblevelup(sd)) ;
|
while(pc_checkjoblevelup(sd)) ;
|
||||||
|
|
||||||
@ -4779,33 +4793,6 @@ unsigned int pc_nextjobexp(struct map_session_data *sd)
|
|||||||
return exp_table[sd->status.class_][1][sd->status.job_level-1];
|
return exp_table[sd->status.class_][1][sd->status.job_level-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==========================================
|
|
||||||
* base level after next [Valaris]
|
|
||||||
*------------------------------------------
|
|
||||||
*/
|
|
||||||
unsigned int pc_nextbaseafter(struct map_session_data *sd)
|
|
||||||
{
|
|
||||||
nullpo_retr(0, sd);
|
|
||||||
|
|
||||||
if(sd->status.base_level>=pc_maxbaselv(sd) || sd->status.base_level<=0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return exp_table[sd->status.class_][0][sd->status.base_level];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*==========================================
|
|
||||||
* job level after next [Valaris]
|
|
||||||
*------------------------------------------
|
|
||||||
*/
|
|
||||||
unsigned int pc_nextjobafter(struct map_session_data *sd)
|
|
||||||
{
|
|
||||||
nullpo_retr(0, sd);
|
|
||||||
|
|
||||||
if(sd->status.job_level>=pc_maxjoblv(sd) || sd->status.job_level<=0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return exp_table[sd->status.class_][1][sd->status.job_level];
|
|
||||||
}
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
|
|
||||||
* 必要ステ?タスポイント計算
|
* 必要ステ?タスポイント計算
|
||||||
@ -5208,7 +5195,7 @@ int pc_resetskill(struct map_session_data* sd)
|
|||||||
int i, skill, inf2;
|
int i, skill, inf2;
|
||||||
nullpo_retr(0, sd);
|
nullpo_retr(0, sd);
|
||||||
|
|
||||||
if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobafter(sd))
|
if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
|
||||||
clif_status_load(&sd->bl, SI_DEVIL, 0); //Remove perma blindness due to skill-reset. [Skotlex]
|
clif_status_load(&sd->bl, SI_DEVIL, 0); //Remove perma blindness due to skill-reset. [Skotlex]
|
||||||
|
|
||||||
for (i = 1; i < MAX_SKILL; i++) {
|
for (i = 1; i < MAX_SKILL; i++) {
|
||||||
|
@ -123,9 +123,7 @@ int pc_checkbaselevelup(struct map_session_data *sd);
|
|||||||
int pc_checkjoblevelup(struct map_session_data *sd);
|
int pc_checkjoblevelup(struct map_session_data *sd);
|
||||||
int pc_gainexp(struct map_session_data*,unsigned int,unsigned int);
|
int pc_gainexp(struct map_session_data*,unsigned int,unsigned int);
|
||||||
unsigned int pc_nextbaseexp(struct map_session_data *);
|
unsigned int pc_nextbaseexp(struct map_session_data *);
|
||||||
unsigned int pc_nextbaseafter(struct map_session_data *); // [Valaris]
|
|
||||||
unsigned int pc_nextjobexp(struct map_session_data *);
|
unsigned int pc_nextjobexp(struct map_session_data *);
|
||||||
unsigned int pc_nextjobafter(struct map_session_data *); // [Valaris]
|
|
||||||
int pc_need_status_point(struct map_session_data *,int);
|
int pc_need_status_point(struct map_session_data *,int);
|
||||||
int pc_statusup(struct map_session_data*,int);
|
int pc_statusup(struct map_session_data*,int);
|
||||||
int pc_statusup2(struct map_session_data*,int,int);
|
int pc_statusup2(struct map_session_data*,int,int);
|
||||||
|
@ -1766,6 +1766,10 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
|
|||||||
//武器スキル?ここまで
|
//武器スキル?ここまで
|
||||||
switch(skillid){
|
switch(skillid){
|
||||||
case AS_SPLASHER:
|
case AS_SPLASHER:
|
||||||
|
case ASC_METEORASSAULT:
|
||||||
|
case SG_SUN_WARM:
|
||||||
|
case SG_MOON_WARM:
|
||||||
|
case SG_STAR_WARM:
|
||||||
clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
|
clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
|
||||||
break;
|
break;
|
||||||
case ASC_BREAKER: // [celest]
|
case ASC_BREAKER: // [celest]
|
||||||
|
@ -1618,7 +1618,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
|||||||
// Relative modifiers from passive skills
|
// Relative modifiers from passive skills
|
||||||
if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0)
|
if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0)
|
||||||
sd->aspd_rate -= (skill/2);
|
sd->aspd_rate -= (skill/2);
|
||||||
if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobafter(sd))
|
if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
|
||||||
sd->aspd_rate -= (skill*3);
|
sd->aspd_rate -= (skill*3);
|
||||||
|
|
||||||
if(pc_isriding(sd))
|
if(pc_isriding(sd))
|
||||||
@ -3740,8 +3740,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
|
|||||||
|
|
||||||
//Check for inmunities / sc fails
|
//Check for inmunities / sc fails
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SC_STONE:
|
|
||||||
case SC_FREEZE:
|
case SC_FREEZE:
|
||||||
|
if (elem == 1 && !(flag&1))
|
||||||
|
return 0; //Can't freeze water elementals.
|
||||||
|
case SC_STONE:
|
||||||
//I've been informed that undead chars are inmune to stone curse too. [Skotlex]
|
//I've been informed that undead chars are inmune to stone curse too. [Skotlex]
|
||||||
if (undead_flag && !(flag&1))
|
if (undead_flag && !(flag&1))
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user