Exemplo n.º 1
0
void MapRenderer::renderOrthoLayer(const unsigned short layerdata[256][256]) {

	const Point upperleft = floor(screen_to_map(0, 0, shakycam.x, shakycam.y));

	short int startj = std::max(0, upperleft.y);
	short int starti = std::max(0, upperleft.x);
	const short max_tiles_width =  std::min(w, static_cast<short int>(starti + (VIEW_W / TILE_W) + 2 * tset.max_size_x));
	const short max_tiles_height = std::min(h, static_cast<short int>(startj + (VIEW_H / TILE_H) + 2 * tset.max_size_y));

	short int i;
	short int j;

	for (j = startj; j < max_tiles_height; j++) {
		Point p = map_to_screen(starti, j, shakycam.x, shakycam.y);
		p = center_tile(p);
		for (i = starti; i < max_tiles_width; i++) {

			if (const unsigned short current_tile = layerdata[i][j]) {
				Rect dest;
				dest.x = p.x - tset.tiles[current_tile].offset.x;
				dest.y = p.y - tset.tiles[current_tile].offset.y;
				tset.tiles[current_tile].tile->setDest(dest);
				render_device->render(tset.tiles[current_tile].tile);
			}
			p.x += TILE_W;
		}
	}
}
Exemplo n.º 2
0
/**
 * On mouseover, display NPC's name
 */
void NPCManager::renderTooltips(Point cam, Point mouse) {
	Point p;
	SDL_Rect r;
	TooltipData td;
	
	for(int i=0; i<npc_count; i++) {

		p = map_to_screen(npcs[i]->pos.x, npcs[i]->pos.y, cam.x, cam.y);
	
		r.w = npcs[i]->render_size.x;
		r.h = npcs[i]->render_size.y;
		r.x = p.x - npcs[i]->render_offset.x;
		r.y = p.y - npcs[i]->render_offset.y;
		
		if (isWithin(r, mouse)) {
		
			// adjust dest.y so that the tooltip floats above the item
			p.y -= tooltip_margin;
			
			td.num_lines = 1;
			td.colors[0] = FONT_WHITE;
			td.lines[0] = npcs[i]->name;
			
			tip->render(td, p, STYLE_TOPLABEL);
		}
	}
}
Exemplo n.º 3
0
void MapRenderer::drawRenderable(std::vector<Renderable>::iterator r_cursor) {
	if (r_cursor->image != NULL) {
		Rect dest;
		Point p = map_to_screen(r_cursor->map_pos.x, r_cursor->map_pos.y, shakycam.x, shakycam.y);
		dest.x = p.x - r_cursor->offset.x;
		dest.y = p.y - r_cursor->offset.y;
		render_device->render(*r_cursor, dest);
	}
}
Exemplo n.º 4
0
void MapIso::checkTooltip() {
	Point p;
	SDL_Rect r;
	Point tip_pos;
	bool skip;
	
	for (int i=0; i<event_count; i++) {
		skip = false;
		if(!isActive(i)) skip = true;

		if (skip) continue;

		p = map_to_screen(events[i].location.x * UNITS_PER_TILE + UNITS_PER_TILE/2, events[i].location.y * UNITS_PER_TILE + UNITS_PER_TILE/2, cam.x, cam.y);
		r.x = p.x + events[i].hotspot.x;
		r.y = p.y + events[i].hotspot.y;
		r.h = events[i].hotspot.h;
		r.w = events[i].hotspot.w;
		 
		// DEBUG TOOL: outline hotspot
		/*
		SDL_Rect screen_size;
		screen_size.x = screen_size.y = 0;
		screen_size.w = VIEW_W;
		screen_size.h = VIEW_H;
		Point pixpos;
		pixpos.x = r.x;
		pixpos.y = r.y;
		if (isWithin(screen_size, pixpos))
			drawPixel(screen, r.x, r.y, 255);
		pixpos.x = r.x+r.w;
		pixpos.y = r.y;
		if (isWithin(screen_size, pixpos))
			drawPixel(screen, r.x+r.w, r.y, 255);
		pixpos.x = r.x;
		pixpos.y = r.y+r.h;
		if (isWithin(screen_size, pixpos))
			drawPixel(screen, r.x, r.y+r.h, 255);
		pixpos.x = r.x+r.w;
		pixpos.y = r.y+r.h;
		if (isWithin(screen_size, pixpos))
			drawPixel(screen, r.x+r.w, r.y+r.h, 255);
		*/
		
		if (isWithin(r,inp->mouse) && events[i].tooltip != "") {
			TooltipData td;
			td.num_lines = 1;
			td.colors[0] = FONT_WHITE;
			td.lines[0] = events[i].tooltip;
			
			tip_pos.x = r.x + r.w/2;
			tip_pos.y = r.y;
			tip->render(td, tip_pos, STYLE_TOPLABEL);
		}
	}
}
Exemplo n.º 5
0
/**
 * Click on the map to pick up loot.  We need the camera position to translate
 * screen coordinates to map locations.
 */
