Quellcode durchsuchen

- Modified map_searchrandfreecell to always do a check on a 9x9 area around the target tile, and to return the x,y coordinates modified with the new target.
- Modified map_addflooritem so that the type is &1 for mvp drops and &2 for stacking checks, when &2 the item to drop cannot stack on the floor, otherwise it has no stacking limit.


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

skotlex vor 19 Jahren
Ursprung
Commit
2f074dc2d4
4 geänderte Dateien mit 28 neuen und 55 gelöschten Zeilen
  1. 3 0
      Changelog-Trunk.txt
  2. 24 53
      src/map/map.c
  3. 0 1
      src/map/map.h
  4. 1 1
      src/map/pc.c

+ 3 - 0
Changelog-Trunk.txt

@@ -5,6 +5,9 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.  EV
 GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
 
 2006/02/10
+	* Modified the drop item routines to perform stacking checks only for
+	  player attempted item drops, therefore, mob drops will stack up to
+	  infinity. [Skotlex]
 	* NPC_POWERUP now gives +20% attack per skill level. [Skotlex]
 2006/02/09
 	* Fixed "set baselevel, X" sending one to a different level than the one

+ 24 - 53
src/map/map.c

@@ -1314,83 +1314,54 @@ int map_clearflooritem_timer(int tid,unsigned int tick,int id,int data) {
 }
 
 /*==========================================
- * (m,x,y)の周?rangeマス?の空き(=侵入可能)cellの
- * ?から適?なマス目の座標をx+(y<<16)で返す
- *
- * 現?range=1でアイテムドロップ用途のみ
+ * (m,x,y) locates a random available free cell around the given coordinates
+ * to place an BL_ITEM object. Scan area is 9x9, returns 1 on success.
+ * x and y are modified with the target cell when successful.
  *------------------------------------------
  */
-int map_searchrandfreecell(int m,int x,int y,int range) {
+int map_searchrandfreecell(int m,int *x,int *y,int stack) {
 	int free_cell,i,j;
-	int* free_cells;
+	int free_cells[9][2];
 
-	if (range < 0)
-		return -1;
-	
-	//FIXME: Would it be quicker to hardcode an array of 9 since this function is always called with range 1?
-	free_cells = aCalloc((2*range+1)*(2*range+1), sizeof(int)); //better use more memory than having to wipe twice the cells. [Skotlex]
-	
-	for(free_cell=0,i=-range;i<=range;i++){
+	for(free_cell=0,i=-1;i<=1;i++){
 		if(i+y<0 || i+y>=map[m].ys)
 			continue;
-		for(j=-range;j<=range;j++){
+		for(j=-1;j<=1;j++){
 			if(j+x<0 || j+x>=map[m].xs)
 				continue;
 			if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS))
 				continue;
-			if(map_count_oncell(m,j+x,i+y, BL_ITEM) > 1) //Avoid item stacking to prevent against exploits. [Skotlex]
+			//Avoid item stacking to prevent against exploits. [Skotlex]
+			if(stack && map_count_oncell(m,j+x,i+y, BL_ITEM) > stack)
 				continue;
-			free_cells[free_cell++] = j+x+((i+y)<<16);
+			free_cells[free_cell][0] = j+x;
+			free_cells[free_cell++][1] = i+y;
 		}
 	}
 	if(free_cell==0)
-	{
-		aFree(free_cells);
-		return -1;
-	}
-	free_cell=free_cells[rand()%free_cell];
-	aFree(free_cells);
-	return free_cell;
-/*
-	for(i=-range;i<=range;i++){
-		if(i+y<0 || i+y>=map[m].ys)
-			continue;
-		for(j=-range;j<=range;j++){
-			if(j+x<0 || j+x>=map[m].xs)
-				continue;
-			if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS))
-				continue;
-			if(map_count_oncell(m,j+x,i+y, BL_ITEM) > 1) //Avoid item stacking to prevent against exploits. [Skotlex]
-				continue;
-			if(free_cell==0){
-				x+=j;
-				y+=i;
-				i=range+1;
-				break;
-			}
-			free_cell--;
-		}
-	}
-
-	return x+(y<<16);
-*/
+		return 0;
+	free_cell = rand()%free_cell;
+	*x = free_cells[free_cell][0];
+	*y = free_cells[free_cell][1];
+	return 1;
 }
 
 /*==========================================
  * (m,x,y)を中心に3x3以?に床アイテム設置
  *
  * item_dataはamount以外をcopyする
+ * type flag: &1 MVP item. &2 do stacking check.
  *------------------------------------------
  */
 int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,struct map_session_data *first_sd,
     struct map_session_data *second_sd,struct map_session_data *third_sd,int type) {
-	int xy,r;
+	int r;
 	unsigned int tick;
 	struct flooritem_data *fitem=NULL;
 
 	nullpo_retr(0, item_data);
 
-	if((xy=map_searchrandfreecell(m,x,y,1))<0)
+	if(!map_searchrandfreecell(m,&x,&y,type&2?1:0))
 		return 0;
 	r=rand();
 
@@ -1398,8 +1369,8 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,struct
 	fitem->bl.type=BL_ITEM;
 	fitem->bl.prev = fitem->bl.next = NULL;
 	fitem->bl.m=m;
-	fitem->bl.x=xy&0xffff;
-	fitem->bl.y=(xy>>16)&0xffff;
+	fitem->bl.x=x;
+	fitem->bl.y=y;
 	fitem->bl.id = map_addobject(&fitem->bl);
 	if(fitem->bl.id==0){
 		aFree(fitem);
@@ -1409,21 +1380,21 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,struct
 	tick = gettick();
 	if(first_sd) {
 		fitem->first_get_id = first_sd->bl.id;
-		if(type)
+		if(type&1)
 			fitem->first_get_tick = tick + battle_config.mvp_item_first_get_time;
 		else
 			fitem->first_get_tick = tick + battle_config.item_first_get_time;
 	}
 	if(second_sd) {
 		fitem->second_get_id = second_sd->bl.id;
-		if(type)
+		if(type&1)
 			fitem->second_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time;
 		else
 			fitem->second_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time;
 	}
 	if(third_sd) {
 		fitem->third_get_id = third_sd->bl.id;
-		if(type)
+		if(type&1)
 			fitem->third_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time + battle_config.mvp_item_third_get_time;
 		else
 			fitem->third_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time + battle_config.item_third_get_time;

+ 0 - 1
src/map/map.h

@@ -1250,7 +1250,6 @@ int map_clearflooritem_timer(int,unsigned int,int,int);
 int map_removemobs_timer(int,unsigned int,int,int);
 #define map_clearflooritem(id) map_clearflooritem_timer(0,0,id,1)
 int map_addflooritem(struct item *,int,int,int,int,struct map_session_data *,struct map_session_data *,struct map_session_data *,int);
-int map_searchrandfreecell(int,int,int,int);
 
 // キャラid=>キャラ名 変換関連
 void map_addchariddb(int charid,char *name);

+ 1 - 1
src/map/pc.c

@@ -2593,7 +2593,7 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount)
 		log_pick(sd, "P", 0, sd->status.inventory[n].nameid, -amount, (struct item*)&sd->status.inventory[n]);
 	//Logs
 
-	if (map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, NULL, NULL, NULL, 0) != 0)
+	if (map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, NULL, NULL, NULL, 2) != 0)
 		pc_delitem(sd, n, amount, 0);
 	else
 		clif_delitem(sd,n,0);