void BuildingObject::changeTeleportDestination(Vector & position, float & yaw) const { if (!isAuthoritative()) { WARNING(true, ("BuildingObject::changeTeleportDestination called on " "non-authoritative building %s", getNetworkId().getValueString().c_str())); return; } // call a script trigger that will give us the index of the cloning facility // tube to respawn in, if any int index = -1; ScriptParams params; params.addParam(index); IGNORE_RETURN(const_cast<GameScriptObject *>(getScriptObject())->trigAllScripts( Scripting::TRIG_GET_RESPAWN_LOC, params)); index = params.getIntParam(0); if (index >= 0) { DataTable * respawnTable = DataTableManager::getTable(CLONE_RESPAWN_TABLE, true); if (respawnTable != NULL) { int row = respawnTable->searchColumnString(0, getTemplateName()); if (row >= 0) { char buffer[32]; sprintf(buffer, "TUBE%d_X", index+1); int column = respawnTable->findColumnNumber(buffer); if (column >= 0) { position.x = respawnTable->getFloatValue(column, row); position.z = respawnTable->getFloatValue(column+1, row); yaw = convertDegreesToRadians(respawnTable->getFloatValue(column+2, row)); } } } } }
void LevelManager::install() { if(m_installed) return; m_installed = true; DataTable *playerLevelDatatable = DataTableManager::getTable("datatables/player/player_level.iff", true); if (playerLevelDatatable) { ms_numLevels = playerLevelDatatable->getNumRows(); const int levelColumn = playerLevelDatatable->findColumnNumber("level"); const int xp_requiredColumn = playerLevelDatatable->findColumnNumber("xp_required"); const int health_grantedColumn = playerLevelDatatable->findColumnNumber("health_granted"); const int xp_typeColumn = playerLevelDatatable->findColumnNumber("xp_type"); const int xp_multiplierColumn = playerLevelDatatable->findColumnNumber("xp_multiplier"); // @NOTE: there are basically two independent tables in this data file // there is level information and xp type information // these are independent and have diffent lengths, so I'm putting the info // into two different data structures int i; for(i = 0; i < ms_numLevels; ++i) { LevelRecord levelRecord; levelRecord.level = (int16) playerLevelDatatable->getIntValue(levelColumn, i); levelRecord.xp_required = playerLevelDatatable->getIntValue(xp_requiredColumn, i); levelRecord.health = playerLevelDatatable->getIntValue(health_grantedColumn, i); ms_levelRecords.insert(std::make_pair(levelRecord.level, levelRecord)); std::string xpTypeName = playerLevelDatatable->getStringValue(xp_typeColumn, i); if (!xpTypeName.empty()) { const uint32 xpTypeNameCrc = Crc::calculate(xpTypeName.c_str()); const int xpMultiplier = playerLevelDatatable->getIntValue(xp_multiplierColumn, i); ms_xpTypeRecords.insert(std::make_pair(xpTypeNameCrc, xpMultiplier)); } if(levelRecord.level > ms_maxLevel) ms_maxLevel = levelRecord.level; } DataTableManager::close("datatables/player/player_level.iff"); } DataTable *skillDatatable = DataTableManager::getTable("datatables/skill/skills.iff", true); if (skillDatatable) { const int numSkillRows = skillDatatable->getNumRows(); const int skill_nameColumn = skillDatatable->findColumnNumber("NAME"); const int type_nameColumn = skillDatatable->findColumnNumber("XP_TYPE"); const int xp_costColumn = skillDatatable->findColumnNumber("XP_COST"); int i; for(i = 0; i < numSkillRows; i++) { SkillRecord skillRecord; std::string skillName = skillDatatable->getStringValue(skill_nameColumn, i); uint32 skillNameCrc = Crc::calculate(skillName.c_str()); std::string xpTypeName = skillDatatable->getStringValue(type_nameColumn, i); skillRecord.xp_type_name_Crc = Crc::calculate(xpTypeName.c_str()); skillRecord.xp_cost = skillDatatable->getIntValue(xp_costColumn, i); ms_skillRecords.insert(std::make_pair(skillNameCrc, skillRecord)); } DataTableManager::close("datatables/skill/skills.iff"); } ExitChain::add(LevelManager::remove, "LevelManager::remove", 0, false); }
void CitizenRankDataTable::install() { DataTable * table = DataTableManager::getTable(cs_citizenRankDataTableName, true); if (table) { int const columnRankName = table->findColumnNumber("rankName"); int const columnRankSlotId = table->findColumnNumber("rankSlotId"); int const columnTitle = table->findColumnNumber("title"); // the can be a variable number of "alternate title" columns, as long as the columns // are named alternateTitle1, alternateTitle2, alternateTitle3, alternateTitle4, // alternateTitle5, and so on std::vector<int> columnAlternateTitle; char buffer[128]; int columnNumber; for (int i = 1; i <= 1000000000; ++i) { snprintf(buffer, sizeof(buffer)-1, "alternateTitle%d", i); buffer[sizeof(buffer)-1] = '\0'; columnNumber = table->findColumnNumber(buffer); if (columnNumber < 0) break; columnAlternateTitle.push_back(columnNumber); } FATAL((columnRankName < 0), ("column \"rankName\" not found in %s", cs_citizenRankDataTableName)); FATAL((columnRankSlotId < 0), ("column \"rankSlotId\" not found in %s", cs_citizenRankDataTableName)); FATAL((columnTitle < 0), ("column \"title\" not found in %s", cs_citizenRankDataTableName)); CitizenRankDataTable::CitizenRank const * currentRank = NULL; int const numRows = table->getNumRows(); std::string rankName, alternateTitle; int slotId; bool title; std::vector<std::string> titles; std::map<std::string, int> names; std::map<int, CitizenRankDataTable::CitizenRank const *> allRanksById; for (int i = 0; i < numRows; ++i) { rankName = table->getStringValue(columnRankName, i); if (rankName.empty()) continue; FATAL((names.count(rankName) >= 1), ("%s, row %d: rank name %s already used at row %d (either as a rank name or rank alternate title)", cs_citizenRankDataTableName, (i+3), rankName.c_str(), names[rankName])); names[rankName] = (i+3); slotId = table->getIntValue(columnRankSlotId, i); title = (table->getIntValue(columnTitle, i) != 0); // read all alternate titles titles.clear(); if (title) titles.push_back(rankName); for (std::vector<int>::const_iterator iterColumnAlternateTitle = columnAlternateTitle.begin(); iterColumnAlternateTitle != columnAlternateTitle.end(); ++iterColumnAlternateTitle) { alternateTitle = table->getStringValue(*iterColumnAlternateTitle, i); if (!alternateTitle.empty()) { FATAL((names.count(alternateTitle) >= 1), ("%s, row %d: alternate title %s already used at row %d (either as a rank name or rank alternate title)", cs_citizenRankDataTableName, (i+3), alternateTitle.c_str(), names[alternateTitle])); names[alternateTitle] = (i+3); titles.push_back(alternateTitle); } } FATAL((!titles.empty() && !title), ("%s: rank %s cannot have any alternate titles unless it is defined as \"titleable\")", cs_citizenRankDataTableName, rankName.c_str())); // check for valid slot id FATAL((slotId < 0), ("%s, row %d: rank slot id %d must be >= 0", cs_citizenRankDataTableName, (i+3), slotId)); // create citizen rank info currentRank = new CitizenRank(rankName, slotId, titles); // check for duplicate slot id FATAL((allRanksById.count(slotId) >= 1), ("%s, row %d: rank slot id %d already used by rank %s", cs_citizenRankDataTableName, (i+3), slotId, allRanksById[slotId]->name.c_str())); allRanksById[slotId] = currentRank; s_allCitizenRankNames.push_back(currentRank->name); s_allCitizenRanks.push_back(currentRank); if (!currentRank->titles.empty()) s_allTitleableCitizenRanks.push_back(currentRank); s_allCitizenRanksByName[currentRank->name] = currentRank; for (std::vector<std::string>::const_iterator iterTitle = currentRank->titles.begin(); iterTitle != currentRank->titles.end(); ++iterTitle) s_allCitizenRanksByTitle[*iterTitle] = currentRank; } DataTableManager::close(cs_citizenRankDataTableName); // do additional verification slotId = -1; for (std::map<int, CitizenRankDataTable::CitizenRank const *>::const_iterator iterSlotId = allRanksById.begin(); iterSlotId != allRanksById.end(); ++iterSlotId) { FATAL((iterSlotId->first != iterSlotId->second->slotId), ("%s: slot id mismatch for slot %s (%d, %d)", cs_citizenRankDataTableName, iterSlotId->second->name.c_str(), iterSlotId->first, iterSlotId->second->slotId)); // make sure that slot ids start at 0 and there are no "holes" in the slot ids if (iterSlotId == allRanksById.begin()) { FATAL((iterSlotId->first != 0), ("%s: slot id must start at 0", cs_citizenRankDataTableName)); } else { FATAL(((slotId + 1) != iterSlotId->first), ("%s: slot id must be contiguous (there is a \"hole\" between %d and %d)", cs_citizenRankDataTableName, slotId, iterSlotId->first)); } slotId = iterSlotId->first; } } else { FATAL(true, ("citizen rank datatable %s not found", cs_citizenRankDataTableName)); } ExitChain::add(remove, "CitizenRankDataTable::remove"); }