ItemStack LootManager::checkPickup(Point mouse, FPoint cam, FPoint hero_pos, MenuInventory *inv) {
	Rect r;
	ItemStack loot_stack;

	// check left mouse click
	if (!NO_MOUSE) {
		// I'm starting at the end of the loot list so that more recently-dropped
		// loot is picked up first.  If a player drops several loot in the same
		// location, picking it back up will work like a stack.
		std::vector<Loot>::iterator it;
		for (it = loot.end(); it != loot.begin(); ) {
			--it;

			// loot close enough to pickup?
			if (fabs(hero_pos.x - it->pos.x) < INTERACT_RANGE && fabs(hero_pos.y - it->pos.y) < INTERACT_RANGE && !it->isFlying()) {
				Point p = map_to_screen(it->pos.x, it->pos.y, cam.x, cam.y);

				r.x = p.x - TILE_W_HALF;
				r.y = p.y - TILE_H_HALF;
				r.w = TILE_W;
				r.h = TILE_H;

				// clicked in pickup hotspot?
				if (isWithin(r, mouse)) {
					curs->setCursor(CURSOR_INTERACT);
					if (inpt->pressing[MAIN1] && !inpt->lock[MAIN1]) {
						inpt->lock[MAIN1] = true;
						if (!it->stack.empty()) {
							if (!(inv->full(it->stack.item))) {
								loot_stack = it->stack;
								it = loot.erase(it);
								return loot_stack;
							}
							else {
								full_msg = true;
							}
						}
					}
				}
			}
		}
	}

	// check pressing Enter/Return
	if (inpt->pressing[ACCEPT] && !inpt->lock[ACCEPT]) {
		loot_stack = checkNearestPickup(hero_pos, inv);
		if (!loot_stack.empty()) {
			inpt->lock[ACCEPT] = true;
		}
	}

	return loot_stack;
}
Exemplo n.º 6
0
void CombatText::addMessage(std::string message, Point location, int displaytype) {
    if (COMBAT_TEXT) {
	    Point p = map_to_screen(location.x - UNITS_PER_TILE, location.y - UNITS_PER_TILE, cam.x, cam.y);
        Combat_Text_Item *c = new Combat_Text_Item();
        WidgetLabel *label = new WidgetLabel();
        c->pos = p;
        c->label = label;
        c->text = message;
        c->lifespan = duration;
        c->displaytype = displaytype;
        combat_text.push_back(*c);
        delete c;
    }
}
Exemplo n.º 7
0
void MapRenderer::checkNearestEvent() {
	if (NO_MOUSE) show_tooltip = false;

	std::vector<Event>::iterator it;
	std::vector<Event>::iterator nearest = events.end();
	float best_distance = std::numeric_limits<float>::max();

	// loop in reverse because we may erase elements
	for (it = events.end(); it != events.begin(); ) {
		--it;

		// skip inactive events
		if (!EventManager::isActive(*it)) continue;

		// skip events without hotspots
		if ((*it).hotspot.h == 0) continue;

		// skip events on cooldown
		if ((*it).cooldown_ticks != 0) continue;

		float distance = calcDist(cam, (*it).center);
		if ((((*it).reachable_from.w == 0 && (*it).reachable_from.h == 0) || isWithin((*it).reachable_from, floor(cam)))
				&& distance < INTERACT_RANGE && distance < best_distance) {
			best_distance = distance;
			nearest = it;
		}

	}

	if (nearest != events.end()) {
		if (NO_MOUSE || TOUCHSCREEN) {
			// new tooltip?
			createTooltip((*nearest).getComponent("tooltip"));
			tip_pos = map_to_screen((*nearest).center.x, (*nearest).center.y, shakycam.x, shakycam.y);
			if ((*nearest).getComponent("npc_hotspot")) {
				tip_pos.y -= npc_tooltip_margin;
			}
			else {
				tip_pos.y -= TILE_H;
			}
		}

		if (inpt->pressing[ACCEPT] && !inpt->lock[ACCEPT]) {
			if (inpt->pressing[ACCEPT]) inpt->lock[ACCEPT] = true;

			if(EventManager::executeEvent(*nearest))
				events.erase(nearest);
		}
	}
}
Exemplo n.º 8
0
void MapIso::checkEventClick() {
	Point p;
	SDL_Rect r;
	for(int i=0; i<event_count; i++) {
		p = map_to_screen(events[i].location.x * UNITS_PER_TILE + UNITS_PER_TILE/2, events[i].location.y * UNITS_PER_TILE + UNITS_PER_TILE/2, cam.x, cam.y);
		r.x = p.x + events[i].hotspot.x;
		r.y = p.y + events[i].hotspot.y;
		r.h = events[i].hotspot.h;
		r.w = events[i].hotspot.w;
		// execute if: EVENT IS ACTIVE && MOUSE IN HOTSPOT && HOTSPOT EXISTS && CLICKING && HERO WITHIN RANGE
		if (isActive(i) && isWithin(r, inp->mouse) && (events[i].hotspot.h != 0) && inp->pressing[MAIN1] && !inp->lock[MAIN1] && (abs(cam.x - events[i].location.x * UNITS_PER_TILE) < CLICK_RANGE && abs(cam.y - events[i].location.y * UNITS_PER_TILE) < CLICK_RANGE)) {
			inp->lock[MAIN1] = true;
			executeEvent(i);
		}
	}
}
Exemplo n.º 9
0
void MapRenderer::renderOrthoFrontObjects(std::vector<Renderable> &r) {

	short int i;
	short int j;
	Rect dest;
	std::vector<Renderable>::iterator r_cursor = r.begin();
	std::vector<Renderable>::iterator r_end = r.end();

	const Point upperleft = floor(screen_to_map(0, 0, shakycam.x, shakycam.y));

	short int startj = std::max(0, upperleft.y);
	short int starti = std::max(0, upperleft.x);
	const short max_tiles_width  = std::min(w, static_cast<short int>(starti + (VIEW_W / TILE_W) + 2 * tset.max_size_x));
	const short max_tiles_height = std::min(h, static_cast<short int>(startj + (VIEW_H / TILE_H) + 2 * tset.max_size_y));

	while (r_cursor != r_end && (int)(r_cursor->map_pos.y) < startj)
		++r_cursor;

	if (index_objectlayer >= layers.size())
		return;

	maprow *objectlayer = layers[index_objectlayer];
	for (j = startj; j < max_tiles_height; j++) {
		Point p = map_to_screen(starti, j, shakycam.x, shakycam.y);
		p = center_tile(p);
		for (i = starti; i<max_tiles_width; i++) {

			if (const unsigned short current_tile = objectlayer[i][j]) {
				dest.x = p.x - tset.tiles[current_tile].offset.x;
				dest.y = p.y - tset.tiles[current_tile].offset.y;
				tset.tiles[current_tile].tile->setDest(dest);
				render_device->render(tset.tiles[current_tile].tile);
			}
			p.x += TILE_W;

			while (r_cursor != r_end && (int)(r_cursor->map_pos.y) == j && (int)(r_cursor->map_pos.x) < i) // implicit floor
				++r_cursor;

			// some renderable entities go in this layer
			while (r_cursor != r_end && (int)(r_cursor->map_pos.y) == j && (int)(r_cursor->map_pos.x) == i) // implicit floor
				drawRenderable(r_cursor++);
		}
		while (r_cursor != r_end && (int)(r_cursor->map_pos.y) <= j) // implicit floor
			++r_cursor;
	}
}
Exemplo n.º 10
0
/**
 * Click on the map to pick up loot.  We need the camera position to translate
 * screen coordinates to map locations.  We need the hero position because
 * the hero has to be within range to pick up an item.
 */
