* Questlog code cleanup.
* Fixed range check of autospell and autospell2 using wrong target when it should be used on yourself. * Implemented official behavior of party_show_share_picker. * Restricted zones in 'item_noequip.txt' can now stack. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13987 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
2a499f4eda
commit
52bac46cfe
@ -3,6 +3,11 @@ Date Added
|
||||
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.
|
||||
|
||||
09/08/01
|
||||
* Questlog code cleanup. [Inkfish]
|
||||
* Fixed range check on autospell and autospell2. [Inkfish]
|
||||
* Implemented official behavior of party_show_share_picker. [Inkfish]
|
||||
* Fixed a typo on reading no_equip list. [Inkfish]
|
||||
09/07/28
|
||||
* Kaahi heals no matter if attack connects. (bugreport:2440) [Inkfish]
|
||||
* Fixed a typo causing skillitem always resets skill delay. (bugreport:3431) [Inkfish]
|
||||
|
@ -31,8 +31,14 @@ party_update_interval: 1000
|
||||
party_hp_mode: 0
|
||||
|
||||
// When 'Party Share' item sharing is enabled in a party,
|
||||
// tell the picker which party-member received the item? (Note 1)
|
||||
show_party_share_picker: no
|
||||
// announce in the party which party-member received the item and what's he received? (Note 1)
|
||||
show_party_share_picker: yes
|
||||
|
||||
// What types of items are going to be announced when 'show_party_share_picker' is active?
|
||||
// 1: IT_HEALING, 2: IT_UNKNOWN, 4: IT_USABLE, 8: IT_ETC,
|
||||
// 16: IT_WEAPON, 32: IT_ARMOR, 64: IT_CARD, 128: IT_PETEGG,
|
||||
// 256: IT_PETARMOR, 512: IT_UNKNOWN2, 1024: IT_AMMO, 2048: IT_DELAYCONSUME
|
||||
show_picker.item_type: 112
|
||||
|
||||
// Method of distribution when item party share is enabled in a party:
|
||||
//
|
||||
|
@ -58,57 +58,6 @@ int mapif_quests_fromsql(int char_id, struct quest questlog[])
|
||||
return i;
|
||||
}
|
||||
|
||||
//Save quests
|
||||
int mapif_parse_quest_save(int fd)
|
||||
{
|
||||
int i, j, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest);
|
||||
int char_id = RFIFOL(fd,4);
|
||||
struct quest qd1[MAX_QUEST_DB],qd2[MAX_QUEST_DB];
|
||||
uint8 buf[MAX_QUEST_DB];
|
||||
int count = 0;
|
||||
|
||||
memset(qd1, 0, sizeof(qd1));
|
||||
memset(qd2, 0, sizeof(qd2));
|
||||
memcpy(&qd1, RFIFOP(fd,8), RFIFOW(fd,2)-8);
|
||||
num2 = mapif_quests_fromsql(char_id, qd2);
|
||||
|
||||
for( i = 0; i < num1; i++ )
|
||||
{
|
||||
ARR_FIND( 0, num2, j, qd1[i].quest_id == qd2[j].quest_id );
|
||||
if( j < num2 ) // Update existed quests
|
||||
{ // Only states and counts are changable.
|
||||
if( qd1[i].state != qd2[j].state || qd1[i].count[0] != qd2[j].count[0] || qd1[i].count[1] != qd2[j].count[1] || qd1[i].count[2] != qd2[j].count[2] )
|
||||
mapif_quest_update(char_id, qd1[i]);
|
||||
|
||||
if( j < (--num2) )
|
||||
{
|
||||
memmove(&qd2[j],&qd2[j+1],sizeof(struct quest)*(num2-j));
|
||||
memset(&qd2[num2], 0, sizeof(struct quest));
|
||||
}
|
||||
|
||||
}
|
||||
else // Add new quests
|
||||
{
|
||||
mapif_quest_add(char_id, qd1[i]);
|
||||
|
||||
WBUFL(buf,count*4) = qd1[i].quest_id;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < num2; i++ ) // Quests not in qd1 but in qd2 are to be erased.
|
||||
mapif_quest_delete(char_id, qd2[i].quest_id);
|
||||
|
||||
WFIFOHEAD(fd,8+4*count);
|
||||
WFIFOW(fd,0) = 0x3861;
|
||||
WFIFOW(fd,2) = 8+4*count;
|
||||
WFIFOL(fd,4) = char_id;
|
||||
memcpy(WFIFOP(fd,8), buf, count*4);
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Delete a quest
|
||||
int mapif_quest_delete(int char_id, int quest_id)
|
||||
{
|
||||
@ -159,6 +108,57 @@ int mapif_quest_update(int char_id, struct quest qd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Save quests
|
||||
int mapif_parse_quest_save(int fd)
|
||||
{
|
||||
int i, j, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest);
|
||||
int char_id = RFIFOL(fd,4);
|
||||
struct quest qd1[MAX_QUEST_DB],qd2[MAX_QUEST_DB];
|
||||
int buf[MAX_QUEST_DB];
|
||||
int count = 0;
|
||||
|
||||
memset(qd1, 0, sizeof(qd1));
|
||||
memset(qd2, 0, sizeof(qd2));
|
||||
memcpy(&qd1, RFIFOP(fd,8), RFIFOW(fd,2)-8);
|
||||
num2 = mapif_quests_fromsql(char_id, qd2);
|
||||
|
||||
for( i = 0; i < num1; i++ )
|
||||
{
|
||||
ARR_FIND( 0, num2, j, qd1[i].quest_id == qd2[j].quest_id );
|
||||
if( j < num2 ) // Update existed quests
|
||||
{ // Only states and counts are changable.
|
||||
if( qd1[i].state != qd2[j].state || qd1[i].count[0] != qd2[j].count[0] || qd1[i].count[1] != qd2[j].count[1] || qd1[i].count[2] != qd2[j].count[2] )
|
||||
mapif_quest_update(char_id, qd1[i]);
|
||||
|
||||
if( j < (--num2) )
|
||||
{
|
||||
memmove(&qd2[j],&qd2[j+1],sizeof(struct quest)*(num2-j));
|
||||
memset(&qd2[num2], 0, sizeof(struct quest));
|
||||
}
|
||||
|
||||
}
|
||||
else // Add new quests
|
||||
{
|
||||
mapif_quest_add(char_id, qd1[i]);
|
||||
|
||||
WBUFL(buf,count*4) = qd1[i].quest_id;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < num2; i++ ) // Quests not in qd1 but in qd2 are to be erased.
|
||||
mapif_quest_delete(char_id, qd2[i].quest_id);
|
||||
|
||||
WFIFOHEAD(fd,8+4*count);
|
||||
WFIFOW(fd,0) = 0x3861;
|
||||
WFIFOW(fd,2) = 8+4*count;
|
||||
WFIFOL(fd,4) = char_id;
|
||||
memcpy(WFIFOP(fd,8), buf, count*4);
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Send questlog to map server
|
||||
int mapif_parse_quest_load(int fd)
|
||||
{
|
||||
|
@ -8,9 +8,6 @@
|
||||
struct quest;
|
||||
|
||||
int inter_quest_parse_frommap(int fd);
|
||||
int mapif_quest_delete(int char_id, int quest_id);
|
||||
int mapif_quest_add(int char_id, struct quest qd);
|
||||
int mapif_quest_update(int char_id, struct quest qd);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -3656,7 +3656,8 @@ static const struct _battle_data {
|
||||
{ "vending_over_max", &battle_config.vending_over_max, 1, 0, 1, },
|
||||
{ "show_steal_in_same_party", &battle_config.show_steal_in_same_party, 0, 0, 1, },
|
||||
{ "party_hp_mode", &battle_config.party_hp_mode, 0, 0, 1, },
|
||||
{ "show_party_share_picker", &battle_config.party_show_share_picker, 0, 0, 1, },
|
||||
{ "show_party_share_picker", &battle_config.party_show_share_picker, 1, 0, 1, },
|
||||
{ "show_picker.item_type", &battle_config.show_picker_item_type, 112, 0, INT_MAX, },
|
||||
{ "party_update_interval", &battle_config.party_update_interval, 1000, 100, INT_MAX, },
|
||||
{ "party_item_share_type", &battle_config.party_share_type, 0, 0, 1|2|3, },
|
||||
{ "attack_attr_none", &battle_config.attack_attr_none, ~BL_PC, BL_NUL, BL_ALL, },
|
||||
|
@ -283,6 +283,7 @@ extern struct Battle_Config
|
||||
int party_share_type;
|
||||
int party_hp_mode;
|
||||
int party_show_share_picker;
|
||||
int show_picker_item_type;
|
||||
int attack_attr_none;
|
||||
int item_rate_mvp, item_rate_common, item_rate_common_boss, item_rate_card, item_rate_card_boss,
|
||||
item_rate_equip, item_rate_equip_boss, item_rate_heal, item_rate_heal_boss, item_rate_use,
|
||||
|
@ -13139,6 +13139,27 @@ void clif_instance_leave(int fd)
|
||||
WFIFOSET(fd,packet_len(0x02CE));
|
||||
}
|
||||
|
||||
void clif_party_show_picker(struct map_session_data * sd, struct item * item_data)
|
||||
{
|
||||
unsigned char buf[22];
|
||||
|
||||
WBUFW(buf,0)=0x2b8;
|
||||
WBUFL(buf,2) = sd->status.account_id;
|
||||
WBUFW(buf,6) = item_data->nameid;
|
||||
WBUFB(buf,8) = item_data->identify;
|
||||
WBUFB(buf,9) = item_data->attribute;
|
||||
WBUFB(buf,10) = item_data->refine;
|
||||
WBUFW(buf,11) = item_data->card[0];
|
||||
WBUFW(buf,13) = item_data->card[1];
|
||||
WBUFW(buf,15) = item_data->card[2];
|
||||
WBUFW(buf,17) = item_data->card[3];
|
||||
//Unknown
|
||||
//WBUFB(buf,19) = 0;
|
||||
//WBUFB(buf,20) = 0;
|
||||
//WBUFB(buf,21) = 0;
|
||||
clif_send(buf, packet_len(0x2b8), &sd->bl, PARTY_SAMEMAP_WOS);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* パケットデバッグ
|
||||
*------------------------------------------*/
|
||||
@ -13409,7 +13430,7 @@ static int packetdb_readdb(void)
|
||||
0, 0, 0, 6, 0, 0, 0, 0, 0, 8, 18, 0, 0, 0, 0, 0,
|
||||
0, 4, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0,117, 6, 0, 7, 7, 0,191, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0,117, 6, 0, 7, 7, 22,191, 0, 0, 0, 0, 0, 0,
|
||||
//#0x02C0
|
||||
0, 0, 0, 0, 0, 30, 0, 0, 0, 3, 0, 65, 4, 71, 10, 0,
|
||||
0, 0, 0, 0, 0, 0, 6, -1, 10, 10, 3, 0, -1, 32, 6, 0,
|
||||
|
@ -479,4 +479,7 @@ void clif_rental_expired(int fd, int nameid);
|
||||
// BOOK READING
|
||||
void clif_readbook(int fd, int book_id, int page);
|
||||
|
||||
// Show Picker
|
||||
void clif_party_show_picker(struct map_session_data * sd, struct item * item_data);
|
||||
|
||||
#endif /* _CLIF_H_ */
|
||||
|
@ -603,7 +603,7 @@ static int itemdb_read_noequip(void)
|
||||
if(nameid<=0 || !(id=itemdb_exists(nameid)))
|
||||
continue;
|
||||
|
||||
id->flag.no_equip=atoi(str[1]);
|
||||
id->flag.no_equip |= atoi(str[1]);
|
||||
|
||||
ln++;
|
||||
|
||||
|
@ -921,11 +921,9 @@ int party_share_loot(struct party_data* p, struct map_session_data* sd, struct i
|
||||
if(log_config.enable_logs&0x8) //Logs items, taken by (P)layers [Lupus]
|
||||
log_pick_pc(target, "P", item_data->nameid, item_data->amount, item_data);
|
||||
|
||||
if(battle_config.party_show_share_picker && target != sd) {
|
||||
char output[80];
|
||||
sprintf(output, "%s acquired %s.",target->status.name, itemdb_jname(item_data->nameid));
|
||||
clif_disp_onlyself(sd,output,strlen(output));
|
||||
}
|
||||
if( p && battle_config.party_show_share_picker && battle_config.show_picker_item_type&(1<<itemdb_type(item_data->nameid)) )
|
||||
clif_party_show_picker(target, item_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,17 @@ struct s_quest_db {
|
||||
};
|
||||
struct s_quest_db quest_db[MAX_QUEST_DB];
|
||||
|
||||
int quest_search_db(int quest_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
ARR_FIND(0, MAX_QUEST_DB,i,quest_id == quest_db[i].id);
|
||||
if( i == MAX_QUEST_DB )
|
||||
return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
//Send quest info on login
|
||||
int quest_pc_login(TBL_PC * sd)
|
||||
{
|
||||
@ -61,19 +72,19 @@ int quest_add(TBL_PC * sd, int quest_id)
|
||||
|
||||
if( sd->num_quests >= MAX_QUEST_DB )
|
||||
{
|
||||
ShowError("quest_add: your quest log is full.(max quests: %d)\n", MAX_QUEST_DB);
|
||||
ShowError("quest_add: Character %d has got all the quests.(max quests: %d)\n", sd->status.char_id, MAX_QUEST_DB);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( quest_check(sd, quest_id, HAVEQUEST) >= 0 )
|
||||
{
|
||||
ShowError("quest_add: you already have quest %d.\n",quest_id);
|
||||
ShowError("quest_add: Character %d already has quest %d.\n", sd->status.char_id, quest_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( (j = quest_search_db(quest_id)) < 0 )
|
||||
{
|
||||
ShowError("quest_add: quest %d not found in DB.\n",quest_id);
|
||||
ShowError("quest_add: quest %d not found in DB.\n", quest_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -107,19 +118,19 @@ int quest_change(TBL_PC * sd, int qid1, int qid2)
|
||||
|
||||
if( sd->num_quests >= MAX_QUEST_DB )
|
||||
{
|
||||
ShowError("quest_change: your quest log is full.(max quests: %d)\n", MAX_QUEST_DB);
|
||||
ShowError("quest_change: Character %d has got all the quests.(max quests: %d)\n", sd->status.char_id, MAX_QUEST_DB);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( quest_check(sd, qid2, HAVEQUEST) >= 0 )
|
||||
{
|
||||
ShowError("quest_change: you already have quest %d.\n",qid2);
|
||||
ShowError("quest_change: Character %d already has quest %d.\n", sd->status.char_id, qid2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( quest_check(sd, qid1, HAVEQUEST) < 0 )
|
||||
{
|
||||
ShowError("quest_change: you don't have quest %d.\n",qid1);
|
||||
ShowError("quest_change: Character %d doesn't have quest %d.\n", sd->status.char_id, qid1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -132,7 +143,7 @@ int quest_change(TBL_PC * sd, int qid1, int qid2)
|
||||
ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == qid1);
|
||||
if(i == sd->avail_quests)
|
||||
{
|
||||
ShowError("quest_change: Quest %d not found in your quest log!\n", qid1);
|
||||
ShowError("quest_change: Character %d has completed quests %d.\n", sd->status.char_id, qid1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -169,7 +180,7 @@ int quest_delete(TBL_PC * sd, int quest_id)
|
||||
ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
|
||||
if(i == sd->num_quests)
|
||||
{
|
||||
ShowError("quest_delete: quest %d not found in your quest log.\n",quest_id);
|
||||
ShowError("quest_delete: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -219,7 +230,7 @@ int quest_update_status(TBL_PC * sd, int quest_id, quest_state status)
|
||||
ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == quest_id);
|
||||
if(i == sd->avail_quests)
|
||||
{
|
||||
ShowError("quest_update_status: Quest %d not found in your quest log!\n", quest_id);
|
||||
ShowError("quest_update_status: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -269,7 +280,7 @@ int quest_check(TBL_PC * sd, int quest_id, quest_check_type type)
|
||||
|
||||
if( j < 0 )
|
||||
{
|
||||
ShowError("quest_check_quest: quest not found in DB\n");
|
||||
ShowError("quest_check_quest: quest %d not found in DB.\n",quest_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -291,17 +302,6 @@ int quest_check(TBL_PC * sd, int quest_id, quest_check_type type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int quest_search_db(int quest_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
ARR_FIND(0, MAX_QUEST_DB,i,quest_id == quest_db[i].id);
|
||||
if( i == MAX_QUEST_DB )
|
||||
return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int quest_read_db(void)
|
||||
{
|
||||
FILE *fp;
|
||||
|
@ -15,8 +15,6 @@ void quest_update_objective(TBL_PC * sd, int mob);
|
||||
int quest_update_status(TBL_PC * sd, int quest_id, quest_state status);
|
||||
int quest_check(TBL_PC * sd, int quest_id, quest_check_type type);
|
||||
|
||||
int quest_search_db(int quest_id);
|
||||
|
||||
void do_init_quest();
|
||||
|
||||
#endif
|
||||
|
@ -1010,13 +1010,10 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
|
||||
if (rand()%1000 > rate)
|
||||
continue;
|
||||
|
||||
if( !battle_check_range(src, bl, skill_get_range2(src, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) )
|
||||
continue; //Autocasts should always fail if the target is outside the skill range or an obstacle is in between.[Inkfish]
|
||||
tbl = (sd->autospell[i].id < 0) ? src : bl;
|
||||
|
||||
if (sd->autospell[i].id < 0)
|
||||
tbl = src;
|
||||
else
|
||||
tbl = bl;
|
||||
if( !battle_check_range(src, tbl, skill_get_range2(src, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) )
|
||||
continue; //Autocasts should always fail if the target is outside the skill range or an obstacle is in between.[Inkfish]
|
||||
|
||||
sd->state.autocast = 1;
|
||||
skill_consume_requirement(sd,skill,skilllv,1);
|
||||
@ -1275,12 +1272,11 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
|
||||
continue;
|
||||
if (rand()%1000 > rate)
|
||||
continue;
|
||||
if( !battle_check_range(src, bl, skill_get_range2(src, skillid,skilllv) + (skillid == RG_CLOSECONFINE?0:1)) )
|
||||
|
||||
tbl = (dstsd->autospell2[i].id < 0) ? bl : src;
|
||||
|
||||
if( !battle_check_range(src, tbl, skill_get_range2(src, skillid,skilllv) + (skillid == RG_CLOSECONFINE?0:1)) )
|
||||
continue;
|
||||
if (dstsd->autospell2[i].id < 0)
|
||||
tbl = bl;
|
||||
else
|
||||
tbl = src;
|
||||
|
||||
dstsd->state.autocast = 1;
|
||||
skill_consume_requirement(dstsd,skillid,skilllv,1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user