Пример #1
0
	void World::updateNaviMap(bool full_recompute) {
		FWK_PROFILE("updateNaviMap");
			
		//TODO: what about static entities that are added during the game?

		if(full_recompute) {
			vector<IBox> bboxes, blockers;
			bboxes.reserve(m_tile_map.size() + m_entity_map.size());

			for(int n = 0; n < m_tile_map.size(); n++) {
				const Tile *tile = m_tile_map[n].ptr;
				if(!tile || !Flags::test(tile->flags(), Flags::all | Flags::colliding))
					continue;

				bool is_walkable = Flags::test(tile->flags(), Flags::walkable_tile | Flags::wall_tile);
				(is_walkable? bboxes : blockers).push_back((IBox)m_tile_map[n].bbox);
			}


			for(int n = 0; n < m_entity_map.size(); n++)
				if(m_entity_map[n].ptr && Flags::test(m_entity_map[n].flags, Flags::static_entity | Flags::colliding))
					blockers.push_back(enclosingIBox(m_entity_map[n].ptr->boundingBox()));

			NaviHeightmap heightmap(m_tile_map.dimensions());
			heightmap.update(bboxes, blockers);
			//heightmap.saveLevels();
			//heightmap.printInfo();

			for(int m = 0; m < (int)m_navi_maps.size(); m++) {
				m_navi_maps[m].update(heightmap);
				//m_navi_maps[m].printInfo();
			}
		}

		for(int m = 0; m < (int)m_navi_maps.size(); m++) {
			NaviMap &navi_map = m_navi_maps[m];
			navi_map.removeColliders();

			for(int n = 0; n < m_entity_map.size(); n++) {
				auto &object = m_entity_map[n];
				if(!object.ptr)
					continue;

				if(Flags::test(object.flags, Flags::dynamic_entity | Flags::colliding)) {
					const IBox &box = enclosingIBox(object.ptr->boundingBox());
					navi_map.addCollider(box, n);
				}
			}
			navi_map.updateReachability();
		}
	}
Пример #2
0
	bool Actor::handleOrder(TrackOrder &order, EntityEvent event, const EntityEventParams &params) {
		if(event == EntityEvent::init_order || event == EntityEvent::think) {
			order.m_time_for_update -= timeDelta();
			const Entity *target = refEntity(order.m_target);
			if(!target)
				return false;

			if(order.m_time_for_update < 0.0f) {
				fixPosition();

				int3 cur_pos = (int3)pos();

				int3 target_pos;
				FBox target_box = target->boundingBox();

				if(!world()->findClosestPos(target_pos, cur_pos, enclosingIBox(target_box), ref()))
					return failOrder();

				order.m_path_pos = PathPos();
				if(!world()->findPath(order.m_path, cur_pos, target_pos, ref()))
					return failOrder();
				order.m_time_for_update = 0.25f;
			}
			
			if(distance(boundingBox(), target->boundingBox()) <= order.m_min_distance)
				return false;

			if(event == EntityEvent::init_order) {
				if(order.m_please_run && m_proto.simpleAnimId(Action::run, m_stance) == -1)
					order.m_please_run = 0;

				if(!animate(order.m_please_run? Action::run : Action::walk))
					return failOrder();
			}

			FollowPathResult result = order.needCancel()? FollowPathResult::finished :
				followPath(order.m_path, order.m_path_pos, order.m_please_run);	

			if(result != FollowPathResult::moved)
				return false;
		}
		
		if(order.m_path.length(order.m_path_pos) > 1.0f) {
			if(event == EntityEvent::anim_finished && m_stance == Stance::crouch) {
				animate(m_action);
			}
			if(event == EntityEvent::step) {
				SurfaceId standing_surface = surfaceUnder();
				playSound(m_proto.step_sounds[m_stance][standing_surface], pos());
			}
		}

		return true;
	}