Example #1
0
void MonsterController::pre_step(GameState* gs) {
	perf_timer_begin(FUNCNAME);

	CollisionAvoidance& coll_avoid = gs->collision_avoidance();
	PlayerInst* local_player = gs->local_player();
	std::vector<EnemyOfInterest> eois;

	players = gs->players_in_level();

	//Update 'mids' to only hold live objects
	std::vector<obj_id> mids2;
	mids2.reserve(mids.size());
	mids.swap(mids2);

	for (int i = 0; i < mids2.size(); i++) {
		EnemyInst* e = (EnemyInst*)gs->get_instance(mids2[i]);
		if (e == NULL)
			continue;
		EnemyBehaviour& eb = e->behaviour();
		eb.step();

		//Add live instances back to monster id list
		mids.push_back(mids2[i]);

		int closest_player_index = find_player_to_target(gs, e);

		if (eb.current_action == EnemyBehaviour::INACTIVE
				&& e->cooldowns().is_hurting()) {
			eb.current_action = EnemyBehaviour::CHASING_PLAYER;
		}
		if (closest_player_index == -1
				&& eb.current_action == EnemyBehaviour::CHASING_PLAYER) {
			eb.current_action = EnemyBehaviour::INACTIVE;
			e->target() = NONE;
		}

		if (eb.current_action == EnemyBehaviour::CHASING_PLAYER)
			eois.push_back(
					EnemyOfInterest(e, closest_player_index,
							inst_distance(e, players[closest_player_index])));
		else if (eb.current_action == EnemyBehaviour::INACTIVE)
			monster_wandering(gs, e);
		else
			//if (eb.current_action == EnemyBehaviour::FOLLOWING_PATH)
			monster_follow_path(gs, e);
	}

	set_monster_headings(gs, eois);

	//Update player positions for collision avoidance simulator
	for (int i = 0; i < players.size(); i++) {
		PlayerInst* p = players[i];
		coll_avoid.set_position(p->collision_simulation_id(), p->x, p->y);
	}

	for (int i = 0; i < mids.size(); i++) {
		EnemyInst* e = (EnemyInst*)gs->get_instance(mids[i]);
		lua_State* L = gs->luastate();
		lua_gameinst_callback(L, e->etype().step_event.get(L), e);
		update_velocity(gs, e);
		simul_id simid = e->collision_simulation_id();
		coll_avoid.set_position(simid, e->rx, e->ry);
		coll_avoid.set_preferred_velocity(simid, e->vx, e->vy);
	}

	coll_avoid.step();

	for (int i = 0; i < mids.size(); i++) {
		EnemyInst* e = (EnemyInst*)gs->get_instance(mids[i]);
		update_position(gs, e);
	}

	perf_timer_end(FUNCNAME);
}