AW: [CF List] BIGworld

Michael Toennies michael.toennies at nord-com.net
Wed Oct 9 17:25:11 CDT 2002


As i like the tiled maps idea (i use it strong in daimonin),
i must tell you that the code for it is mostly broken in the source
and need alot of rework. In fact i had coded several days hard on it to
make it stable.

Moving on tiled maps is somewhat safe but nearly every other action will
kick
the server in the dust. Put monsters in tiled maps and try it out... It
looks ok
for the first moment, then the server will explode.

Even try fire arrows around corner from one map to another.

This is the reason (only one example function, used for tiled maps):

int wall(mapstruct *m, int x,int y) {
    if (out_of_map(m,x,y))
	return 1;
    return (GET_MAP_FLAGS(m,x,y) & P_NO_PASS);
}

Like this function from map.c are most other function broken (several dozen)
which
access maps.

out_of_map() will look for tiled map. this will return true when there is a
tiled
map attached: out_of_map(m,-1,-1). GET_MAP_FLAGS() and all other macros will
be out
of bound and access memory somewhere.

When you do a source search with out_of_map you will see alot and alot of
this unsafe
functions.

The second more bad point is ... that out_of_map() and get_map_from_coord()
are broken too!
The fixed version i tested ALOT in daimonin ( and the server runs fine with
it) looks like
this.

mapstruct *out_of_map(mapstruct *m, int *x, int *y)
{
    /* Simple case - coordinates are within this local
     * map.
     */
	if(!m)
		return NULL;

   if (*x>=0 && *x<MAP_WIDTH(m) && *y>=0 && *y < MAP_HEIGHT(m))
	return m;

    if (*x<0) {
	if (!m->tile_path[3]) goto y_test2;
	if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY)
	    load_and_link_tiled_map(m, 3);

	    *x += MAP_WIDTH(m->tile_map[3]);
        return (out_of_map(m->tile_map[3], x, y));
    }
    if (*x>=MAP_WIDTH(m)) {
	if (!m->tile_path[1]) goto y_test2;
	if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY)
	    load_and_link_tiled_map(m, 1);

	*x -= MAP_WIDTH(m);
    return (out_of_map(m->tile_map[1], x, y));
    }
y_test2:
    if (*y<0) {
	if (!m->tile_path[0]) return NULL;
	if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY)
	    load_and_link_tiled_map(m, 0);

	*y += MAP_HEIGHT(m->tile_map[0]);
    return (out_of_map(m->tile_map[0], x, y));
    }
    if (*y>=MAP_HEIGHT(m)) {
	if (!m->tile_path[2]) return NULL;
	if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY)
	    load_and_link_tiled_map(m, 2);

	*y -= MAP_HEIGHT(m);
    return (out_of_map(m->tile_map[2], x, y));
    }
    return NULL;    /* Shouldn't get here */
}

If you test all cases of map tiling you will find out why the old one is
broken.
When i remember right will you see the effect when you firing a arrow (fix
the arrow
function first) from map point 0,0 in direction northwest = to point -1,-1.
Because
the destination map is not direct attached to the map we stand, the
out_of_map() function
has moving through the other maps first. This will fail in some special
cases with the
crossfire function. Try the other positions too, you will see more bad
effects.

Also, you see i changed out_of_map() to get_map_from_coord() and deleted
get_map_from_coord(). Its a bad idea to have both version. In nearly every
case
you use out_of_map() you will need the new map pointer... so its much better
and
faster and cleaner to call this function as pointer variant.

btw, i have a way in mind, we can put moving multi arch objects on tiled
maps.
ATM, its is not possible to add multi arch monsters on tiled maps. If there
is still
a spell or something which can summon multi arch mobs, tiled maps will die
horribly
when the monster stay on map borders. Then the map will swaped out and the
objects will
released - but only parts.

