* Follow up to: 99098c1

-- 'bonus_script' is now by default will be store on 'bonus_script' table. CAUTION: Please import 'upgrade_20131111.sql' file or execute the query inside to make `bonus_script` table.
-- Updated bonus_script documentation following flag &8 (BONUS_FLAG_REM_ON_LOGOUT) behavior. By default, bonus_script will be stored when player logs out and will be continued when player logs in.

* And small changes.
This commit is contained in:
Cahyadi Ramadhan Togihon
2013-11-11 19:59:35 +07:00
parent 4d61cc0e14
commit 9e8e3cfacc
15 changed files with 282 additions and 46 deletions

View File

@@ -104,6 +104,7 @@ mercenary_owner_db: mercenary_owner
elemental_db: elemental
ragsrvinfo_db: ragsrvinfo
skillcooldown_db: skillcooldown
bonus_script_db: bonus_script
// Map Database Tables
item_db_db: item_db

View File

@@ -5063,24 +5063,25 @@ autobonus and autobonus3).
This command will attach a script to a player for a given duration, in seconds.
After that time, the script will automatically expire. The same bonus cannot be
stacked.
stacked. By default, this bonus will be stored on `bonus_script` table when player
logs out.
Note that the maximum number of 'bonus_script' commands that can run simultaneously
for a player is 10 (MAX_PC_BONUS_SCRIPT in 'src/map/pc.h').
Flags:
&1: Remove when dead.
&2: Removable by Dispell.
&4: Removable by Clearance.
&8: Save script when player logs out and resume next login. [TODO]
&1: Remove when dead.
&2: Removable by Dispell.
&4: Removable by Clearance.
&8: Remove when player logs out.
Types:
0: Buff
1: Debuff
0: Buff
1: Debuff
Example:
// Apple gives you +5 Str bonus for 1 minute when it's consumed.
512,Apple,Apple,0,15,,20,,,,,0xFFFFFFFF,63,2,,,,,,{ bonus_script "{ bonus bStr,5; }",60; },{},{}
// Apple gives you +5 Str bonus for 1 minute when it's consumed.
512,Apple,Apple,0,15,,20,,,,,0xFFFFFFFF,63,2,,,,,,{ bonus_script "{ bonus bStr,5; }",60; },{},{}
---------------------------------------

View File

