daAlx1 has proposed merging lp:~amdat/widelands/HunterBug1407418 into lp:widelands.
Requested reviews: Widelands Developers (widelands-dev) For more details, see: https://code.launchpad.net/~amdat/widelands/HunterBug1407418/+merge/251689 solves Bug 1407418 Multiple Hunters hunt for same animal -- Your team Widelands Developers is requested to review the proposed merge of lp:~amdat/widelands/HunterBug1407418 into lp:widelands.
=== modified file 'src/logic/immovable.cc' --- src/logic/immovable.cc 2015-02-05 11:26:01 +0000 +++ src/logic/immovable.cc 2015-03-04 05:39:16 +0000 @@ -135,8 +135,8 @@ */ ImmovableProgram::ImmovableProgram(const std::string& directory, - Profile& prof, - const std::string& _name, + Profile& prof, + const std::string& _name, ImmovableDescr& immovable) : m_name(_name) { Section& program_s = prof.get_safe_section(_name.c_str()); @@ -178,7 +178,7 @@ } ImmovableProgram::ImmovableProgram(const std::string& init_name, - const std::vector<std::string>& lines, + const std::vector<std::string>& lines, ImmovableDescr* immovable) : m_name(init_name) { for (const std::string& line : lines) { @@ -319,7 +319,7 @@ world.editor_immovable_categories().get_index(table.get_string("editor_category")); if (editor_category_index < 0) { throw GameDataError("Unknown editor_category: %s\n", - table.get_string("editor_category").c_str()); + table.get_string("editor_category").c_str()); } editor_category_ = world.editor_immovable_categories().get(editor_category_index); @@ -407,8 +407,7 @@ m_program_ptr (0), m_anim_construction_total(0), m_anim_construction_done(0), -m_program_step(0), -m_reserved_by_worker(false) +m_program_step(0) {} Immovable::~Immovable() @@ -575,28 +574,14 @@ .str(); m_construct_string = as_uifont(m_construct_string); dst.blit(pos - Point(0, 48), - UI::g_fh1->render(m_construct_string), - BlendMode::UseAlpha, - UI::Align_Center); + UI::g_fh1->render(m_construct_string), + BlendMode::UseAlpha, + UI::Align_Center); } } -/** - * Returns whether this immovable was reserved by a worker. - */ -bool Immovable::is_reserved_by_worker() const -{ - return m_reserved_by_worker; -} -/** - * Change whether this immovable is marked as reserved by a worker. - */ -void Immovable::set_reserved_by_worker(bool reserve) -{ - m_reserved_by_worker = reserve; -} /** * Set the current action's data to \p data. @@ -690,8 +675,10 @@ imm.m_program_step = fr.signed_32(); + //TODO(daAlx1): reserved_by_worker is already dealt with in MapObject, + //so storing / loading twice is redundant but I keep it for compatability if (version >= 3) - imm.m_reserved_by_worker = fr.unsigned_8(); + imm.m_reserved_by_worker = fr.unsigned_8(); if (version >= 4) { std::string dataname = fr.c_string(); @@ -753,6 +740,8 @@ fw.unsigned_32(m_program_ptr); fw.signed_32(m_program_step); + //TODO(daAlx1): reserved_by_worker is already dealt with in MapObject, + //so storing / loading twice is redundant, I keep it for compatability fw.unsigned_8(m_reserved_by_worker); if (m_action_data) { @@ -1012,7 +1001,7 @@ const ImmovableDescr& descr = immovable.descr(); if (logic_rand_as_double(&game) < - probability_to_grow(descr.terrain_affinity(), f, map, game.world().terrains())) { + probability_to_grow(descr.terrain_affinity(), f, map, game.world().terrains())) { TribeDescr const* const owner_tribe = tribe ? descr.get_owner_tribe() : nullptr; immovable.remove(game); // Now immovable is a dangling reference! game.create_immovable(f, type_name, owner_tribe); @@ -1112,7 +1101,7 @@ const ImmovableDescr& descr = immovable.descr(); if (logic_rand_as_double(&game) < - probability_to_grow(descr.terrain_affinity(), f, map, game.world().terrains())) { + probability_to_grow(descr.terrain_affinity(), f, map, game.world().terrains())) { // Seed a new tree. MapFringeRegion<> mr(map, Area<>(f, 0)); uint32_t fringe_size = 0; @@ -1127,10 +1116,10 @@ const FCoords new_location = map.get_fcoords(mr.location()); if (!new_location.field->get_immovable() && - (new_location.field->nodecaps() & MOVECAPS_WALK) && - logic_rand_as_double(&game) < - probability_to_grow( - descr.terrain_affinity(), new_location, map, game.world().terrains())) { + (new_location.field->nodecaps() & MOVECAPS_WALK) && + logic_rand_as_double(&game) < + probability_to_grow( + descr.terrain_affinity(), new_location, map, game.world().terrains())) { game.create_immovable( mr.location(), type_name, tribe ? immovable.descr().get_owner_tribe() : nullptr); } === modified file 'src/logic/immovable.h' --- src/logic/immovable.h 2015-02-08 18:16:41 +0000 +++ src/logic/immovable.h 2015-03-04 05:39:16 +0000 @@ -197,8 +197,6 @@ bool construct_ware(Game & game, WareIndex index); bool construct_remaining_buildcost(Game & game, Buildcost * buildcost); - bool is_reserved_by_worker() const; - void set_reserved_by_worker(bool reserve); void set_action_data(ImmovableActionData * data); template<typename T> @@ -248,14 +246,7 @@ */ std::unique_ptr<ImmovableActionData> m_action_data; - /** - * Immovables like trees are reserved by a worker that is walking - * towards them, so that e.g. two lumberjacks don't attempt to - * work on the same tree simultaneously. - */ - bool m_reserved_by_worker; - - // Load/save support + // Load/save support protected: struct Loader : public BaseImmovable::Loader { void load(FileRead &, uint8_t version); === modified file 'src/logic/instances.cc' --- src/logic/instances.cc 2014-12-01 21:28:21 +0000 +++ src/logic/instances.cc 2015-03-04 05:39:16 +0000 @@ -293,7 +293,7 @@ } void MapObjectDescr::add_attributes(const std::vector<std::string>& attributes, - const std::set<uint32_t>& allowed_special) { + const std::set<uint32_t>& allowed_special) { for (const std::string& attribute : attributes) { uint32_t const attrib = get_attribute_id(attribute); if (attrib < MapObject::HIGHEST_FIXED_ATTRIBUTE) { @@ -355,7 +355,10 @@ * Zero-initialize a map object */ MapObject::MapObject(const MapObjectDescr * const the_descr) : -m_descr(the_descr), m_serial(0), m_logsink(nullptr) +m_descr(the_descr), +m_serial(0), +m_logsink(nullptr), +m_reserved_by_worker(false) {} @@ -481,7 +484,18 @@ } -#define CURRENT_SAVEGAME_VERSION 1 +bool MapObject::is_reserved_by_worker() const +{ + return m_reserved_by_worker; +} + +void MapObject::set_reserved_by_worker(bool reserve) +{ + m_reserved_by_worker = reserve; +} + + +#define CURRENT_SAVEGAME_VERSION 2 /** * Load the entire data package from the given file. @@ -501,7 +515,7 @@ ("header is %u, expected %u", header, HeaderMapObject); uint8_t const version = fr.unsigned_8(); - if (version != CURRENT_SAVEGAME_VERSION) + if (version <= 0 || version > CURRENT_SAVEGAME_VERSION) throw GameDataError("unknown/unhandled version %u", version); Serial const serial = fr.unsigned_32(); @@ -510,6 +524,9 @@ } catch (const WException & e) { throw wexception("%u: %s", serial, e.what()); } + + if (version == CURRENT_SAVEGAME_VERSION) + get_object()->m_reserved_by_worker = fr.unsigned_8(); } catch (const WException & e) { throw wexception("map object: %s", e.what()); } @@ -551,6 +568,7 @@ fw.unsigned_8(CURRENT_SAVEGAME_VERSION); fw.unsigned_32(mos.get_object_file_index(*this)); + fw.unsigned_8(m_reserved_by_worker); } std::string to_string(const MapObjectType type) { === modified file 'src/logic/instances.h' --- src/logic/instances.h 2014-11-30 18:49:38 +0000 +++ src/logic/instances.h 2015-03-04 05:39:16 +0000 @@ -90,8 +90,8 @@ struct MapObjectDescr { MapObjectDescr(const MapObjectType init_type, - const std::string& init_name, - const std::string& init_descname) + const std::string& init_name, + const std::string& init_descname) : m_type(init_type), m_name(init_name), m_descname(init_descname) { } virtual ~MapObjectDescr() {m_anims.clear();} @@ -278,6 +278,28 @@ HeaderFleet = 11, }; + protected: + /** + * MapObjects like trees are reserved by a worker that is walking + * towards them, so that e.g. two lumberjacks don't attempt to + * work on the same tree simultaneously or two hunters try to hunt + * the same animal. + */ + bool m_reserved_by_worker; + + public: + + /** + * Returns whether this immovable was reserved by a worker. + */ + bool is_reserved_by_worker() const; + + /** + * Change whether this immovable is marked as reserved by a worker. + */ + void set_reserved_by_worker(bool reserve); + + /** * Static load functions of derived classes will return a pointer to * a Loader class. The caller needs to call the virtual functions === modified file 'src/logic/worker.cc' --- src/logic/worker.cc 2015-02-24 13:51:38 +0000 +++ src/logic/worker.cc 2015-03-04 05:39:16 +0000 @@ -117,8 +117,8 @@ if (static_cast<int8_t>(res) == -1) // TODO(unknown): ARGH!! throw GameDataError (_ - ("should mine resource %s, which does not exist in world; tribe " - "is not compatible with world"), + ("should mine resource %s, which does not exist in world; tribe " + "is not compatible with world"), action.sparam1.c_str()); // Select one of the fields randomly @@ -222,8 +222,8 @@ if (static_cast<int8_t>(res) == -1) // TODO(unknown): ARGH!! throw GameDataError (_ - ("should breed resource type %s, which does not exist in world; " - "tribe is not compatible with world"), + ("should breed resource type %s, which does not exist in world; " + "tribe is not compatible with world"), action.sparam1.c_str()); // Select one of the fields randomly @@ -394,8 +394,9 @@ Map & map = game.map(); Area<FCoords> area (map.get_fcoords(get_position()), 0); + bool found_reserved = false; + if (action.sparam1 == "immovable") { - bool found_reserved = false; for (;; ++area.radius) { if (action.iparam1 < area.radius) { @@ -414,10 +415,10 @@ std::vector<ImmovableFound> list; if (action.iparam2 < 0) map.find_reachable_immovables - (area, &list, cstep); + (area, &list, cstep); else map.find_reachable_immovables - (area, &list, cstep, FindImmovableAttribute(action.iparam2)); + (area, &list, cstep, FindImmovableAttribute(action.iparam2)); for (int idx = list.size() - 1; idx >= 0; idx--) { if (upcast(Immovable, imm, list[idx].object)) { @@ -439,7 +440,7 @@ if (!list.empty()) { set_program_objvar - (game, state, list[game.logic_rand() % list.size()].object); + (game, state, list[game.logic_rand() % list.size()].object); break; } } @@ -448,10 +449,17 @@ if (action.iparam1 < area.radius) { send_signal(game, "fail"); // no object found, cannot run program pop_task(game); - if (upcast(ProductionSite, productionsite, get_location(game))) - productionsite->notify_player(game, 30); + if (upcast(ProductionSite, productionsite, get_location(game))){ + if (!found_reserved) { + productionsite->notify_player(game, 30); + } + else { + productionsite->unnotify_player(); + } + } return true; } + //Todo(DaAlx1): Check whether this else branch is a copy and paste error? else { if (upcast(ProductionSite, productionsite, get_location(game))) productionsite->unnotify_player(); @@ -459,19 +467,27 @@ std::vector<Bob *> list; if (action.iparam2 < 0) map.find_reachable_bobs - (area, &list, cstep); + (area, &list, cstep); else map.find_reachable_bobs - (area, &list, cstep, FindBobAttribute(action.iparam2)); + (area, &list, cstep, FindBobAttribute(action.iparam2)); + for (int idx = list.size() - 1; idx >= 0; idx--) { + if (upcast(MapObject, bop, list[idx])) { + if (bop->is_reserved_by_worker()) { + found_reserved = true; + list.erase(list.begin() + idx); + } + } + } if (!list.empty()) { set_program_objvar - (game, state, list[game.logic_rand() % list.size()]); + (game, state, list[game.logic_rand() % list.size()]); break; } + } } - ++state.ivar1; schedule_act(game, 10); return true; @@ -565,7 +581,7 @@ if (action.iparam4) functor.add (FindNodeResourceBreedable - (world.get_resource(action.sparam1.c_str()))); + (world.get_resource(action.sparam1.c_str()))); else functor.add (FindNodeResource(world.get_resource(action.sparam1.c_str()))); @@ -662,11 +678,11 @@ if (! start_task_movepath - (game, - dest, - 10, - descr().get_right_walk_anims(does_carry_ware()), - forceonlast, max_steps)) + (game, + dest, + 10, + descr().get_right_walk_anims(does_carry_ware()), + forceonlast, max_steps)) { molog(" could not find path\n"); send_signal(game, "fail"); @@ -945,7 +961,7 @@ //NoLog(" Field is no longer empty\n"); } else if (const ResourceDescription * const rdescr = - world.get_resource(position.field->get_resources())) + world.get_resource(position.field->get_resources())) { // Geologist also sends a message notifying the player if (rdescr->detectable() && position.field->get_resources_amount()) { @@ -976,9 +992,9 @@ *new Message (message_type, game.get_gametime(), - rdescr->descname(), - message, - position, + rdescr->descname(), + message, + position, m_serial ), 300000, 8); @@ -988,9 +1004,9 @@ game.create_immovable (position, t.get_resource_indicator - (rdescr, - rdescr->detectable() ? - position.field->get_resources_amount() : 0), + (rdescr, + rdescr->detectable() ? + position.field->get_resources_amount() : 0), &t); } @@ -1314,8 +1330,8 @@ */ WareIndex Worker::gain_experience(Game & game) { return descr().get_needed_experience() == -1 || ++m_current_exp < descr().get_needed_experience() ? - INVALID_INDEX : - level(game); + INVALID_INDEX : + level(game); } @@ -1548,10 +1564,10 @@ if (index >= 0) { if (start_task_movepath - (game, - path, - index, - descr().get_right_walk_anims(does_carry_ware()))) + (game, + path, + index, + descr().get_right_walk_anims(does_carry_ware()))) { molog ("[transfer]: from road %u to flag %u\n", @@ -1861,10 +1877,10 @@ if (! start_task_movepath - (game, - location->base_flag().get_position(), - 15, - descr().get_right_walk_anims(does_carry_ware()))) + (game, + location->base_flag().get_position(), + 15, + descr().get_right_walk_anims(does_carry_ware()))) { molog("[return]: Failed to return\n"); const std::string message = @@ -1876,9 +1892,9 @@ *new Message (Message::Type::kGameLogic, game.get_gametime(), - _("Worker got lost!"), + _("Worker got lost!"), message, - get_position()), + get_position()), m_serial); set_location(nullptr); return pop_task(game); @@ -1951,14 +1967,15 @@ { assert(state.task == &taskProgram); - if (upcast(Immovable, imm, state.objvar1.get(game))) { - imm->set_reserved_by_worker(false); + + if (state.objvar1.get(game)) { + (state.objvar1.get(game))->set_reserved_by_worker(false); } state.objvar1 = obj; - if (upcast(Immovable, imm, obj)) { - imm->set_reserved_by_worker(true); + if (obj) { + obj->set_reserved_by_worker(true); } } @@ -2558,8 +2575,8 @@ int32_t maxdist = 4 * vision; if (map.find_immovables - (Area<FCoords>(map.get_fcoords(get_position()), maxdist), - &flags, FindFlagWithPlayersWarehouse(*get_owner()))) + (Area<FCoords>(map.get_fcoords(get_position()), maxdist), + &flags, FindFlagWithPlayersWarehouse(*get_owner()))) { int32_t bestdist = -1; Flag * best = nullptr; @@ -2596,12 +2613,12 @@ // perhaps find a closer flag. if (start_task_movepath - (game, - best->get_position(), - 0, - descr().get_right_walk_anims(does_carry_ware()), - false, - 4)) + (game, + best->get_position(), + 0, + descr().get_right_walk_anims(does_carry_ware()), + false, + 4)) return; } } @@ -2615,10 +2632,10 @@ if (start_task_movepath - (game, - game.random_location(get_position(), descr().vision_range()), - 4, - descr().get_right_walk_anims(does_carry_ware()))) + (game, + game.random_location(get_position(), descr().vision_range()), + 4, + descr().get_right_walk_anims(does_carry_ware()))) return; return start_task_idle(game, descr().get_animation("idle"), 50); @@ -2674,7 +2691,7 @@ const World & world = game.world(); Area<FCoords> owner_area (map.get_fcoords - (dynamic_cast<Flag&>(*get_location(game)).get_position()), + (dynamic_cast<Flag&>(*get_location(game)).get_position()), state.ivar2); // Check if it's not time to go home @@ -2744,10 +2761,10 @@ if (! start_task_movepath - (game, - target, - 0, - descr().get_right_walk_anims(does_carry_ware()))) + (game, + target, + 0, + descr().get_right_walk_anims(does_carry_ware()))) { molog("[geologist]: Bug: could not find path\n"); @@ -2767,7 +2784,7 @@ if (! start_task_movepath - (game, owner_area, 0, descr().get_right_walk_anims(does_carry_ware()))) + (game, owner_area, 0, descr().get_right_walk_anims(does_carry_ware()))) { molog("[geologist]: could not find path home\n"); send_signal(game, "fail");
_______________________________________________ Mailing list: https://launchpad.net/~widelands-dev Post to : widelands-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~widelands-dev More help : https://help.launchpad.net/ListHelp