Beispiel #1
0
/**
 * @brief Loads a loading screen.
 */
void loadscreen_load (void)
{
   unsigned int i;
   char file_path[PATH_MAX];
   char **loadscreens;
   uint32_t nload;

   /* Count the loading screens */
   loadscreens = ndata_list( "gfx/loading/", &nload );

   /* Must have loading screens */
   if (nload==0) {
      WARN("No loading screens found!");
      loading = NULL;
      return;
   }

   /* Set the zoom. */
   gl_cameraZoom( conf.zoom_far );

   /* Load the texture */
   snprintf( file_path, PATH_MAX, "gfx/loading/%s", loadscreens[ RNG_SANE(0,nload-1) ] );
   loading = gl_newImage( file_path, 0 );

   /* Create the stars. */
   space_initStars( 1000 );

   /* Clean up. */
   for (i=0; i<nload; i++)
      free(loadscreens[i]);
   free(loadscreens);
}
Beispiel #2
0
/**
 * @brief Opens a texture.
 *
 * @usage t = tex.open( "no_sprites.png" )
 * @usage t = tex.open( "spritesheet.png", 6, 6 )
 *
 *    @luaparam path Path to open.
 *    @luaparam sx Optional number of x sprites (defaults 1).
 *    @luaparam sy Optional number of y sprites (defaults 1).
 *    @luareturn The opened texture or nil on error.
 * @luafunc open( path, sx, sy )
 */
static int texL_open( lua_State *L )
{
   const char *path;
   LuaTex lt;
   int sx, sy;

   /* Defaults. */
   sx = 0;
   sy = 0;

   /* Get path. */
   path = luaL_checkstring( L, 1 );
   if (lua_gettop(L)>1) {
      sx = luaL_checkinteger(L,2);
      sy = luaL_checkinteger(L,3);
      if ((sx < 0 ) || (sy < 0))
         NLUA_ERROR( L, "Spritesheet dimensions must be positive" );
   }

   /* Push new texture. */
   if ((sx <=0 ) || (sy <= 0))
      lt.tex = gl_newImage( path, 0 );
   else
      lt.tex = gl_newSprite( path, sx, sy, 0 );
   if (lt.tex == NULL)
      return 0;
   lua_pushtex( L, lt );
   return 1;
}
Beispiel #3
0
Datei: land.c Projekt: Dinth/naev
/**
 * @brief Opens up all the land dialogue stuff.
 *    @param p Planet to open stuff for.
 *    @param load Whether or not loading the game.
 */
void land( Planet* p, int load )
{
   /* Do not land twice. */
   if (landed)
      return;

   /* Stop player sounds. */
   player_soundStop();

   /* Load stuff */
   land_planet = p;
   gfx_exterior = gl_newImage( p->gfx_exterior, 0 );

   /* Generate the news. */
   if (planet_hasService(land_planet, PLANET_SERVICE_BAR))
      news_load();

   /* Clear the NPC. */
   npc_clear();

   /* Create all the windows. */
   land_genWindows( load, 0 );

   /* Mission forced take off. */
   if (land_takeoff)
      takeoff(0);
}
Beispiel #4
0
/**
 * @brief Opens up all the land dialogue stuff.
 *    @param p Planet to open stuff for.
 *    @param load Whether or not loading the game.
 */
void land( Planet* p, int load )
{
   /* Do not land twice. */
   if (landed)
      return;

   /* Resets the player's heat. */
   pilot_heatReset( player.p );

   /* Stop player sounds. */
   player_soundStop();

   /* Load stuff */
   land_planet = p;
   gfx_exterior = gl_newImage( p->gfx_exterior, 0 );

   /* Generate the news. */
   if (planet_hasService(land_planet, PLANET_SERVICE_BAR))
      news_load();

   /* Clear the NPC. */
   npc_clear();

   /* Create all the windows. */
   land_genWindows( load, 0 );

   /* Hack so that load can run player.takeoff(). */
   if (load)
      hooks_run( "load" );

   /* Mission forced take off. */
   if (land_takeoff)
      takeoff(0);
}
Beispiel #5
0
/**
 * @brief Gets the texture of the planet in exterior.
 *
 * @uasge gfx = p:gfxExterior()
 *    @luatparam Planet p Planet Planet to get texture of.
 *    @luatreturn Tex The exterior texture of the planet.
 * @luafunc gfxExterior( p )
 */
