Exemplo n.º 1
0
Arquivo: npc.c Projeto: Anatolis/naev
/**
 * @brief Frees a single npc.
 */
static void npc_free( NPC_t *npc )
{
   /* Common free stuff. */
   free(npc->name);
   gl_freeTexture(npc->portrait);
   free(npc->desc);

   /* Type-specific free stuff. */
   switch (npc->type) {
      case NPC_TYPE_GIVER:
         mission_cleanup(&npc->u.g);
         break;

      case NPC_TYPE_MISSION:
         free(npc->u.m.func);
         break;

      case NPC_TYPE_EVENT:
         free(npc->u.e.func);
         break;

      default:
         WARN("Freeing NPC of invalid type.");
         return;
   }
}
Exemplo n.º 2
0
Arquivo: npc.c Projeto: Anatolis/naev
/**
 * @brief Approaches a mission giver guy.
 *
 *    @brief Returns 1 on destroyed, 0 on not destroyed.
 */
static int npc_approach_giver( NPC_t *npc )
{
   int i;
   int ret;
   Mission *misn;

   /* Make sure player can accept the mission. */
   for (i=0; i<MISSION_MAX; i++)
      if (player_missions[i].data == NULL)
         break;
   if (i >= MISSION_MAX) {
      dialogue_alert("You have too many active missions.");
      return -1;
   }

   /* Get mission. */
   misn = &npc->u.g;
   ret  = mission_accept( misn );
   if ((ret==0) || (ret==2) || (ret==-1)) { /* success in accepting the mission */
      if (ret==-1)
         mission_cleanup( misn );
      npc_free( npc );
      array_erase( &npc_array, &npc[0], &npc[1] );
      ret = 1;
   }
   else
      ret  = 0;

   return ret;
}
Exemplo n.º 3
0
/**
 * @brief Aborts a mission in the mission menu.
 *    @param str Unused.
 */
static void mission_menu_abort( unsigned int wid, char* str )
{
   (void)str;
   int pos;
   Mission* misn;
   int ret;

   if (dialogue_YesNo( "Abort Mission",
            "Are you sure you want to abort this mission?" )) {

      /* Get the mission. */
      pos = toolkit_getListPos(wid, "lstMission" );
      misn = &player_missions[pos];

      /* We run the "abort" function if it's found. */
      ret = misn_tryRun( misn, "abort" );

      /* Now clean up mission. */
      if (ret != 2) {
         mission_cleanup( misn );
         memmove( misn, &player_missions[pos+1],
               sizeof(Mission) * (MISSION_MAX-pos-1) );
         memset( &player_missions[MISSION_MAX-1], 0, sizeof(Mission) );
      }

      /* Reset markers. */
      mission_sysMark();

      /* Reset claims. */
      claim_activateAll();

      /* Regenerate list. */
      mission_menu_genList(wid ,0);
   }
}
Exemplo n.º 4
0
Arquivo: land.c Projeto: Dinth/naev
/**
 * @brief Cleans up some land-related variables.
 */
void land_cleanup (void)
{
   int i;

   /* Clean up default stuff. */
   land_regen     = 0;
   land_planet    = NULL;
   landed         = 0;
   land_visited   = 0;

   /* Destroy window. */
   if (land_wid > 0)
      window_destroy(land_wid);
   land_wid       = 0;

   /* Clean up possible stray graphic. */
   if (gfx_exterior != NULL)
      gl_freeTexture( gfx_exterior );
   gfx_exterior   = NULL;

   /* Clean up mission computer. */
   for (i=0; i<mission_ncomputer; i++)
      mission_cleanup( &mission_computer[i] );
   if (mission_computer != NULL)
      free(mission_computer);
   mission_computer  = NULL;
   mission_ncomputer = 0;

   /* Clean up bar missions. */
   npc_freeAll();
}
Exemplo n.º 5
0
/**
 * @brief Cleans up all the player's active missions.
 */
