void mission_eval_goals() { int i, result, goal_changed = 0; // before checking whether or not we should evaluate goals, we should run through the events and // process any whose timestamp is valid and has expired. This would catch repeating events only for (i=0; i<Num_mission_events; i++) { if (Mission_events[i].formula != -1) { if ( !timestamp_valid(Mission_events[i].timestamp) || !timestamp_elapsed(Mission_events[i].timestamp) ){ continue; } // if we get here, then the timestamp on the event has popped -- we should reevaluate mission_process_event(i); } } if ( !timestamp_elapsed(Mission_goal_timestamp) ){ return; } // first evaluate the players goals for (i=0; i<Num_goals; i++) { // don't evaluate invalid goals if (Mission_goals[i].type & INVALID_GOAL){ continue; } if (Mission_goals[i].satisfied == GOAL_INCOMPLETE) { result = eval_sexp(Mission_goals[i].formula); if ( Sexp_nodes[Mission_goals[i].formula].value == SEXP_KNOWN_FALSE ) { goal_changed = 1; mission_goal_status_change( i, GOAL_FAILED ); } else if (result) { goal_changed = 1; mission_goal_status_change(i, GOAL_COMPLETE ); } // end if result // tell the player how to end the mission //if ( goal_changed && mission_evaluate_primary_goals() != PRIMARY_GOALS_INCOMPLETE ) { // HUD_sourced_printf(HUD_SOURCE_IMPORTANT, "Press %s to end mission and return to base", textify_scancode(Control_config[END_MISSION].key_id) ); //} } // end if goals[i].satsified != GOAL_COMPLETE } // end for // now evaluate any mission events for (i=0; i<Num_mission_events; i++) { if ( Mission_events[i].formula != -1 ) { // only evaluate this event if the timestamp is not valid. We do this since // we will evaluate repeatable events at the top of the file so we can get // the exact interval that the designer asked for. if ( !timestamp_valid( Mission_events[i].timestamp) ){ mission_process_event( i ); } } } if (The_mission.game_type & MISSION_TYPE_TRAINING){ Mission_goal_timestamp = timestamp(GOAL_TIMESTAMP_TRAINING); } else { Mission_goal_timestamp = timestamp(GOAL_TIMESTAMP); } if ( !hud_disabled() && hud_gauge_active(HUD_DIRECTIVES_VIEW) ) { mission_maybe_play_directive_success_sound(); } // update goal status if playing on a multiplayer standalone server if (Game_mode & GM_STANDALONE_SERVER){ std_multi_update_goals(); } }
void mission_eval_goals() { int i, result; // before checking whether or not we should evaluate goals, we should run through the events and // process any whose timestamp is valid and has expired. This would catch repeating events only for (i=0; i<Num_mission_events; i++) { if (Mission_events[i].formula != -1) { if ( !timestamp_valid(Mission_events[i].timestamp) || !timestamp_elapsed(Mission_events[i].timestamp) ){ continue; } // if we get here, then the timestamp on the event has popped -- we should reevaluate PROFILE("Repeating events", mission_process_event(i)); } } if ( !timestamp_elapsed(Mission_goal_timestamp) ){ return; } // first evaluate the players goals for (i=0; i<Num_goals; i++) { // don't evaluate invalid goals if (Mission_goals[i].type & INVALID_GOAL){ continue; } if (Mission_goals[i].satisfied == GOAL_INCOMPLETE) { result = eval_sexp(Mission_goals[i].formula); if ( Sexp_nodes[Mission_goals[i].formula].value == SEXP_KNOWN_FALSE ) { mission_goal_status_change( i, GOAL_FAILED ); } else if (result) { mission_goal_status_change(i, GOAL_COMPLETE ); } // end if result } // end if goals[i].satsified != GOAL_COMPLETE } // end for // now evaluate any mission events for (i=0; i<Num_mission_events; i++) { if ( Mission_events[i].formula != -1 ) { // only evaluate this event if the timestamp is not valid. We do this since // we will evaluate repeatable events at the top of the file so we can get // the exact interval that the designer asked for. if ( !timestamp_valid( Mission_events[i].timestamp) ){ PROFILE("Nonrepeating events", mission_process_event( i )); } } } // send and remaining sexp data to the clients if (MULTIPLAYER_MASTER) { multi_sexp_flush_packet(); } if (The_mission.game_type & MISSION_TYPE_TRAINING){ Mission_goal_timestamp = timestamp(GOAL_TIMESTAMP_TRAINING); } else { Mission_goal_timestamp = timestamp(GOAL_TIMESTAMP); } if ( !hud_disabled() && hud_gauge_active(HUD_DIRECTIVES_VIEW) ) { mission_maybe_play_directive_success_sound(); } // update goal status if playing on a multiplayer standalone server if (Game_mode & GM_STANDALONE_SERVER){ std_multi_update_goals(); } Snapshot_all_events = false; }
// function which evaluates and processes the given event void mission_process_event( int event ) { int store_flags = Mission_events[event].flags; int store_formula = Mission_events[event].formula; int store_result = Mission_events[event].result; int store_count = Mission_events[event].count; int result, sindex; Directive_count = 0; Event_index = event; sindex = Mission_events[event].formula; result = Mission_events[event].result; // if chained, insure that previous event is true and next event is false if (Mission_events[event].chain_delay >= 0) { // this indicates it's chained if (event > 0){ if (!Mission_events[event - 1].result || ((fix) Mission_events[event - 1].timestamp + i2f(Mission_events[event].chain_delay) > Missiontime)){ sindex = -1; // bypass evaluation } } if ((event < Num_mission_events - 1) && Mission_events[event + 1].result && (Mission_events[event + 1].chain_delay >= 0)){ sindex = -1; // bypass evaluation } } if (sindex >= 0) { Sexp_useful_number = 1; result = eval_sexp(sindex); // if the directive count is a special value, deal with that first. Mark the event as a special // event, and unmark it when the directive is true again. if ( (Directive_count == DIRECTIVE_WING_ZERO) && !(Mission_events[event].flags & MEF_DIRECTIVE_SPECIAL) ) { // make it special - which basically just means that its true until the next wave arrives mission_event_set_directive_special(event); Directive_count = 0; } else if ( (Mission_events[event].flags & MEF_DIRECTIVE_SPECIAL) && Directive_count > 1 ) { // make it non special mission_event_unset_directive_special(event); } if (Mission_events[event].count || (Directive_count > 1)){ Mission_events[event].count = Directive_count; } if (Sexp_useful_number){ Mission_events[event].flags |= MEF_CURRENT; } } Event_index = 0; Mission_events[event].result = result; // if the sexpression is known false, then no need to evaluate anymore if ((sindex >= 0) && (Sexp_nodes[sindex].value == SEXP_KNOWN_FALSE)) { Mission_events[event].timestamp = (int) Missiontime; Mission_events[event].satisfied_time = Missiontime; Mission_events[event].repeat_count = -1; Mission_events[event].formula = -1; return; } if (result && !Mission_events[event].satisfied_time) { Mission_events[event].satisfied_time = Missiontime; if ( Mission_events[event].objective_text ) { Mission_directive_sound_timestamp = timestamp(DIRECTIVE_SOUND_DELAY); } } // decrement the repeat count. When at 0, don't eval this function anymore if ( result || timestamp_valid(Mission_events[event].timestamp) ) { Mission_events[event].repeat_count--; if ( Mission_events[event].repeat_count <= 0 ) { Mission_events[event].timestamp = (int)Missiontime; Mission_events[event].formula = -1; if(Game_mode & GM_MULTIPLAYER){ // squad war multi_team_maybe_add_score((int)(Mission_events[event].score * scoring_get_scale_factor()), Mission_events[event].team); } else { // deal with the player's score Player->stats.m_score += (int)(Mission_events[event].score * scoring_get_scale_factor()); } } else { // set the timestamp to time out 'interval' seconds in the future. We must also reset the // value at the sexpresion node to unknown so that it will get reevaled Mission_events[event].timestamp = timestamp( Mission_events[event].interval * 1000 ); // Sexp_nodes[Mission_events[event].formula].value = SEXP_UNKNOWN; } } // see if anything has changed if(MULTIPLAYER_MASTER && ((store_flags != Mission_events[event].flags) || (store_formula != Mission_events[event].formula) || (store_result != Mission_events[event].result) || (store_count != Mission_events[event].count)) ){ send_event_update_packet(event); } }