* Cleaned up mob drop code, crashfix is still needed though...
* Reduced ignore-list length to 20, added proper reply packet * Cleaned up some very poorly written pm-ignore code (see r141) * Fixed a typo in Warp Portal code displaying an incorrect map name git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10915 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
30041f9799
commit
2afd345d77
@ -3,6 +3,11 @@ Date Added
|
|||||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
||||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||||
|
|
||||||
|
2007/07/27
|
||||||
|
* Cleaned up mob drop code, crashfix is still needed though...
|
||||||
|
* Reduced ignore-list length to 20, added proper reply packet
|
||||||
|
* Cleaned up some very poorly written pm-ignore code (see r141)
|
||||||
|
* Fixed a typo in Warp Portal code displaying an incorrect map name
|
||||||
2007/07/25
|
2007/07/25
|
||||||
* Fixed a missing homunculus info packet when doing @refresh
|
* Fixed a missing homunculus info packet when doing @refresh
|
||||||
* Added support for character rename packet (only dummy code for now)
|
* Added support for character rename packet (only dummy code for now)
|
||||||
|
@ -556,7 +556,8 @@ int mapif_parse_WisReply(int fd) {
|
|||||||
// Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers)
|
// Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers)
|
||||||
int mapif_parse_WisToGM(int fd) {
|
int mapif_parse_WisToGM(int fd) {
|
||||||
unsigned char buf[2048]; // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
|
unsigned char buf[2048]; // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
|
||||||
RFIFOHEAD(fd);
|
|
||||||
|
ShowDebug("Sent packet back!\n");
|
||||||
memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2));
|
memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2));
|
||||||
WBUFW(buf, 0) = 0x3803;
|
WBUFW(buf, 0) = 0x3803;
|
||||||
mapif_sendall(buf, RFIFOW(fd,2));
|
mapif_sendall(buf, RFIFOW(fd,2));
|
||||||
|
@ -10787,74 +10787,62 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd)
|
|||||||
nick[NAME_LENGTH-1] = '\0'; // to be sure that the player name have at maximum 23 characters
|
nick[NAME_LENGTH-1] = '\0'; // to be sure that the player name have at maximum 23 characters
|
||||||
|
|
||||||
WFIFOHEAD(fd,packet_len(0xd1));
|
WFIFOHEAD(fd,packet_len(0xd1));
|
||||||
WFIFOW(fd,0) = 0x0d1; // R 00d1 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
|
WFIFOW(fd,0) = 0x0d1; // R 00d1 <type>.B <result>.B: type: 0: deny, 1: allow, result: 0: success, 1: fail 2: list full
|
||||||
WFIFOB(fd,2) = RFIFOB(fd,26);
|
WFIFOB(fd,2) = RFIFOB(fd,26);
|
||||||
// deny action (we add nick only if it's not already exist
|
|
||||||
if (RFIFOB(fd,26) == 0) { // Add block
|
|
||||||
for(i = 0; i < MAX_IGNORE_LIST &&
|
|
||||||
sd->ignore[i].name[0] != '\0' &&
|
|
||||||
strcmp(sd->ignore[i].name, nick) != 0
|
|
||||||
; i++);
|
|
||||||
|
|
||||||
if (i == MAX_IGNORE_LIST) { //Full List
|
if (RFIFOB(fd,26) == 0)
|
||||||
WFIFOB(fd,3) = 1; // fail
|
{ // Add name to ignore list (block)
|
||||||
WFIFOSET(fd, packet_len(0x0d1));
|
|
||||||
|
// Bot-check...
|
||||||
if (strcmp(wisp_server_name, nick) == 0)
|
if (strcmp(wisp_server_name, nick) == 0)
|
||||||
{ // to found possible bot users who automaticaly ignore people.
|
{ // to find possible bot users who automaticaly ignore people
|
||||||
sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
|
sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
|
||||||
intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
|
intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
|
||||||
}
|
WFIFOB(fd,3) = 1; // fail
|
||||||
|
WFIFOSET(fd, packet_len(0x0d1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(sd->ignore[i].name[0] != '\0')
|
|
||||||
{ //Name already exists.
|
// try to find a free spot, while checking for duplicates at the same time
|
||||||
|
for(i = 0; i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0' && strcmp(sd->ignore[i].name, nick) != 0; i++);
|
||||||
|
|
||||||
|
if (i == MAX_IGNORE_LIST) { // no space for new entry
|
||||||
|
WFIFOB(fd,3) = 2; // fail
|
||||||
|
WFIFOSET(fd, packet_len(0x0d1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(sd->ignore[i].name[0] != '\0') { // name already exists
|
||||||
WFIFOB(fd,3) = 0; // Aegis reports success.
|
WFIFOB(fd,3) = 0; // Aegis reports success.
|
||||||
WFIFOSET(fd, packet_len(0x0d1));
|
WFIFOSET(fd, packet_len(0x0d1));
|
||||||
if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people.
|
|
||||||
sprintf(output, "Character '%s' (account: %d) has tried AGAIN to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
|
|
||||||
intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Insert in position i
|
//Insert in position i
|
||||||
memcpy(sd->ignore[i].name, nick, NAME_LENGTH);
|
memcpy(sd->ignore[i].name, nick, NAME_LENGTH);
|
||||||
WFIFOB(fd,3) = 0; // success
|
WFIFOB(fd,3) = 0; // success
|
||||||
WFIFOSET(fd, packet_len(0x0d1));
|
WFIFOSET(fd, packet_len(0x0d1));
|
||||||
if (strcmp(wisp_server_name, nick) == 0)
|
|
||||||
{ // to found possible bot users who automaticaly ignore people.
|
|
||||||
sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
|
|
||||||
intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
|
|
||||||
// send something to be inform and force bot to ignore twice... If GM receiving block + block again, it's a bot :)
|
|
||||||
clif_wis_message(fd, wisp_server_name,
|
|
||||||
"Adding me in your ignore list will not block my wisps.",
|
|
||||||
strlen("Adding me in your ignore list will not block my wisps.") + 1);
|
|
||||||
}
|
|
||||||
//Sort the ignore list.
|
|
||||||
qsort (sd->ignore[0].name, MAX_IGNORE_LIST, sizeof(sd->ignore[0].name), pstrcmp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Remove name
|
|
||||||
for(i = 0; i < MAX_IGNORE_LIST &&
|
|
||||||
sd->ignore[i].name[0] != '\0' &&
|
|
||||||
strcmp(sd->ignore[i].name, nick) != 0
|
|
||||||
; i++);
|
|
||||||
|
|
||||||
if (i == MAX_IGNORE_LIST || sd->ignore[i].name[i] == '\0')
|
//Sort the ignore list.
|
||||||
{ //Not found
|
//FIXME: why not just use a simple shift-and-insert scheme instead?
|
||||||
|
qsort (sd->ignore[0].name, MAX_IGNORE_LIST, sizeof(sd->ignore[0].name), pstrcmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Remove name from ignore list (unblock)
|
||||||
|
|
||||||
|
for(i = 0; i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0' && strcmp(sd->ignore[i].name, nick) != 0; i++);
|
||||||
|
|
||||||
|
if (i == MAX_IGNORE_LIST || sd->ignore[i].name[i] == '\0') { //Not found
|
||||||
WFIFOB(fd,3) = 1; // fail
|
WFIFOB(fd,3) = 1; // fail
|
||||||
WFIFOSET(fd, packet_len(0x0d1));
|
WFIFOSET(fd, packet_len(0x0d1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Move everything one place down to overwrite removed entry.
|
//Move everything one place down to overwrite removed entry.
|
||||||
memmove(sd->ignore[i].name, sd->ignore[i+1].name,
|
memmove(sd->ignore[i].name, sd->ignore[i+1].name, (MAX_IGNORE_LIST-i-1)*sizeof(sd->ignore[0].name));
|
||||||
(MAX_IGNORE_LIST-i-1)*sizeof(sd->ignore[0].name));
|
|
||||||
memset(sd->ignore[MAX_IGNORE_LIST-1].name, 0, sizeof(sd->ignore[0].name));
|
memset(sd->ignore[MAX_IGNORE_LIST-1].name, 0, sizeof(sd->ignore[0].name));
|
||||||
// success
|
WFIFOB(fd,3) = 0; // success
|
||||||
WFIFOB(fd,3) = 0;
|
|
||||||
WFIFOSET(fd, packet_len(0x0d1));
|
WFIFOSET(fd, packet_len(0x0d1));
|
||||||
|
}
|
||||||
|
|
||||||
// for debug only
|
//for(i = 0; i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0'; i++)
|
||||||
// for(i = 0; i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0'; i++) /
|
|
||||||
// ShowDebug("Ignored player: '%s'\n", sd->ignore[i].name);
|
// ShowDebug("Ignored player: '%s'\n", sd->ignore[i].name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
#define MAX_LEVEL 99
|
#define MAX_LEVEL 99
|
||||||
#define MAX_WALKPATH 32
|
#define MAX_WALKPATH 32
|
||||||
#define MAX_DROP_PER_MAP 48
|
#define MAX_DROP_PER_MAP 48
|
||||||
#define MAX_IGNORE_LIST 80
|
#define MAX_IGNORE_LIST 20 // official is 14
|
||||||
#define MAX_VENDING 12
|
#define MAX_VENDING 12
|
||||||
#define MOBID_EMPERIUM 1288
|
#define MOBID_EMPERIUM 1288
|
||||||
|
|
||||||
|
132
src/map/mob.c
132
src/map/mob.c
@ -1697,13 +1697,14 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* Signals death of mob. type&1 -> no drops, type&2 -> no exp
|
* Signals death of mob.
|
||||||
|
* type&1 -> no drops, type&2 -> no exp
|
||||||
*------------------------------------------*/
|
*------------------------------------------*/
|
||||||
int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||||
{
|
{
|
||||||
struct status_data *status;
|
struct status_data *status;
|
||||||
struct map_session_data *sd = NULL,*tmpsd[DAMAGELOG_SIZE],
|
struct map_session_data *sd = NULL, *tmpsd[DAMAGELOG_SIZE];
|
||||||
*mvp_sd = NULL, *second_sd = NULL,*third_sd = NULL;
|
struct map_session_data *mvp_sd = NULL, *second_sd = NULL, *third_sd = NULL;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct party_data *p;
|
struct party_data *p;
|
||||||
@ -1738,7 +1739,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
|
|
||||||
map_freeblock_lock();
|
map_freeblock_lock();
|
||||||
|
|
||||||
memset(tmpsd,0,sizeof(tmpsd));
|
|
||||||
memset(pt,0,sizeof(pt));
|
memset(pt,0,sizeof(pt));
|
||||||
|
|
||||||
if(src && src->type == BL_MOB)
|
if(src && src->type == BL_MOB)
|
||||||
@ -1765,33 +1765,31 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=count=0,mvp_damage=0;i<DAMAGELOG_SIZE && md->dmglog[i].id;i++)
|
// 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++)
|
||||||
{
|
{
|
||||||
tmpsd[i] = map_charid2sd(md->dmglog[i].id);
|
struct map_session_data* tsd = map_charid2sd(md->dmglog[i].id);
|
||||||
if(tmpsd[i] == NULL)
|
|
||||||
continue;
|
if(tsd == NULL)
|
||||||
if(tmpsd[i]->bl.m != m)
|
continue; // skip empty entries
|
||||||
{
|
if(tsd->bl.m != m)
|
||||||
tmpsd[i] = NULL;
|
continue; // skip players not on this map
|
||||||
continue;
|
|
||||||
}
|
|
||||||
count++; //Only logged into same map chars are counted for the total.
|
count++; //Only logged into same map chars are counted for the total.
|
||||||
if (pc_isdead(tmpsd[i]))
|
if (pc_isdead(tsd))
|
||||||
|
continue; // skip dead players
|
||||||
|
if(md->dmglog[i].flag && !merc_is_hom_active(tsd->hd))
|
||||||
|
continue; // skip homunc's share if inactive
|
||||||
|
|
||||||
|
if(md->dmglog[i].dmg > mvp_damage)
|
||||||
{
|
{
|
||||||
tmpsd[i] = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(md->dmglog[i].flag && !merc_is_hom_active(tmpsd[i]->hd))
|
|
||||||
{ //Homunc's share.
|
|
||||||
tmpsd[i] = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(mvp_damage<md->dmglog[i].dmg){
|
|
||||||
third_sd = second_sd;
|
third_sd = second_sd;
|
||||||
second_sd = mvp_sd;
|
second_sd = mvp_sd;
|
||||||
mvp_sd=tmpsd[i];
|
mvp_sd = tsd;
|
||||||
mvp_damage = md->dmglog[i].dmg;
|
mvp_damage = md->dmglog[i].dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmpsd[i] = tsd; // record as valid damage-log entry
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!battle_config.exp_calc_type && count > 1)
|
if(!battle_config.exp_calc_type && count > 1)
|
||||||
@ -1812,7 +1810,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
(!map[m].flag.nobaseexp || !map[m].flag.nojobexp) //Gives Exp
|
(!map[m].flag.nobaseexp || !map[m].flag.nojobexp) //Gives Exp
|
||||||
) { //Experience calculation.
|
) { //Experience calculation.
|
||||||
|
|
||||||
for(i=0;i<DAMAGELOG_SIZE && md->dmglog[i].id;i++){
|
for(i = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++)
|
||||||
|
{
|
||||||
int flag=1,zeny=0;
|
int flag=1,zeny=0;
|
||||||
unsigned int base_exp,job_exp;
|
unsigned int base_exp,job_exp;
|
||||||
double per; //Your share of the mob's exp
|
double per; //Your share of the mob's exp
|
||||||
@ -1837,7 +1836,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
per += per*((count-1)*battle_config.exp_bonus_attacker)/100.;
|
per += per*((count-1)*battle_config.exp_bonus_attacker)/100.;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(md->special_state.size==1) // change experience for different sized monsters [Valaris]
|
// change experience for different sized monsters [Valaris]
|
||||||
|
if(md->special_state.size==1)
|
||||||
per /=2.;
|
per /=2.;
|
||||||
else if(md->special_state.size==2)
|
else if(md->special_state.size==2)
|
||||||
per *=2.;
|
per *=2.;
|
||||||
@ -1861,44 +1861,26 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
if (map[m].flag.nobaseexp || !md->db->base_exp)
|
if (map[m].flag.nobaseexp || !md->db->base_exp)
|
||||||
base_exp = 0;
|
base_exp = 0;
|
||||||
else {
|
else {
|
||||||
temp = bonus; //Do not alter bonus for the jExp section below.
|
|
||||||
if (map[m].bexp != 100)
|
if (map[m].bexp != 100)
|
||||||
temp = map[m].bexp*temp/100;
|
temp = map[m].bexp*bonus/100;
|
||||||
if (temp != 100)
|
if (temp != 100)
|
||||||
per = per*temp/100.;
|
per = per*temp/100.;
|
||||||
|
|
||||||
base_exp = md->db->base_exp;
|
base_exp = (unsigned int)cap_value(md->db->base_exp * per, 1, UINT_MAX);
|
||||||
|
|
||||||
if (base_exp*per > UINT_MAX)
|
|
||||||
base_exp = UINT_MAX;
|
|
||||||
else
|
|
||||||
base_exp = (unsigned int)(base_exp*per);
|
|
||||||
|
|
||||||
if (base_exp < 1)
|
|
||||||
base_exp = 1;
|
|
||||||
}
|
}
|
||||||
//Homun earned job-exp is always lost.
|
if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag) //Homun earned job-exp is always lost.
|
||||||
if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag)
|
|
||||||
job_exp = 0;
|
job_exp = 0;
|
||||||
else {
|
else {
|
||||||
if (map[m].jexp != 100)
|
if (map[m].jexp != 100)
|
||||||
bonus = map[m].jexp*bonus/100;
|
temp = map[m].jexp*bonus/100;
|
||||||
if (bonus != 100)
|
if (temp != 100)
|
||||||
jper = jper*bonus/100.;
|
jper = jper*temp/100.;
|
||||||
|
|
||||||
job_exp = md->db->job_exp;
|
job_exp = (unsigned int)cap_value(md->db->job_exp * jper, 1, UINT_MAX);
|
||||||
|
|
||||||
if (job_exp*jper > UINT_MAX)
|
|
||||||
job_exp = UINT_MAX;
|
|
||||||
else
|
|
||||||
job_exp = (unsigned int)(job_exp*jper);
|
|
||||||
|
|
||||||
if (job_exp < 1)
|
|
||||||
job_exp = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if((temp = tmpsd[i]->status.party_id )>0 && !md->dmglog[i].flag)
|
if((temp = tmpsd[i]->status.party_id )>0 && !md->dmglog[i].flag) //Homun-done damage (flag 1) is not given to party
|
||||||
{ //Homun-done damage (flag 1) is not given to party
|
{
|
||||||
int j;
|
int j;
|
||||||
for(j=0;j<pnum && pt[j].id!=temp;j++); //Locate party.
|
for(j=0;j<pnum && pt[j].id!=temp;j++); //Locate party.
|
||||||
|
|
||||||
@ -1940,6 +1922,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
|
|
||||||
for(i=0;i<pnum;i++) //Party share.
|
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);
|
party_exp_share(pt[i].p, &md->bl, pt[i].base_exp,pt[i].job_exp,pt[i].zeny);
|
||||||
|
|
||||||
} //End EXP giving.
|
} //End EXP giving.
|
||||||
|
|
||||||
if (!(type&1) &&
|
if (!(type&1) &&
|
||||||
@ -1961,7 +1944,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
dlist->third_sd = third_sd;
|
dlist->third_sd = third_sd;
|
||||||
dlist->item = NULL;
|
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)
|
if (md->db->dropitem[i].nameid <= 0)
|
||||||
continue;
|
continue;
|
||||||
drop_rate = md->db->dropitem[i].p;
|
drop_rate = md->db->dropitem[i].p;
|
||||||
@ -1987,8 +1971,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
(int)(md->level - sd->status.base_level) >= 20)
|
(int)(md->level - sd->status.base_level) >= 20)
|
||||||
drop_rate = (int)(drop_rate*1.25); // pk_mode increase drops if 20 level difference [Valaris]
|
drop_rate = (int)(drop_rate*1.25); // pk_mode increase drops if 20 level difference [Valaris]
|
||||||
|
|
||||||
// if (10000 < rand()%10000+drop_rate) //May be better if MAX_RAND is too low?
|
// attempt to drop the item
|
||||||
if (drop_rate < rand() % 10000 + 1) //fixed 0.01% impossible drops bug [Lupus]
|
if (rand() % 10000 >= drop_rate)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ditem = mob_setdropitem(md->db->dropitem[i].nameid, 1);
|
ditem = mob_setdropitem(md->db->dropitem[i].nameid, 1);
|
||||||
@ -2014,8 +1998,10 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(sd) {
|
if(sd) {
|
||||||
|
// process script-granted extra drop bonuses
|
||||||
int itemid = 0;
|
int itemid = 0;
|
||||||
for (i = 0; i < sd->add_drop_count; i++) {
|
for (i = 0; i < sd->add_drop_count; i++)
|
||||||
|
{
|
||||||
if (sd->add_drop[i].id < 0)
|
if (sd->add_drop[i].id < 0)
|
||||||
continue;
|
continue;
|
||||||
if (sd->add_drop[i].race & (1<<status->race) ||
|
if (sd->add_drop[i].race & (1<<status->race) ||
|
||||||
@ -2026,34 +2012,32 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
//it's negative, then it should be multiplied. e.g. for Mimic,Myst Case Cards, etc
|
//it's negative, then it should be multiplied. e.g. for Mimic,Myst Case Cards, etc
|
||||||
// rate = base_rate * (mob_level/10) + 1
|
// rate = base_rate * (mob_level/10) + 1
|
||||||
drop_rate = -sd->add_drop[i].rate*(md->level/10)+1;
|
drop_rate = -sd->add_drop[i].rate*(md->level/10)+1;
|
||||||
if (drop_rate < battle_config.item_drop_adddrop_min)
|
drop_rate = cap_value(drop_rate, battle_config.item_drop_adddrop_min, battle_config.item_drop_adddrop_max);
|
||||||
drop_rate = battle_config.item_drop_adddrop_min;
|
|
||||||
else if (drop_rate > battle_config.item_drop_adddrop_max)
|
|
||||||
drop_rate = battle_config.item_drop_adddrop_max;
|
|
||||||
if (drop_rate > 10000) drop_rate = 10000;
|
if (drop_rate > 10000) drop_rate = 10000;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
//it's positive, then it goes as it is
|
//it's positive, then it goes as it is
|
||||||
drop_rate = sd->add_drop[i].rate;
|
drop_rate = sd->add_drop[i].rate;
|
||||||
if (drop_rate < rand()%10000 +1)
|
|
||||||
continue;
|
|
||||||
itemid = (sd->add_drop[i].id > 0) ? sd->add_drop[i].id :
|
|
||||||
itemdb_searchrandomid(sd->add_drop[i].group);
|
|
||||||
|
|
||||||
|
if (rand()%10000 >= drop_rate)
|
||||||
|
continue;
|
||||||
|
itemid = (sd->add_drop[i].id > 0) ? sd->add_drop[i].id : itemdb_searchrandomid(sd->add_drop[i].group);
|
||||||
mob_item_drop(md, dlist, mob_setdropitem(itemid,1), 0, drop_rate);
|
mob_item_drop(md, dlist, mob_setdropitem(itemid,1), 0, drop_rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sd->get_zeny_num && rand()%100 < sd->get_zeny_rate) //Gets get_zeny_num per level +/-10% [Skotlex]
|
// process script-granted zeny bonus (get_zeny_num per level +/-10%) [Skotlex]
|
||||||
|
if(sd->get_zeny_num && rand()%100 < sd->get_zeny_rate)
|
||||||
pc_getzeny(sd,md->level*sd->get_zeny_num*(90+rand()%21)/100);
|
pc_getzeny(sd,md->level*sd->get_zeny_num*(90+rand()%21)/100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process items looted by the mob
|
||||||
if(md->lootitem) {
|
if(md->lootitem) {
|
||||||
for(i = 0; i < md->lootitem_count; i++)
|
for(i = 0; i < md->lootitem_count; i++)
|
||||||
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000);
|
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000);
|
||||||
}
|
}
|
||||||
if (dlist->item) //There are drop items.
|
if (dlist->item) //There are drop items.
|
||||||
add_timer(tick + (!battle_config.delay_battle_damage?500:0),
|
add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, (int)dlist, 0);
|
||||||
mob_delay_item_drop, (int)dlist, 0);
|
|
||||||
else //No drops
|
else //No drops
|
||||||
ers_free(item_drop_list_ers, dlist);
|
ers_free(item_drop_list_ers, dlist);
|
||||||
} else if (md->lootitem && md->lootitem_count) { //Loot MUST drop!
|
} else if (md->lootitem && md->lootitem_count) { //Loot MUST drop!
|
||||||
@ -2067,11 +2051,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
dlist->item = NULL;
|
dlist->item = NULL;
|
||||||
for(i = 0; i < md->lootitem_count; i++)
|
for(i = 0; i < md->lootitem_count; i++)
|
||||||
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000);
|
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000);
|
||||||
add_timer(tick + (!battle_config.delay_battle_damage?500:0),
|
add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, (int)dlist, 0);
|
||||||
mob_delay_item_drop, (int)dlist, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mvp_sd && md->db->mexp > 0 && !md->special_state.ai){
|
if(mvp_sd && md->db->mexp > 0 && !md->special_state.ai)
|
||||||
|
{
|
||||||
int log_mvp[2] = {0};
|
int log_mvp[2] = {0};
|
||||||
int j;
|
int j;
|
||||||
unsigned int mexp;
|
unsigned int mexp;
|
||||||
@ -2099,7 +2083,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
if(map[m].flag.nomvploot || type&1)
|
if(map[m].flag.nomvploot || type&1)
|
||||||
; //No drops.
|
; //No drops.
|
||||||
else
|
else
|
||||||
for(j=0;j<3;j++){
|
for(j=0;j<3;j++)
|
||||||
|
{
|
||||||
i = rand() % 3;
|
i = rand() % 3;
|
||||||
|
|
||||||
if(md->db->mvpitem[i].nameid <= 0)
|
if(md->db->mvpitem[i].nameid <= 0)
|
||||||
@ -2167,7 +2152,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
|||||||
if(md->nd)
|
if(md->nd)
|
||||||
mob_script_callback(md, src, CALLBACK_DEAD);
|
mob_script_callback(md, src, CALLBACK_DEAD);
|
||||||
else
|
else
|
||||||
if(md->npc_event[0]){
|
if(md->npc_event[0])
|
||||||
|
{
|
||||||
md->status.hp = 0; //So that npc_event invoked functions KNOW that I am dead.
|
md->status.hp = 0; //So that npc_event invoked functions KNOW that I am dead.
|
||||||
if(src)
|
if(src)
|
||||||
switch (src->type) {
|
switch (src->type) {
|
||||||
|
@ -129,21 +129,15 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*==========================================
|
// The data structures for storing delayed item drops
|
||||||
* The structure object for item drop with delay
|
|
||||||
* Since it is only two being able to pass [ int ] a timer function
|
|
||||||
* Data is put in and passed to this structure object.
|
|
||||||
*------------------------------------------
|
|
||||||
*/
|
|
||||||
struct item_drop {
|
struct item_drop {
|
||||||
struct item item_data;
|
struct item item_data;
|
||||||
struct item_drop* next;
|
struct item_drop* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct item_drop_list {
|
struct item_drop_list {
|
||||||
int m,x,y;
|
int m, x, y; // coordinates
|
||||||
struct map_session_data *first_sd,*second_sd,*third_sd;
|
struct map_session_data *first_sd, *second_sd, *third_sd; // sd's of players with higher pickup priority
|
||||||
struct item_drop *item;
|
struct item_drop* item; // linked list of drops
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mob_db* mob_db(int class_);
|
struct mob_db* mob_db(int class_);
|
||||||
|
@ -6106,7 +6106,7 @@ int skill_castend_pos2 (struct block_list *src, int x, int y, int skillid, int s
|
|||||||
clif_skill_warppoint(sd, skillid, skilllv, sd->status.save_point.map,
|
clif_skill_warppoint(sd, skillid, skilllv, sd->status.save_point.map,
|
||||||
(skilllv >= 2) ? sd->status.memo_point[0].map : 0,
|
(skilllv >= 2) ? sd->status.memo_point[0].map : 0,
|
||||||
(skilllv >= 3) ? sd->status.memo_point[1].map : 0,
|
(skilllv >= 3) ? sd->status.memo_point[1].map : 0,
|
||||||
(skilllv >= 4) ? sd->status.memo_point[1].map : 0
|
(skilllv >= 4) ? sd->status.memo_point[2].map : 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1807,8 +1807,7 @@ int unit_free(struct block_list *bl, int clrtype)
|
|||||||
}
|
}
|
||||||
if (sd->followtimer != -1)
|
if (sd->followtimer != -1)
|
||||||
pc_stop_following(sd);
|
pc_stop_following(sd);
|
||||||
// Force exiting from duel and rejecting
|
// Force exiting from duel and rejecting all duel invitations when player quit [LuzZza]
|
||||||
// all duel invitations when player quit [LuzZza]
|
|
||||||
if(sd->duel_group > 0)
|
if(sd->duel_group > 0)
|
||||||
duel_leave(sd->duel_group, sd);
|
duel_leave(sd->duel_group, sd);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user