// 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; bool bump_timestamp = false; Log_event = false; 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 // What everyone expected the chaining behavior to be, as specified in Karajorma's original fix to Mantis #82 if (Alternate_chaining_behavior) { if (event > 0){ if (!Mission_events[event - 1].result || ((fix) Mission_events[event - 1].satisfied_time + i2f(Mission_events[event].chain_delay) > Missiontime)){ sindex = -1; // bypass evaluation } } } // Volition's original chaining behavior as used in retail and demonstrated in e.g. btm-01.fsm (or btm-01.fs2 in the Port) else { 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; if (Snapshot_all_events || Mission_events[event].mission_log_flags != 0) { Log_event = true; Current_event_log_buffer = &Mission_events[event].event_log_buffer; Current_event_log_variable_buffer = &Mission_events[event].event_log_variable_buffer; Current_event_log_argument_buffer = &Mission_events[event].event_log_argument_buffer; } 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; } if ((Mission_events[event].mission_log_flags != 0) || Snapshot_all_events){ maybe_write_to_event_log(result); } } Log_event = false; Event_index = -1; 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; // _argv[-1] - repeat_count of -1 would mean repeat indefinitely, so set to 0 instead. Mission_events[event].repeat_count = 0; 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 trigger count. When at 0, set the repeat count to 0 so we don't eval this function anymore if (result && (Mission_events[event].trigger_count != 0) && (Mission_events[event].flags & MEF_USING_TRIGGER_COUNT) ) { if (Mission_events[event].trigger_count > 0) Mission_events[event].trigger_count--; if (Mission_events[event].trigger_count == 0) { Mission_events[event].repeat_count = 0; } else { bump_timestamp = true; } } // decrement the repeat count. When at 0, don't eval this function anymore if ( result || timestamp_valid(Mission_events[event].timestamp) ) { // _argv[-1] - negative repeat count means repeat indefinitely. if ( Mission_events[event].repeat_count > 0 ) 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){ // multiplayer missions (scoring is scaled in the multi_team_maybe_add_score() function) multi_team_maybe_add_score(Mission_events[event].score, Mission_events[event].team); multi_player_maybe_add_score(Mission_events[event].score, Mission_events[event].team); } else { // deal with the player's score Player->stats.m_score += (int)(Mission_events[event].score * scoring_get_scale_factor()); } } // Set the timestamp for the next check on this event unless we only have a trigger count and no repeat count and // this event didn't trigger this frame. else if (bump_timestamp || (!((Mission_events[event].repeat_count == -1) && (Mission_events[event].flags & MEF_USING_TRIGGER_COUNT) && (Mission_events[event].trigger_count != 0)))) { // set the timestamp to time out 'interval' seconds in the future. Mission_events[event].timestamp = timestamp( Mission_events[event].interval * 1000 ); } } // 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); } }
// 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); } }