[CF-Devel] patch for generators to create special ability monsters
Norbert Irmer
norbert.irmer at t-online.de
Tue Apr 16 09:27:54 CDT 2002
Mark Wedel wrote:
>
It shouldn't be any different than if the object was a non multipart
>
object. However, the load code doesn't support multipart objects in
>
the inventory.
>
>
I don't think the code to support this is very extensive. I think all
>
that needs to be changed is around line 235 in loader - it should
>
check the return value for lex_load - if LL_MORE is returned, it then
>
needs to link with the previous part. The only problem as I see is
>
that lex_load isn't keep tracking of the last object. Fortunately,
>
insert_ob_in_ob is simplified to the extent that the last object
>
inserted will be in parent->inv, so linking it in should be easy
>
enough - as long as the behaviour of insert_ob_in_ob doesn't change.
>
>
There are also potential problems if the object is merged with
>
something else, but that shouldn't ever happen with multipart objects.
Thanks for your help again. I found out that in the 'lex_load' function
only the head part of
a multipart monster is created and inserted into the map. The creation
of the remaining
parts happens in 'link_multipart_objects(mapstruct *m)' in 'map.c',
which checks if the 'more'
field of the arch of an object (ob->arch->more) is set.
So the solution was quite simple, i do the same, and just add the head
of a multipart monster
(or better said, its arch) into the inventory of a generator, and create
the remaining parts
when the 'generate_monster()' function is called.
So for example an acid pool generator in a map which creates electric
dragons with hp 1000 would simply be:
arch acid_pool
x 1
carrying 200000
arch big_elec
hp 1000
end
end
Only problem now is, that the generator shouldn't get destroyed, or else
you have the
single head part of an electric dragon in your map (this doesn't crashes
the server, but
looks wrong)
Here is my changed 'generate_monster()' function again (i can create a
patch if wanted,
but perhaps this isn't necessary, since this was the only thing i had to
change):
void generate_monster(object *gen) {
int i;
object *op,*head=NULL,*prev=NULL,*gob;
archetype *at;
if(GENERATE_SPEED(gen)&&rndm(0, GENERATE_SPEED(gen)-1))
return;
if(gen->inv!=NULL) {
gob=gen->inv; /* the generator inv just contains the head of the
monster, */
/* if it is mulipart */
i=find_free_spot(gob->arch,gen->map,gen->x,gen->y,1,9);
if (i==-1) return;
op=get_object();
copy_object(gob,op);
op->x=gen->x+freearr_x[i]+gob->arch->clone.x;
op->y=gen->y+freearr_y[i]+gob->arch->clone.y;
if (rndm(0, 9)) generate_artifact(op, gen->map->difficulty);
insert_ob_in_map(op,gen->map,gen,0);
if (QUERY_FLAG(op, FLAG_FREED)) return;
if(op->randomitems!=NULL)
create_treasure(op->randomitems,op,GT_APPLY,
gen->map->difficulty,0);
head=op;
prev=op;
at=gob->arch->more;
}
else {
if(gen->other_arch==NULL) {
LOG(llevError,"Generator without other_arch or inv: %s\n",gen->name);
return;
}
at=gen->other_arch;
i=find_free_spot(at,gen->map,gen->x,gen->y,1,9);
if (i==-1) return;
}
while(at!=NULL) {
op=arch_to_object(at);
op->x=gen->x+freearr_x[i]+at->clone.x;
op->y=gen->y+freearr_y[i]+at->clone.y;
if(head!=NULL)
op->head=head,prev->more=op;
if (rndm(0, 9)) generate_artifact(op, gen->map->difficulty);
insert_ob_in_map(op,gen->map,gen,0);
if (QUERY_FLAG(op, FLAG_FREED)) return;
if(op->randomitems!=NULL)
create_treasure(op->randomitems,op,GT_APPLY,
gen->map->difficulty,0);
if(head==NULL)
head=op;
prev=op;
at=at->more;
}
}
More information about the crossfire
mailing list