Example #1
0
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;
}
Example #3
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);
	}	
}