Rebutalled some comments, the rest are done.

Thanks for the review!

@bunnybot merge

Diff comments:

> 
> === modified file 'src/logic/map_objects/tribes/militarysite.cc'
> --- src/logic/map_objects/tribes/militarysite.cc      2017-06-06 05:26:58 
> +0000
> +++ src/logic/map_objects/tribes/militarysite.cc      2017-06-19 07:06:15 
> +0000
> @@ -43,6 +43,114 @@
>  
>  namespace Widelands {
>  
> +// TODO(sirver): This method should probably return a const reference.

remode the TODOs for now.

> +std::vector<Soldier*> MilitarySite::SoldierControl::present_soldiers() const 
> {
> +     std::vector<Soldier*> soldiers;
> +
> +     for (Worker* worker : military_site_->get_workers()) {
> +             if (upcast(Soldier, soldier, worker)) {
> +                     if (military_site_->is_present(*soldier)) {
> +                             soldiers.push_back(soldier);
> +                     }
> +             }
> +     }
> +     return soldiers;
> +}
> +
> +// TODO(sirver): This method should probably return a const reference.
> +std::vector<Soldier*> MilitarySite::SoldierControl::stationed_soldiers() 
> const {
> +     std::vector<Soldier*> soldiers;
> +
> +     for (Worker* worker : military_site_->get_workers()) {
> +             if (upcast(Soldier, soldier, worker)) {
> +                     soldiers.push_back(soldier);
> +             }
> +     }
> +     return soldiers;
> +}
> +
> +Quantity MilitarySite::SoldierControl::min_soldier_capacity() const {
> +     return 1;
> +}
> +
> +Quantity MilitarySite::SoldierControl::max_soldier_capacity() const {
> +     return military_site_->descr().get_max_number_of_soldiers();
> +}
> +
> +Quantity MilitarySite::SoldierControl::soldier_capacity() const {
> +     return military_site_->capacity_;
> +}
> +
> +void MilitarySite::SoldierControl::set_soldier_capacity(uint32_t const 
> capacity) {
> +     assert(min_soldier_capacity() <= capacity);
> +     assert(capacity <= max_soldier_capacity());
> +     assert(military_site_->capacity_ != capacity);
> +     military_site_->capacity_ = capacity;
> +     military_site_->update_soldier_request();
> +}
> +
> +void MilitarySite::SoldierControl::drop_soldier(Soldier& soldier) {
> +     Game& game = dynamic_cast<Game&>(military_site_->owner().egbase());
> +
> +     if (!military_site_->is_present(soldier)) {
> +             // This can happen when the "drop soldier" player command is 
> delayed
> +             // by network delay or a client has bugs.
> +             military_site_->molog("MilitarySite::drop_soldier(%u): not 
> present\n", soldier.serial());
> +             return;
> +     }
> +     if (present_soldiers().size() <= min_soldier_capacity()) {
> +             military_site_->molog("cannot drop last soldier(s)\n");
> +             return;
> +     }
> +
> +     soldier.reset_tasks(game);
> +     soldier.start_task_leavebuilding(game, true);
> +
> +     military_site_->update_soldier_request();
> +}
> +
> +int MilitarySite::SoldierControl::incorporate_soldier(EditorGameBase& 
> egbase, Soldier& s) {
> +     if (s.get_location(egbase) != military_site_) {
> +             s.set_location(military_site_);
> +     }
> +
> +     // Soldier upgrade is done once the site is full. In soldier upgrade, we
> +     // request one new soldier who is better suited than the existing ones.
> +     // Normally, I kick out one existing soldier as soon as a new guy 
> starts walking
> +     // towards here. However, since that is done via infrequent polling, a 
> new soldier
> +     // can sometimes reach the site before such kick-out happens. In those 
> cases, we
> +     // should either drop one of the existing soldiers or reject the new 
> guy, to
> +     // avoid overstocking this site.
> +
> +     if (stationed_soldiers().size() > 
> military_site_->descr().get_max_number_of_soldiers()) {
> +             return military_site_->incorporate_upgraded_soldier(egbase, s) 
> ? 0 : -1;
> +     }
> +
> +     if (!military_site_->didconquer_) {
> +             military_site_->conquer_area(egbase);
> +             // Building is now occupied - idle animation should be played
> +             military_site_->start_animation(egbase, 
> military_site_->descr().get_animation("idle"));
> +
> +             if (upcast(Game, game, &egbase)) {
> +                     military_site_->send_message(
> +                        *game, Message::Type::kEconomySiteOccupied, 
> military_site_->descr().descname(),
> +                        military_site_->descr().icon_filename(), 
> military_site_->descr().descname(),
> +                        military_site_->descr().occupied_str_, true);
> +             }
> +     }
> +
> +     if (upcast(Game, game, &egbase)) {
> +             // Bind the worker into this house, hide him on the map
> +             s.reset_tasks(*game);
> +             s.start_task_buildingwork(*game);
> +     }
> +
> +     // Make sure the request count is reduced or the request is deleted.
> +     military_site_->update_soldier_request(true);
> +
> +     return 0;
> +}
> +
>  bool MilitarySite::AttackTarget::can_be_attacked() const {
>       return military_site_->didconquer_;
>  }
> 
> === modified file 'src/logic/map_objects/tribes/trainingsite.cc'
> --- src/logic/map_objects/tribes/trainingsite.cc      2017-04-23 12:11:19 
> +0000
> +++ src/logic/map_objects/tribes/trainingsite.cc      2017-06-19 07:06:15 
> +0000
> @@ -178,6 +178,78 @@
>       }
>  }
>  
> +std::vector<Soldier*> TrainingSite::SoldierControl::present_soldiers() const 
> {
> +     return training_site_->soldiers_;
> +}
> +
> +std::vector<Soldier*> TrainingSite::SoldierControl::stationed_soldiers() 
> const {
> +     return training_site_->soldiers_;
> +}
> +
> +Quantity TrainingSite::SoldierControl::min_soldier_capacity() const {
> +     return 0;
> +}
> +Quantity TrainingSite::SoldierControl::max_soldier_capacity() const {
> +     return training_site_->descr().get_max_number_of_soldiers();
> +}
> +Quantity TrainingSite::SoldierControl::soldier_capacity() const {
> +     return training_site_->capacity_;
> +}
> +
> +void TrainingSite::SoldierControl::set_soldier_capacity(Quantity const 
> capacity) {

I added a TODO to investigate if SoldierControl could be shared between 
different kind of buildings. So far, for type safety I do not see how this can 
be shared without templating - which would make the code harder to understand 
IMHO.

> +     assert(min_soldier_capacity() <= capacity);
> +     assert(capacity <= max_soldier_capacity());
> +     assert(training_site_->capacity_ != capacity);
> +     training_site_->capacity_ = capacity;
> +     training_site_->update_soldier_request();
> +}
> +
> +/**
> + * Drop a given soldier.
> + *
> + * 'Dropping' means releasing the soldier from the site. The soldier then
> + * becomes available to the economy.
> + *
> + * \note This is called from player commands, so we need to verify that the
> + * soldier is actually stationed here, without breaking anything if he isn't.
> + */
> +void TrainingSite::SoldierControl::drop_soldier(Soldier& soldier) {
> +     Game& game = dynamic_cast<Game&>(training_site_->owner().egbase());
> +
> +     std::vector<Soldier*>::iterator it = 
> std::find(training_site_->soldiers_.begin(), training_site_->soldiers_.end(), 
> &soldier);
> +     if (it == training_site_->soldiers_.end()) {
> +             
> training_site_->molog("TrainingSite::SoldierControl::drop_soldier: soldier 
> not in training site");
> +             return;
> +     }
> +
> +     training_site_->soldiers_.erase(it);
> +
> +     soldier.reset_tasks(game);
> +     soldier.start_task_leavebuilding(game, true);
> +
> +     // Schedule, so that we can call new soldiers on next act()
> +     training_site_->schedule_act(game, 100);
> +     Notifications::publish(NoteTrainingSiteSoldierTrained(training_site_, 
> training_site_->get_owner()));
> +}
> +
> +int TrainingSite::SoldierControl::incorporate_soldier(EditorGameBase& 
> egbase, Soldier& s) {
> +     if (s.get_location(egbase) != training_site_) {
> +             if (stationed_soldiers().size() + 1 > 
> training_site_->descr().get_max_number_of_soldiers())
> +                     return -1;
> +
> +             s.set_location(training_site_);
> +     }
> +
> +     // Bind the worker into this house, hide him on the map
> +     if (upcast(Game, game, &egbase))
> +             s.start_task_idle(*game, 0, -1);
> +
> +     // Make sure the request count is reduced or the request is deleted.
> +     training_site_->update_soldier_request();
> +
> +     return 0;
> +}
> +
>  /*
>  =============================
>  


-- 
https://code.launchpad.net/~widelands-dev/widelands/00_soldier_control/+merge/325902
Your team Widelands Developers is subscribed to branch 
lp:~widelands-dev/widelands/00_soldier_control.

_______________________________________________
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

Reply via email to