//-------------------------------------------------------------------------------------------- wawalite_data_t *wawalite_data_read(const std::string& filename, wawalite_data_t *profile) { /** * @brief * Read environmental data for the current module. */ if (!profile) { throw std::invalid_argument("nullptr == profile"); } // Reset to defaults. *profile = wawalite_data_t::getDefaults(); ReadContext ctxt(filename); if (!ctxt.ensureOpen()) { Log::get().warn("unable to read water and weather file `%s`\n", filename.c_str()); return nullptr; } //First figure out what version of wawalite this is, so that we know what data we //should expect to load profile->version = vfs_get_version(ctxt); // Random map... // If someone else wants to handle this, here are some thoughts for approaching // it. The .MPD file for the level should give the basic size of the map. Use // a standard tile set like the Palace modules. Only use objects that are in // the module's object directory, and only use some of them. Imagine several Rock // Moles eating through a stone filled level to make a path from the entrance to // the exit. Door placement will be difficult. profile->seed = vfs_get_next_bool(ctxt); wawalite_water_t::read(ctxt, &(profile->water)); wawalite_light_t::read(ctxt, &(profile->light)); wawalite_physics_t::read(ctxt, &(profile->phys)); wawalite_animtile_t::read(ctxt, &(profile->animtile)); wawalite_damagetile_t::read(ctxt, &(profile->damagetile)); wawalite_weather_t::read(ctxt, profile, &(profile->weather)); wawalite_graphics_t::read(ctxt, &(profile->graphics)); wawalite_camera_t::read(ctxt, &(profile->camera)); wawalite_fog_t::read(ctxt, &(profile->fog)); if (profile->fog.found) { // Read extra stuff for damage tile particles... if (ctxt.skipToColon(true)) { profile->damagetile.part_gpip = vfs_get_local_particle_profile_ref(ctxt); profile->damagetile.partand = vfs_get_next_int(ctxt); profile->damagetile.sound_index = vfs_get_next_int(ctxt); } } return profile; }
//-------------------------------------------------------------------------------------------- void wawalite_animtile_t::read(ReadContext& ctxt, wawalite_animtile_t *profile) { if (!profile) { throw std::invalid_argument("nullptr == profile"); } // Reset to defaults. *profile = wawalite_animtile_t::getDefaults(); profile->update_and = vfs_get_next_int(ctxt); profile->frame_and = vfs_get_next_int(ctxt); }
//-------------------------------------------------------------------------------------------- void wawalite_damagetile_t::read(ReadContext& ctxt, wawalite_damagetile_t *profile) { if (!profile) { throw std::invalid_argument("nullptr == profile"); } // Reset to defaults. *profile = wawalite_damagetile_t::getDefaults(); // damage tile profile->amount = vfs_get_next_int(ctxt); /// @todo pass the load name profile->damagetype = vfs_get_next_damage_type(ctxt); }
//-------------------------------------------------------------------------------------------- void wawalite_weather_t::read(ReadContext& ctxt, wawalite_data_t *enclosing, wawalite_weather_t *profile) { if (!profile) { throw std::invalid_argument("nullptr == profile"); } // Reset to defaults. *profile = wawalite_weather_t::getDefaults(); // weather data profile->part_gpip = LocalParticleProfileRef(PIP_WEATHER); if (enclosing->version >= WAWALITE_FILE_VERSION) { STRING line; //Parse the weather type line vfs_get_next_string_lit(ctxt, line, SDL_arraysize(line)); profile->weather_name = line; Ego::toupper(profile->weather_name); } profile->over_water = vfs_get_next_bool(ctxt); profile->timer_reset = vfs_get_next_int(ctxt); }
std::shared_ptr<EnchantProfile> EnchantProfile::readFromFile(const std::string& pathname) { std::shared_ptr<EnchantProfile> profile = std::make_shared<EnchantProfile>(); ReadContext ctxt(pathname); if (!ctxt.ensureOpen()) { return nullptr; } // true/false values profile->retarget = vfs_get_next_bool(ctxt); profile->_override = vfs_get_next_bool(ctxt); profile->remove_overridden = vfs_get_next_bool(ctxt); profile->killtargetonend = vfs_get_next_bool(ctxt); profile->poofonend = vfs_get_next_bool(ctxt); // More stuff profile->lifetime = vfs_get_next_int(ctxt); profile->endmessage = vfs_get_next_int(ctxt); // Drain stuff profile->_owner._manaDrain = vfs_get_next_float(ctxt); profile->_target._manaDrain = vfs_get_next_float(ctxt); profile->endIfCannotPay = vfs_get_next_bool(ctxt); profile->_owner._lifeDrain = vfs_get_next_float(ctxt); profile->_target._lifeDrain = vfs_get_next_float(ctxt); // Specifics profile->required_damagetype = vfs_get_next_damage_type(ctxt); profile->require_damagetarget_damagetype = vfs_get_next_damage_type(ctxt); profile->removedByIDSZ = vfs_get_next_idsz(ctxt); // Now the set values profile->_set[EnchantProfile::SETDAMAGETYPE].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETDAMAGETYPE].value = vfs_get_damage_type(ctxt); profile->_set[EnchantProfile::SETNUMBEROFJUMPS].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETNUMBEROFJUMPS].value = ctxt.readIntegerLiteral(); profile->_set[EnchantProfile::SETLIFEBARCOLOR].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETLIFEBARCOLOR].value = ctxt.readIntegerLiteral(); profile->_set[EnchantProfile::SETMANABARCOLOR].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETMANABARCOLOR].value = ctxt.readIntegerLiteral(); profile->_set[EnchantProfile::SETSLASHMODIFIER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETSLASHMODIFIER].value = vfs_get_damage_modifier(ctxt); profile->_add[EnchantProfile::ADDSLASHRESIST].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETCRUSHMODIFIER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETCRUSHMODIFIER].value = vfs_get_damage_modifier(ctxt); profile->_add[EnchantProfile::ADDCRUSHRESIST].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETPOKEMODIFIER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETPOKEMODIFIER].value = vfs_get_damage_modifier(ctxt); profile->_add[EnchantProfile::ADDPOKERESIST].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETHOLYMODIFIER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETHOLYMODIFIER].value = vfs_get_damage_modifier(ctxt); profile->_add[EnchantProfile::ADDHOLYRESIST].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETEVILMODIFIER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETEVILMODIFIER].value = vfs_get_damage_modifier(ctxt); profile->_add[EnchantProfile::ADDEVILRESIST].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETFIREMODIFIER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETFIREMODIFIER].value = vfs_get_damage_modifier(ctxt); profile->_add[EnchantProfile::ADDFIRERESIST].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETICEMODIFIER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETICEMODIFIER].value = vfs_get_damage_modifier(ctxt); profile->_add[EnchantProfile::ADDICERESIST].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETZAPMODIFIER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETZAPMODIFIER].value = vfs_get_damage_modifier(ctxt); profile->_add[EnchantProfile::ADDZAPRESIST].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETFLASHINGAND].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETFLASHINGAND].value = ctxt.readIntegerLiteral(); profile->_set[EnchantProfile::SETLIGHTBLEND].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETLIGHTBLEND].value = ctxt.readIntegerLiteral(); profile->_set[EnchantProfile::SETALPHABLEND].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETALPHABLEND].value = ctxt.readIntegerLiteral(); profile->_set[EnchantProfile::SETSHEEN].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETSHEEN].value = ctxt.readIntegerLiteral(); profile->_set[EnchantProfile::SETFLYTOHEIGHT].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETFLYTOHEIGHT].value = ctxt.readIntegerLiteral(); profile->_set[EnchantProfile::SETWALKONWATER].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETWALKONWATER].value = ctxt.readBool(); profile->_set[EnchantProfile::SETCANSEEINVISIBLE].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETCANSEEINVISIBLE].value = ctxt.readBool(); Ego::Script::EnumDescriptor<MissileTreatment> enumDescriptor ( "MissileTreatment", { // Normal. {"Normal", MissileTreatment_Normal}, {"NORMAL", MissileTreatment_Normal}, {"N", MissileTreatment_Normal}, // Reflect. {"Reflect", MissileTreatment_Reflect}, {"REFLECT", MissileTreatment_Reflect}, {"R", MissileTreatment_Reflect}, // Deflect. {"Deflect", MissileTreatment_Deflect}, {"DEFLECT", MissileTreatment_Deflect}, {"D", MissileTreatment_Deflect}, } ); profile->_set[EnchantProfile::SETMISSILETREATMENT].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETMISSILETREATMENT].value = ctxt.readEnum(enumDescriptor); profile->_set[EnchantProfile::SETCOSTFOREACHMISSILE].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETCOSTFOREACHMISSILE].value = ctxt.readRealLiteral(); profile->_set[EnchantProfile::SETMORPH].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETMORPH].value = true; // vfs_get_bool( fileread ); //ZF> huh? why always channel and morph? profile->_set[EnchantProfile::SETCHANNEL].apply = vfs_get_next_bool(ctxt); profile->_set[EnchantProfile::SETCHANNEL].value = true; // vfs_get_bool( fileread ); // Now read in the add values profile->_add[EnchantProfile::ADDJUMPPOWER].value = vfs_get_next_float(ctxt); profile->_add[EnchantProfile::ADDBUMPDAMPEN].value = vfs_get_next_int(ctxt) / 256.0f; // Stored as 8.8-fixed, used as float profile->_add[EnchantProfile::ADDBOUNCINESS].value = vfs_get_next_int(ctxt) / 256.0f; // Stored as 8.8-fixed, used as float profile->_add[EnchantProfile::ADDDAMAGE].value = vfs_get_next_float(ctxt); // Stored as float, used as 8.8-fixed profile->_add[EnchantProfile::ADDSIZE].value = vfs_get_next_float(ctxt); // Stored as float, used as float profile->_add[EnchantProfile::ADDACCEL].value = vfs_get_next_int(ctxt) / 80.0f; // Stored as int, used as float profile->_add[EnchantProfile::ADDRED].value = vfs_get_next_int(ctxt); profile->_add[EnchantProfile::ADDGRN].value = vfs_get_next_int(ctxt); profile->_add[EnchantProfile::ADDBLU].value = vfs_get_next_int(ctxt); profile->_add[EnchantProfile::ADDDEFENSE].value = -vfs_get_next_int(ctxt); // Defense is backwards profile->_add[EnchantProfile::ADDMANA].value = vfs_get_next_float(ctxt); // Stored as float, used as 8.8-fixed profile->_add[EnchantProfile::ADDLIFE].value = vfs_get_next_float(ctxt); // Stored as float, used as 8.8-fixed profile->_add[EnchantProfile::ADDSTRENGTH].value = vfs_get_next_float(ctxt); // Stored as float, used as 8.8-fixed profile->_add[EnchantProfile::ADDWISDOM].value = vfs_get_next_float(ctxt); // Deprecated (not used) profile->_add[EnchantProfile::ADDINTELLIGENCE].value = vfs_get_next_float(ctxt); // Stored as float, used as 8.8-fixed profile->_add[EnchantProfile::ADDDEXTERITY].value = vfs_get_next_float(ctxt); // Stored as float, used as 8.8-fixed // Determine which entries are not important for (size_t cnt = 0; cnt < EnchantProfile::MAX_ENCHANT_ADD; cnt++) { profile->_add[cnt].apply = (0.0f != profile->_add[cnt].value); } profile->_add[EnchantProfile::ADDFIRERESIST].apply = profile->_set[EnchantProfile::SETFIREMODIFIER].apply; profile->_add[EnchantProfile::ADDEVILRESIST].apply = profile->_set[EnchantProfile::SETEVILMODIFIER].apply; profile->_add[EnchantProfile::ADDZAPRESIST].apply = profile->_set[EnchantProfile::SETZAPMODIFIER].apply; profile->_add[EnchantProfile::ADDICERESIST].apply = profile->_set[EnchantProfile::SETICEMODIFIER].apply; profile->_add[EnchantProfile::ADDHOLYRESIST].apply = profile->_set[EnchantProfile::SETHOLYMODIFIER].apply; profile->_add[EnchantProfile::ADDPOKERESIST].apply = profile->_set[EnchantProfile::SETPOKEMODIFIER].apply; profile->_add[EnchantProfile::ADDSLASHRESIST].apply = profile->_set[EnchantProfile::SETSLASHMODIFIER].apply; profile->_add[EnchantProfile::ADDCRUSHRESIST].apply = profile->_set[EnchantProfile::SETCRUSHMODIFIER].apply; // Read expansions while (ctxt.skipToColon(true)) { switch(ctxt.readIDSZ().toUint32()) { case IDSZ2::caseLabel('A', 'M', 'O', 'U'): profile->contspawn._amount = ctxt.readIntegerLiteral(); break; case IDSZ2::caseLabel('T', 'Y', 'P', 'E'): profile->contspawn._lpip = vfs_get_local_particle_profile_ref(ctxt); break; case IDSZ2::caseLabel('T', 'I', 'M', 'E'): profile->contspawn._delay = ctxt.readIntegerLiteral(); break; case IDSZ2::caseLabel('F', 'A', 'C', 'E'): profile->contspawn._facingAdd = ctxt.readIntegerLiteral(); break; case IDSZ2::caseLabel('S', 'E', 'N', 'D'): profile->endsound_index = ctxt.readIntegerLiteral(); break; case IDSZ2::caseLabel('S', 'T', 'A', 'Y'): profile->_owner._stay = (0 != ctxt.readIntegerLiteral()); break; case IDSZ2::caseLabel('O', 'V', 'E', 'R'): profile->spawn_overlay = (0 != ctxt.readIntegerLiteral()); break; case IDSZ2::caseLabel('D', 'E', 'A', 'D'): profile->_target._stay = (0 != ctxt.readIntegerLiteral()); break; case IDSZ2::caseLabel('C', 'K', 'U', 'R'): profile->seeKurses = ctxt.readIntegerLiteral(); break; case IDSZ2::caseLabel('D', 'A', 'R', 'K'): profile->darkvision = ctxt.readIntegerLiteral(); break; case IDSZ2::caseLabel('N', 'A', 'M', 'E'): profile->setEnchantName(ctxt.readName()); break; default: /*TODO: log error*/ break; } } profile->_name = pathname; // Limit the endsound_index. profile->endsound_index = Ego::Math::constrain<Sint16>(profile->endsound_index, INVALID_SOUND_ID, MAX_WAVE); return profile; }
void font_bmp_load_vfs( const std::string& szBitmap, const char* szSpacing ) { /// @author ZZ /// @details This function loads the font bitmap and sets up the coordinates /// of each font on that bitmap... Bitmap must have 16x6 fonts font_bmp_init(); const std::shared_ptr<Ego::Texture> &fontTexture = Ego::TextureManager::get().getTexture(szBitmap); if (fontTexture->isDefault()) { std::ostringstream os; os << "load_font() - unable to load file `" << szBitmap << "`" << std::endl; Log::get().error("%s", os.str().c_str()); throw std::runtime_error(os.str()); } // Get the size of the bitmap int xsize = fontTexture->getSourceWidth(); int ysize = fontTexture->getSourceHeight(); if ( 0 == xsize || 0 == ysize ) { std::ostringstream os; os << "bad font size (" << xsize << ", " << ysize << ")" << std::endl; Log::get().error("%s", os.str().c_str()); throw std::runtime_error(os.str()); } // Figure out where each font is and its spacing ReadContext ctxt(szSpacing); uint32_t stt_x = 0; uint32_t stt_y = 0; // Uniform font height is at the top uint32_t yspacing = vfs_get_next_int(ctxt); fontoffset = yspacing; for (size_t cnt = 0; cnt < NUMFONT && ctxt.skipToColon(true); ++cnt) { uint8_t chr = static_cast<uint8_t>(ctxt.readCharacterLiteral()); uint32_t xspacing = ctxt.readIntegerLiteral(); if (asciitofont[chr] == 255) { asciitofont[chr] = static_cast<uint8_t>(cnt); } if (stt_x + xspacing + 1 > 255) { stt_x = 0; stt_y += yspacing; } fontrect[cnt].x = stt_x; fontrect[cnt].w = xspacing; fontrect[cnt].y = stt_y; fontrect[cnt].h = yspacing - 2; fontxspacing[cnt] = xspacing + 1; stt_x += xspacing + 1; } // Space between lines fontyspacing = (yspacing / 2) + FONTADD; }
//-------------------------------------------------------------------------------------------- void wawalite_water_t::read(ReadContext& ctxt, wawalite_water_t *profile) { if (!profile) { throw std::invalid_argument("nullptr == profile"); } // Reset to defaults. *profile = wawalite_water_t::getDefaults(); // Read the water data. profile->layer_count = vfs_get_next_int(ctxt); profile->spek_start = vfs_get_next_int(ctxt); profile->spek_level = vfs_get_next_int(ctxt); profile->douse_level = vfs_get_next_float(ctxt); profile->surface_level = vfs_get_next_float(ctxt); profile->light = vfs_get_next_bool(ctxt); profile->is_water = vfs_get_next_bool(ctxt); profile->overlay_req = vfs_get_next_bool(ctxt); profile->background_req = vfs_get_next_bool(ctxt); // General data info profile->layer[0].dist[XX] = vfs_get_next_float(ctxt); profile->layer[0].dist[YY] = vfs_get_next_float(ctxt); profile->layer[1].dist[XX] = vfs_get_next_float(ctxt); profile->layer[1].dist[YY] = vfs_get_next_float(ctxt); profile->foregroundrepeat = vfs_get_next_float(ctxt); profile->backgroundrepeat = vfs_get_next_float(ctxt); // Read the first water layer. profile->layer[0].z = vfs_get_next_float(ctxt); profile->layer[0].alpha = vfs_get_next_int(ctxt); profile->layer[0].frame_add = vfs_get_next_int(ctxt); profile->layer[0].light_dir = vfs_get_next_int(ctxt); profile->layer[0].light_add = vfs_get_next_int(ctxt); profile->layer[0].amp = vfs_get_next_float(ctxt); profile->layer[0].tx_add[SS] = vfs_get_next_float(ctxt); profile->layer[0].tx_add[TT] = vfs_get_next_float(ctxt); // Read the second water layer. profile->layer[1].z = vfs_get_next_int(ctxt); profile->layer[1].alpha = vfs_get_next_int(ctxt); profile->layer[1].frame_add = vfs_get_next_int(ctxt); profile->layer[1].light_dir = vfs_get_next_int(ctxt); profile->layer[1].light_add = vfs_get_next_int(ctxt); profile->layer[1].amp = vfs_get_next_float(ctxt); profile->layer[1].tx_add[SS] = vfs_get_next_float(ctxt); profile->layer[1].tx_add[TT] = vfs_get_next_float(ctxt); }
//-------------------------------------------------------------------------------------------- bool tile_dictionary_load_vfs( const char * filename, tile_dictionary_t * pdict, int max_dict_size ) { /// @author ZZ /// @details This function loads fan types for the terrain Uint32 cnt, entry, vertices, commandsize; int fantype_count, fantype_offset, fantype; int command_count, command; int definition_count; int itmp; float ftmp; if ( NULL == pdict ) return false; // "delete" the old list *pdict = tile_dictionary_t(); if ( !VALID_CSTR( filename ) ) return false; // handle default parameters if ( max_dict_size < 0 ) { max_dict_size = MAP_FAN_TYPE_MAX; } // Try to open a context. ReadContext ctxt(filename); if (!ctxt.ensureOpen()) { Log::get().error("unable to load tile definitions file `%s`\n", filename); return false; } fantype_count = vfs_get_next_int(ctxt); fantype_offset = 2 * std::pow( 2.0f, std::floor( std::log( fantype_count ) / std::log( 2.0f ) ) ); definition_count = 2 * fantype_offset; if ( definition_count > MAP_FAN_TYPE_MAX ) { Log::get().error( "%s - tile dictionary has too many tile definitions (%d/%d).\n", __FUNCTION__, definition_count, MAP_FAN_TYPE_MAX ); return false; } else if ( definition_count > max_dict_size ) { Log::get().error( "%s - the number of tile difinitions has exceeded the requested number (%d/%d).\n", __FUNCTION__, definition_count, max_dict_size ); return false; } pdict->offset = fantype_offset; pdict->def_count = definition_count; for ( fantype = 0; fantype < fantype_count; fantype++ ) { tile_definition_t& pdef_sml = pdict->def_lst[fantype]; tile_definition_t& pdef_big = pdict->def_lst[fantype + fantype_offset]; vertices = vfs_get_next_int(ctxt); pdef_sml.numvertices = vertices; pdef_big.numvertices = vertices; // Dupe for ( cnt = 0; cnt < vertices; cnt++ ) { itmp = vfs_get_next_int(ctxt); pdef_sml.ref[cnt] = itmp; pdef_sml.grid_ix[cnt] = itmp & 3; pdef_sml.grid_iy[cnt] = ( itmp >> 2 ) & 3; ftmp = vfs_get_next_float(ctxt); pdef_sml.u[cnt] = ftmp; ftmp = vfs_get_next_float(ctxt); pdef_sml.v[cnt] = ftmp; // Dupe pdef_big.ref[cnt] = pdef_sml.ref[cnt]; pdef_big.grid_ix[cnt] = pdef_sml.grid_ix[cnt]; pdef_big.grid_iy[cnt] = pdef_sml.grid_iy[cnt]; pdef_big.u[cnt] = pdef_sml.u[cnt]; pdef_big.v[cnt] = pdef_sml.v[cnt]; } command_count = vfs_get_next_int(ctxt); pdef_sml.command_count = command_count; pdef_big.command_count = command_count; // Dupe for ( entry = 0, command = 0; command < command_count; command++ ) { commandsize = vfs_get_next_int(ctxt); pdef_sml.command_entries[command] = commandsize; pdef_big.command_entries[command] = commandsize; // Dupe for ( cnt = 0; cnt < commandsize; cnt++ ) { itmp = vfs_get_next_int(ctxt); pdef_sml.command_verts[entry] = itmp; pdef_big.command_verts[entry] = itmp; // Dupe entry++; } } } pdict->loaded = true; tile_dictionary_finalize( pdict ); return true; }