[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