void nobBaseWarehouse::HandleCollectEvent() { // Storing wares done? bool storing_done = false; // Is storing still wanted? bool storing_wanted = false; // Untersuchen, welche Waren und Figuren eingelagert werden sollen for(unsigned i = 0; i < WARE_TYPES_COUNT; ++i) { // Soll Ware eingeliefert werden? if(!GetInventorySetting(GoodType(i)).IsSet(EInventorySetting::COLLECT)) continue; storing_wanted = true; // Lagerhaus suchen, das diese Ware enthält nobBaseWarehouse* wh = gwg->GetPlayer(player).FindWarehouse(*this, FW::HasWareButNoCollect(GoodType(i)), false, false); // Gefunden? if(wh) { // Dann bestellen Ware* ware = wh->OrderWare(GoodType(i), this); if(ware) { RTTR_Assert(IsWareDependent(ware)); storing_done = true; break; } } } // Menschen "bestellen" wenn noch keine Ware bestellt wurde if(!storing_done) { for(unsigned i = 0; i < JOB_TYPES_COUNT; ++i) { // Soll dieser Typ von Mensch bestellt werden? if(!GetInventorySetting(Job(i)).IsSet(EInventorySetting::COLLECT)) continue; storing_wanted = true; // Lagerhaus suchen, das diesen Job enthält nobBaseWarehouse* wh = gwg->GetPlayer(player).FindWarehouse(*this, FW::HasFigureButNoCollect(Job(i), false), false, false); // Gefunden? if(wh) { // Dann bestellen if(wh->OrderJob(Job(i), this, false)) break; } } } // Storing still wanted? // Then continue ordering new stuff if(storing_wanted) store_event = em->AddEvent(this, STORE_INTERVAL, 4); }
void nobBaseWarehouse::Clear() { for(unsigned i = 0; i < WARE_TYPES_COUNT; ++i) gwg->GetPlayer(player).DecreaseInventoryWare(GoodType(i), inventory[GoodType(i)]); for(unsigned i = 0; i < JOB_TYPES_COUNT; ++i) gwg->GetPlayer(player).DecreaseInventoryJob(Job(i), inventory[Job(i)]); inventory.clear(); for(std::list<Ware*>::iterator it = waiting_wares.begin(); it != waiting_wares.end(); ++it) { (*it)->WareLost(player); (*it)->Destroy(); delete (*it); } waiting_wares.clear(); for (unsigned i = 0; i < 5; ++i) { // TODO: inventory!? reserve_soldiers_available[i] = 0; reserve_soldiers_claimed_visual[i] = 0; reserve_soldiers_claimed_real[i] = 0; } }
void nobBaseWarehouse::AddToInventory() { for(unsigned int i = 0; i < WARE_TYPES_COUNT; ++i) gwg->GetPlayer(player).IncreaseInventoryWare(GoodType(i), inventory[GoodType(i)]); for(unsigned int i = 0; i < JOB_TYPES_COUNT; ++i) gwg->GetPlayer(player).IncreaseInventoryJob(Job(i), inventory[Job(i)]); }
iwTrade::iwTrade(const nobBaseWarehouse& wh, const GameWorldViewer& gwv, GameCommandFactory& gcFactory) : IngameWindow(wh.CreateGUIID(), (unsigned short) - 2, (unsigned short) - 2, 400, 194, _("Trade"), LOADER.GetImageN("resource", 41)), wh(wh), gwv(gwv), gcFactory(gcFactory), possibleSrcWarehouses(gwv.GetPlayer().GetWarehousesForTrading(wh)) { // Get title of the player SetTitle(_("Trade with %s") + gwv.GetWorld().GetPlayer(wh.GetPlayer()).name); // Gebäudebild und dessen Schatten AddImage( 0, 100, 144, LOADER.GetNationImage(wh.GetNation(), 250 + 5 * wh.GetBuildingType())); const unsigned left_column = 200; this->AddComboBox(4, left_column, 84, 160, 18, TC_GREY, NormalFont, 90); // Ware/Figure names this->AddText(1, left_column, 30, "Deal in:", COLOR_YELLOW, glArchivItem_Font::DF_LEFT, NormalFont); ctrlComboBox* box = this->AddComboBox(2, left_column, 44, 160, 18, TC_GREY, NormalFont, 200); // Ware or figure? box->AddString(_("Wares")); box->AddString(_("Settlers")); this->AddText(3, left_column, 70, "Type:", COLOR_YELLOW, glArchivItem_Font::DF_LEFT, NormalFont); // Create possible wares, figures for(unsigned i = 0; i < WARE_TYPES_COUNT; ++i) { // Only add one shield type if(GoodType(i) != ConvertShields(GoodType(i))) continue; // Don't add nothing or empty water if(i == GD_NOTHING || i == GD_WATEREMPTY) continue; wares.push_back(GoodType(i)); } for(unsigned i = 0; i < JOB_TYPES_COUNT; ++i) { // Can't trade boat carriers if(i == JOB_BOATCARRIER) continue; jobs.push_back(Job(i)); } AddImage(5, left_column + 20, 130, NULL, _("Ware you like to trade")); AddEdit(6, left_column + 34, 120, 39 , 20, TC_GREY, NormalFont)->SetNumberOnly(true); AddText(7, left_column + 75, 125, "/ 20", COLOR_YELLOW, glArchivItem_Font::DF_LEFT, NormalFont); AddTextButton(8, left_column, 150, 150, 22, TC_GREEN2, _("Send"), NormalFont); // Choose wares at first box->SetSelection(0); Msg_ComboSelectItem(2, 0); }
iwTrade::iwTrade(const nobBaseWarehouse& wh, const GameWorldViewer& gwv, GameCommandFactory& gcFactory) : IngameWindow(wh.CreateGUIID(), IngameWindow::posAtMouse, Extent(400, 194), _("Trade"), LOADER.GetImageN("resource", 41)), wh(wh), gwv(gwv), gcFactory(gcFactory), possibleSrcWarehouses(gwv.GetPlayer().GetWarehousesForTrading(wh)) { // Get title of the player SetTitle((boost::format(_("Trade with %s")) % gwv.GetWorld().GetPlayer(wh.GetPlayer()).name).str()); // Gebäudebild und dessen Schatten AddImage(0, DrawPoint(100, 144), LOADER.GetNationImage(wh.GetNation(), 250 + 5 * wh.GetBuildingType())); const unsigned left_column = 200; AddComboBox(4, DrawPoint(left_column, 84), Extent(160, 18), TC_GREY, NormalFont, 90); // Ware/Figure names AddText(1, DrawPoint(left_column, 30), "Deal in:", COLOR_YELLOW, FontStyle::LEFT, NormalFont); ctrlComboBox* box = this->AddComboBox(2, DrawPoint(left_column, 44), Extent(160, 18), TC_GREY, NormalFont, 200); // Ware or figure? box->AddString(_("Wares")); box->AddString(_("Settlers")); AddText(3, DrawPoint(left_column, 70), "Type:", COLOR_YELLOW, FontStyle::LEFT, NormalFont); // Create possible wares, figures for(unsigned i = 0; i < NUM_WARE_TYPES; ++i) { // Only add one shield type if(GoodType(i) != ConvertShields(GoodType(i))) continue; // Don't add empty water if(i == GD_WATEREMPTY) continue; wares.push_back(GoodType(i)); } for(unsigned i = 0; i < NUM_JOB_TYPES; ++i) { // Can't trade boat carriers if(i == JOB_BOATCARRIER) continue; jobs.push_back(Job(i)); } AddImage(5, DrawPoint(left_column + 20, 130), static_cast<ITexture*>(nullptr), _("Ware you like to trade")); AddEdit(6, DrawPoint(left_column + 34, 120), Extent(39, 20), TC_GREY, NormalFont)->SetNumberOnly(true); AddText(7, DrawPoint(left_column + 75, 125), "/ 20", COLOR_YELLOW, FontStyle::LEFT, NormalFont); AddTextButton(8, DrawPoint(left_column, 150), Extent(150, 22), TC_GREEN2, _("Send"), NormalFont); // Choose wares at first box->SetSelection(0); Msg_ComboSelectItem(2, 0); }
Ware::Ware(SerializedGameData& sgd, const unsigned obj_id) : GameObject(sgd, obj_id), next_dir(sgd.PopUnsignedChar()), state(State(sgd.PopUnsignedChar())), location(sgd.PopObject<noRoadNode>(GOT_UNKNOWN)), type(GoodType(sgd.PopUnsignedChar())), goal(sgd.PopObject<noBaseBuilding>(GOT_UNKNOWN)), next_harbor(sgd.PopMapPoint()) {}
/// Fügt einige Güter hinzu void nobBaseWarehouse::AddGoods(const Inventory& goods) { for(unsigned int i = 0; i < WARE_TYPES_COUNT; ++i) { inventory.Add(GoodType(i), goods.goods[i]); if(goods.goods[i]) CheckUsesForNewWare(GoodType(i)); } for(unsigned int i = 0; i < JOB_TYPES_COUNT; ++i) { inventory.Add(Job(i), goods.people[i]); if(goods.people[i]) CheckJobsForNewFigure(Job(i)); } }
bool isAnyGoodStored() { bool anyGoodStored = false; for( int i = 0; i < G_MAX; ++i) { anyGoodStored |= ( goodStore.getCurrentQty( GoodType(i) ) >= 100 ); } return anyGoodStored; }
nofTradeDonkey::nofTradeDonkey(SerializedGameData * sgd, const unsigned obj_id) : noFigure(sgd,obj_id), leader(sgd->PopObject<nofTradeLeader>(GOT_NOF_TRADELEADER)), successor(sgd->PopObject<nofTradeDonkey>(GOT_NOF_TRADEDONKEY)), gt(GoodType(sgd->PopUnsignedChar())), next_dirs(sgd->PopUnsignedInt()) { for(unsigned i = 0;i<next_dirs.size();++i) next_dirs[i] = sgd->PopUnsignedChar(); }
void nobBaseWarehouse::Destroy_nobBaseWarehouse() { if(GetBuildingType() != BLD_HARBORBUILDING) { // Aus der Warenhausliste entfernen gwg->GetPlayer(player).RemoveWarehouse(this); }else { // Harbors should also remove the warehouse RTTR_Assert(!helpers::contains(gwg->GetPlayer(player).GetStorehouses(), this)); } // Den Waren und Figuren Bescheid sagen, die zu uns auf den Weg sind, dass wir nun nicht mehr existieren for(std::list<noFigure*>::iterator it = dependent_figures.begin(); it != dependent_figures.end(); ++it) (*it)->GoHome(); dependent_figures.clear(); for(std::list<Ware*>::iterator it = dependent_wares.begin(); it!=dependent_wares.end(); ++it) WareNotNeeded(*it); dependent_wares.clear(); // ggf. Events abmelden em->RemoveEvent(recruiting_event); em->RemoveEvent(producinghelpers_event); em->RemoveEvent(empty_event); em->RemoveEvent(store_event); // Waiting Wares löschen for(std::list<Ware*>::iterator it = waiting_wares.begin(); it != waiting_wares.end(); ++it) { (*it)->WareLost(player); delete (*it); } waiting_wares.clear(); // restliche Warenbestände von der Inventur wieder abziehen for(unsigned int i = 0; i < WARE_TYPES_COUNT; ++i) gwg->GetPlayer(player).DecreaseInventoryWare(GoodType(i), inventory[GoodType(i)]); // Objekt, das die flüchtenden Leute nach und nach ausspuckt, erzeugen new BurnedWarehouse(pos, player, inventory.real.people); Destroy_nobBaseMilitary(); }
Ware::Ware(SerializedGameData * sgd, const unsigned obj_id) : GameObject(sgd,obj_id), next_dir(sgd->PopUnsignedChar()), state(State(sgd->PopUnsignedChar())), location(sgd->PopObject<noRoadNode>(GOT_UNKNOWN)), type(GoodType(sgd->PopUnsignedChar())), goal(sgd->PopObject<noBaseBuilding>(GOT_UNKNOWN)) { next_harbor.x = sgd->PopUnsignedShort(); next_harbor.y = sgd->PopUnsignedShort(); //assert(obj_id != 1197877); }
int GameWorldBase::LUA_AddWares(lua_State *L) { // GameWorldBase *gw = static_cast<GameWorldBase*>(lua_touserdata(L,lua_upvalueindex(1))); int argc = lua_gettop(L) - 1; if ((argc < 0) || (argc % 2 == 1)) { lua_pushstring(L, "wrong arguments: player, ware1, count1, ware2, count2, ..."); lua_error(L); return(0); } // player unsigned pnr = luaL_checknumber(L, 1); if (pnr >= GAMECLIENT.GetPlayerCount()) { lua_pushstring(L, "player number invalid!"); lua_error(L); return(0); } GameClientPlayer *player = GAMECLIENT.GetPlayer(pnr); nobBaseWarehouse *warehouse = player->GetFirstWH(); if (warehouse == NULL) { lua_pushstring(L, "player has no warehouses!"); lua_error(L); return(0); } Goods goods; unsigned cnt = 2; for (argc >>= 1; argc > 0; --argc) { unsigned type = luaL_checknumber(L, cnt++); unsigned count = luaL_checknumber(L, cnt++); if (type < WARE_TYPES_COUNT) { goods.goods[type] += count; player->IncreaseInventoryWare(GoodType(type), count); } } warehouse->AddGoods(goods); return(0); }
nofBuildingWorker::nofBuildingWorker(SerializedGameData& sgd, const unsigned obj_id) : noFigure(sgd, obj_id), state(State(sgd.PopUnsignedChar())) { if(fs != FS_GOHOME && fs != FS_WANDER) { workplace = sgd.PopObject<nobUsual>(GOT_UNKNOWN); ware = GoodType(sgd.PopUnsignedChar()); was_sounding = sgd.PopBool(); } else { workplace = nullptr; ware = GD_NOTHING; was_sounding = false; } }
nofMetalworker::nofMetalworker(SerializedGameData& sgd, const unsigned obj_id) : nofWorkman(sgd, obj_id), nextProducedTool(GoodType(sgd.PopUnsignedChar())) { if(state == STATE_ENTERBUILDING && current_ev == nullptr && ware == GD_NOTHING && nextProducedTool == GD_NOTHING) { LOG.write("Found invalid metalworker. Assuming corrupted savegame -> Trying to fix this. If you encounter this with a new game, " "report this!"); RTTR_Assert(false); state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; current_ev = GetEvMgr().AddEvent(this, 1000, 2); } toolOrderSub = gwg->GetNotifications().subscribe<ToolNote>([this](const ToolNote& note) { if((note.type == ToolNote::OrderPlaced || note.type == ToolNote::SettingsChanged) && note.player == this->player) CheckForOrders(); }); }
bool nobBaseWarehouse::AreWaresToEmpty() const { // Prüfen, ob Warentyp ausgelagert werden soll und ob noch Waren davon vorhanden sind // Waren überprüfen for(unsigned i = 0; i < WARE_TYPES_COUNT; ++i) { if(GetInventorySetting(GoodType(i)).IsSet(EInventorySetting::SEND) && inventory[GoodType(i)]) return true; } // Figuren überprüfen for(unsigned i = 0; i < JOB_TYPES_COUNT; ++i) { if(GetInventorySetting(Job(i)).IsSet(EInventorySetting::SEND) && inventory[Job(i)]) return true; } return false; }
nofBuildingWorker::nofBuildingWorker(SerializedGameData* sgd, const unsigned obj_id) : noFigure(sgd, obj_id), state(State(sgd->PopUnsignedChar())) { if(fs != FS_GOHOME && fs != FS_WANDER) { workplace = sgd->PopObject<nobUsual>(GOT_UNKNOWN); ware = GoodType(sgd->PopUnsignedChar()); not_working = sgd->PopUnsignedShort(); since_not_working = sgd->PopUnsignedInt(); was_sounding = sgd->PopBool(); } else { workplace = 0; ware = GD_NOTHING; not_working = 0; since_not_working = 0xFFFFFFFF; was_sounding = false; } OutOfRessourcesMsgSent = sgd->PopBool(); }
/// Verändert Ein/Auslagerungseinstellungen (real) void nobBaseWarehouse::SetInventorySetting(const bool isJob, const unsigned char type, InventorySetting state) { state.MakeValid(); InventorySetting oldState; if(isJob) { oldState = inventorySettings.figures[type]; inventorySettings.figures[type] = state; } else { oldState = inventorySettings.wares[type]; inventorySettings.wares[type] = state; } /// Bei anderen Spielern als dem lokalen, der das in Auftrag gegeben hat, müssen die visuellen ebenfalls /// geändert werden oder auch bei Replays if(GAMECLIENT.IsReplayModeOn() || GAMECLIENT.GetPlayerID() != player) SetInventorySettingVisual(isJob, type, state); if(oldState.IsSet(EInventorySetting::STOP) && !state.IsSet(EInventorySetting::STOP)) { // Evtl gabs verlorene Waren, die jetzt in das HQ wieder reinkönnen gwg->GetPlayer(player).FindClientForLostWares(); } // No else here! if(!oldState.IsSet(EInventorySetting::SEND) && state.IsSet(EInventorySetting::SEND)) { // Sind Waren vorhanden, die ausgelagert werden müssen und ist noch kein Auslagerungsevent vorhanden --> neues anmelden if(!empty_event && (isJob ? inventory[Job(type)] : inventory[GoodType(type)])) empty_event = em->AddEvent(this, empty_INTERVAL, 3); }else if(!oldState.IsSet(EInventorySetting::COLLECT) && state.IsSet(EInventorySetting::COLLECT)) { // Sollen Waren eingelagert werden? Dann müssen wir neue bestellen if(!store_event) store_event = em->AddEvent(this, STORE_INTERVAL, 4); } NotifyListeners(1); }
LONG PushContextNode ( struct IFFHandle *iff, LONG type, LONG id, LONG size, LONG scan, struct IFFParseBase_intern *IFFParseBase ) { /* Allocates and puts a new context-node into the top of the context-stack Also does GoodType and GoodID checking */ struct ContextNode *cn; BOOL composite; D(bug("PushContextNode(iff=%p, type=%c%c%c%c, id=%c%c%c%c, size=%d, scan=%d)\n", iff, dmkid(type), dmkid(id), size, scan )); /* Set the composite flag if we have a composite contextnnode */ if (id == ID_FORM || id == ID_LIST || id == ID_CAT || id == ID_PROP) { composite = TRUE; /* We have a new type, check it */ } else { composite = FALSE; /* No composite type found. Get old type from top contextnode */ cn = TopChunk(iff); type = cn->cn_Type; } /* Check if type and ids are valid */ if (!(GoodType(type) && GoodID(id)) ) ReturnInt ("PushContextNode",LONG,IFFERR_MANGLED); /* Allocate a new context node */ if ( !(cn = AllocMem ( sizeof (struct IntContextNode), MEMF_ANY ) ) ) ReturnInt ("PushContextNode",LONG,IFFERR_NOMEM); /* Put the context node at top of the stack */ AddHead ( (struct List*)&( GetIntIH(iff)->iff_CNStack ), (struct Node*)cn ); /* Set the contextnode attrs */ cn->cn_Type = type; cn->cn_ID = id; cn->cn_Size = size; cn->cn_Scan = scan; GetIntCN(cn)->cn_Composite = composite; /* Initialize the LCI-list */ NewList ((struct List*)&( GetIntCN(cn)->cn_LCIList )); /* Deeper stack */ iff->iff_Depth ++; ReturnInt ("PushContextNode",LONG,0L); }
nofMetalworker::nofMetalworker(SerializedGameData* sgd, const unsigned obj_id) : nofWorkman(sgd, obj_id), nextProducedTool(GoodType(sgd->PopUnsignedChar())) { if(state == STATE_ENTERBUILDING && current_ev == NULL && ware == GD_NOTHING && nextProducedTool == GD_NOTHING) { LOG.lprintf("Found invalid metalworker. Assuming corrupted savegame -> Trying to fix this. If you encounter this with a new game, report this!"); state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; current_ev = em->AddEvent(this, 1000, 2); } }
void nobBaseWarehouse::HandleSendoutEvent() { // Fight or something in front of the house? Try again later! if(!gwg->IsRoadNodeForFigures(gwg->GetNeighbour(pos, 4), 4)) { empty_event = em->AddEvent(this, empty_INTERVAL, 3); return; } std::vector<unsigned> possibleIds; // Waren und Figuren zum Auslagern zusammensuchen // Wenn keine Platz an Flagge, dann keine Waren raus if(GetFlag()->IsSpaceForWare()) { for(unsigned i = 0; i < WARE_TYPES_COUNT; ++i) { if(GetInventorySetting(GoodType(i)).IsSet(EInventorySetting::SEND) && inventory[GoodType(i)]) possibleIds.push_back(i); } } for(unsigned i = 0; i < JOB_TYPES_COUNT; ++i) { // Figuren, die noch nicht implementiert sind, nicht nehmen! if(GetInventorySetting(Job(i)).IsSet(EInventorySetting::SEND) && inventory[Job(i)]) possibleIds.push_back(WARE_TYPES_COUNT + i); } // Gibts überhaupt welche? if(possibleIds.empty()) // ansonsten gleich tschüss return; // Eine ID zufällig auswählen unsigned selectedId = possibleIds[RANDOM.Rand(__FILE__, __LINE__, GetObjId(), possibleIds.size())]; if(selectedId < WARE_TYPES_COUNT) { // Ware Ware* ware = new Ware(GoodType(selectedId), NULL, this); noBaseBuilding* wareGoal = gwg->GetPlayer(player).FindClientForWare(ware); if(wareGoal != this) { ware->SetGoal(wareGoal); // Ware zur Liste hinzufügen, damit sie dann rausgetragen wird waiting_wares.push_back(ware); AddLeavingEvent(); // Ware aus Inventar entfernen inventory.real.Remove(GoodType(selectedId)); // Evtl. kein Schwert/Schild/Bier mehr da, sodass das Rekrutieren gestoppt werden muss TryStopRecruiting(); } else { gwg->GetPlayer(player).RemoveWare(ware); ware->Destroy(); deletePtr(ware); } } else { // Figur selectedId -= WARE_TYPES_COUNT; nobBaseWarehouse* wh = gwg->GetPlayer(player).FindWarehouse(*this, FW::AcceptsFigureButNoSend(Job(selectedId)), true, false); if(wh != this) { nofPassiveWorker* fig = new nofPassiveWorker(Job(selectedId), pos, player, NULL); if(wh) fig->GoHome(wh); else fig->StartWandering(); AddLeavingFigure(fig); // Person aus Inventar entfernen inventory.real.Remove(Job(selectedId)); // Evtl. kein Gehilfe mehr da, sodass das Rekrutieren gestoppt werden muss TryStopRecruiting(); } } // Weitere Waren/Figuren zum Auslagern? if(AreWaresToEmpty()) // --> Nächstes Event empty_event = em->AddEvent(this, empty_INTERVAL, 3); }
void nobBaseWarehouse::CheckOuthousing(const bool isJob, unsigned job_ware_id) { // Check if we need to send this ware or figure and register an event for this // If we already have an event, we don't need to do anything if(empty_event) return; // Bootsträger in Träger umwandeln, der evtl dann raus soll if(isJob && job_ware_id == JOB_BOATCARRIER) job_ware_id = JOB_HELPER; const InventorySetting setting = isJob ? GetInventorySetting(Job(job_ware_id)) : GetInventorySetting(GoodType(job_ware_id)); if(setting.IsSet(EInventorySetting::SEND)) empty_event = em->AddEvent(this, empty_INTERVAL, 3); }