static int planetL_gfxExterior( lua_State *L )
{
   Planet *p;
   p = luaL_validplanet(L,1);
   lua_pushtex( L, gl_newImage( p->gfx_exterior, 0 ) );
   return 1;
}
Beispiel #6
0
/**
 * @brief Gets the texture of the planet in exterior.
 *
 * @uasge gfx = p:gfxExterior()
 *    @luaparam p Planet to get texture of.
 *    @luareturn The exterior texture of the planet.
 * @luafunc gfxExterior( p )
 */
static int planetL_gfxExterior( lua_State *L )
{
   Planet *p;
   LuaTex lt;
   p        = luaL_validplanet(L,1);
   lt.tex   = gl_newImage( p->gfx_exterior, 0 );
   lua_pushtex( L, lt );
   return 1;
}
Beispiel #7
0
/**
 * @brief Generates the mission list for the bar.
 *
 *    @param wid Window to create mission list for.
 */
static int bar_genList( unsigned int wid )
{
   glTexture **portraits;
   char **names, *focused;
   int w, h, iw, ih, bw, bh;
   int n;

   /* Get dimensions. */
   bar_getDim( wid, &w, &h, &iw, &ih, &bw, &bh );

   /* Save focus. */
   focused = strdup(window_getFocus(wid));

   /* Destroy widget if already exists. */
   if (widget_exists( wid, "iarMissions" ))
      window_destroyWidget( wid, "iarMissions" );

   /* We sort just in case. */
   npc_sort();

   /* Set up missions. */
   if (mission_portrait == NULL)
      mission_portrait = gl_newImage( PORTRAIT_GFX_PATH"news.png", 0 );
   n = npc_getArraySize();
   if (n <= 0) {
      n            = 1;
      portraits    = malloc(sizeof(glTexture*));
      portraits[0] = mission_portrait;
      names        = malloc(sizeof(char*));
      names[0]     = strdup("News");
   }
   else {
      n            = n+1;
      portraits    = malloc( sizeof(glTexture*) * n );
      portraits[0] = mission_portrait;
      npc_getTextureArray( &portraits[1], n-1 );
      names        = malloc( sizeof(char*) * n );
      names[0]     = strdup("News");
      npc_getNameArray( &names[1], n-1 );
   }
   window_addImageArray( wid, 20, -40,
         iw, ih, "iarMissions", 100, 75,
         portraits, names, n, bar_update, NULL );

   /* write the outfits stuff */
   bar_update( wid, NULL );

   /* Restore focus. */
   window_setFocus( wid, focused );
   free(focused);

   return 0;
}
Beispiel #8
0
/**
 * @brief Gets the texture of the planet in space.
 *
 * @uasge gfx = p:gfxSpace()
 *    @luaparam p Planet to get texture of.
 *    @luareturn The space texture of the planet.
 * @luafunc gfxSpace( p )
 */
static int planetL_gfxSpace( lua_State *L )
{
   Planet *p;
   LuaTex lt;
   p        = luaL_validplanet(L,1);
   if (p->gfx_space == NULL) /* Not loaded. */
      lt.tex   = gl_newImage( p->gfx_spaceName, OPENGL_TEX_MIPMAPS );
   else
      lt.tex   = gl_dupTexture( p->gfx_space );
   lua_pushtex( L, lt );
   return 1;
}
Beispiel #9
0
/**
 * @brief Fade an image in.
 *
 *    @brief side Present image being displayed.
 *    @brief transition Image in transition or on deck.
 *    @brief img_file Path to the PNG on disk.
 */