void missions_cleanup (void)
{
   int i;

   for (i=0; i<MISSION_MAX; i++)
      mission_cleanup( player_missions[i] );
}
Exemplo n.º 6
0
/**
 * @brief Runs missions matching location, all Lua side and one-shot.
 *
 *    @param loc Location to match.
 *    @param faction Faction of the planet.
 *    @param planet Name of the current planet.
 *    @param sysname Name of the current system.
 */
void missions_run( int loc, int faction, const char* planet, const char* sysname )
{
   MissionData* misn;
   Mission mission;
   int i;
   double chance;

   for (i=0; i<mission_nstack; i++) {
      misn = &mission_stack[i];
      if (misn->avail.loc != loc)
         continue;

      if (!mission_meetReq(i, faction, planet, sysname))
         continue;

      chance = (double)(misn->avail.chance % 100)/100.;
      if (chance == 0.) /* We want to consider 100 -> 100% not 0% */
         chance = 1.;

      if (RNGF() < chance) {
         mission_init( &mission, misn, 1, 1, NULL );
         mission_cleanup(&mission); /* it better clean up for itself or we do it */
      }
   }
}
Exemplo n.º 7
0
/**
 * @brief Initializes a mission.
 *
 *    @param mission Mission to initialize.
 *    @param misn Data to use.
 *    @param genid 1 if should generate id, 0 otherwise.
 *    @param create 1 if should run create function, 0 otherwise.
 *    @param[out] id ID of the newly created mission.
 *    @return 0 on success.
 */
static int mission_init( Mission* mission, MissionData* misn, int genid, int create, unsigned int *id )
{
   char *buf;
   uint32_t bufsize;
   int ret;

   /* clear the mission */
   memset( mission, 0, sizeof(Mission) );

   /* Create id if needed. */
   mission->id    = (genid) ? mission_genID() : 0;
   if (id != NULL)
      *id         = mission->id;
   mission->data  = misn;
   if (create) {
      mission->title = strdup(misn->name);
      mission->desc  = strdup("No description.");
   }

   /* init Lua */
   mission->L = nlua_newState();
   if (mission->L == NULL) {
      WARN("Unable to create a new Lua state.");
      return -1;
   }
   nlua_loadBasic( mission->L ); /* pairs and such */
   misn_loadLibs( mission->L ); /* load our custom libraries */

   /* load the file */
   buf = ndata_read( misn->lua, &bufsize );
   if (buf == NULL) {
      WARN("Mission '%s' Lua script not found.", misn->lua );
      return -1;
   }
   if (luaL_dobuffer(mission->L, buf, bufsize, misn->lua) != 0) {
      WARN("Error loading mission file: %s\n"
          "%s\n"
          "Most likely Lua file has improper syntax, please check",
            misn->lua, lua_tostring(mission->L,-1));
      free(buf);
      return -1;
   }
   free(buf);

   /* run create function */
   if (create) {
      /* Failed to create. */
      ret = misn_run( mission, "create");
      if (ret) {
         mission_cleanup(mission);
         return ret;
      }
   }

   return 0;
}
Exemplo n.º 8
0
/**
 * @brief Runs a mission set up with misn_runStart.
 *
 *    @param misn Mission that owns the function.
 *    @param func Name of the function to call.
 *    @return -1 on error, 1 on misn.finish() call, 2 if mission got deleted
 *            and 0 normally.
 */