ItemStack LootManager::checkPickup(Point mouse, Point cam, Point hero_pos, int &gold, bool inv_full) {
	Point p;
	SDL_Rect r;
	ItemStack loot_stack;
	gold = 0;	
	loot_stack.item = 0;
	loot_stack.quantity = 0;
	
	// I'm starting at the end of the loot list so that more recently-dropped
	// loot is picked up first.  If a player drops several loot in the same
	// location, picking it back up will work like a stack.
	for (int i=loot_count-1; i>=0; i--) {

		// loot close enough to pickup?
		if (abs(hero_pos.x - loot[i].pos.x) < LOOT_RANGE && abs(hero_pos.y - loot[i].pos.y) < LOOT_RANGE && !isFlying(i)) {

			p = map_to_screen(loot[i].pos.x, loot[i].pos.y, cam.x, cam.y);
				
			r.w = 32;
			r.h = 48;
			r.x = p.x - 16;
			r.y = p.y - 32;
		
			// clicked in pickup hotspot?
			if (mouse.x > r.x && mouse.x < r.x+r.w &&
				mouse.y > r.y && mouse.y < r.y+r.h) {
				
				if (loot[i].stack.item > 0 && !inv_full) {
					loot_stack = loot[i].stack;
					removeLoot(i);
					return loot_stack;
				}
				else if (loot[i].stack.item > 0) {
					full_msg = true;
				}
				else if (loot[i].gold > 0) {
					gold = loot[i].gold;
					removeLoot(i);

					return loot_stack;
				}
			}
		}
	}
	return loot_stack;
}
Exemplo n.º 11
0
int NPCManager::checkNPCClick(Point mouse, Point cam) {
	Point p;
	SDL_Rect r;
	for(int i=0; i<npc_count; i++) {

		p = map_to_screen(npcs[i]->pos.x, npcs[i]->pos.y, cam.x, cam.y);
	
		r.w = npcs[i]->render_size.x;
		r.h = npcs[i]->render_size.y;
		r.x = p.x - npcs[i]->render_offset.x;
		r.y = p.y - npcs[i]->render_offset.y;
		
		if (isWithin(r, mouse)) {
			return i;
		}
	}
	return -1;
}
Exemplo n.º 12
0
void CombatText::addMessage(int num, Point location, int displaytype, bool from_hero) {
	if (COMBAT_TEXT) {
		Combat_Text_Item *c = new Combat_Text_Item();
		WidgetLabel *label = new WidgetLabel();
		c->pos = map_to_screen(location.x - UNITS_PER_TILE, location.y - UNITS_PER_TILE, cam.x, cam.y);
		c->src_pos = location;
		c->label = label;
		c->from_hero = from_hero;

		std::stringstream ss;
		ss << num;
		c->text = ss.str();

		c->lifespan = duration;
		c->displaytype = displaytype;
		combat_text.push_back(*c);
		delete c;
	}
}
Exemplo n.º 13
0
Enemy* EnemyManager::enemyFocus(Point mouse, Point cam, bool alive_only) {
	Point p;
	SDL_Rect r;
	for(int i = 0; i < enemy_count; i++) {
		if(alive_only && (enemies[i]->stats.cur_state == ENEMY_DEAD || enemies[i]->stats.cur_state == ENEMY_CRITDEAD)) {
			continue;
		}
		p = map_to_screen(enemies[i]->stats.pos.x, enemies[i]->stats.pos.y, cam.x, cam.y);
	
		r.w = enemies[i]->getRender().src.w;
		r.h = enemies[i]->getRender().src.h;
		r.x = p.x - enemies[i]->getRender().offset.x;
		r.y = p.y - enemies[i]->getRender().offset.y;
		
		if (isWithin(r, mouse)) {
			Enemy *enemy = enemies[i];
			return enemy;
		}
	}
	return NULL;
}
Exemplo n.º 14
0
void CombatText::logic(const FPoint& _cam) {
	cam = _cam;

	for(std::vector<Combat_Text_Item>::iterator it = combat_text.begin(); it != combat_text.end(); ++it) {
		it->lifespan--;
		it->floating_offset += speed;

		Point scr_pos;
		scr_pos = map_to_screen(it->pos.x, it->pos.y, cam.x, cam.y);
		scr_pos.y -= static_cast<int>(it->floating_offset);

		it->label->setX(scr_pos.x);
		it->label->setY(scr_pos.y);
	}

	// delete expired messages
	while (combat_text.size() && combat_text.begin()->lifespan <= 0) {
		delete combat_text.begin()->label;
		combat_text.erase(combat_text.begin());
	}
}
Exemplo n.º 15
0
/**
 * Show all tooltips for loot on the floor
 */