static void intro_fade_image_in( intro_img_t *side, intro_img_t *transition,
                                 const char *img_file )
{
    if (NULL == side->tex) {
        /* Simple fade-in. */
        side->tex = gl_newImage( img_file, 0 );
        side->y = (double)SCREEN_H / 2.0 - (side->tex->h / 2.0);
        side->c.a = 0.0;
        side->fade_rate = 0.1;
    }
    else {
        /*
         * Transition or on-deck. The difference is whether one image is
         * replacing the other (transition), or whether the first must fade out
         * completely before the second comes in (on-deck).
         *
         * We can determine which is the case by seeing whether [fadeout] has been
         * called. I.e., is side->fade_rate < 0?
         */
        if (NULL != transition->tex) {
            /* Scrolling is happening faster than fading... */
            WARN( "Intro scrolling too fast!" );
            gl_freeTexture( transition->tex );
        }
        transition->tex = gl_newImage( img_file, 0 );
        transition->y =
            (double)SCREEN_H / 2.0 - (transition->tex->h / 2.0);
        transition->c.a = 0.0;
        if (side->fade_rate < 0.0)
            transition->fade_rate = 0.0; /* put an image on deck. */
        else {
            /* transition. */
            transition->fade_rate = 0.1;
            side->fade_rate = -0.1; /* begin fading out. */
            side->c.a = 0.99;
        }
    }
}
Beispiel #10
0
/**
 * @brief Opens a texture.
 *
 *    @luaparam path Path to open.
 *    @luareturn The opened texture or nil on error.
 * @luafunc open( path )
 */
static int texL_open( lua_State *L )
{
   const char *path;
   LuaTex lt;

   /* Get path. */
   path = luaL_checkstring( L, 1 );

   /* Push new texture. */
   lt.tex = gl_newImage( path, 0 );
   if (lt.tex == NULL)
      return 0;
   lua_pushtex( L, lt );
   return 1;
}
Beispiel #11
0
/**
 * @brief Parses a single faction, but doesn't set the allies/enemies bit.
 *
 *    @param temp Faction to load data into.
 *    @param parent Parent node to extract faction from.
 *    @return Faction created from parent node.
 */
static int faction_parse( Faction* temp, xmlNodePtr parent )
{
   xmlNodePtr node;
   int player;
   char buf[PATH_MAX];

   /* Clear memory. */
   memset( temp, 0, sizeof(Faction) );

   temp->name = xml_nodeProp(parent,"name");
   if (temp->name == NULL) WARN("Faction from "FACTION_DATA" has invalid or no name");

   player = 0;
   node = parent->xmlChildrenNode;
   do {
      /* Can be 0 or negative, so we have to take that into account. */
      if (xml_isNode(node,"player")) {
         temp->player_def = xml_getFloat(node);
         player = 1;
         continue;
      }

      xmlr_strd(node,"longname",temp->longname);
      if (xml_isNode(node, "colour"))
         temp->colour = col_fromName(xml_raw(node));

      if (xml_isNode(node,"logo")) {
         snprintf( buf, PATH_MAX, FACTION_LOGO_PATH"%s_small.png", xml_get(node));
         temp->logo_small = gl_newImage(buf, 0);
         continue;
      }

      if (xml_isNode(node,"static")) {
         faction_setFlag(temp, FACTION_STATIC);
         continue;
      }

      if (xml_isNode(node,"invisible")) {
         faction_setFlag(temp, FACTION_INVISIBLE);
         continue;
      }
   } while (xml_nextNode(node));

   if (player==0)
      DEBUG("Faction '%s' missing player tag.", temp->name);

   return 0;
}
Beispiel #12
0
/**
 * @brief Adds a event NPC to the mission computer.
 */
unsigned int npc_add_event( unsigned int evt, const char *func, const char *name,
      int priority, const char *portrait, const char *desc )
{
   NPC_t npc;

   /* The data. */
   npc.type       = NPC_TYPE_EVENT;
   npc.name       = strdup( name );
   npc.priority   = priority;
   npc.portrait   = gl_newImage( portrait, 0 );
   npc.desc       = strdup( desc );
   npc.u.e.id     = evt;
   npc.u.e.func   = strdup( func );

   return npc_add( &npc );
}
Beispiel #13
0
/**
 * @brief Adds a mission NPC to the mission computer.
 */