int misn_runFunc( Mission *misn, const char *func, int nargs )
{
   int i, ret, errf;
   const char* err;
   lua_State *L;
   int misn_delete;
   Mission *cur_mission;

   /* For comfort. */
   L = misn->L;

#if DEBUGGING
   errf = -2-nargs;
#else /* DEBUGGING */
   errf = 0;
#endif /* DEBUGGING */

   ret = lua_pcall(L, nargs, 0, errf);
   cur_mission = misn_getFromLua(L); /* The mission can change if accepted. */
   if (ret != 0) { /* error has occurred */
      err = (lua_isstring(L,-1)) ? lua_tostring(L,-1) : NULL;
      if ((err==NULL) || (strcmp(err,NLUA_DONE)!=0)) {
         WARN("Mission '%s' -> '%s': %s",
               cur_mission->data->name, func, (err) ? err : "unknown error");
         ret = -1;
      }
      else
         ret = 1;
      lua_pop(L,1);
   }
#if DEBUGGING
   lua_pop(L,1);
#endif /* DEBUGGING */

   /* Get delete. */
   lua_getglobal(L,"__misn_delete");
   misn_delete = lua_toboolean(L,-1);
   lua_pop(L,1);

   /* mission is finished */
   if (misn_delete) {
      ret = 2;
      mission_cleanup( cur_mission );
      for (i=0; i<MISSION_MAX; i++)
         if (cur_mission == &player_missions[i]) {
            memmove( &player_missions[i], &player_missions[i+1],
                  sizeof(Mission) * (MISSION_MAX-i-1) );
            memset( &player_missions[MISSION_MAX-1], 0, sizeof(Mission) );
            break;
         }
   }

   return ret;
}
Exemplo n.º 9
0
/**
 * @brief Accepts the selected mission.
 *    @param wid Window of the mission computer.
 *    @param str Unused.
 */
static void misn_accept( unsigned int wid, char* str )
{
   (void) str;
   char* misn_name;
   Mission* misn;
   int pos;
   int i, ret;

   misn_name = toolkit_getList( wid, "lstMission" );

   /* Make sure you have missions. */
   if (strcmp(misn_name,"No Missions")==0)
      return;

   /* Make sure player can accept the mission. */
   for (i=0; i<MISSION_MAX; i++)
      if (player_missions[i].data == NULL) break;
   if (i >= MISSION_MAX) {
      dialogue_alert("You have too many active missions.");
      return;
   }

   if (dialogue_YesNo("Accept Mission",
         "Are you sure you want to accept this mission?")) {
      pos = toolkit_getListPos( wid, "lstMission" );
      misn = &mission_computer[pos];
      ret = mission_accept( misn );
      if ((ret==0) || (ret==2) || (ret==-1)) { /* success in accepting the mission */
         if (ret==-1)
            mission_cleanup( &mission_computer[pos] );
         memmove( &mission_computer[pos], &mission_computer[pos+1],
               sizeof(Mission) * (mission_ncomputer-pos-1) );
         mission_ncomputer--;

         /* Regenerate list. */
         misn_genList(wid, 0);
         /* Add position persistancey after a mission has been accepted */
         /* NOTE: toolkit_setListPos protects us from a bad position by clamping */
         toolkit_setListPos( wid, "lstMission", pos-1 ); /*looks better without the -1, makes more sense with*/
      }

      /* Reset markers. */
      mission_sysMark();
   }
}
Exemplo n.º 10
0
/**
 * @brief Starts a mission.
 *
 *  Mission must still call misn.accept() to actually get added to the player's
 * active missions.
 *
 *    @param name Name of the mission to start.
 *    @param[out] id ID of the newly created mission.
 *    @return 0 on success, >0 on forced exit (misn.finish), <0 on error.
 */
int mission_start( const char *name, unsigned int *id )
{
   Mission mission;
   MissionData *mdat;
   int ret;

   /* Try to get the mission. */
   mdat = mission_get( mission_getID(name) );
   if (mdat == NULL)
      return -1;

   /* Try to run the mission. */
   ret = mission_init( &mission, mdat, 1, 1, id );
   /* Add to mission giver if necessary. */
   if (landed && (ret==0) && (mdat->avail.loc==MIS_AVAIL_BAR))
      npc_patchMission( &mission );
   else
      mission_cleanup( &mission ); /* Clean up in case not accepted. */

   return ret;
}
Exemplo n.º 11
0
/**
 * @brief Runs the function at the top of the stack.
 *
 *    @param misn Mission that owns the function.
 *    @param func Name of the function to call.
 *    @return -1 on error, 1 on misn.finish() call, 2 if mission got deleted
 *            and 0 normally.
 */
