void OutfitInfoDisplay::UpdateRequirements(const Outfit &outfit) { requirementLabels.clear(); requirementValues.clear(); requirementsHeight = 20; requirementLabels.push_back("cost:"); requirementValues.push_back(Format::Number(outfit.Cost())); requirementsHeight += 20; static const string names[] = { "outfit space needed:", "outfit space", "weapon capacity needed:", "weapon capacity", "engine capacity needed:", "engine capacity", "gun ports needed:", "gun ports", "turret mounts needed:", "turret mounts" }; static const int NAMES = sizeof(names) / sizeof(names[0]); for(int i = 0; i + 1 < NAMES; i += 2) if(outfit.Get(names[i + 1])) { requirementLabels.push_back(string()); requirementValues.push_back(string()); requirementsHeight += 10; requirementLabels.push_back(names[i]); requirementValues.push_back(Format::Number(-outfit.Get(names[i + 1]))); requirementsHeight += 20; } }
void OutfitInfoDisplay::UpdateRequirements(const Outfit &outfit, const PlayerInfo &player, bool canSell) { requirementLabels.clear(); requirementValues.clear(); requirementsHeight = 20; int day = player.GetDate().DaysSinceEpoch(); int64_t cost = outfit.Cost(); int64_t buyValue = player.StockDepreciation().Value(&outfit, day); int64_t sellValue = player.FleetDepreciation().Value(&outfit, day); if(buyValue == cost) requirementLabels.push_back("cost:"); else { ostringstream out; out << "cost (" << (100 * buyValue) / cost << "%):"; requirementLabels.push_back(out.str()); } requirementValues.push_back(Format::Number(buyValue)); requirementsHeight += 20; if(canSell && sellValue != buyValue) { if(sellValue == cost) requirementLabels.push_back("sells for:"); else { ostringstream out; out << "sells for (" << (100 * sellValue) / cost << "%):"; requirementLabels.push_back(out.str()); } requirementValues.push_back(Format::Number(sellValue)); requirementsHeight += 20; } static const string names[] = { "outfit space needed:", "outfit space", "weapon capacity needed:", "weapon capacity", "engine capacity needed:", "engine capacity", "gun ports needed:", "gun ports", "turret mounts needed:", "turret mounts" }; static const int NAMES = sizeof(names) / sizeof(names[0]); for(int i = 0; i + 1 < NAMES; i += 2) if(outfit.Get(names[i + 1])) { requirementLabels.push_back(string()); requirementValues.push_back(string()); requirementsHeight += 10; requirementLabels.push_back(names[i]); requirementValues.push_back(Format::Number(-outfit.Get(names[i + 1]))); requirementsHeight += 20; } }
int push_luavalue(const Outfit& outfit) { g_lua.createTable(0, 8); g_lua.pushInteger(outfit.getId()); g_lua.setField("type"); g_lua.pushInteger(outfit.getAuxId()); g_lua.setField("auxType"); if(g_game.getFeature(Otc::GamePlayerAddons)) { g_lua.pushInteger(outfit.getAddons()); g_lua.setField("addons"); } g_lua.pushInteger(outfit.getHead()); g_lua.setField("head"); g_lua.pushInteger(outfit.getBody()); g_lua.setField("body"); g_lua.pushInteger(outfit.getLegs()); g_lua.setField("legs"); g_lua.pushInteger(outfit.getFeet()); g_lua.setField("feet"); if(g_game.getFeature(Otc::GamePlayerMounts)) { g_lua.pushInteger(outfit.getMount()); g_lua.setField("mount"); } return 1; }
void OutfitterPanel::DrawOutfit(const Outfit &outfit, const Point ¢er, bool isSelected, bool isOwned) { const Sprite *thumbnail = outfit.Thumbnail(); const Sprite *back = SpriteSet::Get( isSelected ? "ui/outfitter selected" : "ui/outfitter unselected"); SpriteShader::Draw(back, center); SpriteShader::Draw(thumbnail, center); // Draw the outfit name. const string &name = outfit.Name(); const Font &font = FontSet::Get(14); Point offset(-.5f * font.Width(name), -.5f * OUTFIT_SIZE + 10.f); font.Draw(name, center + offset, Color((isSelected | isOwned) ? .8 : .5, 0.)); }
bool luavalue_cast(int index, Outfit& outfit) { if(g_lua.isTable(index)) { g_lua.getField("type", index); outfit.setId(g_lua.popInteger()); g_lua.getField("auxType", index); outfit.setAuxId(g_lua.popInteger()); if(g_game.getFeature(Otc::GamePlayerAddons)) { g_lua.getField("addons", index); outfit.setAddons(g_lua.popInteger()); } g_lua.getField("head", index); outfit.setHead(g_lua.popInteger()); g_lua.getField("body", index); outfit.setBody(g_lua.popInteger()); g_lua.getField("legs", index); outfit.setLegs(g_lua.popInteger()); g_lua.getField("feet", index); outfit.setFeet(g_lua.popInteger()); if(g_game.getFeature(Otc::GamePlayerMounts)) { g_lua.getField("mount", index); outfit.setMount(g_lua.popInteger()); } return true; } return false; }
// Call this every time the ship changes. void OutfitInfoDisplay::Update(const Outfit &outfit) { UpdateDescription(outfit.Description()); UpdateRequirements(outfit); UpdateAttributes(outfit); maximumHeight = max(descriptionHeight, max(requirementsHeight, attributesHeight)); }
// Call this every time the ship changes. void OutfitInfoDisplay::Update(const Outfit &outfit, const PlayerInfo &player, bool canSell) { UpdateDescription(outfit.Description()); UpdateRequirements(outfit, player, canSell); UpdateAttributes(outfit); maximumHeight = max(descriptionHeight, max(requirementsHeight, attributesHeight)); }
bool OutfitterPanel::ShipCanSell(const Ship *ship, const Outfit *outfit) { if(!ship->OutfitCount(outfit)) return false; // If this outfit requires ammo, check if we could sell it if we sold all // the ammo for it first. const Outfit *ammo = outfit->Ammo(); if(ammo && ship->OutfitCount(ammo)) { Outfit attributes = ship->Attributes(); attributes.Add(*ammo, -ship->OutfitCount(ammo)); return attributes.CanAdd(*outfit, -1); } // Now, check whether this ship can sell this outfit. return ship->Attributes().CanAdd(*outfit, -1); }
void OutfitInfoDisplay::UpdateDescription(const Outfit &outfit) { description.SetAlignment(WrappedText::JUSTIFIED); description.SetWrapWidth(WIDTH - 20); description.SetFont(FontSet::Get(14)); description.Wrap(outfit.Description()); // Pad by 10 pixels on the top and bottom. descriptionHeight = description.Height() + 20; }
void Game::processOpenOutfitWindow(const Outfit& currentOufit, const std::vector<std::tuple<int, std::string, int> >& outfitList, const std::vector<std::tuple<int, std::string> >& mountList) { // create virtual creature outfit CreaturePtr virtualOutfitCreature = CreaturePtr(new Creature); virtualOutfitCreature->setDirection(Otc::South); Outfit outfit = currentOufit; outfit.setMount(0); virtualOutfitCreature->setOutfit(outfit); // creature virtual mount outfit CreaturePtr virtualMountCreature = nullptr; if(getFeature(Otc::GamePlayerMounts)) { virtualMountCreature = CreaturePtr(new Creature); virtualMountCreature->setDirection(Otc::South); if(currentOufit.getMount() > 0) { Outfit mountOutfit; mountOutfit.setId(currentOufit.getMount()); virtualMountCreature->setOutfit(mountOutfit); } } g_lua.callGlobalField("g_game", "onOpenOutfitWindow", virtualOutfitCreature, outfitList, virtualMountCreature, mountList); }
void ProtocolGame::sendChangeOutfit(const Outfit& outfit) { OutputMessagePtr msg(new OutputMessage); msg->addU8(Proto::ClientChangeOutfit); msg->addU16(outfit.getId()); msg->addU8(outfit.getHead()); msg->addU8(outfit.getBody()); msg->addU8(outfit.getLegs()); msg->addU8(outfit.getFeet()); msg->addU8(outfit.getAddons()); if(g_game.getFeature(Otc::GamePlayerMounts)) msg->addU16(outfit.getMount()); send(msg); }
void Creature::setOutfit(const Outfit& outfit) { if(outfit.getCategory() != ThingCategoryCreature) { if(!g_things.isValidDatId(outfit.getAuxId(), outfit.getCategory())) return; m_outfit.setAuxId(outfit.getAuxId()); m_outfit.setCategory(outfit.getCategory()); } else { if(outfit.getId() > 0 && !g_things.isValidDatId(outfit.getId(), ThingCategoryCreature)) return; m_outfit = outfit; } m_walkAnimationPhase = 0; // might happen when player is walking and outfit is changed. }
void ProtocolGame::sendChangeOutfit(const Outfit& outfit) { OutputMessage msg; msg.addU8(Proto::ClientChangeOutfit); msg.addU16(outfit.getId()); msg.addU8(outfit.getHead()); msg.addU8(outfit.getBody()); msg.addU8(outfit.getLegs()); msg.addU8(outfit.getFeet()); msg.addU8(outfit.getAddons()); send(msg); }
void ProtocolGame::sendSetOutfit(const Outfit& outfit) { OutputMessage oMsg; oMsg.addU8(Proto::ClientSetOutfit); oMsg.addU16(outfit.getId()); oMsg.addU8(outfit.getHead()); oMsg.addU8(outfit.getBody()); oMsg.addU8(outfit.getLegs()); oMsg.addU8(outfit.getFeet()); oMsg.addU8(outfit.getAddons()); send(oMsg); }
void testNames() { Dweller *d = new Dweller("Pip-Boy", 2222222); Outfit *o = new Outfit("Minuteman", 10, 2200220); Weapon *w = new Weapon("Gauss", 16, 16); Vec2D currentPos (3.54, 6.32 ); // hold a list of game objects that was instantiated. vector<GameObject *> gameObjectList; gameObjectList.push_back(d); gameObjectList.push_back(o); gameObjectList.push_back(w); // test Dweller public functions d->getSPECIAL(); d->getCurrentHealth(); d->getCurrentRadDamage(); d->getAttackDmg(); d->setPosition(currentPos); d->getPosition() ; d->receiveHealthDamage(13); d->receiveRadDamage(15); d->receiveEquipmentDamage(4); d->addStimpak(2); d->addRadAway(5); d->useStimpak(); d->useRadAway(); d->assignOutfit(o); d->assignWeapon(w); d->isDead() ; // test Outfit public functions o->getSPECIAL(); o->receiveDamage(1); // test Weapon public functions w->getAttackDmg(); w->receiveDamage(1); // test Item inheritance Item *i = o; i->getDurability(); i->receiveDamage(1); i = w; i->getDurability(); i->receiveDamage(1); // test game object inheritance for (auto go : gameObjectList) { go->getName(); } GameObject::getCount(); // release the memory for (auto go : gameObjectList) { delete go; } }
void OutfitInfoDisplay::UpdateAttributes(const Outfit &outfit) { attributeLabels.clear(); attributeValues.clear(); attributesHeight = 20; map<string, map<string, int>> listing; for(const auto &it : outfit.Attributes()) { if(it.first == "outfit space" || it.first == "weapon capacity" || it.first == "engine capacity" || it.first == "gun ports" || it.first == "turret mounts") continue; string value; double scale = 1.; if(it.first == "thrust" || it.first == "reverse thrust" || it.first == "afterburner thrust") scale = 60. * 60.; else if(ATTRIBUTES_TO_SCALE.count(it.first)) scale = 60.; if(BOOLEAN_ATTRIBUTES.count(it.first)) { attributeLabels.push_back("This outfit is " + it.first + "."); attributeValues.push_back(" "); attributesHeight += 20; } else { attributeLabels.push_back(it.first + ':'); attributeValues.push_back(Format::Number(it.second * scale)); attributesHeight += 20; } } if(!outfit.IsWeapon()) return; attributeLabels.push_back(string()); attributeValues.push_back(string()); attributesHeight += 10; if(outfit.Ammo()) { attributeLabels.push_back("ammo:"); attributeValues.push_back(outfit.Ammo()->Name()); attributesHeight += 20; } attributeLabels.push_back("range:"); attributeValues.push_back(Format::Number(outfit.Range())); attributesHeight += 20; if(outfit.ShieldDamage() && outfit.Reload()) { attributeLabels.push_back("shield damage / second:"); attributeValues.push_back(Format::Number(60. * outfit.ShieldDamage() / outfit.Reload())); attributesHeight += 20; } if(outfit.HullDamage() && outfit.Reload()) { attributeLabels.push_back("hull damage / second:"); attributeValues.push_back(Format::Number(60. * outfit.HullDamage() / outfit.Reload())); attributesHeight += 20; } if(outfit.HeatDamage() && outfit.Reload()) { attributeLabels.push_back("heat damage / second:"); attributeValues.push_back(Format::Number(60. * outfit.HeatDamage() / outfit.Reload())); attributesHeight += 20; } if(outfit.IonDamage() && outfit.Reload()) { attributeLabels.push_back("ion damage / second:"); attributeValues.push_back(Format::Number(6000. * outfit.IonDamage() / outfit.Reload())); attributesHeight += 20; } if(outfit.SlowingDamage() && outfit.Reload()) { attributeLabels.push_back("slowing damage / second:"); attributeValues.push_back(Format::Number(6000. * outfit.SlowingDamage() / outfit.Reload())); attributesHeight += 20; } if(outfit.DisruptionDamage() && outfit.Reload()) { attributeLabels.push_back("disruption damage / second:"); attributeValues.push_back(Format::Number(6000. * outfit.DisruptionDamage() / outfit.Reload())); attributesHeight += 20; } if(outfit.FiringEnergy() && outfit.Reload()) { attributeLabels.push_back("firing energy / second:"); attributeValues.push_back(Format::Number(60. * outfit.FiringEnergy() / outfit.Reload())); attributesHeight += 20; } if(outfit.FiringHeat() && outfit.Reload()) { attributeLabels.push_back("firing heat / second:"); attributeValues.push_back(Format::Number(60. * outfit.FiringHeat() / outfit.Reload())); attributesHeight += 20; } if(outfit.FiringFuel() && outfit.Reload()) { attributeLabels.push_back("firing fuel / second:"); attributeValues.push_back(Format::Number(60. * outfit.FiringFuel() / outfit.Reload())); attributesHeight += 20; } bool isContinuous = (outfit.Reload() <= 1); attributeLabels.push_back("shots / second:"); if(isContinuous) attributeValues.push_back("continuous"); else attributeValues.push_back(Format::Number(60. / outfit.Reload())); attributesHeight += 20; int homing = outfit.Homing(); if(homing) { static const string skill[] = { "no", "poor", "fair", "good", "excellent" }; attributeLabels.push_back("homing:"); attributeValues.push_back(skill[max(0, min(4, homing))]); attributesHeight += 20; } static const string percentNames[] = { "tracking:", "optical tracking:", "infrared tracking:", "radar tracking:", "piercing:" }; double percentValues[] = { outfit.Tracking(), outfit.OpticalTracking(), outfit.InfraredTracking(), outfit.RadarTracking(), outfit.Piercing() }; for(unsigned i = 0; i < sizeof(percentValues) / sizeof(percentValues[0]); ++i) if(percentValues[i]) { int percent = 100. * percentValues[i] + .5; attributeLabels.push_back(percentNames[i]); attributeValues.push_back(Format::Number(percent) + "%"); attributesHeight += 20; } attributeLabels.push_back(string()); attributeValues.push_back(string()); attributesHeight += 10; static const string names[] = { "shield damage / shot:", "hull damage / shot:", "heat damage / shot:", "ion damage / shot:", "slowing damage / shot:", "disruption damage / shot:", "firing energy / shot:", "firing heat / shot:", "firing fuel / shot:", "inaccuracy:", "blast radius:", "missile strength:", "anti-missile:", }; double values[] = { outfit.ShieldDamage(), outfit.HullDamage(), outfit.HeatDamage(), outfit.IonDamage() * 100., outfit.SlowingDamage() * 100., outfit.DisruptionDamage() * 100., outfit.FiringEnergy(), outfit.FiringHeat(), outfit.FiringFuel(), outfit.Inaccuracy(), outfit.BlastRadius(), static_cast<double>(outfit.MissileStrength()), static_cast<double>(outfit.AntiMissile()) }; static const int NAMES = sizeof(names) / sizeof(names[0]); for(int i = (isContinuous ? 9 : 0); i < NAMES; ++i) if(values[i]) { attributeLabels.push_back(names[i]); attributeValues.push_back(Format::Number(values[i])); attributesHeight += 20; } }
Outfit ProtocolGame::internalGetOutfit(InputMessage& msg) { Outfit outfit; int id = msg.getU16(); if(id != 0) { outfit.setCategory(ThingsType::Creature); int head = msg.getU8(); int body = msg.getU8(); int legs = msg.getU8(); int feet = msg.getU8(); int addons = msg.getU8(); outfit.setId(id); outfit.setHead(head); outfit.setBody(body); outfit.setLegs(legs); outfit.setFeet(feet); outfit.setAddons(addons); } else { int id = msg.getU16(); if(id == 0) { outfit.setCategory(ThingsType::Effect); outfit.setId(13); } else { outfit.setCategory(ThingsType::Item); outfit.setId(id); } } return outfit; }
void CreatureManager::internalLoadCreatureBuffer(TiXmlElement* attrib, const CreatureTypePtr& m) { if(std::find(m_creatures.begin(), m_creatures.end(), m) != m_creatures.end()) return; Outfit out; int32 type = attrib->readType<int32>("type"); if(type > 0) { out.setCategory(ThingCategoryCreature); out.setId(type); } else { out.setCategory(ThingCategoryItem); out.setAuxId(attrib->readType<int32>("typeex")); } { out.setHead(attrib->readType<int>(("head"))); out.setBody(attrib->readType<int>(("body"))); out.setLegs(attrib->readType<int>(("legs"))); out.setFeet(attrib->readType<int>(("feet"))); out.setAddons(attrib->readType<int>(("addons"))); out.setMount(attrib->readType<int>(("mount"))); } m->setOutfit(out); m_creatures.push_back(m); }
void OutfitInfoDisplay::UpdateAttributes(const Outfit &outfit) { attributeLabels.clear(); attributeValues.clear(); attributesHeight = 20; map<string, map<string, int>> listing; for(const auto &it : outfit.Attributes()) { if(it.first == "cost" || it.first == "outfit space" || it.first == "weapon capacity" || it.first == "engine capacity" || it.first == "gun ports" || it.first == "turret mounts") continue; attributeLabels.push_back(it.first + ':'); attributeValues.push_back(Format::Number(it.second)); attributesHeight += 20; } if(!outfit.IsWeapon()) return; attributeLabels.push_back(string()); attributeValues.push_back(string()); attributesHeight += 10; if(outfit.Ammo()) { attributeLabels.push_back("ammo:"); attributeValues.push_back(outfit.Ammo()->Name()); attributesHeight += 20; } attributeLabels.push_back("range:"); attributeValues.push_back(Format::Number(outfit.Range())); attributesHeight += 20; if(outfit.ShieldDamage() && outfit.Reload()) { attributeLabels.push_back("shield damage / second:"); attributeValues.push_back(Format::Number(60. * outfit.ShieldDamage() / outfit.Reload())); attributesHeight += 20; } if(outfit.HullDamage() && outfit.Reload()) { attributeLabels.push_back("hull damage / second:"); attributeValues.push_back(Format::Number(60. * outfit.HullDamage() / outfit.Reload())); attributesHeight += 20; } if(outfit.FiringEnergy() && outfit.Reload()) { attributeLabels.push_back("firing energy / second:"); attributeValues.push_back(Format::Number(60. * outfit.FiringEnergy() / outfit.Reload())); attributesHeight += 20; } if(outfit.Reload() > 1) { attributeLabels.push_back("shots / second:"); attributeValues.push_back(Format::Number(60. / outfit.Reload())); attributesHeight += 20; } int homing = outfit.Homing(); if(homing) { static const string skill[] = { "no", "poor", "fair", "good", "excellent" }; attributeLabels.push_back("homing:"); attributeValues.push_back(skill[max(0, min(4, homing))]); attributesHeight += 20; } attributeLabels.push_back(string()); attributeValues.push_back(string()); attributesHeight += 10; static const string names[] = { "inaccuracy:", "firing energy:", "firing heat:", "blast radius:", "missile strength:", "anti-missile:", }; double values[] = { outfit.Inaccuracy(), outfit.FiringEnergy(), outfit.FiringHeat(), outfit.BlastRadius(), static_cast<double>(outfit.MissileStrength()), static_cast<double>(outfit.AntiMissile()) }; static const int NAMES = sizeof(names) / sizeof(names[0]); for(int i = 0; i < NAMES; ++i) if(values[i]) { attributeLabels.push_back(names[i]); attributeValues.push_back(Format::Number(values[i])); attributesHeight += 20; } }