Browse Source

* 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.

Cahyadi Ramadhan Togihon 11 years ago
parent
commit
9e8e3cfacc

+ 1 - 0
conf/inter_athena.conf

@@ -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

+ 10 - 9
doc/script_commands.txt

@@ -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; },{},{}
 
 ---------------------------------------
 

+ 12 - 0
sql-files/main.sql

@@ -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;

+ 11 - 0
sql-files/upgrades/upgrade_20131111.sql

@@ -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;

+ 103 - 1
src/char/char.c

@@ -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);

+ 2 - 0
src/char/char.h

@@ -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]
 

+ 7 - 0
src/common/mmo.h

@@ -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;

+ 113 - 2
src/map/chrif.c

@@ -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
  */

+ 4 - 0
src/map/chrif.h

@@ -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);
 

+ 0 - 2
src/map/clif.c

@@ -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);

+ 6 - 18
src/map/pc.c

@@ -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
  *------------------------------------------*/

+ 2 - 3
src/map/pc.h

@@ -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);

+ 1 - 1
src/map/script.c

@@ -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;

+ 2 - 2
src/map/skill.c

@@ -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;

+ 8 - 8
src/map/status.h

@@ -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]