/** * @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; }
int mission_run() { // current element struct _mission_element *el = NULL; if ((el = mission_get()) == NULL) { // TODO do something special like a waiting circle before ending the mission ? return false; // end of mission } bool el_running = false; switch (el->type) { case MissionWP: el_running = mission_nav_wp(&(el->element.mission_wp)); break; case MissionCircle: el_running = mission_nav_circle(&(el->element.mission_circle)); break; case MissionSegment: el_running = mission_nav_segment(&(el->element.mission_segment)); break; case MissionPath: el_running = mission_nav_path(&(el->element.mission_path)); break; case MissionCustom: el_running = mission_nav_custom(&(el->element.mission_custom), mission.element_time < dt_navigation); break; default: // invalid type or pattern not yet handled break; } // increment element_time mission.element_time += dt_navigation; // test if element is finished or element time is elapsed if (!el_running || (el->duration > 0. && mission.element_time >= el->duration)) { // reset timer mission.element_time = 0.; // go to next element mission.current_idx = (mission.current_idx + 1) % MISSION_ELEMENT_NB; } return true; }
/** * @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; }
int mission_run() { // current element struct _mission_element *el = NULL; if ((el = mission_get()) == NULL) { mission.element_time = 0; mission.current_idx = 0; return FALSE; // end of mission } bool_t el_running = FALSE; switch (el->type) { case MissionWP: el_running = mission_nav_wp(el); break; case MissionCircle: el_running = mission_nav_circle(el); break; case MissionSegment: el_running = mission_nav_segment(el); break; case MissionPath: el_running = mission_nav_path(el); break; default: // invalid type or pattern not yet handled break; } // increment element_time mission.element_time += dt_navigation; if (!el_running) { // reset timer mission.element_time = 0.; // go to next element mission.current_idx = (mission.current_idx + 1) % MISSION_ELEMENT_NB; } return TRUE; }
/** * @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; }