コード例 #1
0
ファイル: commands.cpp プロジェクト: SCMapsAndMods/teippi
static void Command_Sync(uint8_t *data)
{
    if (!IsReplay())
    {
        uint8_t *sync_data = &*bw::sync_data + 0x10c * (data[1] >> 4);
        if (sync_data[8] != data[5] || !Command_Sync_Main(data))
        {
            if (*bw::desync_happened == 0)
            {
                LogSyncData();
                // Saving is kind of pointless as the game cannot be reloaded with all players
                // but it might give some info
                if (Debug)
                {
                    char buf[260];
                    char timestr[50];
                    auto now = std::chrono::system_clock::now();
                    auto timet = std::chrono::system_clock::to_time_t(now);
                    std::strftime(timestr, sizeof timestr, "%m-%d %H-%M", std::localtime(&timet));

                    snprintf(buf, sizeof buf, "%s.%s",
                            bw::net_players[*bw::self_net_player].name, timestr);
                    auto time = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
                    SaveGame(buf, time);
                }
            }
            *bw::desync_happened = 1;
            bw::net_player_flags[*bw::lobby_command_user] = 0x10000; // Jep, ei or
        }
    }
コード例 #2
0
ファイル: commands.cpp プロジェクト: SCMapsAndMods/teippi
void Command_GameData(uint8_t *data, int net_player)
{
    if (*bw::in_lobby || net_player != 0)
        return;
    *bw::tileset = *(uint16_t *)(data + 0x1);
    *bw::map_width_tiles = *(uint16_t *)(data + 0x3);
    *bw::map_height_tiles = *(uint16_t *)(data + 0x5);
    memset(bw::temp_players.v(), 0, sizeof(Player) * Limits::Players);
    for (int i = 0; i < Limits::Players; i++)
    {
        Player *player = &bw::temp_players[i];
        player->id = i;
        player->storm_id = -1;
        player->type = data[0x7 + i];
        player->race = data[0x13 + i];
        player->team = data[0x2b + i];
    }
    if (IsTeamGame())
    {
        int player_id = 0;
        int players_per_team = GetTeamGameTeamSize();
        int team_count = 2;
        if (bw::game_data[0].got.game_type_id != 0xf) // Tvb
            team_count = *bw::team_game;
        for (int i = 0; i < team_count; i++)
        {
            for (int j = 0; j < players_per_team; j++)
            {
                if (!IsActivePlayer(player_id))
                    break;
                Player *player = &bw::temp_players[player_id];
                player->team = i + 1;
                player_id += 1;
            }
        }
    }
    memcpy(bw::player_types_unused.v(), data + 0x1f, 0xc);
    memcpy(bw::force_layout.v(), data + 0x2b, 0xc);
    memcpy(bw::user_select_slots.v(), data + 0x37, 0x8);
    if (!IsReplay())
        memcpy(bw::replay_user_select_slots.v(), data + 0x37, 0x8);
    int save_player_id = *bw::loaded_save ? *bw::loaded_local_player_id : 0;
    int save_unique_player_id = *bw::loaded_save ? *bw::loaded_local_unique_player_id : 0;
    int flags = *bw::own_net_player_flags;
    MakeJoinedGameCommand(flags, 1, save_player_id, save_unique_player_id, *bw::saved_seed, false);
    *bw::lobby_state = 3;
}
コード例 #3
0
void Neutralize(int player)
{
    Assert(player >= 0 && player < Limits::Players);
    if (IsCheatActive(Cheats::Staying_Alive) && IsHumanPlayer(player))
        return;

    if (bw::game_data->got.victory_conditions == 4 || bw::game_data->got.victory_conditions == 5)
    {
        Unit *next = bw::first_player_unit[player];
        while (next != nullptr)
        {
            Unit *unit = next;
            next = unit->player_units.next;
            if (units_dat_flags[unit->unit_id] & UnitFlags::Subunit || unit->sprite == nullptr)
                continue;
            if (unit->order == Order::Die)
                continue;
            if (units_dat_flags[unit->unit_id] & UnitFlags::SingleEntity && unit->powerup.carrying_unit != nullptr)
            {
                Unit *worker = unit->powerup.carrying_unit;
                if (worker->carried_powerup_flags != 0)
                {
                    DeletePowerupImages(worker);
                    if (worker->worker.powerup)
                    {
                        worker->worker.powerup->order_flags |= 0x4;
                        worker->worker.powerup->Kill(nullptr);
                    }
                    worker->worker.powerup = nullptr;
                    worker->carried_powerup_flags = 0;
                }
            }
            else
            {
                unit->Kill(nullptr);
            }
        }
    }
    else
    {
        Unit *next = bw::first_player_unit[player];
        while (next != nullptr)
        {
            Unit *unit = next;
            next = unit->player_units.next;
            NeutralizeUnit(unit);
        }
        RefreshUi();
    }
    if (*bw::team_game)
    {
        for (int i = 0; i < Limits::ActivePlayers; i++)
        {
            if (bw::players[player].team == bw::players[i].team)
                MarkPlayerNeutral(i);
        }
    }
    else
    {
        MarkPlayerNeutral(player);
    }
    if (IsReplay())
    {
        *bw::replay_visions &= ~(1 << player);
        *bw::player_visions &= ~(1 << player);
        *bw::player_exploration_visions &= ~(0x100 << player);
    }
}
コード例 #4
0
ファイル: draw.cpp プロジェクト: neivv/teippi
void GenerateFog()
{
    int screen_x = *bw::screen_pos_x_tiles;
    if (screen_x != 0)
        screen_x--;
    int screen_y = *bw::screen_pos_y_tiles;
    if (screen_y != 0)
        screen_y--;
    uint32_t *flags = (*bw::map_tile_flags) + screen_y * *bw::map_width_tiles + screen_x;
    uint32_t *orig_flags = flags;
    uint8_t *pos = *bw::fog_arr1;
    int shown_value = *bw::fog_variance_amount;
    int fow_value = shown_value / 2;

    int y_pos = screen_y;
    for (int i = 0; i < 0x11; i++)
    {
        int x_pos = *bw::screen_pos_x_tiles - 1;
        flags = orig_flags;
        for (int i = 0; i < 0x18; i++)
        {
            // Obviously people can just remove multiplayer check if they wish
            // Bw had nice vision-based sync but it does not work with dynamically allocated sprites
            if (all_visions && !IsMultiplayer())
            {
                if ((0xff00 & flags[0]) == 0xff00)
                    *pos = 0;
                else if ((0xff & flags[0]) == 0xff)
                    *pos = fow_value;
                else
                    *pos = shown_value;
            }
            else if (IsReplay())
            {
                if (*bw::replay_show_whole_map)
                    *pos = shown_value;
                else if (!((*bw::replay_visions << 8) & ~flags[0]))
                    *pos = 0;
                else if (!(*bw::replay_visions & ~flags[0]))
                    *pos = fow_value;
                else
                    *pos = shown_value;
            }
            else
            {
                if (*bw::player_exploration_visions & flags[0])
                    *pos = 0;
                else if (*bw::player_visions & flags[0])
                    *pos = fow_value;
                else
                    *pos = shown_value;
            }
            if (x_pos < *bw::map_width_tiles - 1 && x_pos >= 0)
                flags++;
            x_pos++;
            pos++;
        }
        if (y_pos < *bw::map_height_tiles - 1 && y_pos >= 0)
            orig_flags += *bw::map_width_tiles;
        y_pos++;
    }

    // Blend fog
    // Screen is 0x18 x 0x11 tiles
    // Well every border has 1 nonvisible tile, it is only used for blending?
    pos = *bw::fog_arr1 + 0x18 + 0x1;
    uint8_t *out = *bw::fog_arr2 + 0x18 + 0x1;
    for (int i = 0; i < 0x11 - 2; i++)
    {
        for (int i = 0; i < 0x18 - 2; i++)
        {
            int val = pos[0] * 2;
            val = (val + pos[-1] + pos[1] + pos[-0x18] + pos[0x18]) * 2;
            val = (val + pos[-0x17] + pos[0x17] + pos[-0x19] + pos[0x19]) / 16;
            *out = val;
            pos++;
            out++;
        }
        pos += 2;
        out += 2;
    }
}