summaryrefslogtreecommitdiff
path: root/src/map/map.c
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-01-31 15:48:04 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-01-31 15:48:04 +0000
commit64b6e20b84aa3dca07228df923e73c0703b3d5af (patch)
tree013b60c9e17b9bf6819a0da06feda229adc78b3d /src/map/map.c
parent4dbc7922cdb25fcedc9ca39fc72ddca926e61efe (diff)
downloadhercules-64b6e20b84aa3dca07228df923e73c0703b3d5af.tar.gz
hercules-64b6e20b84aa3dca07228df923e73c0703b3d5af.tar.bz2
hercules-64b6e20b84aa3dca07228df923e73c0703b3d5af.tar.xz
hercules-64b6e20b84aa3dca07228df923e73c0703b3d5af.zip
objects[] array removal (bugreport:2559)
- Removed the 2 MB wide static array in favor of a general-purpose DBMap (id_db for now). - Inlined functions map_addobject, map_delobject and map_delobjectnofree into their callers' code. - Replaced the free id lookup algorithm from ancient jathena with something more efficient. - Moved the algorithm to map_get_new_object_id() (similar idea as r13481). git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13503 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/map.c')
-rw-r--r--src/map/map.c146
1 files changed, 26 insertions, 120 deletions
diff --git a/src/map/map.c b/src/map/map.c
index c732e2d55..372647088 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -102,8 +102,6 @@ static DBMap* charid_db=NULL; // int char_id -> struct map_session_data*
static DBMap* regen_db=NULL; // int id -> struct block_list* (status_natural_heal processing)
static int map_users=0;
-static struct block_list *objects[MAX_FLOORITEM];
-static int first_free_object_id=0,last_object_id=0;
#define block_free_max 1048576
struct block_list *block_free[block_free_max];
@@ -1129,124 +1127,38 @@ int map_foreachinmap(int (*func)(struct block_list*,va_list), int m, int type,..
return returnCount;
}
-/*==========================================
- * 床アイテムやエフェクト用の一三bj割り?て
- * object[]への保存とid_db登?まで
- *
- * bl->idもこの中で設定して問題無い?
- *------------------------------------------*/
-int map_addobject(struct block_list *bl)
+
+/// Generates a new flooritem object id from the interval [MIN_FLOORITEM, MAX_FLOORITEM).
+/// Used for floor items, skill units and chatroom objects.
+/// @return The new object id
+int map_get_new_object_id(void)
{
+ static int last_object_id = MIN_FLOORITEM - 1;
int i;
- if( bl == NULL ){
- ShowWarning("map_addobject nullpo?\n");
- return 0;
- }
- if(first_free_object_id<2 || first_free_object_id>=MAX_FLOORITEM)
- first_free_object_id=2;
- for(i=first_free_object_id;i<MAX_FLOORITEM && objects[i];i++);
- if(i>=MAX_FLOORITEM){
- ShowWarning("no free object id\n");
- return 0;
- }
- first_free_object_id=i;
- if(last_object_id<i)
- last_object_id=i;
- objects[i]=bl;
- idb_put(id_db,i,bl);
- return i;
-}
-/*==========================================
- * 一三bjectの解放
- * map_delobjectのfreeしないバ?ジョン
- *------------------------------------------*/
-int map_delobjectnofree(int id)
-{
- if( id < 0 || id >= MAX_FLOORITEM )
+ // find a free id
+ i = last_object_id + 1;
+ while( i != last_object_id )
{
- ShowError("map_delobjectnofree: invalid object id '%d'!\n", id);
- return 0;
- }
-
- if(objects[id]==NULL)
- return 0;
-
- map_delblock(objects[id]);
- idb_remove(id_db,id);
- objects[id]=NULL;
-
- if(first_free_object_id>id)
- first_free_object_id=id;
-
- while(last_object_id>2 && objects[last_object_id]==NULL)
- last_object_id--;
+ if( i == MAX_FLOORITEM )
+ i = MIN_FLOORITEM;
- return 0;
-}
-
-/*==========================================
- * 一三bjectの解放
- * block_listからの削除、id_dbからの削除
- * object dataのfree、object[]へのNULL代入
- *
- * addとの??性が無いのが?になる
- *------------------------------------------*/
-int map_delobject(int id)
-{
- struct block_list* bl;
+ if( idb_get(id_db, i) == NULL )
+ break;
- if( id < 0 || id >= MAX_FLOORITEM )
- {
- ShowError("map_delobject: invalid object id '%d'!\n", id);
- return 0;
+ ++i;
}
- if(objects[id]==NULL)
+ if( i == last_object_id )
+ {
+ ShowError("map_addobject: no free object id!\n");
return 0;
-
- bl = objects[id];
- map_delobjectnofree(id);
- map_freeblock(bl);
-
- return 0;
-}
-
-/*==========================================
- * 全一三bj相手にfuncを呼ぶ
- *
- *------------------------------------------*/
-void map_foreachobject(int (*func)(struct block_list*,va_list),int type,...)
-{
- int i;
- int blockcount=bl_list_count;
-
- for(i=2;i<=last_object_id;i++){
- if(objects[i]){
- if(!(objects[i]->type==type)) // Fixed [Lance]
- continue;
- if(bl_list_count>=BL_LIST_MAX) {
- ShowWarning("map_foreachobject: too many blocks !\n");
- break;
- }
- bl_list[bl_list_count++]=objects[i];
- }
}
- map_freeblock_lock();
-
- for(i=blockcount;i<bl_list_count;i++)
- if( bl_list[i]->prev || bl_list[i]->next )
- {
- va_list ap;
- va_start(ap, type);
- func(bl_list[i], ap);
- va_end(ap);
- }
-
- map_freeblock_unlock();
+ // update cursor
+ last_object_id = i;
- bl_list_count = blockcount;
+ return i;
}
/*==========================================
@@ -1259,9 +1171,7 @@ void map_foreachobject(int (*func)(struct block_list*,va_list),int type,...)
*------------------------------------------*/
int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr data)
{
- struct flooritem_data *fitem=NULL;
-
- fitem = (struct flooritem_data *)objects[id];
+ struct flooritem_data* fitem = idb_get(id_db, id);
if(fitem==NULL || fitem->bl.type!=BL_ITEM || (!data && fitem->cleartimer != tid)){
ShowError("map_clearflooritem_timer : error\n");
return 1;
@@ -1271,7 +1181,8 @@ int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr data)
else if(fitem->item_data.card[0] == CARD0_PET)
intif_delete_petdata( MakeDWord(fitem->item_data.card[1],fitem->item_data.card[2]) );
clif_clearflooritem(fitem,0);
- map_delobject(fitem->bl.id);
+ map_delblock(&fitem->bl);
+ map_freeblock(&fitem->bl);
return 0;
}
@@ -1414,7 +1325,7 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int fir
fitem->bl.m=m;
fitem->bl.x=x;
fitem->bl.y=y;
- fitem->bl.id = map_addobject(&fitem->bl);
+ fitem->bl.id = map_get_new_object_id();
if(fitem->bl.id==0){
aFree(fitem);
return 0;
@@ -1433,6 +1344,7 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int fir
fitem->suby=((r>>2)&3)*3+3;
fitem->cleartimer=add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0);
+ map_addiddb(&fitem->bl);
map_addblock(&fitem->bl);
clif_dropflooritem(fitem);
@@ -1765,13 +1677,7 @@ struct map_session_data * map_nick2sd(const char *nick)
*------------------------------------------*/
struct block_list * map_id2bl(int id)
{
- struct block_list *bl;
- if(id >= 0 && id < ARRAYLENGTH(objects))
- bl = objects[id];
- else
- bl = (struct block_list*)idb_get(id_db,id);
-
- return bl;
+ return (struct block_list*)idb_get(id_db,id);
}
/*==========================================