unsigned int npc_add_mission( Mission *misn, const char *func, const char *name,
      int priority, const char *portrait, const char *desc )
{
   NPC_t npc;

   /* The data. */
   npc.type       = NPC_TYPE_MISSION;
   npc.name       = strdup( name );
   npc.priority   = priority;
   npc.portrait   = gl_newImage( portrait, 0 );
   npc.desc       = strdup( desc );
   npc.u.m.misn   = misn;
   npc.u.m.func   = strdup( func );

   return npc_add( &npc );
}
Beispiel #14
0
/**
 * @brief Opens a dialogue window with an ok button, a fixed message and an image.
 *
 *    @param caption Window title.
 *    @param msg Message to display.
 *    @param width Width of the image. Negative uses image width.
 *    @param height Height of the image. Negative uses image height.
 */
void dialogue_msgImgRaw( const char* caption, const char *msg, const char *img, int width, int height )
{
   int w, h, img_width, img_height;
   glFont* font;
   unsigned int msg_wid;
   int done;
   glTexture *gfx;
   char buf[PATH_MAX];

   /* Get the desired texture */
   /* IMPORTANT : texture must not be freed here, it will be freed when the widget closes */
   nsnprintf( buf, sizeof(buf), "%s%s", GFX_PATH, img );
   gfx = gl_newImage( buf, 0 );

   /* Find the popup's dimensions from text and image */
   img_width  = (width < 0)  ? gfx->w : width;
   img_height = (height < 0) ? gfx->h : height;
   font = dialogue_getSize( caption, msg, &w, &h );
   if (h < img_width) {
      h = img_width;
   }

   /* Create the window */
   msg_wid = window_create( caption, -1, -1, img_width + w, 110 + h );
   window_setData( msg_wid, &done );

   /* Add the text box */
   window_addText( msg_wid, img_width+40, -40, w-40, h,  0, "txtMsg",
         font, &cBlack, msg );

   /* Add a placeholder rectangle for the image */
   window_addRect( msg_wid, 20, -40, img_width, img_height,
         "rctGFX", &cGrey10, 1 );

   /* Actually add the texture in the rectangle */
   window_addImage( msg_wid, 20, -40, img_width, img_height,
         "ImgGFX", gfx, 0 );

   /* Add the OK button */
   window_addButton( msg_wid, (img_width+w -50)/2, 20, 50, 30, "btnOK", "OK",
         dialogue_close );

   dialogue_open++;
   toolkit_loop( &done );
}
Beispiel #15
0
/**
 * @brief Sets the current mission NPC.
 *
 * This is used in bar missions where you talk to a person. The portraits are
 *  the ones found in gfx/portraits without the png extension. So for
 *  gfx/portraits/none.png you would just use "none".
 *
 * @usage misn.setNPC( "Invisible Man", "none" )
 *
 *    @luaparam name Name of the NPC.
 *    @luaparam portrait Name of the portrait to use for the NPC.
 * @luafunc setNPC( name, portrait )
 */
static int misn_setNPC( lua_State *L )
{
   char buf[PATH_MAX];
   const char *name, *str;
   Mission *cur_mission;

   cur_mission = misn_getFromLua(L);

   /* Free if portrait is already set. */
   if (cur_mission->portrait != NULL) {
      gl_freeTexture(cur_mission->portrait);
      cur_mission->portrait = NULL;
   }

   /* Free NPC name. */
   if (cur_mission->npc != NULL) {
      free(cur_mission->npc);
      cur_mission->npc = NULL;
   }

   /* For no parameters just leave having freed NPC. */
   if (lua_gettop(L) == 0)
      return 0;

   /* Get parameters. */
   name = luaL_checkstring(L,1);
   str  = luaL_checkstring(L,2);

   /* Set NPC name. */
   cur_mission->npc = strdup(name);

   /* Set portrait. */
   nsnprintf( buf, PATH_MAX, "gfx/portraits/%s.png", str );
   cur_mission->portrait = gl_newImage( buf, 0 );

   return 0;
}
Beispiel #16
0
Datei: menu.c Projekt: zid/naev
/**
 * @brief Opens the main menu (titlescreen).
 */
