Esempio n. 1
0
void ScriptEngine::_AddOpenFile(ScriptDescriptor* sd) {
	// NOTE: This function assumes that the file is not already open
	_open_files.insert(std::make_pair(sd->_filename, sd));
	// Add the lua_State to the list of opened lua states if it is not already present
	if (sd->GetAccessMode() == SCRIPT_READ || sd->GetAccessMode() == SCRIPT_MODIFY) {
		ReadScriptDescriptor* rsd = dynamic_cast<ReadScriptDescriptor*>(sd);
		if (_open_threads.find(rsd->GetFilename()) == _open_threads.end())
			_open_threads[rsd->GetFilename()] = rsd->_lstack;
	}
}
Esempio n. 2
0
void SkillEditor::_LoadSkills(ReadScriptDescriptor &script, vector<GlobalSkill *> &skills, GLOBAL_SKILL type)
{
    script.OpenTable("skills");
    vector<uint32> keys;
    script.ReadTableKeys(keys);
    for(uint32 i = 0; i < keys.size(); ++i)
        skills.push_back(new GlobalSkill(keys[i]));
    script.CloseAllTables();
    script.CloseFile();

} // _LoadSkills(ReadScriptDescriptor, vector<GlobalSkill *>)
Esempio n. 3
0
bool ScriptEngine::ExecuteLuaFunction(const string& filename, const string& function_name, bool open_tablespace) {
    ReadScriptDescriptor script;

    if (script.OpenFile(filename) == false) {
        return false;
    }

    if (script.DoesFunctionExist(function_name) == false) {
        IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed to find function \"" << function_name << "\" to execute in file: "
                                       << filename << endl;
        script.CloseFile();
        return false;
    }

    if (open_tablespace == true) {
        if (script.OpenTablespace() == "") {
            IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed to open tablespace in file: " << filename << endl;
        }
        script.CloseFile();
        return false;
    }

    bool result = script.ExecuteFunction(function_name);
    script.CloseFile();
    return result;
}
Esempio n. 4
0
void ScriptEngine::DEBUG_DumpScriptsState()
{
    std::cout << "Script files open: " << _open_files.size() << std::endl;

    std::cout << "-----------------" << std::endl
                << "Different lua state contents:" << std::endl;
    for (std::pair<std::string, vt_script::ScriptDescriptor*> openedFile : _open_files) {
        std::cout << "Script file: " << openedFile.first << " ";
        if (openedFile.second->GetAccessMode() != SCRIPT_ACCESS_MODE::SCRIPT_READ) {
            std::cout << "(Write mode)" << std::endl;
            continue;
        }
        std::cout << "(Read mode)" << std::endl;
        ReadScriptDescriptor* readScript = static_cast<ReadScriptDescriptor*>(openedFile.second);
        ScriptEngine::DEBUG_PrintLuaStack(readScript->GetLuaState());
    }
    std::cout << "-----------------" << std::endl;
    std::cout << "Global stack content:" << std::endl;
    ScriptEngine::DEBUG_PrintLuaStack(_global_state);
}
Esempio n. 5
0
void SkillEditor::_LoadSkills()
{
    string path = string("dat/skills/");
    ReadScriptDescriptor script;
    script.OpenFile(path + "defense.lua", true);
    script.CloseFile();
    script.OpenFile(path + "support.lua", true);
    script.CloseFile();
    vector<GlobalSkill *> skills;
    if(script.OpenFile(path + "attack.lua", true) != false)
        _LoadSkills(script, skills, GLOBAL_SKILL_ATTACK);
    // Now clean up the skills script (due to the way we're storing the scripts in lua, they're all actually in one big table in lua
    // regardless of the file split on disk
    vector<GlobalSkill *>::iterator i = skills.begin();
    for(; i != skills.end(); ++i) {
        if((*i)->GetType() == GLOBAL_SKILL_ATTACK)
            _attack_skills.push_back(*i);
        else if((*i)->GetType() == GLOBAL_SKILL_DEFEND)
            _defense_skills.push_back(*i);
        else if((*i)->GetType() == GLOBAL_SKILL_SUPPORT)
            _support_skills.push_back(*i);
    }
    if(_attack_skills.size() > 0)
        _current_skill_index[GLOBAL_SKILL_ATTACK] = 0;
    if(_defense_skills.size() > 0)
        _current_skill_index[GLOBAL_SKILL_DEFEND] = 0;
    if(_support_skills.size() > 0)
        _current_skill_index[GLOBAL_SKILL_SUPPORT] = 0;

} // _LoadSkills()
Esempio n. 6
0
void GlobalWeapon::_LoadWeaponBattleAnimations(ReadScriptDescriptor& script)
{
    //std::map <uint32, std::map<std::string, std::string> > _weapon_animations;
    _weapon_animations.clear();

    // The character id keys
    std::vector<uint32> char_ids;

    script.ReadTableKeys("battle_animations", char_ids);
    if (char_ids.empty())
        return;

    if (!script.OpenTable("battle_animations"))
        return;

    for (uint32 i = 0; i < char_ids.size(); ++i) {
        uint32 char_id = char_ids[i];

        // Read all the animation aliases
        std::vector<std::string> anim_aliases;
        script.ReadTableKeys(char_id, anim_aliases);

        if (anim_aliases.empty())
            continue;

        if (!script.OpenTable(char_id))
            continue;

        for (uint32 j = 0; j < anim_aliases.size(); ++j) {
            std::string anim_alias = anim_aliases[j];
            std::string anim_file = script.ReadString(anim_alias);
            _weapon_animations[char_id].insert(std::make_pair(anim_alias, anim_file));
        }

        script.CloseTable(); // char_id
    }

    script.CloseTable(); // battle_animations
}
Esempio n. 7
0
bool TileSupervisor::Load(ReadScriptDescriptor &map_file)
{
    // Load the map dimensions and do some basic sanity checks
    _num_tile_on_y_axis = map_file.ReadInt("num_tile_rows");
    _num_tile_on_x_axis = map_file.ReadInt("num_tile_cols");

    // Load all of the tileset images that are used by this map

    // Contains all of the tileset filenames used (string does not contain path information or file extensions)
    std::vector<std::string> tileset_filenames;
    // Temporarily retains all tile images loaded for each tileset. Each inner vector contains 256 StillImage objects
    std::vector<std::vector<StillImage> > tileset_images;

    map_file.ReadStringVector("tileset_filenames", tileset_filenames);

    for(uint32 i = 0; i < tileset_filenames.size(); i++) {
        std::string tileset_file = tileset_filenames[i];

        ReadScriptDescriptor tileset_script;
        if (!tileset_script.OpenFile(tileset_file)) {
            PRINT_ERROR << "Couldn't open the tileset definition file: " << tileset_file << std::endl;
            return false;
        }

        if (!tileset_script.OpenTable("tileset")) {
            PRINT_ERROR << "Couldn't open the 'tileset' table from file: " << tileset_file << std::endl;
            tileset_script.CloseFile();
            return false;
        }

        std::string image_filename = tileset_script.ReadString("image");
        tileset_script.CloseFile();

        tileset_images.push_back(std::vector<StillImage>(TILES_PER_TILESET));

        // Each tileset image is 512x512 pixels, yielding 16 * 16 (== 256) 32x32 pixel tiles each
        if(!ImageDescriptor::LoadMultiImageFromElementGrid(tileset_images[i], image_filename, 16, 16)) {
            PRINT_ERROR << "failed to load tileset image: " << image_filename << std::endl;
            return false;
        }

        for(uint32 j = 0; j < TILES_PER_TILESET; j++) {
            tileset_images[i][j].SetDimensions(TILE_LENGTH, TILE_LENGTH);
        }
    }

    if(!map_file.DoesTableExist("layers")) {
        PRINT_ERROR << "No 'layers' table in the map file." << std::endl;
        return false;
    }

    // Read in the map tile indeces from all tile layers.
    // The indeces stored for the map layers in this file directly correspond to a location within a tileset. Tilesets contain a total of 256 tiles
    // each, so 0-255 correspond to the first tileset, 256-511 the second, etc. The tile location within the tileset is also determined by the index,
    // where the first 16 indeces in the tileset range are the tiles of the first row (left to right), and so on.

    // Clears out the tiles grid
    _tile_grid.clear();

    std::vector<int32> table_x_indeces; // Used to temporarily store a row of table indeces

    map_file.OpenTable("layers");

    uint32 layers_number = map_file.GetTableSize();

    // layers[0]-[n]
    for(uint32 layer_id = 0; layer_id < layers_number; ++layer_id) {
        // Opens the sub-table: layers[layer_id]
        if(!map_file.DoesTableExist(layer_id))
            continue;

        map_file.OpenTable(layer_id);

        // Add a layer for the base context
        _tile_grid.resize(layer_id + 1);

        LAYER_TYPE layer_type = StringToLayerType(map_file.ReadString("type"));

        if(layer_type == INVALID_LAYER) {
            PRINT_WARNING << "Ignoring unexisting layer type: " << layer_type
                          << " in file: " << map_file.GetFilename() << std::endl;
            map_file.CloseTable(); // layers[i]
            continue;
        }

        _tile_grid[layer_id].layer_type = layer_type;

        // Add the new tile rows (y axis)
        _tile_grid[layer_id].tiles.resize(_num_tile_on_y_axis);

        // Read the tile data
        for(uint32 y = 0; y < _num_tile_on_y_axis; ++y) {
            table_x_indeces.clear();

            // Check to make sure tables are of the proper size
            if(!map_file.DoesTableExist(y)) {
                PRINT_ERROR << "the layers[" << layer_id << "] table size was not equal to the number of tile rows specified by the map, "
                            " first missing row: " << y << std::endl;
                return false;
            }

            map_file.ReadIntVector(y, table_x_indeces);

            // Check the number of columns
            if(table_x_indeces.size() != _num_tile_on_x_axis) {
                PRINT_ERROR << "the layers[" << layer_id << "][" << y << "] table size was not equal to the number of tile columns specified by the map, "
                            "should have " << _num_tile_on_x_axis << " values." << std::endl;
                return false;
            }

            // Prepare the columns (x axis)
            _tile_grid[layer_id].tiles[y].resize(_num_tile_on_x_axis);

            for(uint32 x = 0; x < _num_tile_on_x_axis; ++x) {
                _tile_grid[layer_id].tiles[y][x] = table_x_indeces[x];
            }
        }
        map_file.CloseTable(); // layers[layer_id]
    }

    map_file.CloseTable(); // layers

    // Determine which tiles in each tileset are referenced in this map

    // Used to determine whether each tile is used by the map or not. An entry of -1 indicates that particular tile is not used
    std::vector<int16> tile_references;
    // Set size to be equal to the total number of tiles and initialize all entries to -1 (unreferenced)
    tile_references.assign(tileset_filenames.size() * TILES_PER_TILESET, -1);

    // For each layer
    for(uint32 layer_id = 0; layer_id < layers_number; ++layer_id) {
        // For each tile id
        for(uint32 y = 0; y < _num_tile_on_y_axis; ++y) {
            for(uint32 x = 0; x < _num_tile_on_x_axis; ++x) {
                if(_tile_grid[layer_id].tiles[y][x] >= 0)
                    tile_references[_tile_grid[layer_id].tiles[y][x] ] = 0;
            }
        }
    }

    // Translate the tileset tile indeces into indeces for the vector of tile images

    // Here, we have to convert the original tile indeces defined in the map file into a new form. The original index
    // indicates the tileset where the tile is used and its location in that tileset. We need to convert those indeces
    // so that they serve as an index to the MapMode::_tile_images vector, where the tile images will soon be stored.

    // Keeps track of the next translated index number to assign
    uint32 next_index = 0;

    for(uint32 i = 0; i < tile_references.size(); ++i) {
        if(tile_references[i] >= 0) {
            tile_references[i] = next_index;
            next_index++;
        }
    }

    // Now, go back and re-assign all tile layer indeces with the translated indeces
    // For each layer
    for(uint32 layer_id = 0; layer_id < layers_number; ++layer_id) {
        // For each tile id
        for(uint32 y = 0; y < _num_tile_on_y_axis; ++y) {
            for(uint32 x = 0; x < _num_tile_on_x_axis; ++x) {
                if(_tile_grid[layer_id].tiles[y][x] >= 0)
                    _tile_grid[layer_id].tiles[y][x] = tile_references[_tile_grid[layer_id].tiles[y][x] ];
            }
        }
    }

    // Parse all of the tileset definition files and create any animated tile images that will be used

    // Used to access the tileset definition file
    ReadScriptDescriptor tileset_script;
    // Temporarily retains the animation data (every two elements corresponds to a pair of tile frame index and display time)
    std::vector<uint32> animation_info;
    // Temporarily holds all animated tile images. The map key is the value of the tile index, before reference translation is done in the next step
    std::map<uint32, AnimatedImage *> tile_animations;

    for(uint32 i = 0; i < tileset_filenames.size(); i++) {
        if (!tileset_script.OpenFile(tileset_filenames[i])) {
            PRINT_ERROR << "map failed to load because it could not open a tileset definition file: "
                << tileset_filenames[i] << std::endl;
            return false;
        }

        if (!tileset_script.OpenTable("tileset")) {
            PRINT_ERROR << "map failed to load because it could not open the 'tileset' table from file: "
                << tileset_filenames[i] << std::endl;
            tileset_script.CloseFile();
            return false;
        }

        if(tileset_script.DoesTableExist("animated_tiles")) {
            tileset_script.OpenTable("animated_tiles");
            for(uint32 j = 1; j <= tileset_script.GetTableSize(); j++) {
                animation_info.clear();
                tileset_script.ReadUIntVector(j, animation_info);

                // The index of the first frame in the animation. (i * TILES_PER_TILESET) factors in which tileset the frame comes from
                uint32 first_frame_index = animation_info[0] + (i * TILES_PER_TILESET);

                // If the first tile frame index of this animation was not referenced anywhere in the map, then the animation is unused and
                // we can safely skip over it and move on to the next one. Otherwise if it is referenced, we have to construct the animated image
                if(tile_references[first_frame_index] == -1) {
                    continue;
                }

                AnimatedImage *new_animation = new AnimatedImage();
                new_animation->SetDimensions(TILE_LENGTH, TILE_LENGTH);

                // Each pair of entries in the animation info indicate the tile frame index (k) and the time (k+1)
                for(uint32 k = 0; k < animation_info.size(); k += 2) {
                    new_animation->AddFrame(tileset_images[i][animation_info[k]], animation_info[k + 1]);
                }
                tile_animations.insert(std::make_pair(first_frame_index, new_animation));
            }
            tileset_script.CloseTable();
        }

        tileset_script.CloseTable();
        tileset_script.CloseFile();
    } // for (uint32 i = 0; i < tileset_filenames.size(); i++)

    // Add all referenced tiles to the _tile_images vector, in the proper order

    for(uint32 i = 0; i < tileset_images.size(); i++) {
        for(uint32 j = 0; j < TILES_PER_TILESET; j++) {
            uint32 reference = (i * TILES_PER_TILESET) + j;

            if(tile_references[reference] >= 0) {
                // Add the tile as a StillImage
                if(tile_animations.find(reference) == tile_animations.end()) {
                    _tile_images.push_back(new StillImage(tileset_images[i][j]));
                }

                // Add the tile as an AnimatedImage
                else {
                    _tile_images.push_back(tile_animations[reference]);
                    _animated_tile_images.push_back(tile_animations[reference]);
                    tile_animations.erase(reference);
                }
            }
        }
    }

    if(tile_animations.empty() == false) {
        IF_PRINT_WARNING(MAP_DEBUG) << "one or more tile animations that were created were not added into the map -- this is a memory leak" << std::endl;
    }

    // Remove all tileset images. Any tiles which were not added to _tile_images will no longer exist in memory
    tileset_images.clear();

    return true;
}
Esempio n. 8
0
/** \brief Reads in all of the saved game settings and sets values in the according game manager classes
*** \return True if the settings were loaded successfully
**/
bool LoadSettings()
{
    ReadScriptDescriptor settings;
    if(!settings.OpenFile(GetSettingsFilename()))
        return false;

    if (!settings.OpenTable("settings")) {
        PRINT_ERROR << "Couldn't open the 'settings' table in: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
        settings.CloseFile();
        return false;
    }

    // Load language settings
    SystemManager->SetLanguage(static_cast<std::string>(settings.ReadString("language")));

    if (!settings.OpenTable("key_settings")) {
        PRINT_ERROR << "Couldn't open the 'key_settings' table in: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
        settings.CloseFile();
        return false;
    }

    // Hack to port SDL1.2 arrow values to SDL 2.0
    // DEPRECATED: Dump this in a release aka while in Episode II
    // old - SDL1.2
    // settings.key_settings.up = 273
    // settings.key_settings.down = 274
    // settings.key_settings.left = 276
    // settings.key_settings.right = 275
    // new - SDL 2.0
    // settings.key_settings.up = 1073741906
    // settings.key_settings.down = 1073741905
    // settings.key_settings.left = 1073741904
    // settings.key_settings.right = 1073741903
    int32_t key_code = settings.ReadInt("up");
    if (key_code == 273) key_code = 1073741906;
    InputManager->SetUpKey(static_cast<SDL_Keycode>(key_code));
    key_code = settings.ReadInt("down");
    if (key_code == 274) key_code = 1073741905;
    InputManager->SetDownKey(static_cast<SDL_Keycode>(key_code));
    key_code = settings.ReadInt("left");
    if (key_code == 276) key_code = 1073741904;
    InputManager->SetLeftKey(static_cast<SDL_Keycode>(key_code));
    key_code = settings.ReadInt("right");
    if (key_code == 275) key_code = 1073741903;
    InputManager->SetRightKey(static_cast<SDL_Keycode>(key_code));

    InputManager->SetConfirmKey(static_cast<SDL_Keycode>(settings.ReadInt("confirm")));
    InputManager->SetCancelKey(static_cast<SDL_Keycode>(settings.ReadInt("cancel")));
    InputManager->SetMenuKey(static_cast<SDL_Keycode>(settings.ReadInt("menu")));
    InputManager->SetMinimapKey(static_cast<SDL_Keycode>(settings.ReadInt("minimap")));
    InputManager->SetPauseKey(static_cast<SDL_Keycode>(settings.ReadInt("pause")));
    settings.CloseTable(); // key_settings

    if (!settings.OpenTable("joystick_settings")) {
        PRINT_ERROR << "Couldn't open the 'joystick_settings' table in: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
        settings.CloseFile();
        return false;
    }

    InputManager->SetJoysticksEnabled(!settings.ReadBool("input_disabled"));
    InputManager->SetJoyIndex(static_cast<int32_t>(settings.ReadInt("index")));
    InputManager->SetConfirmJoy(static_cast<uint8_t>(settings.ReadInt("confirm")));
    InputManager->SetCancelJoy(static_cast<uint8_t>(settings.ReadInt("cancel")));
    InputManager->SetMenuJoy(static_cast<uint8_t>(settings.ReadInt("menu")));
    InputManager->SetMinimapJoy(static_cast<uint8_t>(settings.ReadInt("minimap")));
    InputManager->SetPauseJoy(static_cast<uint8_t>(settings.ReadInt("pause")));
    InputManager->SetQuitJoy(static_cast<uint8_t>(settings.ReadInt("quit")));
    // DEPRECATED: Remove the hack in one or two releases...
    if(settings.DoesIntExist("help"))
        InputManager->SetHelpJoy(static_cast<uint8_t>(settings.ReadInt("help")));
    else
        InputManager->SetHelpJoy(15); // A high value to avoid getting in the way

    if(settings.DoesIntExist("x_axis"))
        InputManager->SetXAxisJoy(static_cast<int8_t>(settings.ReadInt("x_axis")));
    if(settings.DoesIntExist("y_axis"))
        InputManager->SetYAxisJoy(static_cast<int8_t>(settings.ReadInt("y_axis")));

    if(settings.DoesIntExist("threshold"))
        InputManager->SetThresholdJoy(static_cast<uint16_t>(settings.ReadInt("threshold")));

    settings.CloseTable(); // joystick_settings

    if (!settings.OpenTable("video_settings")) {
        PRINT_ERROR << "Couldn't open the 'video_settings' table in: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
        settings.CloseFile();
        return false;
    }

    // Load video settings
    int32_t resx = settings.ReadInt("screen_resx");
    int32_t resy = settings.ReadInt("screen_resy");
    VideoManager->SetResolution(resx, resy);
    VideoManager->SetFullscreen(settings.ReadBool("full_screen"));
    if (settings.DoesUIntExist("vsync_mode"))
        VideoManager->SetVSyncMode(settings.ReadUInt("vsync_mode"));
    if (settings.DoesBoolExist("game_update_mode"))
        VideoManager->SetGameUpdateMode(settings.ReadBool("game_update_mode"));
    GUIManager->SetUserMenuSkin(settings.ReadString("ui_theme"));
    settings.CloseTable(); // video_settings

    // Load Audio settings
    if(AUDIO_ENABLE) {
        if (!settings.OpenTable("audio_settings")) {
            PRINT_ERROR << "Couldn't open the 'audio_settings' table in: "
                << settings.GetFilename() << std::endl
                << settings.GetErrorMessages() << std::endl;
            settings.CloseFile();
            return false;
        }

        AudioManager->SetMusicVolume(static_cast<float>(settings.ReadFloat("music_vol")));
        AudioManager->SetSoundVolume(static_cast<float>(settings.ReadFloat("sound_vol")));

        settings.CloseTable(); // audio_settings
    }

    // Load Game settings
    if (!settings.OpenTable("game_options")) {
        SystemManager->SetMessageSpeed(DEFAULT_MESSAGE_SPEED);
    }
    else {
        if (settings.DoesUIntExist("game_difficulty"))
            SystemManager->SetGameDifficulty(settings.ReadUInt("game_difficulty"));

        SystemManager->SetMessageSpeed(settings.ReadFloat("message_speed"));

        if (settings.DoesBoolExist("battle_target_cursor_memory"))
            SystemManager->SetBattleTargetMemory(settings.ReadBool("battle_target_cursor_memory"));

        settings.CloseTable(); // game_options
    }

    settings.CloseTable(); // settings

    if(settings.IsErrorDetected()) {
        PRINT_ERROR << "Errors while attempting to load the setting file: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
        settings.CloseFile();
        return false;
    }

    settings.CloseFile();

    return true;
} // bool LoadSettings()
Esempio n. 9
0
bool TileSupervisor::Load(ReadScriptDescriptor& map_file) {
	// Load the map dimensions and do some basic sanity checks
	_num_tile_on_y_axis = map_file.ReadInt("num_tile_rows");
	_num_tile_on_x_axis = map_file.ReadInt("num_tile_cols");

	std::vector<int32> context_inherits;
	//map_file.ReadUIntVector("context_inherits", context_inherits);
	map_file.OpenTable("contexts");
	uint32 num_contexts = map_file.GetTableSize();
	for (uint32 context_id = 0;  context_id < num_contexts; ++context_id) {
		map_file.OpenTable(context_id);
		int32 inheritance = map_file.ReadInt("inherit_from");

		// The base context can't inherit from another one
		if (context_id == 0)
			inheritance = -1;

		// A context can't inherit from a context with a higher id, or itself.
		if ((int32)context_id <= inheritance || inheritance < -1)
			inheritance = -1;

		context_inherits.push_back(inheritance);

		map_file.CloseTable();
	}
	map_file.CloseTable(); // contexts

	// Load all of the tileset images that are used by this map

	// Contains all of the tileset filenames used (string does not contain path information or file extensions)
	std::vector<std::string> tileset_filenames;
	// Temporarily retains all tile images loaded for each tileset. Each inner vector contains 256 StillImage objects
	std::vector<std::vector<StillImage> > tileset_images;

	map_file.ReadStringVector("tileset_filenames", tileset_filenames);

	for (uint32 i = 0; i < tileset_filenames.size(); i++) {
		// Construct the image filename from the tileset filename and create a new vector to use in the LoadMultiImage call
		std::string image_filename = "img/tilesets/" + tileset_filenames[i] + ".png";
		tileset_images.push_back(std::vector<StillImage>(TILES_PER_TILESET));

		// Each tileset image is 512x512 pixels, yielding 16 * 16 (== 256) 32x32 pixel tiles each
		if (!ImageDescriptor::LoadMultiImageFromElementGrid(tileset_images[i], image_filename, 16, 16)) {
			PRINT_ERROR << "failed to load tileset image: " << image_filename << std::endl;
			return false;
		}

		// The map mode coordinate system used corresponds to a tile size of (2.0, 2.0)
		for (uint32 j = 0; j < TILES_PER_TILESET; j++) {
			tileset_images[i][j].SetDimensions(2.0f, 2.0f);
			tileset_images[i][j].Smooth(VideoManager->ShouldSmoothPixelArt());
		}
	}

	if (!map_file.DoesTableExist("layers")) {
		PRINT_ERROR << "No 'layers' table in the map file." << std::endl;
		return false;
	}

	// Read in the map tile indeces from all tile layers for the base context
	// The indeces stored for the map layers in this file directly correspond to a location within a tileset. Tilesets contain a total of 256 tiles
	// each, so 0-255 correspond to the first tileset, 256-511 the second, etc. The tile location within the tileset is also determined by the index,
	// where the first 16 indeces in the tileset range are the tiles of the first row (left to right), and so on.

	// Create the base context
	_tile_grid.clear();
	_tile_grid.insert(std::make_pair(MAP_CONTEXT_01, Context()));

	std::vector<int32> table_x_indeces; // Used to temporarily store a row of table indeces

	map_file.OpenTable("layers");

	uint32 layers_number = map_file.GetTableSize();

	// layers[0]-[n]
	for (uint32 layer_id = 0; layer_id < layers_number; ++layer_id) {
		// Opens the sub-table: layers[layer_id]
		if (!map_file.DoesTableExist(layer_id))
			continue;

		map_file.OpenTable(layer_id);

		// Add a layer for the base context
		_tile_grid[MAP_CONTEXT_01].resize(layer_id + 1);

		LAYER_TYPE layer_type = getLayerType(map_file.ReadString("type"));

		if (layer_type == INVALID_LAYER) {
			PRINT_WARNING << "Ignoring unexisting layer type: " << layer_type
				<< " in file: " << map_file.GetFilename() << std::endl;
			map_file.CloseTable(); // layers[i]
			continue;
		}

		_tile_grid[MAP_CONTEXT_01][layer_id].layer_type = layer_type;

		// Add the new tile rows (y axis)
		_tile_grid[MAP_CONTEXT_01][layer_id].tiles.resize(_num_tile_on_y_axis);

		// Read the tile data
		for (uint32 y = 0; y < _num_tile_on_y_axis; ++y) {
			table_x_indeces.clear();

			// Check to make sure tables are of the proper size
			if (!map_file.DoesTableExist(y)) {
				PRINT_ERROR << "the layers["<< layer_id <<"] table size was not equal to the number of tile rows specified by the map, "
					" first missing row: " << y << std::endl;
				return false;
			}

			map_file.ReadIntVector(y, table_x_indeces);

			// Check the number of columns
			if (table_x_indeces.size() != _num_tile_on_x_axis){
				PRINT_ERROR << "the layers[" << layer_id << "]["<< y << "] table size was not equal to the number of tile columns specified by the map, "
				"should have " << _num_tile_on_x_axis << " values."<< std::endl;
				return false;
			}

			// Prepare the columns (x axis)
			_tile_grid[MAP_CONTEXT_01][layer_id].tiles[y].resize(_num_tile_on_x_axis);

			for (uint32 x = 0; x < _num_tile_on_x_axis; ++x) {
				_tile_grid[MAP_CONTEXT_01][layer_id].tiles[y][x] = table_x_indeces[x];
			}
		}
		map_file.CloseTable(); // layers[layer_id]
	}

	map_file.CloseTable(); // layers

	// Create each additional context for the map by loading its table data

	// Load the tile data for each additional map context
	for (uint32 ctxt = 1; ctxt < num_contexts; ++ctxt) {
		MAP_CONTEXT this_context = static_cast<MAP_CONTEXT>(1 << ctxt);
		std::string context_name = "context_";
		if (ctxt < 10) // precede single digit context names with a zero
			context_name += "0";
		context_name += NumberToString(ctxt);

		// Check wether the context inhjeritance id is lower than the current one.
		if (context_inherits[ctxt] >= (int32)ctxt) {
			PRINT_WARNING << "Invalid context inheritance found for context id: " << ctxt
			<< ". Permitted values goes from -1 (none) to " << ctxt - 1 << std::endl;
			continue;
		}

		// Initialize this context by making a copy of the base map context first, as most contexts re-use many of the same tiles from the base context
		// If non-inheriting context, start with empty map!
		if (context_inherits[ctxt] > -1) {
			_tile_grid.insert(std::make_pair(this_context,
										_tile_grid[GetContextMaskFromContextId(context_inherits[ctxt])]));
		}
		else {
			_tile_grid.insert(std::make_pair(this_context, Context()));

			// Resize the context to have the same size as the base one
			// The number of layers
			_tile_grid[this_context].resize(layers_number);
			// Fro each layer, set up the grid size
			for (uint32 layer_id = 0; layer_id < layers_number; ++layer_id) {
				// Type
				_tile_grid[this_context][layer_id].layer_type = _tile_grid[MAP_CONTEXT_01][layer_id].layer_type;
				// Height
				_tile_grid[this_context][layer_id].tiles.resize(_num_tile_on_y_axis);
				for (uint32 y = 0; y < _num_tile_on_y_axis; ++y) {
					// and width
					_tile_grid[this_context][layer_id].tiles[y].assign((size_t)_num_tile_on_x_axis, -1);
				}
			}
		}

		// Read the table corresponding to this context and modify each tile accordingly.
		// The context table is an array of integer data. The size of this array should be divisible by four, as every consecutive group of four integers in
		// this table represent one tile context element. The first integer corresponds to the tile layer (0 = lower, 1 = middle, 2 = upper), the second
		// and third represent the row and column of the tile respectively, and the fourth value indicates which tile image should be used for this context.
		// So if the first four entries in the context table were {0, 12, 26, 180}, this would set the lower layer tile at position (12, 26) to the tile
		// index 180.
		std::vector<int32> context_data;
		map_file.ReadIntVector(context_name, context_data);
		if (context_data.size() % 4 != 0) {
			PRINT_WARNING <<  ", context data was not evenly divisible by four (incomplete context data)"
				<< " in context: " << this_context << std::endl;
			continue;
		}

		for (uint32 j = 0; j < context_data.size(); j += 4) {
			int32 layer_id = context_data[j];
			int32 y = context_data[j + 1];
			int32 x = context_data[j + 2];
			int32 tile_id = context_data[j + 3];

			if (y >= _num_tile_on_y_axis ||
					x >= _num_tile_on_x_axis ||
					layer_id >= (int32)_tile_grid[this_context].size()) {
				PRINT_WARNING << "Invalid context data found for context: " << this_context << ": layer id: " << layer_id
					<< ", x: " << x << ", y: " << y << std::endl;
				continue;
			}

			_tile_grid[this_context][layer_id].tiles[y][x] = tile_id;
		}
	} // for (uint32 ctxt = 1; ctxt < map_instance->_num_map_contexts; ++ctxt)


	// Determine which tiles in each tileset are referenced in this map

	// Used to determine whether each tile is used by the map or not. An entry of -1 indicates that particular tile is not used
	std::vector<int16> tile_references;
	// Set size to be equal to the total number of tiles and initialize all entries to -1 (unreferenced)
	tile_references.assign(tileset_filenames.size() * TILES_PER_TILESET, -1);

	std::map<MAP_CONTEXT, Context>::const_iterator it = _tile_grid.begin();
	std::map<MAP_CONTEXT, Context>::const_iterator it_end = _tile_grid.end();
	// For each context
	for (; it != it_end; ++it) {
		// For each layer
		for (uint32 layer_id = 0; layer_id < layers_number; ++layer_id) {
			// For each tile id
			for (uint32 y = 0; y < _num_tile_on_y_axis; ++y) {
				for (uint32 x = 0; x < _num_tile_on_x_axis; ++x) {
					if ((it->second)[layer_id].tiles[y][x] >= 0)
						tile_references[ (it->second)[layer_id].tiles[y][x] ] = 0;
				}
			}
		}
	}

	// Translate the tileset tile indeces into indeces for the vector of tile images

	// Here, we have to convert the original tile indeces defined in the map file into a new form. The original index
	// indicates the tileset where the tile is used and its location in that tileset. We need to convert those indeces
	// so that they serve as an index to the MapMode::_tile_images vector, where the tile images will soon be stored.

	// Keeps track of the next translated index number to assign
	uint32 next_index = 0;

	for (uint32 i = 0; i < tile_references.size(); ++i) {
		if (tile_references[i] >= 0) {
			tile_references[i] = next_index;
			next_index++;
		}
	}

	// Now, go back and re-assign all tile layer indeces with the translated indeces
	std::map<MAP_CONTEXT, Context>::iterator it2 = _tile_grid.begin();
	std::map<MAP_CONTEXT, Context>::iterator it2_end = _tile_grid.end();
	// For each context
	for (; it2 != it2_end; ++it2) {
		// For each layer
		for (uint32 layer_id = 0; layer_id < layers_number; ++layer_id) {
			// For each tile id
			for (uint32 y = 0; y < _num_tile_on_y_axis; ++y) {
				for (uint32 x = 0; x < _num_tile_on_x_axis; ++x) {
					if ((it2->second)[layer_id].tiles[y][x] >= 0)
						(it2->second)[layer_id].tiles[y][x] = tile_references[ (it2->second)[layer_id].tiles[y][x] ];
				}
			}
		}
	}

	// Parse all of the tileset definition files and create any animated tile images that will be used

	// Used to access the tileset definition file
	ReadScriptDescriptor tileset_script;
	// Temporarily retains the animation data (every two elements corresponds to a pair of tile frame index and display time)
	std::vector<uint32> animation_info;
	// Temporarily holds all animated tile images. The map key is the value of the tile index, before reference translation is done in the next step
	std::map<uint32, AnimatedImage*> tile_animations;

	for (uint32 i = 0; i < tileset_filenames.size(); i++) {
		if (tileset_script.OpenFile("dat/tilesets/" + tileset_filenames[i] + ".lua") == false) {
			PRINT_ERROR << "map failed to load because it could not open a tileset definition file: " << tileset_script.GetFilename() << std::endl;
			exit(1);
		}
		tileset_script.OpenTable(tileset_filenames[i]);

		if (tileset_script.DoesTableExist("animated_tiles") == true) {
			tileset_script.OpenTable("animated_tiles");
			for (uint32 j = 1; j <= tileset_script.GetTableSize(); j++) {
				animation_info.clear();
				tileset_script.ReadUIntVector(j, animation_info);

				// The index of the first frame in the animation. (i * TILES_PER_TILESET) factors in which tileset the frame comes from
				uint32 first_frame_index = animation_info[0] + (i * TILES_PER_TILESET);

				// If the first tile frame index of this animation was not referenced anywhere in the map, then the animation is unused and
				// we can safely skip over it and move on to the next one. Otherwise if it is referenced, we have to construct the animated image
				if (tile_references[first_frame_index] == -1) {
					continue;
				}

				AnimatedImage* new_animation = new AnimatedImage();
				new_animation->SetDimensions(2.0f, 2.0f);

				// Each pair of entries in the animation info indicate the tile frame index (k) and the time (k+1)
				for (uint32 k = 0; k < animation_info.size(); k += 2) {
					new_animation->AddFrame(tileset_images[i][animation_info[k]], animation_info[k+1]);
				}
				tile_animations.insert(std::make_pair(first_frame_index, new_animation));
			}
			tileset_script.CloseTable();
		}

		tileset_script.CloseTable();
		tileset_script.CloseFile();
	} // for (uint32 i = 0; i < tileset_filenames.size(); i++)

	// Add all referenced tiles to the _tile_images vector, in the proper order

	for (uint32 i = 0; i < tileset_images.size(); i++) {
		for (uint32 j = 0; j < TILES_PER_TILESET; j++) {
			uint32 reference = (i * TILES_PER_TILESET) + j;

			if (tile_references[reference] >= 0) {
				// Add the tile as a StillImage
				if (tile_animations.find(reference) == tile_animations.end()) {
					_tile_images.push_back(new StillImage(tileset_images[i][j]));
				}

				// Add the tile as an AnimatedImage
				else {
					_tile_images.push_back(tile_animations[reference]);
					_animated_tile_images.push_back(tile_animations[reference]);
					tile_animations.erase(reference);
				}
			}
		}
	}

	if (tile_animations.empty() == false) {
		IF_PRINT_WARNING(MAP_DEBUG) << "one or more tile animations that were created were not added into the map -- this is a memory leak" << std::endl;
	}

	// Remove all tileset images. Any tiles which were not added to _tile_images will no longer exist in memory
	tileset_images.clear();

	return true;
} // bool TileSupervisor::Load(ReadScriptDescriptor& map_file)
Esempio n. 10
0
bool SaveMode::_PreviewGame(const std::string& filename)
{
    // Check for the file existence, prevents a useless warning
    if(!vt_utils::DoesFileExist(filename)) {
        _ClearSaveData(false);
        return false;
    }

    ReadScriptDescriptor file;

    // Clear out the save data namespace to avoid loading false information
    // when dealing with a save game that has an invalid namespace
    ScriptManager->DropGlobalTable("save_game1");

    if(!file.OpenFile(filename)) {
        _ClearSaveData(true);
        return false;
    }

    if(!file.DoesTableExist("save_game1")) {
        file.CloseFile();
        _ClearSaveData(true);
        return false;
    }

    // open the namespace that the save game is encapsulated in.
    file.OpenTable("save_game1");

    // The map file, tested after the save game is closed.
    std::string map_script_filename;
    std::string map_data_filename;
    map_script_filename = file.ReadString("map_script_filename");
    map_data_filename = file.ReadString("map_data_filename");

    // Check whether the map data file is available
    if (map_data_filename.empty() || !vt_utils::DoesFileExist(map_data_filename)) {
        file.CloseTable(); // save_game1
        file.CloseFile();
        _ClearSaveData(true);
        return false;
    }

    // Used to store temp data to populate text boxes
    int32_t hours = file.ReadInt("play_hours");
    int32_t minutes = file.ReadInt("play_minutes");
    int32_t seconds = file.ReadInt("play_seconds");
    int32_t drunes = file.ReadInt("drunes");

    if(!file.DoesTableExist("characters")) {
        file.CloseTable(); // save_game1
        file.CloseFile();
        _ClearSaveData(true);
        return false;
    }

    // Read characters table content
    file.OpenTable("characters");
    std::vector<uint32_t> char_ids;
    file.ReadUIntVector("order", char_ids);
    // Prereserve characters slots
    std::vector<GlobalCharacter*> characters;
    characters.assign(CHARACTERS_SHOWN_SLOTS, nullptr);

    // Loads only up to the first four slots (Visible battle characters)
    for(uint32_t i = 0; i < char_ids.size() && i < CHARACTERS_SHOWN_SLOTS; ++i) {
        // Create a new GlobalCharacter object using the provided id
        // This loads all of the character's "static" data, such as their name, etc.
        characters[i] = nullptr;

        if(!file.DoesTableExist(char_ids[i]))
            continue;

        file.OpenTable(char_ids[i]);

        // Read in all of the character's stats data
        characters[i] = new GlobalCharacter(char_ids[i], false);
        characters[i]->SetExperienceLevel(file.ReadUInt("experience_level"));
        // DEPRECATED: Do not read experience_points anymore in one release
        uint32_t total_xp = file.ReadUInt("experience_points");
        if (total_xp == 0) {
            total_xp = file.ReadUInt("total_experience_points");
        }
        characters[i]->SetTotalExperiencePoints(total_xp);

        characters[i]->SetMaxHitPoints(file.ReadUInt("max_hit_points"));
        characters[i]->SetHitPoints(file.ReadUInt("hit_points"));
        characters[i]->SetMaxSkillPoints(file.ReadUInt("max_skill_points"));
        characters[i]->SetSkillPoints(file.ReadUInt("skill_points"));

        file.CloseTable(); // character id
    }
    file.CloseTable(); // characters

    // Report any errors detected from the previous read operations
    if(file.IsErrorDetected()) {
        PRINT_WARNING << "One or more errors occurred while reading the save game file - they are listed below:"
            << std::endl << file.GetErrorMessages() << std::endl;
            file.ClearErrors();
    }

    file.CloseTable(); // save_game1
    file.CloseFile();

    for(uint32_t i = 0; i < CHARACTERS_SHOWN_SLOTS; ++i) {
        _character_window[i].SetCharacter(characters[i]);
    }

    std::ostringstream time_text;
    time_text << (hours < 10 ? "0" : "") << static_cast<uint32_t>(hours) << ":";
    time_text << (minutes < 10 ? "0" : "") << static_cast<uint32_t>(minutes) << ":";
    time_text << (seconds < 10 ? "0" : "") << static_cast<uint32_t>(seconds);
    _time_textbox.SetDisplayText(MakeUnicodeString(time_text.str()));

    std::ostringstream drunes_amount;
    drunes_amount << drunes;
    _drunes_textbox.SetDisplayText(MakeUnicodeString(drunes_amount.str()));

    // Test the map file

    // Tests the map file and gets the untranslated map hud name from it.
    ReadScriptDescriptor map_file;
    if(!map_file.OpenFile(map_script_filename)) {
        _ClearSaveData(true);
        return false;
    }

    if (map_file.OpenTablespace().empty()) {
        _ClearSaveData(true);
        map_file.CloseFile();
        return false;
    }

    // Read the in-game location of the save
    std::string map_hud_name = map_file.ReadString("map_name");
    _map_name_textbox.SetDisplayText(UTranslate(map_hud_name));

    // Loads the potential location image
    std::string map_image_filename = map_file.ReadString("map_image_filename");
    if (map_image_filename.empty()) {
        _location_image.Clear();
    }
    else {
        if (_location_image.Load(map_image_filename))
            _location_image.SetWidthKeepRatio(340.0f);
    }

    map_file.CloseTable(); // Tablespace
    map_file.CloseFile();

    return true;
}
Esempio n. 11
0
void TileSupervisor::Load(ReadScriptDescriptor& map_file, const MapMode* map_instance) {
	// TODO: Add some more error checking in this function (such as checking for script errors after reading blocks of data from the map file)

	// ---------- (1) Load the map dimensions and do some basic sanity checks
	_num_tile_rows = map_file.ReadInt("num_tile_rows");
	_num_tile_cols = map_file.ReadInt("num_tile_cols");

	// Check to make sure tables are of the proper size
	// TODO: we only check that the number of rows are correct, but not the number of columns
	if (map_file.GetTableSize("lower_layer") != _num_tile_rows) {
		PRINT_ERROR << "the lower_layer table size was not equal to the number of tile rows specified by the map" << endl;
		return;
	}
	if (map_file.GetTableSize("middle_layer") != _num_tile_rows) {
		PRINT_ERROR << "the middle_layer table size was not equal to the number of tile rows specified by the map" << endl;
		return;
	}
	if (map_file.GetTableSize("upper_layer") != _num_tile_rows) {
		PRINT_ERROR << "the upper_layer table size was not equal to the number of tile rows specified by the map" << endl;
		return;
	}

	// ---------- (2) Load all of the tileset images that are used by this map

	// Contains all of the tileset filenames used (string does not contain path information or file extensions)
	vector<string> tileset_filenames;
	// Temporarily retains all tile images loaded for each tileset. Each inner vector contains 256 StillImage objects
	vector<vector<StillImage> > tileset_images;

	map_file.ReadStringVector("tileset_filenames", tileset_filenames);

	for (uint32 i = 0; i < tileset_filenames.size(); i++) {
		// Construct the image filename from the tileset filename and create a new vector to use in the LoadMultiImage call
		string image_filename = "img/tilesets/" + tileset_filenames[i] + ".png";
		tileset_images.push_back(vector<StillImage>(TILES_PER_TILESET));

		// The map mode coordinate system used corresponds to a tile size of (2.0, 2.0)
		for (uint32 j = 0; j < TILES_PER_TILESET; j++) {
			tileset_images[i][j].SetDimensions(2.0f, 2.0f);
		}

		// Each tileset image is 512x512 pixels, yielding 16 * 16 (== 256) 32x32 pixel tiles each
		if (ImageDescriptor::LoadMultiImageFromElementGrid(tileset_images[i], image_filename, 16, 16) == false) {
			PRINT_ERROR << "failed to load tileset image: " << image_filename << endl;
			exit(1);
		}
	}

	// ---------- (3) Read in the map tile indeces from all three tile layers for the base context
	// The indeces stored for the map layers in this file directly correspond to a location within a tileset. Tilesets contain a total of 256 tiles
	// each, so 0-255 correspond to the first tileset, 256-511 the second, etc. The tile location within the tileset is also determined by the index,
	// where the first 16 indeces in the tileset range are the tiles of the first row (left to right), and so on.

	// Create and add the 2D tile grid for the base context
	_tile_grid.clear();
	_tile_grid.insert(make_pair(MAP_CONTEXT_01, vector<vector<MapTile> >(_num_tile_rows)));
	for (uint32 r = 0; r < _num_tile_rows; r++) {
		_tile_grid[MAP_CONTEXT_01][r].resize(_num_tile_cols);
	}

	vector<int32> table_row; // Used to temporarily store a row of table indeces

	// Read the base context tables for all three layers
	map_file.OpenTable("lower_layer");
	for (uint32 r = 0; r < _num_tile_rows; r++) {
		table_row.clear();
		map_file.ReadIntVector(r, table_row);
		for (uint32 c = 0; c < _num_tile_cols; c++) {
			_tile_grid[MAP_CONTEXT_01][r][c].lower_layer = table_row[c];
		}
	}
	map_file.CloseTable();

	map_file.OpenTable("middle_layer");
	for (uint32 r = 0; r < _num_tile_rows; r++) {
		table_row.clear();
		map_file.ReadIntVector(r, table_row);
		for (uint32 c = 0; c < _num_tile_cols; c++) {
			_tile_grid[MAP_CONTEXT_01][r][c].middle_layer = table_row[c];
		}
	}
	map_file.CloseTable();

	map_file.OpenTable("upper_layer");
	for (uint32 r = 0; r < _num_tile_rows; r++) {
		table_row.clear();
		map_file.ReadIntVector(r, table_row);
		for (uint32 c = 0; c < _num_tile_cols; c++) {
			_tile_grid[MAP_CONTEXT_01][r][c].upper_layer = table_row[c];
		}
	}
	map_file.CloseTable();

	// ---------- (4) Create each additional context for the map by loading its table data

	// Load the tile data for each additional map context
	for (uint32 i = 1; i < map_instance->GetNumMapContexts(); i++) {
		MAP_CONTEXT this_context = static_cast<MAP_CONTEXT>(1 << i);
		string context_name = "context_";
		if (i < 10) // precede single digit context names with a zero
			context_name += "0";
		context_name += NumberToString(i);

		// Initialize this context by making a copy of the base map context first, as most contexts re-use many of the same tiles from the base context
		_tile_grid.insert(make_pair(this_context, _tile_grid[MAP_CONTEXT_01]));

		// Read the table corresponding to this context and modify each tile accordingly.
		// The context table is an array of integer data. The size of this array should be divisible by four, as every consecutive group of four integers in
		// this table represent one tile context element. The first integer corresponds to the tile layer (0 = lower, 1 = middle, 2 = upper), the second
		// and third represent the row and column of the tile respectively, and the fourth value indicates which tile image should be used for this context.
		// So if the first four entries in the context table were {0, 12, 26, 180}, this would set the lower layer tile at position (12, 26) to the tile
		// index 180.
		vector<int32> context_data;
		map_file.ReadIntVector(context_name, context_data);
		if (context_data.size() % 4 != 0) {
			IF_PRINT_WARNING(MAP_DEBUG) << "for context " << this_context << ", context data was not evenly divisible by four (incomplete context data)" << endl;
			continue;
		}

		for (uint32 j = 0; j < context_data.size(); j += 4) {
			switch (context_data[j]) {
				case 0: // lower layer
					_tile_grid[this_context][context_data[j+1]][context_data[j+2]].lower_layer = context_data[j+3];
					break;
				case 1: // middle layer
					_tile_grid[this_context][context_data[j+1]][context_data[j+2]].middle_layer = context_data[j+3];
					break;
				case 2: // upper layer
					_tile_grid[this_context][context_data[j+1]][context_data[j+2]].upper_layer = context_data[j+3];
					break;
				default:
					IF_PRINT_WARNING(MAP_DEBUG) << "unknown tile layer index reference when loading map context tiles" << endl;
					break;
			}
		}
	} // for (uint32 i = 1; i < map_instance->_num_map_contexts; i++)


	// ---------- (5) Determine which tiles in each tileset are referenced in this map

	// Used to determine whether each tile is used by the map or not. An entry of -1 indicates that particular tile is not used
	vector<int16> tile_references;
	// Set size to be equal to the total number of tiles and initialize all entries to -1 (unreferenced)
	tile_references.assign(tileset_filenames.size() * TILES_PER_TILESET, -1);

	for (map<MAP_CONTEXT, vector<vector<MapTile> > >::iterator i = _tile_grid.begin(); i != _tile_grid.end(); i++) {
		for (uint32 r = 0; r < _num_tile_rows; r++) {
			for (uint32 c = 0; c < _num_tile_cols; c++) {
				if ((i->second)[r][c].lower_layer >= 0)
					tile_references[(i->second)[r][c].lower_layer] = 0;
				if ((i->second)[r][c].middle_layer >= 0)
					tile_references[(i->second)[r][c].middle_layer] = 0;
				if ((i->second)[r][c].upper_layer >= 0)
					tile_references[(i->second)[r][c].upper_layer] = 0;
			}
		}
	}

	// ---------- (6) Translate the tileset tile indeces into indeces for the vector of tile images

	// Here, we have to convert the original tile indeces defined in the map file into a new form. The original index
	// indicates the tileset where the tile is used and its location in that tileset. We need to convert those indeces
	// so that they serve as an index to the MapMode::_tile_images vector, where the tile images will soon be stored.

	// Keeps track of the next translated index number to assign
	uint32 next_index = 0;

	for (uint32 i = 0; i < tile_references.size(); i++) {
		if (tile_references[i] >= 0) {
			tile_references[i] = next_index;
			next_index++;
		}
	}

	// Now, go back and re-assign all lower, middle, and upper tile layer indeces with the translated indeces
	for (map<MAP_CONTEXT, vector<vector<MapTile> > >::iterator i = _tile_grid.begin(); i != _tile_grid.end(); i++) {
		for (uint32 r = 0; r < _num_tile_rows; r++) {
			for (uint32 c = 0; c < _num_tile_cols; c++) {
				if ((i->second)[r][c].lower_layer >= 0)
					(i->second)[r][c].lower_layer = tile_references[(i->second)[r][c].lower_layer];
				if ((i->second)[r][c].middle_layer >= 0)
					(i->second)[r][c].middle_layer = tile_references[(i->second)[r][c].middle_layer];
				if ((i->second)[r][c].upper_layer >= 0)
					(i->second)[r][c].upper_layer = tile_references[(i->second)[r][c].upper_layer];
			}
		}
	}

	// ---------- (7) Parse all of the tileset definition files and create any animated tile images that will be used

	// Used to access the tileset definition file
	ReadScriptDescriptor tileset_script;
	// Temporarily retains the animation data (every two elements corresponds to a pair of tile frame index and display time)
	vector<uint32> animation_info;
	// Temporarily holds all animated tile images. The map key is the value of the tile index, before reference translation is done in the next step
	map<uint32, AnimatedImage*> tile_animations;

	for (uint32 i = 0; i < tileset_filenames.size(); i++) {
		if (tileset_script.OpenFile("dat/tilesets/" + tileset_filenames[i] + ".lua") == false) {
			PRINT_ERROR << "map failed to load because it could not open a tileset definition file: " << tileset_script.GetFilename() << endl;
			exit(1);
		}
		tileset_script.OpenTable(tileset_filenames[i]);

		if (tileset_script.DoesTableExist("animated_tiles") == true) {
			tileset_script.OpenTable("animated_tiles");
			for (uint32 j = 1; j <= tileset_script.GetTableSize(); j++) {
				animation_info.clear();
				tileset_script.ReadUIntVector(j, animation_info);

				// The index of the first frame in the animation. (i * TILES_PER_TILESET) factors in which tileset the frame comes from
				uint32 first_frame_index = animation_info[0] + (i * TILES_PER_TILESET);

				// If the first tile frame index of this animation was not referenced anywhere in the map, then the animation is unused and
				// we can safely skip over it and move on to the next one. Otherwise if it is referenced, we have to construct the animated image
				if (tile_references[first_frame_index] == -1) {
					continue;
				}

				AnimatedImage* new_animation = new AnimatedImage();
				new_animation->SetDimensions(2.0f, 2.0f);

				// Each pair of entries in the animation info indicate the tile frame index (k) and the time (k+1)
				for (uint32 k = 0; k < animation_info.size(); k += 2) {
					new_animation->AddFrame(tileset_images[i][animation_info[k]], animation_info[k+1]);
				}
				tile_animations.insert(make_pair(first_frame_index, new_animation));
			}
			tileset_script.CloseTable();
		}

		tileset_script.CloseTable();
		tileset_script.CloseFile();
	} // for (uint32 i = 0; i < tileset_filenames.size(); i++)

	// ---------- (8) Add all referenced tiles to the _tile_images vector, in the proper order

	for (uint32 i = 0; i < tileset_images.size(); i++) {
		for (uint32 j = 0; j < TILES_PER_TILESET; j++) {
			uint32 reference = (i * TILES_PER_TILESET) + j;

			if (tile_references[reference] >= 0) {
				// Add the tile as a StillImage
				if (tile_animations.find(reference) == tile_animations.end()) {
					_tile_images.push_back(new StillImage(tileset_images[i][j]));
				}

				// Add the tile as an AnimatedImage
				else {
					_tile_images.push_back(tile_animations[reference]);
					_animated_tile_images.push_back(tile_animations[reference]);
					tile_animations.erase(reference);
				}
			}
		}
	}

	if (tile_animations.empty() == false) {
		IF_PRINT_WARNING(MAP_DEBUG) << "one or more tile animations that were created were not added into the map -- this is a memory leak" << endl;
	}

	// Remove all tileset images. Any tiles which were not added to _tile_images will no longer exist in memory
	tileset_images.clear();
} // void TileSupervisor::Load(ReadScriptDescriptor& map_file)
Esempio n. 12
0
bool SaveMode::_PreviewGame(uint32 id)
{
    std::ostringstream f;
    f << GetUserDataPath() + "saved_game_" << id << ".lua";
    std::string filename = f.str();

    // Check for the file existence, prevents a useless warning
    if(!vt_utils::DoesFileExist(filename)) {
        _ClearSaveData(false);
        return false;
    }

    ReadScriptDescriptor file;

    // Clear out the save data namespace to avoid loading false information
    // when dealing with a save game that has an invalid namespace
    ScriptManager->DropGlobalTable("save_game1");

    if(!file.OpenFile(filename)) {
        _ClearSaveData(true);
        return false;
    }

    if(!file.DoesTableExist("save_game1")) {
        file.CloseFile();
        _ClearSaveData(true);
        return false;
    }

    // open the namespace that the save game is encapsulated in.
    file.OpenTable("save_game1");

    // The map file, tested after the save game is closed.
    // DEPRECATED: Old way, will be removed in one release.
    std::string map_script_filename;
    std::string map_data_filename;
    if (file.DoesStringExist("map_filename")) {
        map_script_filename = file.ReadString("map_filename");
        map_data_filename = file.ReadString("map_filename");
    }
    else {
        map_script_filename = file.ReadString("map_script_filename");
        map_data_filename = file.ReadString("map_data_filename");
    }

    // DEPRECATED: Remove in one release
    // Hack to permit the split of last map data and scripts.
    if (!map_script_filename.empty() && map_data_filename == map_script_filename) {
        std::string map_common_name = map_data_filename.substr(0, map_data_filename.length() - 4);
        map_data_filename = map_common_name + "_map.lua";
        map_script_filename = map_common_name + "_script.lua";
    }

    // Used to store temp data to populate text boxes
    int32 hours = file.ReadInt("play_hours");
    int32 minutes = file.ReadInt("play_minutes");
    int32 seconds = file.ReadInt("play_seconds");
    int32 drunes = file.ReadInt("drunes");

    if(!file.DoesTableExist("characters")) {
        file.CloseTable(); // save_game1
        file.CloseFile();
        _ClearSaveData(true);
        return false;
    }

    file.OpenTable("characters");
    std::vector<uint32> char_ids;
    file.ReadUIntVector("order", char_ids);
    GlobalCharacter *character[4];

    // Loads only up to the first four slots (Visible battle characters)
    for(uint32 i = 0; i < 4 && i < char_ids.size(); ++i) {
        // Create a new GlobalCharacter object using the provided id
        // This loads all of the character's "static" data, such as their name, etc.
        character[i] = new GlobalCharacter(char_ids[i], false);

        if(!file.DoesTableExist(char_ids[i]))
            continue;

        file.OpenTable(char_ids[i]);

        // Read in all of the character's stats data
        character[i]->SetExperienceLevel(file.ReadUInt("experience_level"));
        character[i]->SetExperiencePoints(file.ReadUInt("experience_points"));

        character[i]->SetMaxHitPoints(file.ReadUInt("max_hit_points"));
        character[i]->SetHitPoints(file.ReadUInt("hit_points"));
        character[i]->SetMaxSkillPoints(file.ReadUInt("max_skill_points"));
        character[i]->SetSkillPoints(file.ReadUInt("skill_points"));

        file.CloseTable(); // character id
    }
    file.CloseTable(); // characters

    // Report any errors detected from the previous read operations
    if(file.IsErrorDetected()) {
        PRINT_WARNING << "One or more errors occurred while reading the save game file - they are listed below:"
            << std::endl << file.GetErrorMessages() << std::endl;
            file.ClearErrors();
    }

    file.CloseTable(); // save_game1
    file.CloseFile();

    for(uint32 i = 0; i < 4 && i < char_ids.size(); ++i) {
        _character_window[i].SetCharacter(character[i]);
    }

    std::ostringstream time_text;
    time_text << (hours < 10 ? "0" : "") << static_cast<uint32>(hours) << ":";
    time_text << (minutes < 10 ? "0" : "") << static_cast<uint32>(minutes) << ":";
    time_text << (seconds < 10 ? "0" : "") << static_cast<uint32>(seconds);
    _time_textbox.SetDisplayText(MakeUnicodeString(time_text.str()));

    std::ostringstream drunes_amount;
    drunes_amount << drunes;
    _drunes_textbox.SetDisplayText(MakeUnicodeString(drunes_amount.str()));

    // Test the map file

    // Tests the map file and gets the untranslated map hud name from it.
    ReadScriptDescriptor map_file;
    if(!map_file.OpenFile(map_script_filename)) {
        _ClearSaveData(true);
        return false;
    }

    if (map_file.OpenTablespace().empty()) {
        _ClearSaveData(true);
        map_file.CloseFile();
        return false;
    }

    // Read the in-game location of the save
    std::string map_hud_name = map_file.ReadString("map_name");
    _map_name_textbox.SetDisplayText(UTranslate(map_hud_name));

    // Loads the potential location image
    std::string map_image_filename = map_file.ReadString("map_image_filename");
    if (map_image_filename.empty()) {
        _location_image.Clear();
    }
    else {
        if (_location_image.Load(map_image_filename))
            _location_image.SetWidthKeepRatio(340.0f);
    }

    map_file.CloseTable(); // Tablespace
    map_file.CloseFile();

    return true;
} // bool SaveMode::_PreviewGame(string& filename)
Esempio n. 13
0
/** \brief Reads in all of the saved game settings and sets values in the according game manager classes
*** \return True if the settings were loaded successfully
**/
bool LoadSettings()
{
    ReadScriptDescriptor settings;
    if(!settings.OpenFile(GetSettingsFilename()))
        return false;

    if (!settings.OpenTable("settings")) {
        PRINT_ERROR << "Couldn't open the 'settings' table in: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
        settings.CloseFile();
        return false;
    }

    // Load language settings
    SystemManager->SetLanguage(static_cast<std::string>(settings.ReadString("language")));

    if (!settings.OpenTable("key_settings")) {
        PRINT_ERROR << "Couldn't open the 'key_settings' table in: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
            settings.CloseFile();
        return false;
    }

    InputManager->SetUpKey(static_cast<SDLKey>(settings.ReadInt("up")));
    InputManager->SetDownKey(static_cast<SDLKey>(settings.ReadInt("down")));
    InputManager->SetLeftKey(static_cast<SDLKey>(settings.ReadInt("left")));
    InputManager->SetRightKey(static_cast<SDLKey>(settings.ReadInt("right")));
    InputManager->SetConfirmKey(static_cast<SDLKey>(settings.ReadInt("confirm")));
    InputManager->SetCancelKey(static_cast<SDLKey>(settings.ReadInt("cancel")));
    InputManager->SetMenuKey(static_cast<SDLKey>(settings.ReadInt("menu")));
    InputManager->SetPauseKey(static_cast<SDLKey>(settings.ReadInt("pause")));
    settings.CloseTable(); // key_settings

    if (!settings.OpenTable("joystick_settings")) {
        PRINT_ERROR << "Couldn't open the 'joystick_settings' table in: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
            settings.CloseFile();
        return false;
    }

    InputManager->SetJoysticksEnabled(!settings.ReadBool("input_disabled"));
    InputManager->SetJoyIndex(static_cast<int32>(settings.ReadInt("index")));
    InputManager->SetConfirmJoy(static_cast<uint8>(settings.ReadInt("confirm")));
    InputManager->SetCancelJoy(static_cast<uint8>(settings.ReadInt("cancel")));
    InputManager->SetMenuJoy(static_cast<uint8>(settings.ReadInt("menu")));
    InputManager->SetPauseJoy(static_cast<uint8>(settings.ReadInt("pause")));

    InputManager->SetQuitJoy(static_cast<uint8>(settings.ReadInt("quit")));
    if(settings.DoesIntExist("x_axis"))
        InputManager->SetXAxisJoy(static_cast<int8>(settings.ReadInt("x_axis")));
    if(settings.DoesIntExist("y_axis"))
        InputManager->SetYAxisJoy(static_cast<int8>(settings.ReadInt("y_axis")));

    if(settings.DoesIntExist("threshold"))
        InputManager->SetThresholdJoy(static_cast<uint16>(settings.ReadInt("threshold")));

    settings.CloseTable(); // joystick_settings

    if (!settings.OpenTable("video_settings")) {
        PRINT_ERROR << "Couldn't open the 'video_settings' table in: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
            settings.CloseFile();
        return false;
    }

    // Load video settings
    int32 resx = settings.ReadInt("screen_resx");
    int32 resy = settings.ReadInt("screen_resy");
    VideoManager->SetInitialResolution(resx, resy);
    VideoManager->SetFullscreen(settings.ReadBool("full_screen"));
    // Enforce smooth tiles graphics at first run
    if (settings.DoesBoolExist("smooth_graphics"))
        VideoManager->SetPixelArtSmoothed(settings.ReadBool("smooth_graphics"));
    else
        VideoManager->SetPixelArtSmoothed(true);
    settings.CloseTable(); // video_settings

    // Load Audio settings
    if(AUDIO_ENABLE) {
        if (!settings.OpenTable("audio_settings")) {
            PRINT_ERROR << "Couldn't open the 'audio_settings' table in: "
                << settings.GetFilename() << std::endl
                << settings.GetErrorMessages() << std::endl;
                settings.CloseFile();
            return false;
        }

        AudioManager->SetMusicVolume(static_cast<float>(settings.ReadFloat("music_vol")));
        AudioManager->SetSoundVolume(static_cast<float>(settings.ReadFloat("sound_vol")));

        settings.CloseTable(); // audio_settings
    }
    settings.CloseTable(); // settings

    if(settings.IsErrorDetected()) {
        PRINT_ERROR << "Errors while attempting to load the setting file: "
            << settings.GetFilename() << std::endl
            << settings.GetErrorMessages() << std::endl;
        return false;
    }

    settings.CloseFile();

    return true;
} // bool LoadSettings()