static int misn_runTopStack( Mission *misn, const char *func)
{
   int i, ret;
   const char* err;
   lua_State *L;

   cur_mission = misn;
   misn_delete = 0;
   L = misn->L;

   ret = lua_pcall(L, 0, 0, 0);
   if (ret != 0) { /* error has occured */
      err = (lua_isstring(L,-1)) ? lua_tostring(L,-1) : NULL;
      if (strcmp(err,"Mission Done")!=0)
         WARN("Mission '%s' -> '%s': %s",
               cur_mission->data->name, func, (err) ? err : "unknown error");
      else
         ret = 1;
   }

   /* mission is finished */
   if (misn_delete) {
      ret = 2;
      mission_cleanup( cur_mission );
      for (i=0; i<MISSION_MAX; i++)
         if (cur_mission == &player_missions[i]) {
            memmove( &player_missions[i], &player_missions[i+1],
                  sizeof(Mission) * (MISSION_MAX-i-1) );
            memset( &player_missions[MISSION_MAX-1], 0, sizeof(Mission) );
            break;
         }
   }

   cur_mission = NULL;

   return ret;
}
Exemplo n.º 12
0
/**
 * @brief Makes the player jettison the currently selected cargo.
 *    @param str Unused.
 */
static void cargo_jettison( unsigned int wid, char* str )
{
   (void)str;
   int i, j, f, pos, ret;
   Mission *misn;

   if (player.p->ncommodities==0)
      return; /* No cargo, redundant check */

   pos = toolkit_getListPos( wid, "lstCargo" );

   /* Special case mission cargo. */
   if (player.p->commodities[pos].id != 0) {
      if (!dialogue_YesNo( "Abort Mission",
               "Are you sure you want to abort this mission?" ))
         return;

      /* Get the mission. */
      f = 0;
      for (i=0; i<MISSION_MAX; i++) {
         for (j=0; j<player_missions[i].ncargo; j++) {
            if (player_missions[i].cargo[j] == player.p->commodities[pos].id) {
               f = 1;
               break;
            }
         }
         if (f==1)
            break;
      }
      if (!f) {
         WARN("Cargo '%d' does not belong to any active mission.",
               player.p->commodities[pos].id);
         return;
      }
      misn = &player_missions[i];

      /* We run the "abort" function if it's found. */
      ret = misn_tryRun( misn, "abort" );

      /* Now clean up mission. */
      if (ret != 2) {
         mission_cleanup( misn );
         memmove( misn, &player_missions[i+1],
               sizeof(Mission) * (MISSION_MAX-i-1) );
         memset( &player_missions[MISSION_MAX-1], 0, sizeof(Mission) );
      }

      /* Reset markers. */
      mission_sysMark();

      /* Reset claims. */
      claim_activateAll();

      /* Regenerate list. */
      mission_menu_genList( info_windows[ INFO_WIN_MISN ] ,0);
   }
   else {
      /* Remove the cargo */
      commodity_Jettison( player.p->id, player.p->commodities[pos].commodity,
            player.p->commodities[pos].quantity );
      pilot_cargoRm( player.p, player.p->commodities[pos].commodity,
            player.p->commodities[pos].quantity );
   }

   /* We reopen the menu to recreate the list now. */
   ship_update( info_windows[ INFO_WIN_SHIP ] );
   cargo_genList( wid );
}
Exemplo n.º 13
0
int
main(int argc, char *argv[])
{
	int r;

	char *data_file = NULL;
	char *save_file = NULL;

	int map_generator = 0;


	log_set_file(stdout);

	init_config_data();

	//- read config data
	int screen_width = get_config_int(CONFIG_SCREEN_WIDTH, DEFAULT_SCREEN_WIDTH);
	int screen_height = get_config_int(CONFIG_SCREEN_HEIGHT, DEFAULT_SCREEN_HEIGHT);
	int fullscreen = get_config_bool(CONFIG_FULLSCREEN, 0);
	int log_level = get_config_int(CONFIG_LOGGLEVEL, DEFAULT_LOG_LEVEL);
	enum_lng_t language = str_to_lagEnum((char *)get_config_string(CONFIG_LANGUAGE, "EN"));
	int play_midi = get_config_bool(CONFIG_MUSIC, 1);
	int play_SFX = get_config_bool(CONFIG_SFX, 1);
	int volume = get_config_int(CONFIG_VOLUME, 75);

	//- read command line parameters
	int opt;
	while (1) {
		opt = getopt(argc, argv, "d:fg:hl:r:t:s:");
		if (opt < 0) break;

		switch (opt) {
		case 'd':
			{
				int d = atoi(optarg);
				if (d >= 0 && d < LOG_LEVEL_MAX) {
					log_level = d;
				}
			}
			break;
		case 'f':
			fullscreen = 1;
			break;
		case 'g':
			data_file = (char *)malloc(strlen(optarg)+1);
			if (data_file == NULL) exit(EXIT_FAILURE);
			strcpy(data_file, optarg);
			break;
		case 'h':
			fprintf(stdout, HELP, argv[0]);
			exit(EXIT_SUCCESS);
			break;
		case 'l':
			save_file = (char *)malloc(strlen(optarg)+1);
			if (save_file == NULL) exit(EXIT_FAILURE);
			strcpy(save_file, optarg);
			break;
		case 'r':
			{
				char *hstr = strchr(optarg, 'x');
				if (hstr == NULL) {
					fprintf(stderr, USAGE, argv[0]);
					exit(EXIT_FAILURE);
				}
				screen_width = atoi(optarg);
				screen_height = atoi(hstr+1);
			}
			break;
		case 't':
			map_generator = atoi(optarg);
			break;
		case 's':
			{
				char *  tmp_language_str = (char *) malloc(strlen(optarg) + 1);
				if (tmp_language_str != NULL)
				{
					strcpy(tmp_language_str, optarg);
					language = str_to_lagEnum(tmp_language_str);
				}
			}
			break;
		default:
			fprintf(stderr, USAGE, argv[0]);
			exit(EXIT_FAILURE);
			break;
		}
	}

	/* Set up logging */
	log_set_level((log_level_t)log_level);

	LOGI("main", "freeserf %s", FREESERF_VERSION);

	/* load language */
	init_language_data(language);


	r = load_data_file(data_file);
	if (r < 0) {
		LOGE("main", "Could not load game data.");
		exit(EXIT_FAILURE);
	}

	free(data_file);

	gfx_data_fixup();

	LOGI("main", "SDL init...");

	r = sdl_init();
	if (r < 0) exit(EXIT_FAILURE);

	/* TODO move to right place */
	midi_play_track(MIDI_TRACK_0);
	audio_set_volume(volume);

	midi_enable(play_midi);
	sfx_enable(play_SFX);


	/*gfx_set_palette(DATA_PALETTE_INTRO);*/
	gfx_set_palette(DATA_PALETTE_GAME);

	LOGI("main", "SDL resolution %ix%i...", screen_width, screen_height);

	r = sdl_set_resolution(screen_width, screen_height, fullscreen);
	if (r < 0) exit(EXIT_FAILURE);

	game.map_generator = map_generator;

	/* Initialize global lookup tables */
	init_spiral_pattern();

	game_init();

	/* Initialize Missions*/
	init_mission("missions.xml");

	/* Initialize interface */
	interface_init(&interface);
	gui_object_set_size((gui_object_t *)&interface,
			    screen_width, screen_height);
	gui_object_set_displayed((gui_object_t *)&interface, 1);

	/* Either load a save game if specified or
	   start a new game. */
	if (save_file != NULL) {
		int r = game_load_save_game(save_file);
		if (r < 0) exit(EXIT_FAILURE);
		free(save_file);

		interface_set_player(&interface, 0);
	} else {
		int r = game_load_random_map(3, &interface.random);
		if (r < 0) exit(EXIT_FAILURE);

		/* Add default player */
		r = game_add_player(12, 64, 40, 40, 40);
		if (r < 0) exit(EXIT_FAILURE);

		interface_set_player(&interface, r);
	}

	viewport_map_reinit();

	if (save_file != NULL) {
		interface_close_game_init(&interface);
	}

	/* Start game loop */
	game_loop();

	LOGI("main", "Cleaning up...");

	/* Clean up */
	map_deinit();
	viewport_map_deinit();
	audio_cleanup();
	sdl_deinit();
	gfx_unload();
	language_cleanup();
	mission_cleanup();
	config_cleanup();

	return EXIT_SUCCESS;
}