bool loadDroidTemplates(const char *filename) { WzConfig ini(filename, WzConfig::ReadOnlyAndRequired); QStringList list = ini.childGroups(); for (int i = 0; i < list.size(); ++i) { ini.beginGroup(list[i]); DROID_TEMPLATE design = loadTemplateCommon(ini); design.id = list[i]; design.name = ini.value("name").toString(); design.multiPlayerID = generateNewObjectId(); design.prefab = true; design.stored = false; design.enabled = true; bool available = ini.value("available", false).toBool(); char const *droidResourceName = getDroidResourceName(list[i].toUtf8().constData()); design.name = droidResourceName != NULL ? droidResourceName : GetDefaultTemplateName(&design); ini.endGroup(); for (int i = 0; i < MAX_PLAYERS; ++i) { // Give those meant for humans to all human players. if (NetPlay.players[i].allocated && available) { design.prefab = false; copyTemplate(i, &design); // This sets up the UI templates for display purposes ONLY--we still only use droidTemplates for making them. // FIXME: Why are we doing this here, and not on demand ? // Only add unique designs to the UI list (Note, perhaps better to use std::map instead?) std::list<DROID_TEMPLATE>::iterator it; for (it = localTemplates.begin(); it != localTemplates.end(); ++it) { DROID_TEMPLATE *psCurr = &*it; if (psCurr->multiPlayerID == design.multiPlayerID) { debug(LOG_ERROR, "Design id:%d (%s) *NOT* added to UI list (duplicate), player= %d", design.multiPlayerID, getName(&design), i); break; } } if (it == localTemplates.end()) { debug(LOG_NEVER, "Design id:%d (%s) added to UI list, player =%d", design.multiPlayerID, getName(&design), i); localTemplates.push_back(design); } } else if (!NetPlay.players[i].allocated) // AI template { design.prefab = true; // prefabricated templates referenced from VLOs copyTemplate(i, &design); } } debug(LOG_NEVER, "Droid template found, Name: %s, MP ID: %d, ref: %u, ID: %s, prefab: %s, type:%d (loading)", getName(&design), design.multiPlayerID, design.ref, getID(&design), design.prefab ? "yes" : "no", design.droidType); } return true; }
/////////////////////////////////////////////////////////////////////////////// // splatter artifact gifts randomly about. void addMultiPlayerRandomArtifacts(uint8_t quantity, FEATURE_TYPE type) { int i, count; uint32_t x, y; uint8_t player = ANYPLAYER; debug(LOG_FEATURE, "Sending %u artifact(s) type: (%s)", quantity, feature_names[type]); NETbeginEncode(NETgameQueue(selectedPlayer), GAME_ARTIFACTS); NETuint8_t(&quantity); NETenum(&type); ASSERT(mapWidth > 20, "map not big enough"); ASSERT(mapHeight > 20, "map not big enough"); for (count = 0; count < quantity; count++) { uint32_t id = generateNewObjectId(); for (i = 0; i < 3; i++) // try three times { // Between 10 and mapwidth - 10 x = (rand()%(mapWidth - 20)) + 10; y = (rand()%(mapHeight - 20)) + 10; if (pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT)) { break; } else if (i == 2) { debug(LOG_FEATURE, "Unable to find a free location after 3 tries; giving up."); x = INVALID_XY; } } NETuint32_t(&x); NETuint32_t(&y); NETuint32_t(&id); NETuint8_t(&player); } NETend(); }
bool initTemplates() { WzConfig ini("templates.ini"); if (ini.status() != QSettings::NoError) { debug(LOG_FATAL, "Could not open templates.ini"); return false; } QStringList list = ini.childGroups(); for (int i = 0; i < list.size(); ++i) { ini.beginGroup(list[i]); DROID_TEMPLATE design; design.pName = NULL; design.droidType = (DROID_TYPE)ini.value("droidType").toInt(); design.multiPlayerID = generateNewObjectId(); design.asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("body", QString("ZNULLBODY")).toString().toUtf8().constData()); design.asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("brain", QString("ZNULLBRAIN")).toString().toUtf8().constData()); design.asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("propulsion", QString("ZNULLPROP")).toString().toUtf8().constData()); design.asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("repair", QString("ZNULLREPAIR")).toString().toUtf8().constData()); design.asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("ecm", QString("ZNULLECM")).toString().toUtf8().constData()); design.asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("sensor", QString("ZNULLSENSOR")).toString().toUtf8().constData()); design.asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("construct", QString("ZNULLCONSTRUCT")).toString().toUtf8().constData()); design.asWeaps[0] = getCompFromName(COMP_WEAPON, ini.value("weapon/1", QString("ZNULLWEAPON")).toString().toUtf8().constData()); design.asWeaps[1] = getCompFromName(COMP_WEAPON, ini.value("weapon/2", QString("ZNULLWEAPON")).toString().toUtf8().constData()); design.asWeaps[2] = getCompFromName(COMP_WEAPON, ini.value("weapon/3", QString("ZNULLWEAPON")).toString().toUtf8().constData()); design.numWeaps = ini.value("weapons").toInt(); design.prefab = false; // not AI template design.stored = true; bool valid = intValidTemplate(&design, ini.value("name").toString().toUtf8().constData()); if (!valid) { debug(LOG_ERROR, "Invalid template %d / %s from stored templates", i, list[i].toUtf8().constData()); continue; } addTemplateToList(&design, &apsDroidTemplates[selectedPlayer]); localTemplates.push_back(design); ini.endGroup(); } return true; }
// //////////////////////////////////////////////////////////////////////////// // add an artifact on destruction if required. void technologyGiveAway(const STRUCTURE *pS) { uint8_t count = 1; FEATURE_TYPE type = FEAT_GEN_ARTE; // If a fully built factory (or with modules under construction) which is our responsibility got destroyed if (pS->pStructureType->type == REF_FACTORY && (pS->status == SS_BUILT || pS->currentBuildPts >= pS->body) && myResponsibility(pS->player)) { uint32_t x = map_coord(pS->pos.x); uint32_t y = map_coord(pS->pos.y); uint32_t id = generateNewObjectId(); // Pick a tile to place the artifact if (!pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT)) { ASSERT(false, "technologyGiveAway: Unable to find a free location"); } NETbeginEncode(NETgameQueue(selectedPlayer), GAME_ARTIFACTS); { /* Make sure that we don't have to violate the constness of pS. * Since the nettype functions aren't const correct when sending */ uint8_t player = pS->player; NETuint8_t(&count); NETenum(&type); NETuint32_t(&x); NETuint32_t(&y); NETuint32_t(&id); NETuint8_t(&player); } NETend(); } return; }
bool initTemplates() { WzConfig ini("userdata/" + QString(rulesettag) + "/templates.ini"); if (ini.status() != QSettings::NoError) { debug(LOG_FATAL, "Could not open templates.ini"); return false; } QStringList list = ini.childGroups(); for (int i = 0; i < list.size(); ++i) { ini.beginGroup(list[i]); DROID_TEMPLATE design; design.droidType = (DROID_TYPE)ini.value("droidType").toInt(); design.multiPlayerID = generateNewObjectId(); design.asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("body", QString("ZNULLBODY")).toString()); design.asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("brain", QString("ZNULLBRAIN")).toString()); design.asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("propulsion", QString("ZNULLPROP")).toString()); design.asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("repair", QString("ZNULLREPAIR")).toString()); design.asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("ecm", QString("ZNULLECM")).toString()); design.asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("sensor", QString("ZNULLSENSOR")).toString()); design.asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("construct", QString("ZNULLCONSTRUCT")).toString()); design.asWeaps[0] = getCompFromName(COMP_WEAPON, ini.value("weapon/1", QString("ZNULLWEAPON")).toString()); design.asWeaps[1] = getCompFromName(COMP_WEAPON, ini.value("weapon/2", QString("ZNULLWEAPON")).toString()); design.asWeaps[2] = getCompFromName(COMP_WEAPON, ini.value("weapon/3", QString("ZNULLWEAPON")).toString()); design.numWeaps = ini.value("weapons").toInt(); design.prefab = false; // not AI template design.stored = true; if (!(asBodyStats + design.asParts[COMP_BODY])->designable || !(asPropulsionStats + design.asParts[COMP_PROPULSION])->designable || (design.asParts[COMP_BRAIN] > 0 && !(asBrainStats + design.asParts[COMP_BRAIN])->designable) || (design.asParts[COMP_REPAIRUNIT] > 0 && !(asRepairStats + design.asParts[COMP_REPAIRUNIT])->designable) || (design.asParts[COMP_ECM] > 0 && !(asECMStats + design.asParts[COMP_ECM])->designable) || (design.asParts[COMP_SENSOR] > 0 && !(asSensorStats + design.asParts[COMP_SENSOR])->designable) || (design.asParts[COMP_CONSTRUCT] > 0 && !(asConstructStats + design.asParts[COMP_CONSTRUCT])->designable) || (design.numWeaps > 0 && !(asWeaponStats + design.asWeaps[0])->designable) || (design.numWeaps > 1 && !(asWeaponStats + design.asWeaps[1])->designable) || (design.numWeaps > 2 && !(asWeaponStats + design.asWeaps[2])->designable)) { debug(LOG_ERROR, "Template %d / %s from stored templates cannot be designed", i, list[i].toUtf8().constData()); continue; } bool valid = intValidTemplate(&design, ini.value("name").toString().toUtf8().constData(), false, selectedPlayer); if (!valid) { debug(LOG_ERROR, "Invalid template %d / %s from stored templates", i, list[i].toUtf8().constData()); continue; } DROID_TEMPLATE *psDestTemplate = apsDroidTemplates[selectedPlayer]; while (psDestTemplate != NULL) { // Check if template is identical to a loaded template if (psDestTemplate->droidType == design.droidType && psDestTemplate->name.compare(design.name) == 0 && psDestTemplate->numWeaps == design.numWeaps && psDestTemplate->asWeaps[0] == design.asWeaps[0] && psDestTemplate->asWeaps[1] == design.asWeaps[1] && psDestTemplate->asWeaps[2] == design.asWeaps[2] && psDestTemplate->asParts[COMP_BODY] == design.asParts[COMP_BODY] && psDestTemplate->asParts[COMP_PROPULSION] == design.asParts[COMP_PROPULSION] && psDestTemplate->asParts[COMP_REPAIRUNIT] == design.asParts[COMP_REPAIRUNIT] && psDestTemplate->asParts[COMP_ECM] == design.asParts[COMP_ECM] && psDestTemplate->asParts[COMP_SENSOR] == design.asParts[COMP_SENSOR] && psDestTemplate->asParts[COMP_CONSTRUCT] == design.asParts[COMP_CONSTRUCT] && psDestTemplate->asParts[COMP_BRAIN] == design.asParts[COMP_BRAIN]) { break; } psDestTemplate = psDestTemplate->psNext; } if (psDestTemplate) { psDestTemplate->stored = true; // assimilate it ini.endGroup(); continue; // next! } design.enabled = allowDesign; addTemplateToList(&design, &apsDroidTemplates[selectedPlayer]); sendTemplate(selectedPlayer, &design); localTemplates.push_back(design); ini.endGroup(); } return true; }
/* load the Droid stats for the components from the Access database */ bool loadDroidTemplates(const char *filename) { WzConfig ini(filename, WzConfig::ReadOnlyAndRequired); QStringList list = ini.childGroups(); for (int i = 0; i < list.size(); ++i) { ini.beginGroup(list[i]); DROID_TEMPLATE design; QString droidType = ini.value("type").toString(); design.id = list[i]; design.name = ini.value("name").toString(); if (droidType == "PERSON") design.droidType = DROID_PERSON; else if (droidType == "CYBORG") design.droidType = DROID_CYBORG; else if (droidType == "CYBORG_SUPER") design.droidType = DROID_CYBORG_SUPER; else if (droidType == "CYBORG_CONSTRUCT") design.droidType = DROID_CYBORG_CONSTRUCT; else if (droidType == "CYBORG_REPAIR") design.droidType = DROID_CYBORG_REPAIR; else if (droidType == "TRANSPORTER") design.droidType = DROID_TRANSPORTER; else if (droidType == "SUPERTRANSPORTER") design.droidType = DROID_SUPERTRANSPORTER; else if (droidType == "DROID") design.droidType = DROID_DEFAULT; else ASSERT(false, "No such droid type \"%s\" for %s", droidType.toUtf8().constData(), getID(&design)); design.multiPlayerID = generateNewObjectId(); design.asParts[COMP_BODY] = getCompFromName(COMP_BODY, ini.value("compBody", "ZNULLBODY").toString()); design.asParts[COMP_BRAIN] = getCompFromName(COMP_BRAIN, ini.value("compBrain", "ZNULLBRAIN").toString()); design.asParts[COMP_REPAIRUNIT] = getCompFromName(COMP_REPAIRUNIT, ini.value("compRepair", "ZNULLREPAIR").toString()); design.asParts[COMP_CONSTRUCT] = getCompFromName(COMP_CONSTRUCT, ini.value("compConstruct", "ZNULLCONSTRUCT").toString()); design.asParts[COMP_ECM] = getCompFromName(COMP_ECM, ini.value("compECM", "ZNULLECM").toString()); design.asParts[COMP_SENSOR] = getCompFromName(COMP_SENSOR, ini.value("compSensor", "ZNULLSENSOR").toString()); design.asParts[COMP_PROPULSION] = getCompFromName(COMP_PROPULSION, ini.value("compPropulsion", "ZNULLPROP").toString()); QStringList weapons = ini.value("weapons").toStringList(); for (int j = 0; j < weapons.size(); j++) { design.asWeaps[j] = getCompFromName(COMP_WEAPON, weapons[j]); } design.numWeaps = weapons.size(); design.prefab = true; design.stored = false; design.enabled = true; bool available = ini.value("available", false).toBool(); char const *droidResourceName = getDroidResourceName(list[i].toUtf8().constData()); design.name = droidResourceName != NULL? droidResourceName : GetDefaultTemplateName(&design); ini.endGroup(); for (int i = 0; i < MAX_PLAYERS; ++i) { // Give those meant for humans to all human players. if (NetPlay.players[i].allocated && available) { design.prefab = false; addTemplateToList(&design, &apsDroidTemplates[i]); // This sets up the UI templates for display purposes ONLY--we still only use apsDroidTemplates for making them. // FIXME: Why are we doing this here, and not on demand ? // Only add unique designs to the UI list (Note, perhaps better to use std::map instead?) std::list<DROID_TEMPLATE>::iterator it; for (it = localTemplates.begin(); it != localTemplates.end(); ++it) { DROID_TEMPLATE *psCurr = &*it; if (psCurr->multiPlayerID == design.multiPlayerID) { debug(LOG_ERROR, "Design id:%d (%s) *NOT* added to UI list (duplicate), player= %d", design.multiPlayerID, getName(&design), i); break; } } if (it == localTemplates.end()) { debug(LOG_NEVER, "Design id:%d (%s) added to UI list, player =%d", design.multiPlayerID, getName(&design), i); localTemplates.push_front(design); } } else if (!NetPlay.players[i].allocated) // AI template { design.prefab = true; // prefabricated templates referenced from VLOs addTemplateToList(&design, &apsDroidTemplates[i]); } } debug(LOG_NEVER, "Droid template found, Name: %s, MP ID: %d, ref: %u, ID: %s, prefab: %s, type:%d (loading)", getName(&design), design.multiPlayerID, design.ref, getID(&design), design.prefab ? "yes":"no", design.droidType); } return true; }
bool initTemplates() { WzConfig ini("userdata/" + QString(rulesettag) + "/templates.json", WzConfig::ReadOnly); if (!ini.status()) { debug(LOG_WZ, "Could not open %s", ini.fileName().toUtf8().constData()); return false; } int version = ini.value("version", 0).toInt(); if (version == 0) { return true; // too old version } ini.beginArray("templates"); while (ini.remainingArrayItems()) { DROID_TEMPLATE design = loadTemplateCommon(ini); design.multiPlayerID = generateNewObjectId(); design.prefab = false; // not AI template design.stored = true; if (!(asBodyStats + design.asParts[COMP_BODY])->designable || !(asPropulsionStats + design.asParts[COMP_PROPULSION])->designable || (design.asParts[COMP_BRAIN] > 0 && !(asBrainStats + design.asParts[COMP_BRAIN])->designable) || (design.asParts[COMP_REPAIRUNIT] > 0 && !(asRepairStats + design.asParts[COMP_REPAIRUNIT])->designable) || (design.asParts[COMP_ECM] > 0 && !(asECMStats + design.asParts[COMP_ECM])->designable) || (design.asParts[COMP_SENSOR] > 0 && !(asSensorStats + design.asParts[COMP_SENSOR])->designable) || (design.asParts[COMP_CONSTRUCT] > 0 && !(asConstructStats + design.asParts[COMP_CONSTRUCT])->designable) || (design.numWeaps > 0 && !(asWeaponStats + design.asWeaps[0])->designable) || (design.numWeaps > 1 && !(asWeaponStats + design.asWeaps[1])->designable) || (design.numWeaps > 2 && !(asWeaponStats + design.asWeaps[2])->designable)) { debug(LOG_ERROR, "Template %s from stored templates cannot be designed", design.name.toUtf8().constData()); ini.nextArrayItem(); continue; } bool valid = intValidTemplate(&design, ini.value("name").toString().toUtf8().constData(), false, selectedPlayer); if (!valid) { debug(LOG_ERROR, "Invalid template %s from stored templates", design.name.toUtf8().constData()); ini.nextArrayItem(); continue; } DROID_TEMPLATE *psDestTemplate = NULL; for (auto &keyvaluepair : droidTemplates[selectedPlayer]) { psDestTemplate = keyvaluepair.second; // Check if template is identical to a loaded template if (psDestTemplate->droidType == design.droidType && psDestTemplate->name.compare(design.name) == 0 && psDestTemplate->numWeaps == design.numWeaps && psDestTemplate->asWeaps[0] == design.asWeaps[0] && psDestTemplate->asWeaps[1] == design.asWeaps[1] && psDestTemplate->asWeaps[2] == design.asWeaps[2] && psDestTemplate->asParts[COMP_BODY] == design.asParts[COMP_BODY] && psDestTemplate->asParts[COMP_PROPULSION] == design.asParts[COMP_PROPULSION] && psDestTemplate->asParts[COMP_REPAIRUNIT] == design.asParts[COMP_REPAIRUNIT] && psDestTemplate->asParts[COMP_ECM] == design.asParts[COMP_ECM] && psDestTemplate->asParts[COMP_SENSOR] == design.asParts[COMP_SENSOR] && psDestTemplate->asParts[COMP_CONSTRUCT] == design.asParts[COMP_CONSTRUCT] && psDestTemplate->asParts[COMP_BRAIN] == design.asParts[COMP_BRAIN]) { break; } psDestTemplate = NULL; } if (psDestTemplate) { psDestTemplate->stored = true; // assimilate it ini.nextArrayItem(); continue; // next! } design.enabled = allowDesign; copyTemplate(selectedPlayer, &design); localTemplates.push_back(design); ini.nextArrayItem(); } ini.endArray(); return true; }