void LootManager::renderTooltips(FPoint cam) {
	Point dest;

	std::vector<Loot>::iterator it;
	for (it = loot.end(); it != loot.begin(); ) {
		--it;

		if (it->on_ground) {
			Point p = map_to_screen(it->pos.x, it->pos.y, cam.x, cam.y);
			dest.x = p.x;
			dest.y = p.y + TILE_H_HALF;

			// adjust dest.y so that the tooltip floats above the item
			dest.y -= tooltip_margin;

			// set hitbox for mouse hover
			Rect hover;
			hover.x = p.x - TILE_W_HALF;
			hover.y = p.y - TILE_H_HALF;
			hover.w = TILE_W;
			hover.h = TILE_H;

			if (LOOT_TOOLTIPS || inpt->pressing[ALT] || isWithin(hover, inpt->mouse)) {
				// create tooltip data if needed
				if (it->tip.isEmpty()) {

					if (!it->stack.empty()) {
						it->tip = items->getShortTooltip(it->stack);
					}
				}

				tip->render(it->tip, dest, STYLE_TOPLABEL);

				// only display one tooltip if we got it from hovering
				if (!LOOT_TOOLTIPS && !inpt->pressing[ALT])
					break;
			}
		}
	}
}
Exemplo n.º 16
0
void CombatText::render() {
	for(std::vector<Combat_Text_Item>::iterator it = combat_text.begin(); it != combat_text.end(); ++it) {

		it->lifespan--;
		it->floating_offset += speed;

		Point scr_pos;
		scr_pos = map_to_screen(it->pos.x, it->pos.y, cam.x, cam.y);
		scr_pos.y -= it->floating_offset;

		it->label->set(scr_pos.x, scr_pos.y, JUSTIFY_CENTER, VALIGN_BOTTOM, it->text, msg_color[it->displaytype]);

		if (it->lifespan > 0)
			it->label->render();

	}
	// delete expired messages
	while (combat_text.size() && combat_text.begin()->lifespan <= 0) {
		delete combat_text.begin()->label;
		combat_text.erase(combat_text.begin());
	}
}
Exemplo n.º 17
0
void CombatText::render() {
	for(std::vector<Combat_Text_Item>::iterator it = combat_text.begin(); it != combat_text.end(); it++) {
		it->lifespan--;

		// check if we need to position the text relative to the map
		if (!it->from_hero) {
			it->ydelta += speed;
			it->pos = map_to_screen(it->src_pos.x - UNITS_PER_TILE, it->src_pos.y - UNITS_PER_TILE, cam.x, cam.y);
			it->pos.y -= it->ydelta;
		} else {
			it->pos.y -= speed;
		}

		it->label->set(it->pos.x, it->pos.y, JUSTIFY_CENTER, VALIGN_BOTTOM, it->text, msg_color[it->displaytype]);

		if (it->lifespan > 0)
			it->label->render();

	}
	// delete expired messages
	while (combat_text.size() > 0 && combat_text.begin()->lifespan <= 0) {
		combat_text.erase(combat_text.begin());
	}
}
Exemplo n.º 18
0
void ListWeatherCloud::renderSnow(){
	if (!spr_flake) return;
    int nr = 0;
    int i = 0;
    int j = 0;
    int r3 = 1; // changes type
    int r4 = 2;// changes offset
    int density = 3;

    Point p;
    FPoint fp; // needed to check if is_valid_position

    if (is_strong_rainfall){
        density = 2;
    }

    // initialize the flake_state Array, if it isn't yet
    if (!flakes_arr_initialized){

        flakes_arr_initialized = true;
        while (nr < MAX_NUMBER_OF_FLAKES){
            r3 = randBetween(0,6);
            r4 = randBetween(-2,2);
            flake_state[nr][0] = r3; // type, stays the same
            flake_state[nr][1] = r4; // offset x
            flake_state[nr][2] = 0; // dx
            flake_state[nr][3] = 0; // dy
            flake_state[nr][4] = randBetween(-2,2); // offset y
            flake_state[nr][5] = randBetween(0,6); // change offset, stays
            nr+=1;
        }

    }

    i = -RADIUS;
    j = -RADIUS;

    while(j < RADIUS){
        if (nr>=MAX_NUMBER_OF_FLAKES) nr=0;
        // update of position info should be rather slow...
          // otherwise the snowflakes appear to move with the hero
        if ((cycle_i % (RENDER_CHANGE_AFTER * 10) == 0) || mapr->map_change) {
            p_flakes = floor(mapr->cam);
        }
        spr_flake->setClipW(8);
        spr_flake->setClipH(10);
        spr_flake->setClipX(flake_state[nr][0]*9);

        // TODO: take into account wind direction (variable 'direction')
        p = map_to_screen(p_flakes.x + i, p_flakes.y + j, mapr->cam.x, mapr->cam.y);
        if ((cycle_i + flake_state[nr][5]) % RENDER_CHANGE_AFTER == 0) {
			flake_state[nr][1] = flake_state[nr][1] + randBetween(-2,2); // offset x
            flake_state[nr][2] = flake_state[nr][2] + randBetween(-1,1); // dx
            flake_state[nr][3] = flake_state[nr][3] + randBetween(-1,2); // dy
            flake_state[nr][4] = flake_state[nr][4] + randBetween(-2,2); // Offset y
        }

        spr_flake->setOffset(flake_state[nr][1],flake_state[nr][4]);
        spr_flake->setDestX(p.x + flake_state[nr][2]);
        spr_flake->setDestY(p.y + (flake_state[nr][3] % 160) - 160);

        if (mapr->collider.is_valid_position(p_flakes.x + i, p_flakes.y + j, MOVEMENT_FLYING, false)){
			// fade off effect for snowflakes near the ground
			if (flake_state[nr][3] % 160 > 60){
				spr_flake->setClipY(10);
			}
			else spr_flake->setClipY(0);

			render_device->render(spr_flake);

        }
        i+=density;
        if (i>RADIUS){
            i= -RADIUS;
            j+=density;
        }
        nr+=1;
    }
}
Exemplo n.º 19
0
void ListWeatherCloud::renderClouds(){
	//if (cycle_i > time_of_rain) renderRainfall();
    renderRainfall(); // TODO: remove this line, uncomment previous

	if ( (clouds_arr_initialized) && (!cloud_list.empty()) ){
		std::list<WeatherCloud*>::iterator it=cloud_list.begin();
		WeatherCloud *cloud;
		Sprite *spr_cloud;
		Point p;
		FPoint fp;
		Point dest_p;
		int i, j, nr=0;

		i=-RADIUS;
		j=0; // -> with j=-RADIUS: segmentation faults quite common

		while (j < RADIUS){
			// use a cloud from the list several times if needed
			if ((it == cloud_list.end())) it=cloud_list.begin();

			cloud = *it;
			if (cloud==NULL){
				it++;
				continue; // break;
			}

			spr_cloud = cloud->getSprite();

			if (spr_cloud==NULL) break;

			fp.x = cloud_state[nr][4] + i;
			fp.y = cloud_state[nr][5] + j;
			if (!isWithin(mapr->cam,RADIUS + 4,fp)){
				// move cloud to the opposite direction
				direction = calcDirection(mapr->cam.x, mapr->cam.y, fp.x, fp.y);
				if (direction < 4) direction +=4;
				else direction -=4;
				FPoint fpn = calcVector(fp, direction, RADIUS+24);
				cloud_state[nr][4] = floor(fpn.x) - i;
				cloud_state[nr][5] = floor(fpn.y) - j;
			}

			p = map_to_screen(cloud_state[nr][4] + i, cloud_state[nr][5] + j, mapr->cam.x, mapr->cam.y);
			if (cycle_i % RENDER_CHANGE_AFTER/2 == 0) {
				// TODO: should depend on wind direction and perhaps speed;
				cloud_state[nr][2] = cloud_state[nr][2] + randBetween(1,2);
				cloud_state[nr][3] = cloud_state[nr][3] + randBetween(1,2);
				direction = calcDirection(0.0,0.0, cloud_state[nr][2], cloud_state[nr][3]);
			} // overflow of cloud_state[nr][2] possible, but with little consequences

			dest_p.x = p.x + (cloud_state[nr][2] % 800) - 400;
			dest_p.y = p.y + (cloud_state[nr][3] % 600) - 300;

			spr_cloud->setOffset(cloud_state[nr][1],cloud_state[nr][1]);
			spr_cloud->setDest(dest_p);

			render_device->render(spr_cloud);

			i+=cloud_distance;
			if (i>RADIUS){
				i=-RADIUS;
				j+=cloud_distance;
			}
			it++;
			nr++;
        }

	}
}
Exemplo n.º 20
0
/**
 * Show all tooltips for loot on the floor
 */
