Browse Source

* Added script_setarray_pc for setting temporary character array variables outside of script.c without requiring them to use script-interal code (add_str and reference_uid).
- Applied script_setarray_pc to assignment of dynamic shop arrays (related r5841).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14613 54d463be-8e91-2dee-dedb-b68131a5f0ec

ai4rei 14 years ago
parent
commit
b86d48e71a
4 changed files with 56 additions and 9 deletions
  1. 2 0
      Changelog-Trunk.txt
  2. 17 9
      src/map/npc.c
  3. 36 0
      src/map/script.c
  4. 1 0
      src/map/script.h

+ 2 - 0
Changelog-Trunk.txt

@@ -1,6 +1,8 @@
 Date	Added
 
 2010/12/21
+	* Added script_setarray_pc for setting temporary character array variables outside of script.c without requiring them to use script-interal code (add_str and reference_uid). [Ai4rei]
+	- Applied script_setarray_pc to assignment of dynamic shop arrays (related r5841).
 	* Replaced in-place generation of uid of script array elements with reference_uid macro (follow up to r10813). [Ai4rei]
 	* Fixed dynamic shop arrays @bought_nameid, @bought_quantity, @sold_nameid and @sold_quantity not getting reset to zero before use, thus providing attached script with wrong/old data, if it did not clear them by itself in previous call (bugreport:1574, since r5841). [Ai4rei]
 	* Removed 'strsignal' forward-declaration from 'sig' plugin to prevent random gcc distributions from failing to compile due to mismatched declaration already present in <string.h> (bugreport:4644, topic:262284, follow up to r14591). [Ai4rei]

+ 17 - 9
src/map/npc.c

@@ -1142,19 +1142,24 @@ static int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* i
 {
 	char npc_ev[NAME_LENGTH*2+3];
 	int i;
-	int regkey = add_str("@bought_nameid");
-	int regkey2 = add_str("@bought_quantity");
+	int key_nameid = 0;
+	int key_amount = 0;
 
 	// discard old contents
 	script_cleararray_pc(sd, "@bought_nameid", (void*)0);
 	script_cleararray_pc(sd, "@bought_quantity", (void*)0);
 
-	snprintf(npc_ev, ARRAYLENGTH(npc_ev), "%s::OnBuyItem", nd->exname);
-	for(i=0;i<n;i++){
-		pc_setreg(sd,regkey+(i<<24),(int)item_list[i*2+1]);
-		pc_setreg(sd,regkey2+(i<<24),(int)item_list[i*2]);
+	// save list of bought items
+	for( i = 0; i < n; i++ )
+	{
+		script_setarray_pc(sd, "@bought_nameid", i, (void*)item_list[i*2+1], &key_nameid);
+		script_setarray_pc(sd, "@bought_quantity", i, (void*)item_list[i*2], &key_amount);
 	}
+
+	// invoke event
+	snprintf(npc_ev, ARRAYLENGTH(npc_ev), "%s::OnBuyItem", nd->exname);
 	npc_event(sd, npc_ev, 0);
+
 	return 0;
 }
 /*==========================================
@@ -1367,6 +1372,8 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
 {
 	double z;
 	int i,skill;
+	int key_nameid = 0;
+	int key_amount = 0;
 	struct npc_data *nd;
 	
 	nullpo_retr(1, sd);
@@ -1409,9 +1416,10 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
 		if(log_config.enable_logs&0x20) //Logs items, Sold to NPC (S)hop [Lupus]
 			log_pick_pc(sd, "S", nameid, -qty, &sd->status.inventory[idx]);
 
-		if(nd) {
-			pc_setreg(sd,add_str("@sold_nameid")+(i<<24),(int)sd->status.inventory[idx].nameid);
-			pc_setreg(sd,add_str("@sold_quantity")+(i<<24),qty);
+		if( nd )
+		{
+			script_setarray_pc(sd, "@sold_nameid", i, (void*)sd->status.inventory[idx].nameid, &key_nameid);
+			script_setarray_pc(sd, "@sold_quantity", i, (void*)qty, &key_amount);
 		}
 		pc_delitem(sd,idx,qty,0,6);
 	}

+ 36 - 0
src/map/script.c

@@ -3579,6 +3579,42 @@ void script_cleararray_pc(struct map_session_data* sd, const char* varname, void
 }
 
 
+/// sets a temporary character array variable element idx to given value
+/// @param refcache Pointer to an int variable, which keeps a copy of the reference to varname and must be initialized to 0. Can be NULL if only one element is set.
+void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache)
+{
+	int key;
+
+	if( not_array_variable(varname[0]) || !not_server_variable(varname[0]) )
+	{
+		ShowError("script_setarray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id);
+		return;
+	}
+
+	if( idx >= SCRIPT_MAX_ARRAYSIZE )
+	{
+		ShowError("script_setarray_pc: Variable '%s' has invalid index '%d' (char_id=%d).\n", varname, (int)idx, sd->status.char_id);
+		return;
+	}
+
+	key = ( refcache && refcache[0] ) ? refcache[0] : add_str(varname);
+
+	if( is_string_variable(varname) )
+	{
+		pc_setregstr(sd, reference_uid(key, idx), (const char*)value);
+	}
+	else
+	{
+		pc_setreg(sd, reference_uid(key, idx), (int)value);
+	}
+
+	if( refcache )
+	{// save to avoid repeated add_str calls
+		refcache[0] = key;
+	}
+}
+
+
 /*==========================================
  * �I—¹
  *------------------------------------------*/

+ 1 - 0
src/map/script.h

@@ -168,6 +168,7 @@ struct DBMap* script_get_userfunc_db(void);
 void script_run_autobonus(const char *autobonus,int id, int pos);
 
 void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value);
+void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache);
 
 int script_config_read(char *cfgName);
 int do_init_script(void);