예제 #1
0
static void
draw_minimap_buildings(minimap_t *minimap, frame_t *frame)
{
	const int building_remap[] = {
		BUILDING_CASTLE,
		BUILDING_STOCK, BUILDING_TOWER, BUILDING_HUT,
		BUILDING_FORTRESS, BUILDING_TOOLMAKER, BUILDING_SAWMILL,
		BUILDING_WEAPONSMITH, BUILDING_STONECUTTER, BUILDING_BOATBUILDER,
		BUILDING_FORESTER, BUILDING_LUMBERJACK, BUILDING_PIGFARM,
		BUILDING_FARM, BUILDING_FISHER, BUILDING_MILL, BUILDING_BUTCHER,
		BUILDING_BAKER, BUILDING_STONEMINE, BUILDING_COALMINE,
		BUILDING_IRONMINE, BUILDING_GOLDMINE, BUILDING_STEELSMELTER,
		BUILDING_GOLDSMELTER
	};

	for (int row = 0; row < game.map.rows; row++) {
		for (int col = 0; col < game.map.cols; col++) {
			int pos = MAP_POS(col, row);
			int obj = MAP_OBJ(pos);
			if (obj > MAP_OBJ_FLAG && obj <= MAP_OBJ_CASTLE) {
				int color = game.player[MAP_OWNER(pos)]->color;
				if (minimap->advanced > 0) {
					building_t *bld = game_get_building(MAP_OBJ_INDEX(pos));
					if (BUILDING_TYPE(bld) == building_remap[minimap->advanced]) {
						draw_minimap_point(minimap, col, row, color,
								   minimap->scale, frame);
					}
				} else {
					draw_minimap_point(minimap, col, row, color,
							   minimap->scale, frame);
				}
			}
		}
	}
}
예제 #2
0
파일: player.c 프로젝트: Radderz81/freeserf
static int
available_knights_at_pos(player_t *player, map_pos_t pos, int index, int dist)
{
    const int min_level_hut[] = { 1, 1, 2, 2, 3 };
    const int min_level_tower[] = { 1, 2, 3, 4, 6 };
    const int min_level_fortress[] = { 1, 3, 6, 9, 12 };

    if (MAP_OWNER(pos) != player->player_num ||
            MAP_TYPE_UP(pos) < 4 || MAP_TYPE_DOWN(pos) < 4 ||
            MAP_OBJ(pos) < MAP_OBJ_SMALL_BUILDING ||
            MAP_OBJ(pos) > MAP_OBJ_CASTLE) {
        return index;
    }

    int bld_index = MAP_OBJ_INDEX(pos);
    for (int i = 0; i < index; i++) {
        if (player->attacking_buildings[i] == bld_index) {
            return index;
        }
    }

    building_t *building = game_get_building(bld_index);
    if (!BUILDING_IS_DONE(building) ||
            BUILDING_IS_BURNING(building)) {
        return index;
    }

    const int *min_level = NULL;
    switch (BUILDING_TYPE(building)) {
    case BUILDING_HUT:
        min_level = min_level_hut;
        break;
    case BUILDING_TOWER:
        min_level = min_level_tower;
        break;
    case BUILDING_FORTRESS:
        min_level = min_level_fortress;
        break;
    default:
        return index;
        break;
    }

    if (index >= 64) return index;

    player->attacking_buildings[index] = bld_index;

    int state = BUILDING_STATE(building);
    int knights_present = building->stock[0].available;
    int to_send = knights_present - min_level[player->knight_occupation[state] & 0xf];

    if (to_send > 0) player->attacking_knights[dist] += to_send;

    return index + 1;
}
예제 #3
0
static void
draw_minimap_ownership(minimap_t *minimap, int density, frame_t *frame)
{
	for (int row = 0; row < game.map.rows; row++) {
		for (int col = 0; col < game.map.cols; col++) {
			map_pos_t pos = MAP_POS(col, row);
			if (MAP_HAS_OWNER(pos)) {
				int color = game.player[MAP_OWNER(pos)]->color;
				draw_minimap_point(minimap, col, row, color,
						   density, frame);
			}
		}
	}
}
예제 #4
0
static void
draw_minimap_traffic(minimap_t *minimap, frame_t *frame)
{
	for (int row = 0; row < game.map.rows; row++) {
		for (int col = 0; col < game.map.cols; col++) {
			int pos = MAP_POS(col, row);
			if (MAP_IDLE_SERF(pos)) {
				int color = game.player[MAP_OWNER(pos)]->color;
				draw_minimap_point(minimap, col, row, color,
						   minimap->scale, frame);
			}
		}
	}
}
예제 #5
0
파일: minimap.c 프로젝트: rayyee/freeserf
static void
draw_minimap_ownership(minimap_t *minimap, int density, frame_t *frame)
{
	const int player_colors[] = {
		64, 72, 68, 76
	};

	for (int row = 0; row < game.map.rows; row++) {
		for (int col = 0; col < game.map.cols; col++) {
			map_pos_t pos = MAP_POS(col, row);
			if (MAP_HAS_OWNER(pos)) {
				int color = player_colors[MAP_OWNER(pos)];
				draw_minimap_point(minimap, col, row, color,
						   density, frame);
			}
		}
	}
}
예제 #6
0
파일: minimap.c 프로젝트: rayyee/freeserf
static void
draw_minimap_traffic(minimap_t *minimap, frame_t *frame)
{
	const int player_colors[] = {
		64, 72, 68, 76
	};

	for (int row = 0; row < game.map.rows; row++) {
		for (int col = 0; col < game.map.cols; col++) {
			int pos = MAP_POS(col, row);
			if (MAP_IDLE_SERF(pos)) {
				int color = player_colors[MAP_OWNER(pos)];
				draw_minimap_point(minimap, col, row, color,
						   minimap->scale, frame);
			}
		}
	}
}
예제 #7
0
파일: player.c 프로젝트: Radderz81/freeserf
void
player_start_attack(player_t *player)
{
    const int min_level_hut[] = { 1, 1, 2, 2, 3 };
    const int min_level_tower[] = { 1, 2, 3, 4, 6 };
    const int min_level_fortress[] = { 1, 3, 6, 9, 12 };

    building_t *target = game_get_building(player->building_attacked);
    if (!BUILDING_IS_DONE(target) ||
            (BUILDING_TYPE(target) != BUILDING_HUT &&
             BUILDING_TYPE(target) != BUILDING_TOWER &&
             BUILDING_TYPE(target) != BUILDING_FORTRESS &&
             BUILDING_TYPE(target) != BUILDING_CASTLE) ||
            !BUILDING_IS_ACTIVE(target) ||
            BUILDING_STATE(target) != 3) {
        return;
    }

    for (int i = 0; i < player->attacking_building_count; i++) {
        /* TODO building index may not be valid any more(?). */
        building_t *b = game_get_building(player->attacking_buildings[i]);
        if (BUILDING_IS_BURNING(b) ||
                MAP_OWNER(b->pos) != player->player_num) {
            continue;
        }

        map_pos_t flag_pos = MAP_MOVE_DOWN_RIGHT(b->pos);
        if (MAP_SERF_INDEX(flag_pos) != 0) {
            /* Check if building is under siege. */
            serf_t *s = game_get_serf(MAP_SERF_INDEX(flag_pos));
            if (SERF_PLAYER(s) != player->player_num) continue;
        }

        const int *min_level = NULL;
        switch (BUILDING_TYPE(b)) {
        case BUILDING_HUT:
            min_level = min_level_hut;
            break;
        case BUILDING_TOWER:
            min_level = min_level_tower;
            break;
        case BUILDING_FORTRESS:
            min_level = min_level_fortress;
            break;
        default:
            continue;
            break;
        }

        int state = BUILDING_STATE(b);
        int knights_present = b->stock[0].available;
        int to_send = knights_present - min_level[player->knight_occupation[state] & 0xf];

        for (int j = 0; j < to_send; j++) {
            /* Find most approriate knight to send according to player settings. */
            int best_type = PLAYER_SEND_STRONGEST(player) ? SERF_KNIGHT_0 : SERF_KNIGHT_4;
            int best_index = -1;

            int knight_index = b->serf_index;
            while (knight_index != 0) {
                serf_t *knight = game_get_serf(knight_index);
                if (PLAYER_SEND_STRONGEST(player)) {
                    if (SERF_TYPE(knight) >= best_type) {
                        best_index = knight_index;
                        best_type = SERF_TYPE(knight);
                    }
                } else {
                    if (SERF_TYPE(knight) <= best_type) {
                        best_index = knight_index;
                        best_type = SERF_TYPE(knight);
                    }
                }

                knight_index = knight->s.defending.next_knight;
            }

            /* Unlink knight from list. */
            int *def_index = &b->serf_index;
            serf_t *def_serf = game_get_serf(*def_index);
            while (*def_index != best_index) {
                def_index = &def_serf->s.defending.next_knight;
                def_serf = game_get_serf(*def_index);
            }
            *def_index = def_serf->s.defending.next_knight;
            b->stock[0].available -= 1;

            target->progress |= BIT(0);

            /* Calculate distance to target. */
            int dist_col = (MAP_POS_COL(target->pos) -
                            MAP_POS_COL(def_serf->pos)) & game.map.col_mask;
            if (dist_col >= game.map.cols/2) dist_col -= game.map.cols;

            int dist_row = (MAP_POS_ROW(target->pos) -
                            MAP_POS_ROW(def_serf->pos)) & game.map.row_mask;
            if (dist_row >= game.map.rows/2) dist_row -= game.map.rows;

            /* Send this serf off to fight. */
            serf_log_state_change(def_serf, SERF_STATE_KNIGHT_LEAVE_FOR_WALK_TO_FIGHT);
            def_serf->state = SERF_STATE_KNIGHT_LEAVE_FOR_WALK_TO_FIGHT;
            def_serf->s.leave_for_walk_to_fight.dist_col = dist_col;
            def_serf->s.leave_for_walk_to_fight.dist_row = dist_row;
            def_serf->s.leave_for_walk_to_fight.field_D = 0;
            def_serf->s.leave_for_walk_to_fight.field_E = 0;
            def_serf->s.leave_for_walk_to_fight.next_state = SERF_STATE_KNIGHT_FREE_WALKING;

            player->knights_attacking -= 1;
            if (player->knights_attacking == 0) return;
        }
    }
}