// 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);
	}
}
Пример #2
0
// 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);
	}	
}