void LootManager::renderTooltips(const FPoint& cam) {
	if (!SHOW_HUD) return;

	Point dest;
	bool tooltip_below = true;

	std::vector<Loot>::iterator it;
	for (it = loot.begin(); it != loot.end(); ) {
		it->tip_visible = false;

		if (it->on_ground) {
			Point p = map_to_screen(it->pos.x, it->pos.y, cam.x, cam.y);
			dest.x = p.x;
			dest.y = p.y + TILE_H_HALF;

			// adjust dest.y so that the tooltip floats above the item
			dest.y -= tooltip_margin;

			// set hitbox for mouse hover
			Rect hover;
			hover.x = p.x - TILE_W_HALF;
			hover.y = p.y - TILE_H_HALF;
			hover.w = TILE_W;
			hover.h = TILE_H;

			if ((LOOT_TOOLTIPS && !inpt->pressing[ALT]) || (!LOOT_TOOLTIPS && inpt->pressing[ALT]) || isWithinRect(hover, inpt->mouse)) {
				it->tip_visible = true;

				// create tooltip data if needed
				if (it->tip.isEmpty()) {
					if (!it->stack.empty()) {
						it->tip = items->getShortTooltip(it->stack);
					}
				}

				// try to prevent tooltips from overlapping
				tip->prerender(it->tip, dest, STYLE_TOPLABEL);
				std::vector<Loot>::iterator test_it;
				for (test_it = loot.begin(); test_it != it; ) {
					if (rectsOverlap(test_it->tip_bounds, tip->bounds)) {
						if (tooltip_below)
							dest.y = test_it->tip_bounds.y + test_it->tip_bounds.h + TOOLTIP_OFFSET;
						else
							dest.y = test_it->tip_bounds.y - test_it->tip_bounds.h + TOOLTIP_OFFSET;

						tip->bounds.y = dest.y;
					}

					++test_it;
				}

				tip->render(it->tip, dest, STYLE_TOPLABEL);
				it->tip_bounds = tip->bounds;

				// only display one tooltip if we got it from hovering
				if (!LOOT_TOOLTIPS && !inpt->pressing[ALT])
					break;
			}
		}

		tooltip_below = !tooltip_below;

		++it;
	}
}
Exemplo n.º 21
0
/**
 * Some events have a hotspot (rectangle screen area) where the user can click
 * to trigger the event.
 *
 * The hero must be within range (INTERACT_RANGE) to activate an event.
 *
 * This function checks valid mouse clicks against all clickable events, and
 * executes
 */