@@ -696,3 +696,15 @@ CREATE TABLE IF NOT EXISTS `interreg` (
) ENGINE=InnoDB;
INSERT INTO `interreg` (`varname`, `value`) VALUES
('unique_id', '0');
--
-- Table structure for table `bonus_script`
--
CREATE TABLE IF NOT EXISTS `bonus_script` (
`char_id` int(11) NOT NULL,
`script` varchar(1024) NOT NULL,
`tick` int(11) NOT NULL,
`flag` tinyint(3) unsigned NOT NULL DEFAULT '0',
`type` tinyint(1) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@@ -0,0 +1,11 @@
--
-- Table structure for table `bonus_script`
--
CREATE TABLE IF NOT EXISTS `bonus_script` (
`char_id` int(11) NOT NULL,
`script` varchar(1024) NOT NULL,
`tick` int(11) NOT NULL,
`flag` tinyint(3) unsigned NOT NULL DEFAULT '0',
`type` tinyint(1) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@@ -69,6 +69,7 @@ char mercenary_db[256] = "mercenary";
char mercenary_owner_db[256] = "mercenary_owner";
char elemental_db[256] = "elemental";
char ragsrvinfo_db[256] = "ragsrvinfo";
char bonus_script_db[256] = "bonus_script";
// show loading/saving messages
int save_log = 1;
@@ -206,6 +207,10 @@ struct fame_list smith_fame_list[MAX_FAME_LIST];
struct fame_list chemist_fame_list[MAX_FAME_LIST];
struct fame_list taekwon_fame_list[MAX_FAME_LIST];
//Bonus Script
void bonus_script_get(int fd);///Get bonus_script data
void bonus_script_save(int fd); ///Save bonus_script data
// check for exit signal
// 0 is saving complete
// other is char_id
@@ -1807,6 +1812,10 @@ int delete_char_sql(int char_id)
Sql_ShowDebug(sql_handle);
#endif
/* bonus_scripts */
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", bonus_script_db, char_id) )
Sql_ShowDebug(sql_handle);
if (log_char) {
if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`char_msg`,`name`) VALUES (NOW(), '%d', '%d', 'Deleted char (CID %d)', '%s')",
charlog_db, account_id, 0, char_id, esc_name) )
@@ -3671,7 +3680,19 @@ int parse_frommap(int fd)
break;
case 0x2b28: mapif_parse_UpdBankInfo(fd); break;
case 0x2b2a: mapif_parse_ReqBankInfo(fd); break;
case 0x2b2a: mapif_parse_ReqBankInfo(fd); break;
case 0x2b2d: //Load data
if (RFIFOREST(fd) < 6)
return 0;
bonus_script_get(fd);
break;
case 0x2b2e: //Save data
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
bonus_script_save(fd);
break;
default:
{
@@ -4975,6 +4996,83 @@ void moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short ind
WFIFOSET(fd,8);
}
/** [Cydh]
* Get bonus_script data(s) from table to load
* @param fd
*/
void bonus_script_get(int fd) {
int cid;
cid = RFIFOL(fd,2);
if (SQL_ERROR == Sql_Query(sql_handle,"SELECT `script`, `tick`, `flag`, `type` FROM `%s` WHERE `char_id`='%d'",
bonus_script_db,cid))
{
Sql_ShowDebug(sql_handle);
return;
}
if (Sql_NumRows(sql_handle) > 0) {
struct bonus_script_data bsdata;
int count;
char *data;
WFIFOHEAD(fd,10+50*sizeof(struct bonus_script_data));
WFIFOW(fd,0) = 0x2b2f;
WFIFOL(fd,4) = cid;
for (count = 0; count < 20 && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count) {
Sql_GetData(sql_handle,0,&data,NULL); memcpy(bsdata.script,data,strlen(data)+1);
Sql_GetData(sql_handle,1,&data,NULL); bsdata.tick = atoi(data);
Sql_GetData(sql_handle,2,&data,NULL); bsdata.flag = atoi(data);
Sql_GetData(sql_handle,3,&data,NULL); bsdata.type = atoi(data);
memcpy(WFIFOP(fd,10+count*sizeof(struct bonus_script_data)),&bsdata,sizeof(struct bonus_script_data));
}
if (count >= 50)
ShowWarning("Too many bonus_script for %d, some of them were not loaded.\n",cid);
if (count > 0) {
WFIFOW(fd,2) = 10 + count*sizeof(struct bonus_script_data);
WFIFOW(fd,8) = count;
WFIFOSET(fd,WFIFOW(fd,2));
//Clear the data once loaded.
if (SQL_ERROR == Sql_Query(sql_handle,"DELETE FROM `%s` WHERE `char_id`='%d'",bonus_script_db,cid))
Sql_ShowDebug(sql_handle);
}
}
Sql_FreeResult(sql_handle);
RFIFOSKIP(fd,6);
}
/** [Cydh]
* Svae bonus_script data(s) to the table
* @param fd
*/
void bonus_script_save(int fd) {
int count, cid;
cid = RFIFOL(fd,4);
count = RFIFOW(fd,8);
if (count > 0) {
struct bonus_script_data bs;
StringBuf buf;
int i;
char esc_script[MAX_BONUS_SCRIPT_LENGTH] = "";
StringBuf_Init(&buf);
StringBuf_Printf(&buf,"INSERT INTO `%s` (`char_id`, `script`, `tick`, `flag`, `type`) VALUES ",bonus_script_db);
for (i = 0; i < count; ++i) {
memcpy(&bs,RFIFOP(fd,10+i*sizeof(struct bonus_script_data)),sizeof(struct bonus_script_data));
Sql_EscapeString(sql_handle,esc_script,bs.script);
if (i > 0)
StringBuf_AppendStr(&buf,", ");
StringBuf_Printf(&buf,"(%d,'%s',%d,%d,%d)",cid,esc_script,bs.tick,bs.flag,bs.type);
}
if (SQL_ERROR == Sql_QueryStr(sql_handle,StringBuf_Value(&buf)))
Sql_ShowDebug(sql_handle);
StringBuf_Destroy(&buf);
}
RFIFOSKIP(fd,RFIFOW(fd,2));
}
//------------------------------------------------
//Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't
//replies/disconnect the player we tried to kick. [Skotlex]
@@ -5143,6 +5241,10 @@ void sql_config_read(const char* cfgName)
safestrncpy(mercenary_owner_db,w2,sizeof(mercenary_owner_db));
else if(!strcmpi(w1,"elemental_db"))
safestrncpy(elemental_db,w2,sizeof(elemental_db));
else if(!strcmpi(w1,"skillcooldown_db"))
safestrncpy(skillcooldown_db, w2, sizeof(skillcooldown_db));
else if(!strcmpi(w1,"bonus_script_db"))
safestrncpy(bonus_script_db, w2, sizeof(bonus_script_db));
//support the import command, just like any other config
else if(!strcmpi(w1,"import"))
sql_config_read(w2);

