=== modified file 'src/economy/flag.cc' --- src/economy/flag.cc 2010-11-01 13:22:44 +0000 +++ src/economy/flag.cc 2010-11-30 20:51:40 +0000 @@ -374,6 +374,20 @@ pi.item = &item; pi.pending = false; pi.nextstep = 0; + pi.priority = 0; + + Transfer * trans = item.get_transfer(); + if (trans) { + uint32_t trans_steps = trans->get_steps_left(); + if (trans_steps < 3) + pi.priority = 2; + else if (trans_steps == 3) + pi.priority = 1; + + Request * req = trans->get_request(); + if (req) + pi.priority = pi.priority + req->get_transfer_priority(); + } item.set_location(egbase, this); @@ -403,10 +417,20 @@ /** * Called by carrier code to indicate that the carrier is moving to pick up an - * item. + * item. Item with highest transfer priority is chosen. * \return true if an item is actually waiting for the carrier. */ + + +// Clamp the maximal value +// After reaching this value actually FIFO approach works + +#define MAX_TRANSFER_PRIORITY 16 + bool Flag::ack_pending_item(Game &, Flag & destflag) { + int32_t highest_pri = -1; + int32_t i_pri = -1; + for (int32_t i = 0; i < m_item_filled; ++i) { if (!m_items[i].pending) continue; @@ -414,7 +438,18 @@ if (m_items[i].nextstep != &destflag) continue; - m_items[i].pending = false; + if (m_items[i].priority > highest_pri) { + highest_pri = m_items[i].priority; + i_pri = i; + + // Increase item priority, it matters only if the ware has to wait. + if (m_items[i].priority < MAX_TRANSFER_PRIORITY) + m_items[i].priority++; + } + } + + if (i_pri >= 0) { + m_items[i_pri].pending = false; return true; } === modified file 'src/economy/flag.h' --- src/economy/flag.h 2010-11-01 13:22:44 +0000 +++ src/economy/flag.h 2010-11-30 20:03:15 +0000 @@ -137,6 +137,7 @@ struct PendingItem { WareInstance * item; ///< the item itself bool pending; ///< if the item is pending + int32_t priority; ///< carrier prefers the item with highest priority OPtr nextstep; ///< next step that this item is sent to }; === modified file 'src/economy/request.cc' --- src/economy/request.cc 2010-11-07 15:36:29 +0000 +++ src/economy/request.cc 2010-11-30 19:49:55 +0000 @@ -389,6 +389,27 @@ modifier); } + +/** + * Return the transfer priority, based on the priority set at the destination + */ +uint32_t Request::get_transfer_priority() const +{ + uint32_t pri = 0; + + if (m_target_building) { + if (m_target_productionsite && m_target_productionsite->is_stopped()) + return 0; + + pri = m_target_building->get_priority(get_type(), get_index()); + if (m_target_constructionsite) + return pri + 3; + else if (m_target_warehouse) + return pri - 2; + } + return pri; +} + /** * Change the Economy we belong to. */ === modified file 'src/economy/request.h' --- src/economy/request.h 2010-05-25 18:06:53 +0000 +++ src/economy/request.h 2010-11-30 19:36:12 +0000 @@ -82,6 +82,7 @@ int32_t get_required_time() const; int32_t get_last_request_time() const {return m_last_request_time;} int32_t get_priority(int32_t cost) const; + uint32_t get_transfer_priority() const; uint32_t get_num_transfers() const {return m_transfers.size();} Flag & target_flag() const; === modified file 'src/economy/transfer.cc' --- src/economy/transfer.cc 2010-11-21 11:44:22 +0000 +++ src/economy/transfer.cc 2010-11-30 18:39:33 +0000 @@ -182,6 +182,8 @@ &m_route.get_flag(m_game, m_route.get_nrsteps() - 1)) m_route.truncate(m_route.get_nrsteps() - 1); + m_steps_left = m_route.get_nrsteps(); + // Now decide where we want to go if (dynamic_cast(location)) { assert(&m_route.get_flag(m_game, 0) == location); === modified file 'src/economy/transfer.h' --- src/economy/transfer.h 2010-11-20 16:35:24 +0000 +++ src/economy/transfer.h 2010-11-30 18:39:18 +0000 @@ -56,6 +56,7 @@ void set_request(Request * req); void set_destination(PlayerImmovable & imm); PlayerImmovable * get_destination(Game & g); + uint32_t get_steps_left() const {return m_steps_left;} /// Called by the controlled ware or worker PlayerImmovable * get_next_step(PlayerImmovable *, bool & psuccess); @@ -81,6 +82,7 @@ WareInstance * m_item; ///< non-null if ware is an item Worker * m_worker; ///< non-null if ware is a worker Route m_route; + uint32_t m_steps_left; }; } === modified file 'src/map_io/widelands_map_flagdata_data_packet.cc' --- src/map_io/widelands_map_flagdata_data_packet.cc 2010-03-17 18:16:04 +0000 +++ src/map_io/widelands_map_flagdata_data_packet.cc 2010-11-30 20:03:19 +0000 @@ -37,7 +37,7 @@ namespace Widelands { -#define CURRENT_PACKET_VERSION 3 +#define CURRENT_PACKET_VERSION 4 void Map_Flagdata_Data_Packet::Read (FileSystem & fs, @@ -134,6 +134,10 @@ flag.m_item_filled = items_filled; for (uint32_t i = 0; i < items_filled; ++i) { flag.m_items[i].pending = fr.Unsigned8(); + if (packet_version < 4) + flag.m_items[i].priority = 0; + else + flag.m_items[i].priority = fr.Signed32();; uint32_t const item_serial = fr.Unsigned32(); try { flag.m_items[i].item = @@ -256,6 +260,7 @@ for (int32_t i = 0; i < flag->m_item_filled; ++i) { fw.Unsigned8(flag->m_items[i].pending); + fw.Signed32(flag->m_items[i].priority); assert(mos.is_object_known(*flag->m_items[i].item)); fw.Unsigned32(mos.get_object_file_index(*flag->m_items[i].item)); if