void MapRenderer::checkHotspots() {
	if (NO_MOUSE) return;

	show_tooltip = false;

	std::vector<Event>::iterator it;

	// work backwards through events because events can be erased in the loop.
	// this prevents the iterator from becoming invalid.
	for (it = events.end(); it != events.begin(); ) {
		--it;

		for (int x=it->hotspot.x; x < it->hotspot.x + it->hotspot.w; ++x) {
			for (int y=it->hotspot.y; y < it->hotspot.y + it->hotspot.h; ++y) {
				bool matched = false;
				bool is_npc = false;

				Event_Component* npc = (*it).getComponent("npc_hotspot");
				if (npc) {
					is_npc = true;

					Point p = map_to_screen(float(npc->x), float(npc->y), shakycam.x, shakycam.y);
					p = center_tile(p);

					Rect dest;
					dest.x = p.x - npc->z;
					dest.y = p.y - npc->a;
					dest.w = npc->b;
					dest.h = npc->c;

					if (isWithin(dest, inpt->mouse)) {
						matched = true;
						tip_pos.x = dest.x + dest.w/2;
						tip_pos.y = p.y - npc_tooltip_margin;
					}
				}
				else {
					for (unsigned index = 0; index <= index_objectlayer; ++index) {
						maprow *current_layer = layers[index];
						Point p = map_to_screen(float(x), float(y), shakycam.x, shakycam.y);
						p = center_tile(p);

						if (const short current_tile = current_layer[x][y]) {
							// first check if mouse pointer is in rectangle of that tile:
							Rect dest;
							dest.x = p.x - tset.tiles[current_tile].offset.x;
							dest.y = p.y - tset.tiles[current_tile].offset.y;
							dest.w = tset.tiles[current_tile].tile->getClip().w;
							dest.h = tset.tiles[current_tile].tile->getClip().h;

							if (isWithin(dest, inpt->mouse)) {
								matched = true;
								tip_pos = map_to_screen(it->center.x, it->center.y, shakycam.x, shakycam.y);
								tip_pos.y -= TILE_H;
							}
						}
					}
				}

				if (matched) {
					// skip inactive events
					if (!EventManager::isActive(*it)) continue;

					// skip events without hotspots
					if ((*it).hotspot.h == 0) continue;

					// skip events on cooldown
					if ((*it).cooldown_ticks != 0) continue;

					// new tooltip?
					createTooltip((*it).getComponent("tooltip"));

					if ((((*it).reachable_from.w == 0 && (*it).reachable_from.h == 0) || isWithin((*it).reachable_from, floor(cam)))
							&& calcDist(cam, (*it).center) < INTERACT_RANGE) {

						// only check events if the player is clicking
						// and allowed to click
						if (is_npc) {
							curs->setCursor(CURSOR_TALK);
						}
						else {
							curs->setCursor(CURSOR_INTERACT);
						}
						if (!inpt->pressing[MAIN1]) return;
						else if (inpt->lock[MAIN1]) return;

						inpt->lock[MAIN1] = true;
						if (EventManager::executeEvent(*it))
							it = events.erase(it);
					}
					return;
				}
				else show_tooltip = false;
			}
		}
	}
}
Exemplo n.º 22
0
void MapRenderer::renderIsoLayer(const unsigned short layerdata[256][256]) {
	int_fast16_t i; // first index of the map array
	int_fast16_t j; // second index of the map array
	Rect dest;
	const Point upperleft = floor(screen_to_map(0, 0, shakycam.x, shakycam.y));
	const int_fast16_t max_tiles_width =   (VIEW_W / TILE_W) + 2*tset.max_size_x;
	const int_fast16_t max_tiles_height = (2 * VIEW_H / TILE_H) + 2*tset.max_size_y;

	j = upperleft.y - tset.max_size_y/2 + tset.max_size_x;
	i = upperleft.x - tset.max_size_y/2 - tset.max_size_x;

	for (uint_fast16_t y = max_tiles_height ; y; --y) {
		int_fast16_t tiles_width = 0;

		// make sure the isometric corners are not rendered:
		// corner north west, upper left  (i < 0)
		if (i < -1) {
			j += i + 1;
			tiles_width -= i + 1;
			i = -1;
		}
		// corner north east, upper right (j > mapheight)
		const int_fast16_t d = j - h;
		if (d >= 0) {
			j -= d;
			tiles_width += d;
			i += d;
		}

		// lower right (south east) corner is covered by (j+i-w+1)
		// lower left (south west) corner is caught by having 0 in there, so j>0
		const int_fast16_t j_end = std::max(static_cast<int_fast16_t>(j+i-w+1),	std::max(static_cast<int_fast16_t>(j - max_tiles_width), static_cast<int_fast16_t>(0)));

		Point p = map_to_screen(float(i), float(j), shakycam.x, shakycam.y);
		p = center_tile(p);

		// draw one horizontal line
		while (j > j_end) {
			--j;
			++i;
			++tiles_width;
			p.x += TILE_W;

			if (const uint_fast16_t current_tile = layerdata[i][j]) {
				dest.x = p.x - tset.tiles[current_tile].offset.x;
				dest.y = p.y - tset.tiles[current_tile].offset.y;
				// no need to set w and h in dest, as it is ignored
				// by SDL_BlitSurface
				tset.tiles[current_tile].tile->setDest(dest);
				render_device->render(tset.tiles[current_tile].tile);
			}
		}
		j += tiles_width;
		i -= tiles_width;
		// Go one line deeper, the starting position goes zig-zag
		if (y % 2)
			i++;
		else
			j++;
	}
}
Exemplo n.º 23
0
void MapRenderer::renderIsoFrontObjects(std::vector<Renderable> &r) {
	Rect dest;

	const Point upperleft = floor(screen_to_map(0, 0, shakycam.x, shakycam.y));
	const int_fast16_t max_tiles_width =   (VIEW_W / TILE_W) + 2 * tset.max_size_x;
	const int_fast16_t max_tiles_height = ((VIEW_H / TILE_H) + 2 * tset.max_size_y)*2;

	std::vector<Renderable>::iterator r_cursor = r.begin();
	std::vector<Renderable>::iterator r_end = r.end();

	// object layer
	int_fast16_t j = upperleft.y - tset.max_size_y + tset.max_size_x;
	int_fast16_t i = upperleft.x - tset.max_size_y - tset.max_size_x;

	while (r_cursor != r_end && ((int)(r_cursor->map_pos.x) + (int)(r_cursor->map_pos.y) < i + j || (int)(r_cursor->map_pos.x) < i)) // implicit floor
		++r_cursor;

	if (index_objectlayer >= layers.size())
		return;

	maprow *objectlayer = layers[index_objectlayer];
	for (uint_fast16_t y = max_tiles_height ; y; --y) {
		int_fast16_t tiles_width = 0;

		// make sure the isometric corners are not rendered:
		if (i < -1) {
			j += i + 1;
			tiles_width -= i + 1;
			i = -1;
		}
		const int_fast16_t d = j - h;
		if (d >= 0) {
			j -= d;
			tiles_width += d;
			i += d;
		}
		const int_fast16_t j_end = std::max(static_cast<int_fast16_t>(j+i-w+1), std::max(static_cast<int_fast16_t>(j - max_tiles_width), static_cast<int_fast16_t>(0)));

		// draw one horizontal line
		Point p = map_to_screen(float(i), float(j), shakycam.x, shakycam.y);
		p = center_tile(p);
		while (j > j_end) {
			--j;
			++i;
			++tiles_width;
			p.x += TILE_W;

			if (const uint_fast16_t current_tile = objectlayer[i][j]) {
				dest.x = p.x - tset.tiles[current_tile].offset.x;
				dest.y = p.y - tset.tiles[current_tile].offset.y;
				tset.tiles[current_tile].tile->setDest(dest);
				render_device->render(tset.tiles[current_tile].tile);
			}

			// some renderable entities go in this layer
			while (r_cursor != r_end && ((int)r_cursor->map_pos.x == i && (int)r_cursor->map_pos.y == j)) { // implicit floor by int cast
				drawRenderable(r_cursor);
				++r_cursor;
			}
		}
		j += tiles_width;
		i -= tiles_width;
		if (y % 2)
			i++;
		else
			j++;

		while (r_cursor != r_end && ((int)r_cursor->map_pos.x + (int)r_cursor->map_pos.y < i + j || (int)r_cursor->map_pos.x <= i)) // implicit floor by int cast
			++r_cursor;
	}
}