void add_tooltip(const SDL_Rect& rect, const std::string& message, const std::string& action)
{
	for(std::vector<tooltip>::iterator i = tips.begin(); i != tips.end(); ++i) {
		if(rects_overlap(i->rect,rect)) {
			*i = tooltip(rect, message, action);
			return;
		}
	}

	tips.push_back(tooltip(rect, message, action));
	current_tooltip = tips.end();
}
void clear_tooltips(const SDL_Rect& rect)
{
	for(std::vector<tooltip>::iterator i = tips.begin(); i != tips.end(); ) {
		if(rects_overlap(i->rect,rect)) {
			if (i==current_tooltip) {
				clear_tooltip();
			}
			i = tips.erase(i);
			current_tooltip = tips.end();
		} else {
			++i;
		}
	}
}
Exemple #3
0
// @draw_area_unit[OUT]: units_from_rect fill valid units to it.
// return value
//  size of filled units
// remark:
//  1)unit overlapped multi-grid, return center loc only
size_t base_map::units_from_rect(base_unit** draw_area_unit, const rect_of_hexes& draw_area_rect)
{
	size_t draw_area_unit_size = 0;

	int draw_area_min_x = std::max(0, draw_area_rect.left);
	int draw_area_max_x = std::min(gmap_.w() - 1, draw_area_rect.right);
	int draw_area_min_y[2], draw_area_max_y[2];
	draw_area_min_y[0] = std::max(0, draw_area_rect.top[0]);
	draw_area_min_y[1] = std::max(0, draw_area_rect.top[1]);
	draw_area_max_y[0] = std::min(gmap_.h() - 1, draw_area_rect.bottom[0]);
	draw_area_max_y[1] = std::min(gmap_.h() - 1, draw_area_rect.bottom[1]);

	if (consistent_) {
		std::set<const base_unit*> calculated;
		for (int x = draw_area_min_x; x <= draw_area_max_x; x ++) {
			for (int y = draw_area_min_y[x & 1]; y <= draw_area_max_y[x & 1]; y ++) {
				base_unit* u = coor_map_[index(x, y)].base;
				if (u && !calculated.count(u)) {
					calculated.insert(u);
					draw_area_unit[draw_area_unit_size ++] = u;
				}
				u = coor_map_[index(x, y)].overlay;
				if (u && !calculated.count(u)) {
					calculated.insert(u);
					draw_area_unit[draw_area_unit_size ++] = u;
				}
				
			}
		}
	} else {
		display& disp = controller_.get_display();
		int zoom = disp.hex_size();
		SDL_Rect rect = create_rect(draw_area_min_x * zoom, draw_area_min_y[0] * zoom,
			(draw_area_max_x - draw_area_min_x + 1) * zoom,
			(draw_area_max_y[0] - draw_area_min_y[0] + 1) * zoom);
		for (int i = 0; i < map_vsize_; i ++) {
			base_unit* u = map_[i];
			if (rects_overlap(u->get_rect(), rect)) {
				draw_area_unit[draw_area_unit_size ++] = u;
			}
		}
	}

	return draw_area_unit_size;
}
Exemple #4
0
bool effect::render()
{
	if(disp == NULL) {
		return false;
	}

	if(loc_.x != -1 && loc_.y != -1) {
		if(disp->shrouded(loc_)) {
			return false;
		} else {
			// The location of a halo is an x,y value and not a map location.
			// This means when a map is zoomed, the halo's won't move,
			// This glitch is most visible on [item] haloes.
			// This workaround always recalculates the location of the halo
			// (item haloes have a location parameter to hide them under the shroud)
			// and reapplies that location.
			// It might be optimized by storing and comparing the zoom value.
			set_location(
				disp->get_location_x(loc_) + disp->hex_size() / 2,
				disp->get_location_y(loc_) + disp->hex_size() / 2);
		}
	}

	images_.update_last_draw_time();
	surf_.assign(image::get_image(current_image(),image::SCALED_TO_ZOOM));
	if(surf_ == NULL) {
		return false;
	}
	if(orientation_ == HREVERSE || orientation_ == HVREVERSE) {
		surf_.assign(image::reverse_image(surf_));
	}
	if(orientation_ == VREVERSE || orientation_ == HVREVERSE) {
		surf_.assign(flop_surface(surf_));
	}

	const map_location zero_loc(0,0);
	const int screenx = disp->get_location_x(zero_loc);
	const int screeny = disp->get_location_y(zero_loc);

	const int xpos = x_ + screenx - surf_->w/2;
	const int ypos = y_ + screeny - surf_->h/2;

	SDL_Rect rect = create_rect(xpos, ypos, surf_->w, surf_->h);
	rect_ = rect;
	SDL_Rect clip_rect = disp->map_outside_area();

	// If rendered the first time, need to determine the area affected.
	// If a halo changes size, it is not updated.
	if(overlayed_hexes_.empty()) {
		rect_of_hexes hexes = disp->hexes_under_rect(rect);
		rect_of_hexes::iterator i = hexes.begin(), end = hexes.end();
		for (;i != end; ++i) {
			overlayed_hexes_.push_back(*i);
		}
	}

	if(rects_overlap(rect,clip_rect) == false) {
		buffer_.assign(NULL);
		return false;
	}

	surface screen = disp->get_screen_surface();

	const clip_rect_setter clip_setter(screen, &clip_rect);
	if(buffer_ == NULL || buffer_->w != rect.w || buffer_->h != rect.h) {
		SDL_Rect rect = rect_;
		buffer_.assign(get_surface_portion(screen,rect));
	} else {
		SDL_Rect rect = rect_;
		sdl_blit(screen,&rect,buffer_,NULL);
	}

	sdl_blit(surf_,NULL,screen,&rect);

	return true;
}
Exemple #5
0
void World::update(WorldState &state, float timeDelta) {
#ifdef AI_PLAYS_FOR_HUMAN
	float aiIdealDistanceToCoverHuman = state.ball.getCenter().y - state.human.getCenter().y;
	if (aiIdealDistanceToCoverHuman > PLAYER_SPEED * timeDelta) {
		state.human.speed.y = PLAYER_SPEED;
	} else if (aiIdealDistanceToCoverHuman < -PLAYER_SPEED * timeDelta) {
		state.human.speed.y = -PLAYER_SPEED;
	} else {
		state.human.speed.y = 0;
	}
#else
	//handle non-event-based input
	const Uint8 *keysDown = SDL_GetKeyboardState(nullptr);
	if (keysDown[SDL_SCANCODE_UP]) {
		state.human.speed.y = -PLAYER_SPEED;
	} else if (keysDown[SDL_SCANCODE_DOWN]) {
		state.human.speed.y = PLAYER_SPEED;
	} else {
		state.human.speed.y = 0;
	}
#endif

	//"ai" for opponent player
	float aiIdealDistanceToCover = state.ball.getCenter().y - state.opponent.getCenter().y;
	if (aiIdealDistanceToCover > PLAYER_SPEED * timeDelta) {
		state.opponent.speed.y = PLAYER_SPEED;
	} else if (aiIdealDistanceToCover < -PLAYER_SPEED * timeDelta) {
		state.opponent.speed.y = -PLAYER_SPEED;
	} else {
		state.opponent.speed.y = 0;
	}

	//simulate
	state.human.pos.y += state.human.speed.y * timeDelta;
	state.opponent.pos.y += state.opponent.speed.y * timeDelta;
	state.ball.pos.x += state.ball.speed.x * timeDelta;
	state.ball.pos.y += state.ball.speed.y * timeDelta;

	//fixup

	//FIXME ball can go so fast it will move past the paddles
	if (rects_overlap(state.human.pos.x, state.human.pos.y, state.human.size.x, state.human.size.y,
			state.ball.pos.x, state.ball.pos.y,
			state.ball.size.x * 2, state.ball.size.y)) {
		state.ball.speed.x = abs(state.ball.speed.x) * 1.1f;
		state.ball.pos.x = state.human.pos.x + state.human.size.x;
		std::cout << "Paddle collision (HUMAN) - ball speed is now " << state.ball.speed.x << std::endl;
	}
	if (rects_overlap(state.opponent.pos.x, state.opponent.pos.y, state.opponent.size.x, state.opponent.size.y,
			state.ball.pos.x - state.ball.size.x, state.ball.pos.y,
			state.ball.size.x * 2, state.ball.size.y)) {
		state.ball.speed.x = -abs(state.ball.speed.x) * 1.1f;
		state.ball.pos.x = state.opponent.pos.x - state.ball.size.x;
		std::cout << "Paddle collision (OPPON) - ball speed is now " << state.ball.speed.x << std::endl;
	}

	if (state.ball.pos.y < 0) {
		state.ball.speed.y *= -1;
		state.ball.pos.y = 0;
	} else if (state.ball.pos.y + state.ball.size.y > this->height) {
		state.ball.speed.y *= -1;
		state.ball.pos.y = this->height - state.ball.size.y;
	}

	if (state.human.pos.y < 0) {
		state.human.pos.y = 0;
	} else if (state.human.pos.y + state.human.size.y > this->height) {
		state.human.pos.y = this->height - state.human.size.y;
	}
	if (state.opponent.pos.y < 0) {
		state.opponent.pos.y = 0;
	} else if (state.opponent.pos.y + state.opponent.size.y > this->height) {
		state.opponent.pos.y = this->height - state.opponent.size.y;
	}

	if (state.ball.pos.x + state.ball.size.x < 0) {
		++state.opponentScore;
		std::cout << "AI player wins round! Score: " << state.humanScore 
			<< " | " << state.opponentScore << std::endl;
		startRound(state);
	} else if (state.ball.pos.x > width) {
		++state.humanScore;
		std::cout << "Human player wins round! Score: " << state.humanScore 
			<< " | " << state.opponentScore << std::endl;
		startRound(state);
	}
}
Exemple #6
0
bool widget::hidden() const
{
	return (state_ == HIDDEN || hidden_override_ || state_ == UNINIT
		|| (clip_ && !rects_overlap(clip_rect_, rect_)));
}