- 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
This commit is contained in:
skotlex 2006-02-10 14:21:52 +00:00
parent 6a96ab5afc
commit 2f074dc2d4
4 changed files with 28 additions and 55 deletions

View File

@ -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 GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
2006/02/10 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] * NPC_POWERUP now gives +20% attack per skill level. [Skotlex]
2006/02/09 2006/02/09
* Fixed "set baselevel, X" sending one to a different level than the one * Fixed "set baselevel, X" sending one to a different level than the one

View File

@ -1314,83 +1314,54 @@ int map_clearflooritem_timer(int tid,unsigned int tick,int id,int data) {
} }
/*========================================== /*==========================================
* (m,x,y)?rangeマス?(=)cellの * (m,x,y) locates a random available free cell around the given coordinates
* ??x+(y<<16) * 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.
* ?range=1
*------------------------------------------ *------------------------------------------
*/ */
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_cell,i,j;
int* free_cells; int free_cells[9][2];
if (range < 0) for(free_cell=0,i=-1;i<=1;i++){
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++){
if(i+y<0 || i+y>=map[m].ys) if(i+y<0 || i+y>=map[m].ys)
continue; continue;
for(j=-range;j<=range;j++){ for(j=-1;j<=1;j++){
if(j+x<0 || j+x>=map[m].xs) if(j+x<0 || j+x>=map[m].xs)
continue; continue;
if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS)) if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS))
continue; 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; 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) if(free_cell==0)
{ return 0;
aFree(free_cells); free_cell = rand()%free_cell;
return -1; *x = free_cells[free_cell][0];
} *y = free_cells[free_cell][1];
free_cell=free_cells[rand()%free_cell]; return 1;
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);
*/
} }
/*========================================== /*==========================================
* (m,x,y)3x3以? * (m,x,y)3x3以?
* *
* item_dataはamount以外をcopyする * 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, 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) { struct map_session_data *second_sd,struct map_session_data *third_sd,int type) {
int xy,r; int r;
unsigned int tick; unsigned int tick;
struct flooritem_data *fitem=NULL; struct flooritem_data *fitem=NULL;
nullpo_retr(0, item_data); 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; return 0;
r=rand(); 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.type=BL_ITEM;
fitem->bl.prev = fitem->bl.next = NULL; fitem->bl.prev = fitem->bl.next = NULL;
fitem->bl.m=m; fitem->bl.m=m;
fitem->bl.x=xy&0xffff; fitem->bl.x=x;
fitem->bl.y=(xy>>16)&0xffff; fitem->bl.y=y;
fitem->bl.id = map_addobject(&fitem->bl); fitem->bl.id = map_addobject(&fitem->bl);
if(fitem->bl.id==0){ if(fitem->bl.id==0){
aFree(fitem); aFree(fitem);
@ -1409,21 +1380,21 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,struct
tick = gettick(); tick = gettick();
if(first_sd) { if(first_sd) {
fitem->first_get_id = first_sd->bl.id; 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; fitem->first_get_tick = tick + battle_config.mvp_item_first_get_time;
else else
fitem->first_get_tick = tick + battle_config.item_first_get_time; fitem->first_get_tick = tick + battle_config.item_first_get_time;
} }
if(second_sd) { if(second_sd) {
fitem->second_get_id = second_sd->bl.id; 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; fitem->second_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time;
else else
fitem->second_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time; fitem->second_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time;
} }
if(third_sd) { if(third_sd) {
fitem->third_get_id = third_sd->bl.id; 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; 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 else
fitem->third_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time + battle_config.item_third_get_time; fitem->third_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time + battle_config.item_third_get_time;

View File

@ -1250,7 +1250,6 @@ int map_clearflooritem_timer(int,unsigned int,int,int);
int map_removemobs_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) #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_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キャラ名 変換関連 // キャラidキャラ名 変換関連
void map_addchariddb(int charid,char *name); void map_addchariddb(int charid,char *name);

View File

@ -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]); log_pick(sd, "P", 0, sd->status.inventory[n].nameid, -amount, (struct item*)&sd->status.inventory[n]);
//Logs //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); pc_delitem(sd, n, amount, 0);
else else
clif_delitem(sd,n,0); clif_delitem(sd,n,0);