void menu_main (void)
{
   int offset_logo, offset_wdw, freespace;
   unsigned int bwid, wid;
   glTexture *tex;

   /* Play load music. */
   music_choose("load");

   /* Load background and friends. */
   tex = gl_newImage( "gfx/NAEV.png", 0 );
   main_naevLogo = tex;
   nebu_prep( 300., 0. ); /* Needed for nebula to not spaz out */

   /* Calculate Logo and window offset. */
   freespace = SCREEN_H - tex->sh - MAIN_HEIGHT;
   if (freespace < 0) { /* Not enough freespace, this can get ugly. */
      offset_logo = SCREEN_W - tex->sh;
      offset_wdw  = 0;
   }
   else {
      /* We'll want a maximum seperation of 30 between logo and text. */
      if (freespace/3 > 25) {
         freespace -= 25;
         offset_logo = -25;
         offset_wdw  = -25 - tex->sh - 25;
      }
      /* Otherwise space evenly. */
      else {
         offset_logo = -freespace/3;
         offset_wdw  = freespace/3;
      }
   }

   /* create background image window */
   bwid = window_create( "BG", -1, -1, SCREEN_W, SCREEN_H );
   window_onClose( bwid, menu_main_cleanBG );
   window_addRect( bwid, 0, 0, SCREEN_W, SCREEN_H, "rctBG", &cBlack, 0 );
   window_addCust( bwid, 0, 0, SCREEN_W, SCREEN_H, "cstBG", 0,
         menu_main_nebu, NULL, &menu_main_lasttick );
   window_addImage( bwid, (SCREEN_W-tex->sw)/2., offset_logo, "imgLogo", tex, 0 );
   window_addText( bwid, 0., 10, SCREEN_W, 30., 1, "txtBG", NULL,
         &cWhite, naev_version(1) );

   /* create menu window */
   wid = window_create( "Main Menu", -1, offset_wdw,
         MAIN_WIDTH, MAIN_HEIGHT );
   window_addButton( wid, 20, 20 + (BUTTON_HEIGHT+20)*4,
         BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnLoad", "Load Game", menu_main_load );
   window_addButton( wid, 20, 20 + (BUTTON_HEIGHT+20)*3,
         BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnNew", "New Game", menu_main_new );
   window_addButton( wid, 20, 20 + (BUTTON_HEIGHT+20)*2,
         BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnOptions", "Options", menu_options_button );
   window_addButton( wid, 20, 20 + (BUTTON_HEIGHT+20),
         BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnCredits", "Credits", menu_main_credits );
   window_addButton( wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnExit", "Exit", menu_exit );

   /* Make the background window a parent of the menu. */
   window_setParent( bwid, wid );

   /* Reset timer. */
   menu_main_lasttick = SDL_GetTicks();

   menu_Open(MENU_MAIN);
}
Beispiel #17
0
Datei: menu.c Projekt: naev/naev
/**
 * @brief Opens the main menu (titlescreen).
 */
void menu_main (void)
{
   int offset_logo, offset_wdw, freespace;
   unsigned int bwid, wid;
   glTexture *tex;
   int h, y;

   if (menu_isOpen(MENU_MAIN)) {
      WARN( _("Menu main is already open.") );
      return;
   }

   /* Clean up GUI - must be done before using SCREEN_W or SCREEN_H. */
   gui_cleanup();
   player_soundStop(); /* Stop sound. */

   /* Play load music. */
   music_choose("load");

   /* Load background and friends. */
   tex = gl_newImage( GFX_PATH"Naev.png", 0 );
   main_naevLogo = tex;
   menu_main_bkg_system();

   /* Set dimensions */
   y  = 20 + (BUTTON_HEIGHT+20)*5;
   h  = y + 80;
   if (conf.devmode) {
      h += BUTTON_HEIGHT + 20;
      y += BUTTON_HEIGHT + 20;
   }

   /* Calculate Logo and window offset. */
   freespace = SCREEN_H - tex->sh - h;
   if (freespace < 0) { /* Not enough freespace, this can get ugly. */
      offset_logo = SCREEN_W - tex->sh;
      offset_wdw  = 0;
   }
   /* Otherwise space evenly. */
   else {
      offset_logo = -freespace/4;
      offset_wdw  = freespace/2;
   }

   /* create background image window */
   bwid = window_create( "BG", -1, -1, -1, -1 );
   window_onClose( bwid, menu_main_cleanBG );
   window_setBorder( bwid, 0 );
   window_addImage( bwid, (SCREEN_W-tex->sw)/2., offset_logo, 0, 0, "imgLogo", tex, 0 );
   window_addText( bwid, 0, 10, SCREEN_W, 30., 1, "txtBG", NULL,
         &cWhite, naev_version(1) );

   /* create menu window */
   wid = window_create( "Main Menu", -1, offset_wdw, MAIN_WIDTH, h );
   window_setCancel( wid, main_menu_promptClose );

   /* Buttons. */
   window_addButtonKey( wid, 20, y, BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnLoad", _("Load Game"), menu_main_load, SDLK_l );
   y -= BUTTON_HEIGHT+20;
   window_addButtonKey( wid, 20, y, BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnNew", _("New Game"), menu_main_new, SDLK_n );
   y -= BUTTON_HEIGHT+20;
   window_addButtonKey( wid, 20, y, BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnTutorial", _("Tutorial"), menu_main_tutorial, SDLK_t );
   y -= BUTTON_HEIGHT+20;
   if (conf.devmode) {
      window_addButtonKey( wid, 20, y, BUTTON_WIDTH, BUTTON_HEIGHT,
            "btnEditor", _("Editors"), menu_editors_open, SDLK_e );
      y -= BUTTON_HEIGHT+20;
   }
   window_addButtonKey( wid, 20, y, BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnOptions", _("Options"), menu_options_button, SDLK_o );
   y -= BUTTON_HEIGHT+20;
   window_addButtonKey( wid, 20, y, BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnCredits", _("Credits"), menu_main_credits, SDLK_c );
   y -= BUTTON_HEIGHT+20;
   window_addButtonKey( wid, 20, y, BUTTON_WIDTH, BUTTON_HEIGHT,
         "btnExit", _("Exit"), menu_exit, SDLK_x );

   /* Disable load button if there are no saves. */
   if (!save_hasSave())
      window_disableButton( wid, "btnLoad" );

   /* Make the background window a child of the menu. */
   window_setParent( bwid, wid );

   unpause_game();
   menu_Open(MENU_MAIN);
}
Beispiel #18
0
/**
 * @brief Parses a single faction, but doesn't set the allies/enemies bit.
 *
 *    @param temp Faction to load data into.
 *    @param parent Parent node to extract faction from.
 *    @return Faction created from parent node.
 */
static int faction_parse( Faction* temp, xmlNodePtr parent )
{
   xmlNodePtr node;
   int player;
   char buf[PATH_MAX], *dat;
   uint32_t ndat;

   /* Clear memory. */
   memset( temp, 0, sizeof(Faction) );

   temp->name = xml_nodeProp(parent,"name");
   if (temp->name == NULL)
      WARN("Faction from "FACTION_DATA_PATH" has invalid or no name");

   player = 0;
   node = parent->xmlChildrenNode;
   do {

      /* Only care about nodes. */
      xml_onlyNodes(node);

      /* Can be 0 or negative, so we have to take that into account. */
      if (xml_isNode(node,"player")) {
         temp->player_def = xml_getFloat(node);
         player = 1;
         continue;
      }

      xmlr_strd(node,"longname",temp->longname);
      xmlr_strd(node,"display",temp->displayname);
      if (xml_isNode(node, "colour")) {
         temp->colour = col_fromName(xml_raw(node));
         continue;
      }

      if (xml_isNode(node, "spawn")) {
         if (temp->sched_state != NULL)
            WARN("Faction '%s' has duplicate 'spawn' tag.", temp->name);
         nsnprintf( buf, sizeof(buf), "dat/factions/spawn/%s.lua", xml_raw(node) );
         temp->sched_state = nlua_newState();
         nlua_loadStandard( temp->sched_state, 0 );
         dat = ndata_read( buf, &ndat );
         if (luaL_dobuffer(temp->sched_state, dat, ndat, buf) != 0) {
            WARN("Failed to run spawn script: %s\n"
                  "%s\n"
                  "Most likely Lua file has improper syntax, please check",
                  buf, lua_tostring(temp->sched_state,-1));
            lua_close( temp->sched_state );
            temp->sched_state = NULL;
         }
         free(dat);
         continue;
      }

      if (xml_isNode(node, "standing")) {
         if (temp->state != NULL)
            WARN("Faction '%s' has duplicate 'standing' tag.", temp->name);
         nsnprintf( buf, sizeof(buf), "dat/factions/standing/%s.lua", xml_raw(node) );
         temp->state = nlua_newState();
         nlua_loadStandard( temp->state, 0 );
         dat = ndata_read( buf, &ndat );
         if (luaL_dobuffer(temp->state, dat, ndat, buf) != 0) {
            WARN("Failed to run standing script: %s\n"
                  "%s\n"
                  "Most likely Lua file has improper syntax, please check",
                  buf, lua_tostring(temp->state,-1));
            lua_close( temp->state );
            temp->state = NULL;
         }
         free(dat);
         continue;
      }

      if (xml_isNode(node, "known")) {
         faction_setFlag(temp, FACTION_KNOWN);
         continue;
      }

      if (xml_isNode(node, "equip")) {
         if (temp->equip_state != NULL)
            WARN("Faction '%s' has duplicate 'equip' tag.", temp->name);
         nsnprintf( buf, sizeof(buf), "dat/factions/equip/%s.lua", xml_raw(node) );
         temp->equip_state = nlua_newState();
         nlua_loadStandard( temp->equip_state, 0 );
         dat = ndata_read( buf, &ndat );
         if (luaL_dobuffer(temp->equip_state, dat, ndat, buf) != 0) {
            WARN("Failed to run equip script: %s\n"
                  "%s\n"
                  "Most likely Lua file has improper syntax, please check",
                  buf, lua_tostring(temp->equip_state,-1));
            lua_close( temp->equip_state );
            temp->equip_state = NULL;
         }
         free(dat);
         continue;
      }

      if (xml_isNode(node,"logo")) {
         if (temp->logo_small != NULL)
            WARN("Faction '%s' has duplicate 'logo' tag.", temp->name);
         nsnprintf( buf, PATH_MAX, FACTION_LOGO_PATH"%s_small.png", xml_get(node));
         temp->logo_small = gl_newImage(buf, 0);
         nsnprintf( buf, PATH_MAX, FACTION_LOGO_PATH"%s_tiny.png", xml_get(node));
         temp->logo_tiny = gl_newImage(buf, 0);
         continue;
      }

      if (xml_isNode(node,"static")) {
         faction_setFlag(temp, FACTION_STATIC);
         continue;
      }

      if (xml_isNode(node,"invisible")) {
         faction_setFlag(temp, FACTION_INVISIBLE);
         continue;
      }

      /* Avoid warnings. */
      if (xml_isNode(node,"allies") || xml_isNode(node,"enemies"))
         continue;

      DEBUG("Unknown node '%s' in faction '%s'",node->name,temp->name);
   } while (xml_nextNode(node));

   if (player==0)
      DEBUG("Faction '%s' missing player tag.", temp->name);
   if ((temp->state!=NULL) && faction_isFlag( temp, FACTION_STATIC ))
      WARN("Faction '%s' has Lua and is static!", temp->name);
   if ((temp->state==NULL) && !faction_isFlag( temp, FACTION_STATIC ))
      WARN("Faction '%s' has no Lua and isn't static!", temp->name);

   return 0;
}