This can be avoided, when we use a kind of dirty flag. when inserting mob on
a map, we will
trace on which map we insert every part. We simply add a refcount to every
map header
where every multi arch add +1 when it adds a tail part to it and the head is
in a different
map. If the multi arch is removed/move or dead, the remove_ob decrease the
refcount.

Now a map can see there is a monster only partial on it. When we do the same
for a map, where the head is but some tails on different maps, we can even
avoid alot of dead locks.
The map can say: aha, 2 mobs from me are on different maps, and on this
different maps is not a player. So we can remove our objects and swap out.

I will release daimonin 0.95 in some days. If you wait for it, you can grap
the source
and do a out_of_map search. Nearly every function i fixed is still source
compatible
to crossfire and can be copied 1:1. This can then be useful for both
projects. Because
it was really alot of work and i was not able to test every function or
case.

This remembers me to one more bad function... This time remove_ob()!!!
First, i must say that this bug is very, very hidden. It will invoke very
hidden side effects.

Mainly 2 things: Some time, moving light sources are not shown right. The
seem
to "move behind the object" and drawn only every 2nd frame. Second,
sometimes your
pet or summoned golem leave for map window (the part you see in the client)
and even
you are sure it can return when you call him back (with range fire keys), it
stucked
somewhere. When you then moving behind him, you see it coming down from
above.

This effects will come and go, i don't was able to find out what it
triggers. But i find
out that the reason was not right set map flags - mainly IS_ALIVE. I traced
it to
remove_ob() and i find there this code part:

..................
   if (last==NULL) {
	/* set P_NEED_UPDATE, otherwise update_position will complain.  In theory,
	 * we could preserve the flags (GET_MAP_FLAGS), but update_position figures
	 * those out anyways, and if there are any flags set right now, they won't
	 * be correct anyways.
	 */
	SET_MAP_FLAGS(op->map, op->x, op->y,  P_NEED_UPDATE);
	update_position(op->map, op->x, op->y);
    }
    else
	update_object(last, UP_OBJ_REMOVE);
...........

This was looking very strange for me. In fact, i has never really understand
what
this code should avoid or do.

I DELETED this code part and insert this instead:

	update_object(op, UP_OBJ_REMOVE);

After this, the strange side effect never happens again for me.


Todd Mitchell wrote:

>
     
      > There are some options when you run java that may help this
     
     >
     
      > out: -Xmx<num>mb increase the heap size the program can use.
     
     
Yes indeed. If you want to open a lot of maps at once and/or
huge ones, run it like "java -Xmx128mb -jar CFJavaEditor.jar".

>
     
      > Monsters can cross tiled maps. [...]
     
     >
     
      >
     
     >
     
      One problem I see with this is player a stirs up some monsters and
     
     >
     
      player b comes walking by on his way to newbie map Alpha and gets
     
     >
     
      eaten alive.
     
     
I agree it would be great if monsters relyably sticked to
certain areas.

Simple blocking squares could help there in several ways.
Having certain mountain- and forest tiles block movement would
allow a better structured worldmap: You can't always go straight,
there can be hidden places, restricted areas, monsters
can't rush around freely...

It might be cool for example to encircle Brest with an unpassable
mountain ridge. Players would have to walk through some underground
dungeons to get to Brest, as it is a mid/high-level area.

Also useful would be some kind of invisible "monster blocker"
object that monsters cannot pass while players can.
Movers don't do the job because groups of monsters always
push each other across them.
Basically any means to keep monsters sticking to a place
would do. The main problem about it is to avoid monsters
being kind of "trapped" and too easily killed.


AndreasV

--
+++ GMX - Mail, Messaging & more  
     
     http://www.gmx.net
     
      +++
NEU: Mit GMX ins Internet. Rund um die Uhr für 1 ct/ Min. surfen!

_______________________________________________
crossfire-list mailing list
     
     crossfire-list at lists.real-time.com
     
     
     https://mailman.real-time.com/mailman/listinfo/crossfire-list
     
     
    


More information about the crossfire mailing list