Bug fixes & misc:

- Follow up 7fd6776, correcting how to make player sit by autotrade persistance.
- Follow up 7fd6776, pc_setstand() does a check if player can stand or not.
- bugreport:9174, buyingstore_close() doesn't clear buyingstores data on table.
- Fixed "missing" buyingstore search (purchase type search) in searchstore, by adding DBMap *buyingstore_db.
- Added nullpo checks on some buyingstore.c functions.
- Added do_init_buyingstore() and do_final_buyingstore().
- Failing autotrader from pc_setpos(). (Since autotrade doesn't have 'fd'? FIXME later)

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
Cydh Ramdh
2014-08-02 11:07:26 +07:00
parent caa80ecfc7
commit 8a819403c1
17 changed files with 181 additions and 114 deletions

View File

@@ -3545,7 +3545,7 @@ ACMD_FUNC(recallall)
count++;
else {
if (pc_isdead(pl_sd)) { //Wake them up
pc_setstand(pl_sd);
pc_setstand(pl_sd, true);
pc_setrestartvalue(pl_sd,1);
}
pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
@@ -5766,7 +5766,7 @@ ACMD_FUNC(autotrade) {
Sql_ShowDebug( mmysql_handle );
}
}else if( sd->state.buyingstore ){
if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;", buyingstore_db, sd->buyer_id ) != SQL_SUCCESS ){
if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;", buyingstores_db, sd->buyer_id ) != SQL_SUCCESS ){
Sql_ShowDebug( mmysql_handle );
}
}
@@ -5778,7 +5778,7 @@ ACMD_FUNC(autotrade) {
channel_pcquit(sd,0xF); //leave all chan
clif_authfail_fd(sd->fd, 15);
chrif_save(sd,3);
return 0;
@@ -9532,7 +9532,7 @@ ACMD_FUNC(cloneequip) {
else {
int8 i;
for (i = 0; i < EQI_MAX; i++) {
int8 idx;
short idx;
char flag = 0;
struct item tmp_item;
if ((idx = pl_sd->equip_index[i]) < 0)

View File

@@ -889,7 +889,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
(flag&BF_LONG || sc->data[SC_SPURT])
&& rnd()%100 < 20)
{
if (sd && pc_issit(sd)) pc_setstand(sd); //Stand it to dodge.
if (sd && pc_issit(sd)) pc_setstand(sd, true); //Stand it to dodge.
clif_skill_nodamage(bl,bl,TK_DODGE,1,1);
if (!sc->data[SC_COMBO])
sc_start4(src,bl, SC_COMBO, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
@@ -3556,7 +3556,7 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
break;
case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield DEF x 10) + (Casters VIT x 2)] %
if (sd && skill_lv == 1) {
int index = sd->equip_index[EQI_HAND_L];
short index = sd->equip_index[EQI_HAND_L];
if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR)
skillratio += sd->inventory_data[index]->def * 10;
@@ -6379,6 +6379,9 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int64 rdamage, int64 ldama
struct weapon_data *wd;
int64 *damage;
int thp = 0, tsp = 0, rhp = 0, rsp = 0, hp=0, sp=0, i;
if (!CHK_RACE(race) && !CHK_CLASS(class_))
return;
for (i = 0; i < 4; i++) {
//First two iterations: Right hand
if (i < 2) { wd = &sd->right_weapon; damage = &rdamage; }
@@ -6538,7 +6541,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
sd->state.arrow_atk = (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE));
if (sd->state.arrow_atk)
{
int index = sd->equip_index[EQI_AMMO];
short index = sd->equip_index[EQI_AMMO];
if (index < 0) {
clif_arrow_fail(sd,0);
return ATK_NONE;

View File

@@ -1,6 +1,7 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#include "../common/nullpo.h"
#include "../common/cbasetypes.h"
#include "../common/db.h" // ARR_FIND
#include "../common/malloc.h" // aMalloc, aFree
@@ -48,6 +49,11 @@ static void do_final_buyingstore_autotrade(void);
#define BUYINGSTORE_MAX_PRICE 99990000
#define BUYINGSTORE_MAX_AMOUNT 9999
static DBMap *buyingstore_db;
DBMap *buyingstore_getdb(void) {
return buyingstore_db;
}
/// failure constants for clif functions
enum e_buyingstore_failure
@@ -80,6 +86,8 @@ static unsigned int buyingstore_getuid(void)
* @return 0 If success, 1 - Cannot open, 2 - Manner penalty, 3 - Mapflag restiction, 4 - Cell restriction
*/
char buyingstore_setup(struct map_session_data* sd, unsigned char slots){
nullpo_retr(1, sd);
if (!battle_config.feature_buying_store || sd->state.vending || sd->state.buyingstore || sd->state.trading || slots == 0) {
return 1;
}
@@ -128,6 +136,8 @@ char buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
unsigned int i, weight, listidx;
char message_sql[MESSAGE_SIZE*2];
nullpo_retr(1, sd);
if( !result || count == 0 )
{// canceled, or no items
return 5;
@@ -239,7 +249,7 @@ char buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`id`,`account_id`,`char_id`,`sex`,`map`,`x`,`y`,`title`,`limit`,`autotrade`, `body_direction`, `head_direction`, `sit`) "
"VALUES( %d, %d, %d, '%c', '%s', %d, %d, '%s', %d, %d, '%d', '%d', '%d' );",
buyingstore_db, sd->buyer_id, sd->status.account_id, sd->status.char_id, sd->status.sex == 0 ? 'F' : 'M', map[sd->bl.m].name, sd->bl.x, sd->bl.y, message_sql, sd->buyingstore.zenylimit, sd->state.autotrade, sd->ud.dir, sd->head_dir, pc_issit(sd) ) != SQL_SUCCESS ){
buyingstores_db, sd->buyer_id, sd->status.account_id, sd->status.char_id, sd->status.sex == 0 ? 'F' : 'M', map[sd->bl.m].name, sd->bl.x, sd->bl.y, message_sql, sd->buyingstore.zenylimit, sd->state.autotrade, sd->ud.dir, sd->head_dir, pc_issit(sd) ) != SQL_SUCCESS ){
Sql_ShowDebug(mmysql_handle);
}
@@ -251,30 +261,30 @@ char buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
clif_buyingstore_myitemlist(sd);
clif_buyingstore_entry(sd);
idb_put(buyingstore_db, sd->status.char_id, sd);
return 0;
}
/**
* Close buying store
* Close buying store and clear buying store data from tables
* @param sd
*/
void buyingstore_close(struct map_session_data* sd)
{
if( sd->state.buyingstore )
{
if( !sd->state.autotrade ){
if(
Sql_Query( mmysql_handle, "DELETE FROM `%s` WHERE buyingstore_id = %d;", buyingstore_items_db, sd->buyer_id ) != SQL_SUCCESS ||
Sql_Query( mmysql_handle, "DELETE FROM `%s` WHERE `id` = %d;", buyingstore_db, sd->buyer_id ) != SQL_SUCCESS
){
Sql_ShowDebug(mmysql_handle);
}
void buyingstore_close(struct map_session_data* sd) {
nullpo_retv(sd);
if( sd->state.buyingstore ) {
if(
Sql_Query( mmysql_handle, "DELETE FROM `%s` WHERE buyingstore_id = %d;", buyingstore_items_db, sd->buyer_id ) != SQL_SUCCESS ||
Sql_Query( mmysql_handle, "DELETE FROM `%s` WHERE `id` = %d;", buyingstores_db, sd->buyer_id ) != SQL_SUCCESS
) {
Sql_ShowDebug(mmysql_handle);
}
// invalidate data
sd->state.buyingstore = false;
sd->buyer_id = 0;
memset(&sd->buyingstore, 0, sizeof(sd->buyingstore));
idb_remove(buyingstore_db, sd->status.char_id);
// notify other players
clif_buyingstore_disappear_entry(sd);
@@ -290,6 +300,8 @@ void buyingstore_open(struct map_session_data* sd, int account_id)
{
struct map_session_data* pl_sd;
nullpo_retv(sd);
if( !battle_config.feature_buying_store || pc_istrading(sd) )
{// not allowed to sell
return;
@@ -328,6 +340,8 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int
unsigned int i, weight, listidx, k;
struct map_session_data* pl_sd;
nullpo_retv(sd);
if( count == 0 )
{// nothing to do
return;
@@ -490,7 +504,7 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int
}
else
{// continue buying
if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `limit` = %d WHERE `id` = %d;", buyingstore_db, pl_sd->buyingstore.zenylimit, pl_sd->buyer_id ) != SQL_SUCCESS ){
if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `limit` = %d WHERE `id` = %d;", buyingstores_db, pl_sd->buyingstore.zenylimit, pl_sd->buyer_id ) != SQL_SUCCESS ){
Sql_ShowDebug( mmysql_handle );
}
@@ -513,6 +527,8 @@ bool buyingstore_search(struct map_session_data* sd, unsigned short nameid)
{
unsigned int i;
nullpo_ret(sd);
if( !sd->state.buyingstore )
{// not buying
return false;
@@ -535,6 +551,8 @@ bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_st
unsigned int i, idx;
struct s_buyingstore_item* it;
nullpo_ret(sd);
if( !sd->state.buyingstore )
{// not buying
return true;
@@ -578,8 +596,10 @@ bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_st
* @param sd Player as autotrader
*/
void buyingstore_reopen( struct map_session_data* sd ){
nullpo_retv(sd);
// Ready to open buyingstore for this char
if ( sd && autotrader_count > 0 && autotraders){
if ( autotrader_count > 0 && autotraders){
uint16 i;
uint8 *data, *p, fail = 0;
uint16 j, count;
@@ -619,7 +639,7 @@ void buyingstore_reopen( struct map_session_data* sd ){
// Set him to autotrade
if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1, `body_direction` = '%d', `head_direction` = '%d', `sit` = '%d' "
"WHERE `id` = %d;",
buyingstore_db, autotraders[i]->dir, autotraders[i]->head_dir, autotraders[i]->sit, sd->buyer_id ) != SQL_SUCCESS )
buyingstores_db, autotraders[i]->dir, autotraders[i]->head_dir, autotraders[i]->sit, sd->buyer_id ) != SQL_SUCCESS )
{
Sql_ShowDebug( mmysql_handle );
}
@@ -627,8 +647,11 @@ void buyingstore_reopen( struct map_session_data* sd ){
// Make buyer look perfect
pc_setdir(sd, autotraders[i]->dir, autotraders[i]->head_dir);
clif_changed_dir(&sd->bl, AREA_WOS);
if( autotraders[i]->sit )
if( autotraders[i]->sit ) {
pc_setsit(sd);
skill_sit(sd, 1);
clif_sitting(&sd->bl);
}
// Immediate save
chrif_save(sd, 3);
@@ -662,7 +685,7 @@ void do_init_buyingstore_autotrade( void ) {
"FROM `%s` "
"WHERE `autotrade` = 1 AND `limit` > 0 AND (SELECT COUNT(`buyingstore_id`) FROM `%s` WHERE `buyingstore_id` = `id`) > 0 "
"ORDER BY `id`;",
buyingstore_db, buyingstore_items_db ) != SQL_SUCCESS )
buyingstores_db, buyingstore_items_db ) != SQL_SUCCESS )
{
Sql_ShowDebug(mmysql_handle);
return;
@@ -758,12 +781,12 @@ void do_init_buyingstore_autotrade( void ) {
Sql_FreeResult(mmysql_handle);
}
ShowStatus("Done loading '"CL_WHITE"%d"CL_RESET"' autotraders with '"CL_WHITE"%d"CL_RESET"' items.\n", autotrader_count, items);
ShowStatus("Done loading '"CL_WHITE"%d"CL_RESET"' buyingstore autotraders with '"CL_WHITE"%d"CL_RESET"' items.\n", autotrader_count, items);
}
}
// Everything is loaded fine, their entries will be reinserted once they are loaded
if (Sql_Query( mmysql_handle, "DELETE FROM `%s`;", buyingstore_db ) != SQL_SUCCESS ||
if (Sql_Query( mmysql_handle, "DELETE FROM `%s`;", buyingstores_db ) != SQL_SUCCESS ||
Sql_Query( mmysql_handle, "DELETE FROM `%s`;", buyingstore_items_db ) != SQL_SUCCESS)
{
Sql_ShowDebug(mmysql_handle);
@@ -798,3 +821,21 @@ void do_final_buyingstore_autotrade(void) {
autotrader_count = 0;
}
}
/**
* Initialise the buyingstore module
* called in map::do_init
*/
void do_final_buyingstore(void) {
db_destroy(buyingstore_db);
do_final_buyingstore_autotrade();
}
/**
* Destory the buyingstore module
* called in map::do_final
*/
void do_init_buyingstore(void) {
buyingstore_db = idb_alloc(DB_OPT_BASE);
buyingstore_nextid = 0;
}

View File

@@ -29,6 +29,9 @@ void buyingstore_open(struct map_session_data* sd, int account_id);
void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count);
bool buyingstore_search(struct map_session_data* sd, unsigned short nameid);
bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_store_search* s);
DBMap *buyingstore_getdb(void);
void do_final_buyingstore(void);
void do_init_buyingstore(void);
void do_init_buyingstore_autotrade( void );
void buyingstore_reopen( struct map_session_data* sd );

View File

@@ -10372,18 +10372,12 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
return;
}
// Cannot stand yet
// TODO: Move to SCS_NOSTAND [Cydh]
if (&sd->sc && (sd->sc.data[SC_SITDOWN_FORCE] || sd->sc.data[SC_BANANA_BOMB_SITDOWN])) {
return;
if (pc_setstand(sd, false)) {
if (battle_config.idletime_option&IDLE_SIT)
sd->idletime = last_tick;
skill_sit(sd, 0);
clif_standing(&sd->bl);
}
if (battle_config.idletime_option&IDLE_SIT)
sd->idletime = last_tick;
pc_setstand(sd);
skill_sit(sd, 0);
clif_standing(&sd->bl);
break;
}
}

View File

@@ -70,7 +70,7 @@ char map_server_db[32] = "ragnarok";
Sql* mmysql_handle;
int db_use_sqldbs = 0;
char buyingstore_db[32] = "buyingstores";
char buyingstores_db[32] = "buyingstores";
char buyingstore_items_db[32] = "buyingstore_items";
char item_db_db[32] = "item_db";
char item_db2_db[32] = "item_db2";
@@ -1768,6 +1768,9 @@ int map_quit(struct map_session_data *sd) {
if (sd->state.vending)
idb_remove(vending_getdb(), sd->status.char_id);
if (sd->state.buyingstore)
idb_remove(buyingstore_getdb(), sd->status.char_id);
pc_damage_log_clear(sd,0);
party_booking_delete(sd); // Party Booking [Spiria]
pc_makesavestatus(sd);
@@ -3587,7 +3590,7 @@ int inter_config_read(char *cfgName)
continue;
if( strcmpi( w1, "buyingstore_db" ) == 0 )
strcpy( buyingstore_db, w2 );
strcpy( buyingstores_db, w2 );
else if( strcmpi( w1, "buyingstore_items_db" ) == 0 )
strcpy( buyingstore_items_db, w2 );
else if(strcmpi(w1,"item_db_db")==0)
@@ -3881,6 +3884,7 @@ void do_final(void)
do_final_cashshop();
do_final_channel(); //should be called after final guild
do_final_vending();
do_final_buyingstore();
map_db->destroy(map_db, map_db_final);
@@ -4191,6 +4195,7 @@ int do_init(int argc, char *argv[])
do_init_battleground();
do_init_duel();
do_init_vending();
do_init_buyingstore();
npc_event_do_oninit(); // Init npcs (OnInit)

View File

@@ -936,7 +936,7 @@ extern int db_use_sqldbs;
extern Sql* mmysql_handle;
extern Sql* logmysql_handle;
extern char buyingstore_db[32];
extern char buyingstores_db[32];
extern char buyingstore_items_db[32];
extern char item_db_db[32];
extern char item_db2_db[32];

View File

@@ -4019,9 +4019,9 @@ static int mob_read_sqldb(void)
*------------------------------------------*/
static bool mob_readdb_mobavail(char* str[], int columns, int current)
{
int mob_id, k;
int mob_id, sprite_id;
mob_id=atoi(str[0]);
mob_id = atoi(str[0]);
if(mob_db(mob_id) == mob_dummy) // invalid class (probably undefined in db)
{
@@ -4029,13 +4029,13 @@ static bool mob_readdb_mobavail(char* str[], int columns, int current)
return false;
}
k=atoi(str[1]);
sprite_id = atoi(str[1]);
memset(&mob_db_data[mob_id]->vd, 0, sizeof(struct view_data));
mob_db_data[mob_id]->vd.class_=k;
mob_db_data[mob_id]->vd.class_ = sprite_id;
//Player sprites
if(pcdb_checkid(k) && columns==12) {
if(pcdb_checkid(sprite_id) && columns==12) {
mob_db_data[mob_id]->vd.sex=atoi(str[2]);
mob_db_data[mob_id]->vd.hair_style=atoi(str[3]);
mob_db_data[mob_id]->vd.hair_color=atoi(str[4]);

View File

@@ -849,7 +849,7 @@ bool pc_isequipped(struct map_session_data *sd, unsigned short nameid)
for( i = 0; i < EQI_MAX; i++ )
{
int8 index = sd->equip_index[i], j;
short index = sd->equip_index[i], j;
if( index < 0 )
continue;
if( pc_is_same_equip_index((enum equip_index)i, sd->equip_index, index) )
@@ -5152,8 +5152,11 @@ char pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int
return 1;
}
if ( sd->state.autotrade && (sd->vender_id || sd->buyer_id) ) // Player with autotrade just causes clif glitch! @ FIXME
return 1;
if( battle_config.revive_onwarp && pc_isdead(sd) ) { //Revive dead people before warping them
pc_setstand(sd);
pc_setstand(sd, true);
pc_setrestartvalue(sd,1);
}
@@ -7059,7 +7062,7 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype)
if( sd->bg_id && bg_member_respawn(sd) )
return; // member revived by battleground
pc_setstand(sd);
pc_setstand(sd, true);
pc_setrestartvalue(sd,3);
if( pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype) )
clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
@@ -7090,7 +7093,7 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
return;
if( pc_issit(sd) ) {
pc_setstand(sd);
pc_setstand(sd, true);
skill_sit(sd,0);
}
@@ -7471,7 +7474,7 @@ void pc_revive(struct map_session_data *sd,unsigned int hp, unsigned int sp) {
if(hp) clif_updatestatus(sd,SP_HP);
if(sp) clif_updatestatus(sd,SP_SP);
pc_setstand(sd);
pc_setstand(sd, true);
if(battle_config.pc_invincible_time > 0)
pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
@@ -8076,6 +8079,8 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
elemental_delete(sd->ed, 0);
if (sd->state.vending)
vending_closevending(sd);
if (sd->state.buyingstore)
buyingstore_close(sd);
map_foreachinmap(jobchange_killclone, sd->bl.m, BL_MOB, sd->bl.id);
@@ -8910,8 +8915,7 @@ static int pc_checkcombo(struct map_session_data *sd, struct item_data *data) {
bool found = false;
for( k = 0; k < EQI_MAX; k++ ) {
int8 index;
index = sd->equip_index[k];
short index = sd->equip_index[k];
if( index < 0 )
continue;
if( pc_is_same_equip_index((enum equip_index)k, sd->equip_index, index) )
@@ -9051,8 +9055,8 @@ int pc_load_combo(struct map_session_data *sd) {
int i, ret = 0;
for( i = 0; i < EQI_MAX; i++ ) {
struct item_data *id = NULL;
int idx = sd->equip_index[i];
if( sd->equip_index[i] < 0 || !(id = sd->inventory_data[idx] ) )
short idx = sd->equip_index[i];
if( idx < 0 || !(id = sd->inventory_data[idx] ) )
continue;
if( id->combos_count )
ret += pc_checkcombo(sd,id);
@@ -9889,8 +9893,19 @@ int map_night_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
}
void pc_setstand(struct map_session_data *sd){
nullpo_retv(sd);
/**
* Attempt to stand up a player
* @param sd
* @param force Ignore the check, ask player to stand up. Used in some cases like pc_damage(), pc_revive(), etc
* @return True if success, Fals if failed
*/
bool pc_setstand(struct map_session_data *sd, bool force){
nullpo_ret(sd);
// Cannot stand yet
// TODO: Move to SCS_NOSTAND [Cydh]
if (!force && &sd->sc && (sd->sc.data[SC_SITDOWN_FORCE] || sd->sc.data[SC_BANANA_BOMB_SITDOWN]))
return false;
status_change_end(&sd->bl, SC_TENSIONRELAX, INVALID_TIMER);
clif_status_load(&sd->bl,SI_SIT,0);
@@ -9898,6 +9913,7 @@ void pc_setstand(struct map_session_data *sd){
//Reset sitting tick.
sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0;
sd->state.dead_sit = sd->vd.dead_sit = 0;
return true;
}
/**
@@ -11144,7 +11160,7 @@ short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id)
* @param index Known index item in inventory from sd->equip_index[] to compare with specified EQI in *equip_index
* @return True if item in same inventory index, False if doesn't
*/
bool pc_is_same_equip_index(enum equip_index eqi, int *equip_index, int8 index) {
bool pc_is_same_equip_index(enum equip_index eqi, short *equip_index, short index) {
if (index < 0 || index >= MAX_INVENTORY)
return true;
// Dual weapon checks

View File

@@ -252,7 +252,7 @@ struct map_session_data {
struct registry save_reg;
struct item_data* inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups)
int equip_index[EQI_MAX];
short equip_index[EQI_MAX];
unsigned int weight,max_weight;
int cart_weight,cart_num,cart_weight_max;
int fd;
@@ -1010,7 +1010,7 @@ struct map_session_data *pc_get_child(struct map_session_data *sd);
void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick);
void pc_regen (struct map_session_data *sd, unsigned int diff_tick);
void pc_setstand(struct map_session_data *sd);
bool pc_setstand(struct map_session_data *sd, bool force);
bool pc_candrop(struct map_session_data *sd,struct item *item);
bool pc_can_attack(struct map_session_data *sd, int target_id);
@@ -1122,7 +1122,7 @@ void pc_itemgrouphealrate_clear(struct map_session_data *sd);
short pc_get_itemgroup_bonus(struct map_session_data* sd, unsigned short nameid);
short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id);
bool pc_is_same_equip_index(enum equip_index eqi, int *equip_index, int8 index);
bool pc_is_same_equip_index(enum equip_index eqi, short *equip_index, short index);
/// Check if player is Taekwon Ranker and the level is >= 90 (battle_config.taekwon_ranker_min_lv)
#define pc_is_taekwon_ranker(sd) (((sd)->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && (sd)->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank((sd)->status.char_id,MAPID_TAEKWON))

View File

@@ -308,7 +308,7 @@ const char* parse_syntax_close_sub(const char* p,int* flag);
const char* parse_syntax(const char* p);
static int parse_syntax_for_flag = 0;
extern int current_equip_item_index; //for New CARDS Scripts. It contains Inventory Index of the EQUIP_SCRIPT caller item. [Lupus]
extern short current_equip_item_index; //for New CARDS Scripts. It contains Inventory Index of the EQUIP_SCRIPT caller item. [Lupus]
int potion_flag=0; //For use on Alchemist improved potions/Potion Pitcher. [Skotlex]
int potion_hp=0, potion_per_hp=0, potion_sp=0, potion_per_sp=0;
int potion_target=0;
@@ -13145,8 +13145,7 @@ BUILDIN_FUNC(skilleffect)
/* Ensure we're standing because the following packet causes the client to virtually set the char to stand,
* which leaves the server thinking it still is sitting. */
if( pc_issit(sd) ) {
pc_setstand(sd);
if( pc_issit(sd) && pc_setstand(sd, false) ) {
skill_sit(sd, 0);
clif_standing(&sd->bl);
}
@@ -14014,7 +14013,7 @@ BUILDIN_FUNC(isday)
BUILDIN_FUNC(isequippedcnt)
{
TBL_PC *sd;
int i, j, k, id = 1;
int i, id = 1;
int ret = 0;
sd = script_rid2sd(st);
@@ -14024,13 +14023,13 @@ BUILDIN_FUNC(isequippedcnt)
}
for (i=0; id!=0; i++) {
short j;
FETCH (i+2, id) else id = 0;
if (id <= 0)
continue;
for (j=0; j<EQI_MAX; j++) {
int index;
index = sd->equip_index[j];
short index = sd->equip_index[j];
if(index < 0)
continue;
if (pc_is_same_equip_index((enum equip_index)j, sd->equip_index, index))
@@ -14043,6 +14042,7 @@ BUILDIN_FUNC(isequippedcnt)
if (sd->inventory_data[index]->nameid == id)
ret+= sd->status.inventory[index].amount;
} else { //Count cards.
short k;
if (itemdb_isspecial(sd->status.inventory[index].card[0]))
continue; //No cards
for(k=0; k<sd->inventory_data[index]->slot; k++) {
@@ -14066,8 +14066,7 @@ BUILDIN_FUNC(isequippedcnt)
BUILDIN_FUNC(isequipped)
{
TBL_PC *sd;
int i, j, k, id = 1;
int index, flag;
int i, id = 1;
int ret = -1;
//Original hash to reverse it when full check fails.
unsigned int setitem_hash = 0, setitem_hash2 = 0;
@@ -14076,18 +14075,19 @@ BUILDIN_FUNC(isequipped)
if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing...
script_pushint(st,0);
return 0;
return SCRIPT_CMD_SUCCESS;
}
setitem_hash = sd->bonus.setitem_hash;
setitem_hash2 = sd->bonus.setitem_hash2;
for (i=0; id!=0; i++) {
int flag = 0;
short j;
FETCH (i+2, id) else id = 0;
if (id <= 0)
continue;
flag = 0;
for (j=0; j<EQI_MAX; j++) {
index = sd->equip_index[j];
short index = sd->equip_index[j];
if(index < 0)
continue;
if (pc_is_same_equip_index((enum equip_index)i, sd->equip_index, index))
@@ -14102,6 +14102,7 @@ BUILDIN_FUNC(isequipped)
flag = 1;
break;
} else { //Cards
short k;
if (sd->inventory_data[index]->slot == 0 ||
itemdb_isspecial(sd->status.inventory[index].card[0]))
continue;
@@ -18296,8 +18297,7 @@ BUILDIN_FUNC(stand)
if( sd == NULL)
return SCRIPT_CMD_FAILURE;
if( pc_issit(sd) ) {
pc_setstand(sd);
if( pc_issit(sd) && pc_setstand(sd, false)) {
skill_sit(sd, 0);
clif_standing(&sd->bl);
}

View File

@@ -115,6 +115,7 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
searchstore_searchall_t store_searchall;
time_t querytime;
DBMap *vending_db = vending_getdb();
DBMap *buyingstore_db = buyingstore_getdb();
if( !battle_config.feature_search_stores ) {
return;
@@ -179,7 +180,7 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
s.card_count = card_count;
s.min_price = min_price;
s.max_price = max_price;
iter = db_iterator(vending_db);
iter = db_iterator((type == SEARCHTYPE_VENDING) ? vending_db : buyingstore_db);
for( pl_sd = dbi_first(iter); dbi_exists(iter); pl_sd = dbi_next(iter) ) {
if( sd == pl_sd ) {// skip own shop, if any

View File

@@ -2081,7 +2081,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
!(skill_get_inf(skill_id)&(INF_GROUND_SKILL|INF_SELF_SKILL)) &&
(rate=pc_checkskill(sd,HW_SOULDRAIN))>0
){ //Soul Drain should only work on targetted spells [Skotlex]
if (pc_issit(sd)) pc_setstand(sd); //Character stuck in attacking animation while 'sitting' fix. [Skotlex]
if (pc_issit(sd)) pc_setstand(sd, true); //Character stuck in attacking animation while 'sitting' fix. [Skotlex]
clif_skill_nodamage(src,bl,HW_SOULDRAIN,rate,1);
status_heal(src, 0, status_get_lv(bl)*(95+15*rate)/100, 2);
}
@@ -2277,7 +2277,7 @@ int skill_break_equip (struct block_list *src,struct block_list *bl, unsigned sh
return 0;
if (sd) {
for (i = 0; i < EQI_MAX; i++) {
int j = sd->equip_index[i];
short j = sd->equip_index[i];
if (j < 0 || sd->status.inventory[j].attribute == 1 || !sd->inventory_data[j])
continue;
@@ -8117,8 +8117,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
continue;
if(map_getcell(src->m,src->x+dx[j],src->y+dy[j],CELL_CHKNOREACH))
dx[j] = dy[j] = 0;
pc_setpos(dstsd, map_id2index(src->m), src->x+dx[j], src->y+dy[j], CLR_RESPAWN);
called++;
if (!pc_setpos(dstsd, map_id2index(src->m), src->x+dx[j], src->y+dy[j], CLR_RESPAWN))
called++;
}
}
if (sd)
@@ -9141,11 +9141,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
else if( sd ) {
int opt = rnd()%3 + 1;
int val = 0, splash = 0;
int index = sd->equip_index[EQI_HAND_L];
short index = sd->equip_index[EQI_HAND_L];
struct item_data *shield_data = NULL;
if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
shield_data = sd->inventory_data[index];
if( !shield_data || shield_data->type != IT_ARMOR ) { // No shield?
if( index < 0 || !(shield_data = sd->inventory_data[index]) || shield_data->type == IT_ARMOR ) { // No shield?
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
break;
}
@@ -9215,8 +9213,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case 3: // refine based
{
struct item *shield = &sd->status.inventory[sd->equip_index[EQI_HAND_L]];
if( !shield || !shield->refine ) {
struct item *shield = NULL;
if( sd->equip_index[EQI_HAND_L] < 0 || !(shield = &sd->status.inventory[sd->equip_index[EQI_HAND_L]]) || !shield->refine ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
@@ -9753,7 +9751,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( sd ) {
short ammo_id;
i = sd->equip_index[EQI_AMMO];
if( i <= 0 )
if( i < 0 )
break; // No ammo.
ammo_id = sd->inventory_data[i]->nameid;
if( ammo_id <= 0 )

View File

@@ -60,7 +60,7 @@ static int atkmods[3][MAX_WEAPON_TYPE]; /// ATK weapon modification for size (si
static struct eri *sc_data_ers; /// For sc_data entries
static struct status_data dummy_status;
int current_equip_item_index; /// Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus]
short current_equip_item_index; /// Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus]
int current_equip_card_id; /// To prevent card-stacking (from jA) [Skotlex]
// We need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only to avoid cards exploits
@@ -2755,7 +2755,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
const struct status_change *sc = &sd->sc;
struct s_skill b_skill[MAX_SKILL]; ///< Previous skill tree
int b_weight, b_max_weight, b_cart_weight_max, ///< Previous weight
i, index, skill,refinedef=0;
i, skill,refinedef=0;
short index = -1;
if (++calculating > 10) // Too many recursive calls!
return -1;
@@ -5183,7 +5184,7 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
#ifndef RENEWAL
else {
TBL_PC *sd = (TBL_PC*)bl;
int index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
short index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
watk += sc->data[SC_NIBELUNGEN]->val2;
@@ -6499,7 +6500,7 @@ const char* status_get_name(struct block_list *bl)
}
/**
* Gets the class of the given bl
* Gets the class/sprite id of the given bl
* @param bl: Object whose class to get [PC|MOB|PET|HOM|MER|NPC|ELEM]
* @return class or 0 if any other bl->type than noted above
**/
@@ -7664,7 +7665,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
// Strip skills, need to divest something or it fails.
case SC_STRIPWEAPON:
if (sd && !(flag&4)) { // Apply sc anyway if loading saved sc_data
int i;
short i;
opt_flag = 0; // Reuse to check success condition.
if(sd->bonus.unstripable_equip&EQP_WEAPON)
return 0;
@@ -7687,7 +7688,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
if( val2 == 1 ) val2 = 0; // GX effect. Do not take shield off..
else
if (sd && !(flag&4)) {
int i;
short i;
if(sd->bonus.unstripable_equip&EQP_SHIELD)
return 0;
i = sd->equip_index[EQI_HAND_L];
@@ -7699,7 +7700,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
break;
case SC_STRIPARMOR:
if (sd && !(flag&4)) {
int i;
short i;
if(sd->bonus.unstripable_equip&EQP_ARMOR)
return 0;
i = sd->equip_index[EQI_ARMOR];
@@ -7711,7 +7712,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
break;
case SC_STRIPHELM:
if (sd && !(flag&4)) {
int i;
short i;
if(sd->bonus.unstripable_equip&EQP_HELM)
return 0;
i = sd->equip_index[EQI_HEAD_TOP];
@@ -7783,7 +7784,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
break;
case SC__STRIPACCESSORY:
if( sd ) {
int i = -1;
short i = -1;
if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) {
i = sd->equip_index[EQI_ACC_L];
if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
@@ -9435,10 +9436,13 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
tick_time = 10000; // [GodLesZ] tick time
break;
case SC_EXEEDBREAK:
val1 *= 100; // 100 * skill_lv
if( sd && sd->inventory_data[sd->equip_index[EQI_HAND_R]] ) {
val1 += (sd->inventory_data[sd->equip_index[EQI_HAND_R]]->weight/10 * sd->inventory_data[sd->equip_index[EQI_HAND_R]]->wlv * status_get_lv(bl) / 100);
val1 += 10 * sd->status.job_level;
{
short idx = -1;
val1 *= 100; // 100 * skill_lv
if( sd && (idx = sd->equip_index[EQI_HAND_R]) >= 0 && sd->inventory_data[idx] ) {
val1 += (sd->inventory_data[idx]->weight/10 * sd->inventory_data[idx]->wlv * status_get_lv(bl) / 100);
val1 += 10 * sd->status.job_level;
}
}
break;
case SC_PRESTIGE:
@@ -9919,7 +9923,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
case SC_STONE:
case SC_DEEPSLEEP:
if (sd && pc_issit(sd)) // Avoid sprite sync problems.
pc_setstand(sd);
pc_setstand(sd, true);
case SC_TRICKDEAD:
status_change_end(bl, SC_DANCING, INVALID_TIMER);
// Cancel cast when get status [LuzZza]
@@ -10803,8 +10807,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc_start(bl, bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
break;
case SC_SITDOWN_FORCE:
if( sd && pc_issit(sd) ) {
pc_setstand(sd);
if( sd && pc_issit(sd) && pc_setstand(sd, false) ) {
clif_standing(bl);
}
break;
@@ -10863,8 +10866,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
status_change_end(bl,SC_TEARGAS_SOB,INVALID_TIMER);
break;
case SC_BANANA_BOMB_SITDOWN:
if( sd && pc_issit(sd) ) {
pc_setstand(sd);
if( sd && pc_issit(sd) && pc_setstand(sd, false) ) {
skill_sit(sd,0);
clif_standing(bl);
}

View File

@@ -1535,7 +1535,7 @@ enum e_joint_break
BREAK_FLAGS = BREAK_ANKLE | BREAK_WRIST | BREAK_KNEE | BREAK_SHOULDER | BREAK_WAIST | BREAK_NECK,
};
extern int current_equip_item_index;
extern short current_equip_item_index;
extern int current_equip_card_id;
//Mode definitions to clear up code reading. [Skotlex]
@@ -1556,9 +1556,9 @@ enum e_mode {
MD_CHANGETARGET_CHASE = 0x002000,
MD_TARGETWEAK = 0x004000,
MD_RANDOMTARGET = 0x008000,
MD_IGNOREMELEE = 0x010000,
MD_IGNOREMELEE = 0x010000, //! TODO: Unused yet
MD_IGNOREMAGIC = 0x020000,
MD_IGNORERANGED = 0x040000,
MD_IGNORERANGED = 0x040000, //! TODO: Unused yet
MD_MVP = 0x080000,
MD_IGNOREMISC = 0x100000,
MD_KNOCKBACK_IMMUNE = 0x200000,

View File

@@ -2413,7 +2413,6 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
chat_leavechat(sd,0);
if(sd->trade_partner)
trade_tradecancel(sd);
buyingstore_close(sd);
searchstore_close(sd);
if (sd->menuskill_id != AL_TELEPORT) { //bugreport:8027
if (sd->state.storage_flag == 1)
@@ -2451,8 +2450,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
if(sd->duel_group > 0)
duel_leave(sd->duel_group, sd);
if(pc_issit(sd)) {
pc_setstand(sd);
if(pc_issit(sd) && pc_setstand(sd, false)) {
skill_sit(sd,0);
}
party_send_dot_remove(sd);// minimap dot fix [Kevin]

View File

@@ -85,6 +85,7 @@ void vending_closevending(struct map_session_data* sd)
}
sd->state.vending = false;
sd->vender_id = 0;
clif_closevendingboard(&sd->bl, 0);
idb_remove(vending_db, sd->status.char_id);
}
@@ -483,8 +484,10 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
* @param sd Player as autotrader
*/
void vending_reopen( struct map_session_data* sd ){
nullpo_retv(sd);
// Ready to open vending for this char
if ( sd && autotrader_count > 0 && autotraders){
if ( autotrader_count > 0 && autotraders){
uint16 i;
uint8 *data, *p, fail = 0;
uint16 j, count;
@@ -538,8 +541,11 @@ void vending_reopen( struct map_session_data* sd ){
// Make vendor look perfect
pc_setdir(sd, autotraders[i]->dir, autotraders[i]->head_dir);
clif_changed_dir(&sd->bl, AREA_WOS);
if( autotraders[i]->sit )
if( autotraders[i]->sit ) {
pc_setsit(sd);
skill_sit(sd, 1);
clif_sitting(&sd->bl);
}
// Immediate save
chrif_save(sd, 3);
@@ -671,7 +677,7 @@ void do_init_vending_autotrade( void ) {
Sql_FreeResult(mmysql_handle);
}
ShowStatus("Done loading '"CL_WHITE"%d"CL_RESET"' autotraders with '"CL_WHITE"%d"CL_RESET"' items.\n", autotrader_count, items);
ShowStatus("Done loading '"CL_WHITE"%d"CL_RESET"' vending autotraders with '"CL_WHITE"%d"CL_RESET"' items.\n", autotrader_count, items);
}
}