/** * @brief Finishes the mission. * * @luaparam properly If true and the mission is unique it marks the mission * as completed. If false it deletes the mission but * doesn't mark it as completed. If the parameter isn't * passed it just ends the mission (without removing it * from the player's list of active missions). * @luafunc finish( properly ) */ static int misn_finish( lua_State *L ) { int b; Mission *cur_mission; if (lua_isboolean(L,1)) b = lua_toboolean(L,1); else { lua_pushstring(L, NLUA_DONE); lua_error(L); /* THERE IS NO RETURN */ return 0; } lua_pushboolean( L, 1 ); lua_setglobal( L, "__misn_delete" ); cur_mission = misn_getFromLua(L); if (b && mis_isFlag(cur_mission->data,MISSION_UNIQUE)) player_missionFinished( mission_getID( cur_mission->data->name ) ); lua_pushstring(L, NLUA_DONE); lua_error(L); /* shouldn't return */ return 0; }
/** * @brief Gets mission data from a name. */ MissionData* mission_getFromName( const char* name ) { int id; id = mission_getID( name ); if (id < 0) return NULL; return mission_get( id ); }
/** * @brief Checks to see if a mission meets the requirements. * * @param mission ID of the mission to check. * @param faction Faction of the current planet. * @param planet Name of the current planet. * @param sysname Name of the current system. * @return 1 if requirements are met, 0 if they aren't. */ static int mission_meetReq( int mission, int faction, const char* planet, const char* sysname ) { MissionData* misn; int c; misn = mission_get( mission ); if (misn == NULL) /* In case it doesn't exist */ return 0; /* If planet, must match planet. */ if ((misn->avail.planet != NULL) && (strcmp(misn->avail.planet,planet)!=0)) return 0; /* If system, must match system. */ if ((misn->avail.system != NULL) && (strcmp(misn->avail.system,sysname)!=0)) return 0; /* Match faction. */ if ((faction >= 0) && !mission_matchFaction(misn,faction)) return 0; /* Must not be already done or running if unique. */ if (mis_isFlag(misn,MISSION_UNIQUE) && (player_missionAlreadyDone(mission) || mission_alreadyRunning(misn))) return 0; /* Must meet Lua condition. */ if (misn->avail.cond != NULL) { c = cond_check(misn->avail.cond); if (c < 0) { WARN("Conditional for mission '%s' failed to run", misn->name); return 0; } else if (!c) return 0; } /* Must meet previous mission requirements. */ if ((misn->avail.done != NULL) && (player_missionAlreadyDone( mission_getID(misn->avail.done) ) == 0)) return 0; return 1; }
/** * @brief Checks to see if player has done a mission. * * @usage if player.misnDone( "The Space Family" ) then -- Player finished mission * * @luaparam name Name of the mission to check. * @luareturn true if mission was finished, false if it wasn't. * @luafunc misnDone( name ) */ static int playerL_misnDone( lua_State *L ) { const char *str; int id; /* Handle parameters. */ str = luaL_checkstring(L, 1); /* Get mission ID. */ id = mission_getID( str ); if (id == -1) { NLUA_ERROR(L, "Mission '%s' not found in stack", str); return 0; } return player_missionAlreadyDone( id ); }
/** * @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; }
/** * @brief Finishes the mission. * * @luaparam properly If true and the mission is unique it marks the mission * as completed. If false it deletes the mission but * doesn't mark it as completed. If the parameter isn't * passed it just ends the mission. * @luafunc finish( properly ) */ static int misn_finish( lua_State *L ) { int b; if (lua_isboolean(L,1)) b = lua_toboolean(L,1); else { lua_pushstring(L, "Mission Done"); lua_error(L); /* THERE IS NO RETURN */ return 0; } misn_delete = 1; if (b && mis_isFlag(cur_mission->data,MISSION_UNIQUE)) player_missionFinished( mission_getID( cur_mission->data->name ) ); lua_pushstring(L, "Mission Done"); lua_error(L); /* shouldn't return */ return 0; }
/** * @brief Parses the actual individual mission nodes. * * @param parent Parent node to parse. * @return 0 on success. */ static int missions_parseActive( xmlNodePtr parent ) { Mission *misn; MissionData *data; int m, i; char *buf; char *title; const char **items; int nitems; int id, sys, type; StarSystem *ssys; xmlNodePtr node, cur, nest; m = 0; /* start with mission 0 */ node = parent->xmlChildrenNode; do { if (xml_isNode(node,"mission")) { misn = player_missions[m]; /* process the attributes to create the mission */ xmlr_attr(node,"data",buf); data = mission_get(mission_getID(buf)); if (data == NULL) { WARN("Mission '%s' from savegame not found in game - ignoring.", buf); free(buf); continue; } else { if (mission_init( misn, data, 0, 0, NULL )) { WARN("Mission '%s' from savegame failed to load properly - ignoring.", buf); free(buf); continue; } misn->accepted = 1; } free(buf); /* this will orphan an identifier */ xmlr_attr(node,"id",buf); misn->id = atol(buf); free(buf); cur = node->xmlChildrenNode; do { xmlr_strd(cur,"title",misn->title); xmlr_strd(cur,"desc",misn->desc); xmlr_strd(cur,"reward",misn->reward); /* Get the markers. */ if (xml_isNode(cur,"markers")) { nest = cur->xmlChildrenNode; do { if (xml_isNode(nest,"marker")) { /* Get ID. */ xmlr_attr(nest,"id",buf); id = (buf != NULL) ? atoi(buf) : -1; if (buf != NULL) free(buf); /* Get type. */ xmlr_attr(nest,"type",buf); type = (buf != NULL) ? atoi(buf) : -1; if (buf != NULL) free(buf); /* Get system. */ ssys = system_get( xml_get( nest )); if (ssys == NULL) { WARN( "System Marker to '%s' does not exist", xml_get( nest ) ); continue; } sys = system_index( ssys ); mission_addMarker( misn, id, sys, type ); } } while (xml_nextNode(nest)); } /* Cargo. */ if (xml_isNode(cur,"cargos")) { nest = cur->xmlChildrenNode; do { if (xml_isNode(nest,"cargo")) mission_linkCargo( misn, xml_getLong(nest) ); } while (xml_nextNode(nest)); } /* OSD. */ if (xml_isNode(cur,"osd")) { xmlr_attr(cur,"nitems",buf); if (buf != NULL) { nitems = atoi(buf); free(buf); } else continue; xmlr_attr(cur,"title",title); items = malloc( nitems * sizeof(char*) ); i = 0; nest = cur->xmlChildrenNode; do { if (xml_isNode(nest,"msg")) { if (i > nitems) { WARN("Inconsistency with 'nitems' in savefile."); break; } items[i] = xml_get(nest); i++; } } while (xml_nextNode(nest)); /* Create the osd. */ misn->osd = osd_create( title, nitems, items, data->avail.priority ); free(items); free(title); /* Set active. */ xmlr_attr(cur,"active",buf); if (buf != NULL) { osd_active( misn->osd, atoi(buf) ); free(buf); } } /* Claims. */ if (xml_isNode(cur,"claims")) misn->claims = claim_xmlLoad( cur ); if (xml_isNode(cur,"lua")) /* start the unpersist routine */ nxml_unpersistLua( misn->L, cur ); } while (xml_nextNode(cur)); m++; /* next mission */ if (m >= MISSION_MAX) break; /* full of missions, must be an error */ } } while (xml_nextNode(node)); return 0; }