View File

@@ -83,6 +83,8 @@ extern char mercenary_db[256];
extern char mercenary_owner_db[256];
extern char elemental_db[256];
extern char ragsrvinfo_db[256];
extern char bonus_script_db[256];
extern char skillcooldown_db[256];
extern int db_use_sqldbs; // added for sql item_db read for char server [Valaris]

View File

@@ -249,6 +249,13 @@ struct status_change_data {
long val1, val2, val3, val4, tick; //Remaining duration.
};
#define MAX_BONUS_SCRIPT_LENGTH 1024
struct bonus_script_data {
char script[MAX_BONUS_SCRIPT_LENGTH];
long tick;
short type, flag;
};
struct skill_cooldown_data {
unsigned short skill_id;
long tick;

View File

@@ -46,7 +46,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
11,10,10, 0,11, -1,266,10, // 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, U->2b15, U->2b16, U->2b17
2,10, 2,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
-1,10, 8, 2, 2,14,19,19, // 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, U->2b24, U->2b25, U->2b26, U->2b27
10,10, 6, 0, 0, 0, 0, 0, // 2b28-2b2f: U->2b28, U->2b29, U->2b2a, F->2b2b, F->2b2c, F->2b2d, F->2b2e, F->2b2f
10,10, 6, 0, 0, 6, -1, -1, // 2b28-2b2f: U->2b28, U->2b29, U->2b2a, F->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
};
//Used Packets:
@@ -101,6 +101,11 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b28: Outgoing, chrif_save_bankdata -> 'send bank data to be saved'
//2b29: Incoming, chrif_load_bankdata -> 'received bank data for playeer to be loaded'
//2b2a: Outgoing, chrif_bankdata_request -> 'request bank data for charid'
//2b2b: FREE
//2b2c: FREE
//2b2d: Outgoing, chrif_bsdata_request -> request bonus_script for pc_authok'ed char.
//2b2e: Outgoing, chrif_save_bsdata -> Send bonus_script of player for saving.
//2b2f: Incoming, chrif_load_bsdata -> received bonus_script of player for loading.
int chrif_connected = 0;
int char_fd = -1;
@@ -284,6 +289,7 @@ int chrif_save(struct map_session_data *sd, int flag) {
chrif_save_scdata(sd);
chrif_skillcooldown_save(sd);
chrif_save_bankdata(sd);
chrif_save_bsdata(sd);
}
if ( !chrif_auth_logout(sd,flag == 1 ? ST_LOGOUT : ST_MAPCHANGE) )
ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id);
@@ -1568,7 +1574,7 @@ int chrif_parse(int fd) {
case 0x2b04: chrif_recvmap(fd); break;
case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
case 0x2b0b: chrif_skillcooldown_load(fd); break;
case 0x2b0b: chrif_skillcooldown_load(fd); break;
case 0x2b0d: chrif_changedsex(fd); break;
case 0x2b0f: chrif_char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
case 0x2b12: chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break;
@@ -1584,6 +1590,7 @@ int chrif_parse(int fd) {
case 0x2b25: chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
case 0x2b27: chrif_authfail(fd); break;
case 0x2b29: chrif_load_bankdata(fd); break;
case 0x2b2f: chrif_load_bsdata(fd); break;
default:
ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
set_eof(fd);
@@ -1705,6 +1712,110 @@ int chrif_send_report(char* buf, int len) {
return 0;
}
/** [Cydh]
* Requets bonus_script datas
* @param char_id
*/
int chrif_bsdata_request(int char_id) {
chrif_check(-1);
WFIFOHEAD(char_fd,6);
WFIFOW(char_fd,0) = 0x2b2d;
WFIFOL(char_fd,2) = char_id;
WFIFOSET(char_fd,6);
return 0;
}
/** [Cydh]
* Stores bonus_script data(s) to the table
* @param sd
*/
int chrif_save_bsdata(struct map_session_data *sd) {
int i, count=0;
unsigned int tick;
struct bonus_script_data bs;
const struct TimerData *timer;
chrif_check(-1);
tick = gettick();
WFIFOHEAD(char_fd,10+MAX_PC_BONUS_SCRIPT*sizeof(struct bonus_script_data));
WFIFOW(char_fd,0) = 0x2b2e;
WFIFOL(char_fd,4) = sd->status.char_id;
//Clear un-saved data
pc_bonus_script_check(sd,BONUS_FLAG_REM_ON_LOGOUT);
for (i = 0; i < MAX_PC_BONUS_SCRIPT; i++) {
if (!(&sd->bonus_script[i]) || !sd->bonus_script[i].script || strlen(sd->bonus_script[i].script_str) == 0)
continue;
timer = get_timer(sd->bonus_script[i].tid);
if (timer == NULL || DIFF_TICK(timer->tick,tick) < 0)
continue;
memcpy(bs.script,sd->bonus_script[i].script_str,strlen(sd->bonus_script[i].script_str)+1);
bs.tick = DIFF_TICK(timer->tick,tick);
bs.flag = sd->bonus_script[i].flag;
bs.type = (sd->bonus_script[i].isBuff) ? 1 : 0;
memcpy(WFIFOP(char_fd,10+count*sizeof(struct bonus_script_data)),&bs,sizeof(struct bonus_script_data));
delete_timer(sd->bonus_script[i].tid,pc_bonus_script_timer);
count++;
}
if (count == 0)
return 0;
WFIFOW(char_fd,8) = count;
WFIFOW(char_fd,2) = 10+count*sizeof(struct bonus_script_data);
WFIFOSET(char_fd,WFIFOW(char_fd,2));
return 0;
}
/** [Cydh]
* Loads bonus_script datas
* @param fd
*/
int chrif_load_bsdata(int fd) {
struct map_session_data *sd;
struct bonus_script_data *bs;
int cid, count;
uint8 i, count_ = 0;
cid = RFIFOL(fd,4);
sd = map_charid2sd(cid);
if (!sd) {
ShowError("chrif_load_bsdata: Player with CID %d not found!\n",cid);
return -1;
}
if (sd->status.char_id != cid) {
ShowError("chrif_load_bsdata: Receiving data for char id does not matches (%d != %d)!\n",sd->status.char_id,cid);
return -1;
}
count = RFIFOW(fd,8);
for (i = 0; i < count; i++) {
struct script_code *script;
bs = (struct bonus_script_data*)RFIFOP(fd,10 + i*sizeof(struct bonus_script_data));
if (!(script = parse_script(bs->script,"chrif_load_bsdata",1,1)))
continue;
memcpy(sd->bonus_script[i].script_str,bs->script,strlen(bs->script));
sd->bonus_script[i].script = script;
sd->bonus_script[i].tick = gettick() + bs->tick;
sd->bonus_script[i].flag = (uint8)bs->flag;
sd->bonus_script[i].isBuff = (bs->type) ? true : false;
count_++;
}
if (count_)
status_calc_pc(sd,false);
return 0;
}
/**
* @see DBApply
*/

View File

@@ -67,6 +67,10 @@ int chrif_divorce(int partner_id1, int partner_id2);
int chrif_removefriend(int char_id, int friend_id);
int chrif_send_report(char* buf, int len);
int chrif_bsdata_request(int char_id);
int chrif_save_bsdata(struct map_session_data *sd);
int chrif_load_bsdata(int fd);
int do_final_chrif(void);
int do_init_chrif(void);

View File

@@ -9877,7 +9877,6 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd)
{
set_eof(fd);
pc_damage_log_clear(sd,0);
pc_bonus_script_clear(sd);
clif_disconnect_ack(sd, 0);
} else {
clif_disconnect_ack(sd, 1);
@@ -10248,7 +10247,6 @@ void clif_parse_Restart(int fd, struct map_session_data *sd)
(!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
{ //Send to char-server for character selection.
pc_damage_log_clear(sd,0);
pc_bonus_script_clear(sd);
chrif_charselectreq(sd, session[fd]->client_addr);
} else {
clif_disconnect_ack(sd, 1);

View File

@@ -1284,6 +1284,7 @@ int pc_reg_received(struct map_session_data *sd)
chrif_scdata_request(sd->status.account_id, sd->status.char_id);
chrif_skillcooldown_request(sd->status.account_id, sd->status.char_id);
chrif_bankdata_request(sd->status.account_id, sd->status.char_id);
chrif_bsdata_request(sd->status.char_id);
intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
intif_request_questlog(sd);
@@ -6922,7 +6923,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
}
//Remove bonus_script when dead
pc_bonus_script_check(sd,BSF_REM_ON_DEAD);
pc_bonus_script_check(sd,BONUS_FLAG_REM_ON_DEAD);
// changed penalty options, added death by player if pk_mode [Valaris]
if(battle_config.death_penalty_type
@@ -10407,7 +10408,7 @@ int pc_bonus_script_timer(int tid, unsigned int tick, int id, intptr_t data) {
}
/** [Cydh]
* Remove bonus_script data from sd
* Remove bonus_script data from sd (not deleting timer)
* @param sd target
* @param i script index
**/
@@ -10416,7 +10417,7 @@ void pc_bonus_script_remove(struct map_session_data *sd, uint8 i) {
return;
memset(&sd->bonus_script[i].script,0,sizeof(sd->bonus_script[i].script));
sd->bonus_script[i].script_str = NULL;
memset(sd->bonus_script[i].script_str,'\0',sizeof(sd->bonus_script[i].script_str));
sd->bonus_script[i].tick = 0;
sd->bonus_script[i].tid = 0;
sd->bonus_script[i].flag = 0;
@@ -10427,7 +10428,7 @@ void pc_bonus_script_remove(struct map_session_data *sd, uint8 i) {
* @param sd target
* @param flag reason to remove the bonus_script
**/
void pc_bonus_script_check(struct map_session_data *sd, enum e_bonus_script_flag flag) {
void pc_bonus_script_check(struct map_session_data *sd, enum e_bonus_script_flags flag) {
uint8 i, count = 0;
if (!sd)
return;
@@ -10439,23 +10440,10 @@ void pc_bonus_script_check(struct map_session_data *sd, enum e_bonus_script_flag
count++;
}
}
if (count)
if (count && flag != BONUS_FLAG_REM_ON_LOGOUT) //Don't need do this if log out
status_calc_pc(sd,false);
}
/** [Cydh]
* Clear all active timer(s) of bonus_script data from sd
* @param sd target
**/
void pc_bonus_script_clear(struct map_session_data *sd) {
uint8 i;
if (!sd)
return;
for (i = 0; i < MAX_PC_BONUS_SCRIPT; i++)
if (&sd->bonus_script[i] && sd->bonus_script[i].tid)
delete_timer(sd->bonus_script[i].tid,pc_bonus_script_timer);
}
/*==========================================
* pc Init/Terminate
*------------------------------------------*/

View File

@@ -556,7 +556,7 @@ struct map_session_data {
//Timed bonus 'bonus_script' struct [Cydh]
struct s_script {
struct script_code *script;
const char *script_str; //Used for comparing and storing on table
char script_str[MAX_BONUS_SCRIPT_LENGTH]; //Used for comparing and storing on table
uint32 tick;
uint8 flag;
bool isBuff; //Can be used for deciding which bonus that buff or debuff
@@ -1037,8 +1037,7 @@ void pc_show_version(struct map_session_data *sd);
int pc_bonus_script_timer(int tid, unsigned int tick, int id, intptr_t data);
void pc_bonus_script_remove(struct map_session_data *sd, uint8 i);
void pc_bonus_script_check(struct map_session_data *sd, enum e_bonus_script_flag flag);
void pc_bonus_script_clear(struct map_session_data *sd);
void pc_bonus_script_check(struct map_session_data *sd, enum e_bonus_script_flags flag);
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_race, uint32 mob_mode, int type);

View File

@@ -18148,7 +18148,7 @@ BUILDIN_FUNC(bonus_script) {
}
//Add the script data
sd->bonus_script[i].script_str = script_str;
memcpy(sd->bonus_script[i].script_str,script_str,strlen(script_str)+1);
sd->bonus_script[i].script = script;
sd->bonus_script[i].tick = gettick() + dur;
sd->bonus_script[i].flag = flag;

View File

@@ -6837,7 +6837,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
//Remove bonus_script when dispelled
if (dstsd)
pc_bonus_script_check(dstsd,BSF_REM_ON_DISPELL);
pc_bonus_script_check(dstsd,BONUS_FLAG_REM_ON_DISPELL);
if(!tsc || !tsc->count)
break;
@@ -8339,7 +8339,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
//Remove bonus_script when cleared
if (dstsd)
pc_bonus_script_check(dstsd,BSF_REM_ON_CLEARANCE);
pc_bonus_script_check(dstsd,BONUS_FLAG_REM_ON_CLEARANCE);
if(!tsc || !tsc->count)
break;

View File

@@ -1671,17 +1671,17 @@ enum scb_flag
};
///Enum for bonus_script's flag
enum e_bonus_script_flag {
BSF_REM_ON_DEAD = 0x1,
BSF_REM_ON_DISPELL = 0x2,
BSF_REM_ON_CLEARANCE = 0x4,
//BSF_DB_SAVE = 0x8, //TODO!
enum e_bonus_script_flags {
BONUS_FLAG_REM_ON_DEAD = 0x1, //Remove bonus when dead
BONUS_FLAG_REM_ON_DISPELL = 0x2, //Removable by Dispell
BONUS_FLAG_REM_ON_CLEARANCE = 0x4, //Removable by Clearance
BONUS_FLAG_REM_ON_LOGOUT = 0x8, //Remove bonus when player logged out
};
///Enum for bonus_script's type
enum e_bonus_script_type {
BST_BUFF = 0,
BST_DEBUFF = 1,
enum e_bonus_script_types {
BONUS_TYPE_BUFF = 0,
BONUS_TYPE_DEBUFF = 1,
};
//Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex]