Index: bb5/arbiter/SPlayer.cc===================================================================--- bb5/arbiter/SPlayer.cc (rvision 1425)+++ bb5/arbiter/SPlayer.cc (copie de travail)@@ -326,23 +326,15 @@ setHasPlayed(); else setHasBlocked();- - int mod_st_atk = getSt();- int mod_st_df = target_->getSt();- if (mod_st_atk > 2 * mod_st_df || mod_st_df > 2 * mod_st_atk)- nb_block_dices_ = 3;- else if (mod_st_atk != mod_st_df)- nb_block_dices_ = 2;- else- nb_block_dices_ = 1;+ int dices = f_->getNbBlockDices(pos_, target_->pos_);+ if (dices == 0) { ERR("target undefined or synchronisation error between field and players"); }+ nb_block_dices_ = (dices < 0 ? dices * -1 : dices); if (nb_block_dices_ == 1) dice_chooser_id_ = -1;- else if (mod_st_atk < mod_st_df) // Strongest team chooses the dice.- dice_chooser_id_ = r_->getCurrentOpponentTeamId(); else- dice_chooser_id_ = team_id_;+ dice_chooser_id_ = (dices < 0 ? r_->getCurrentOpponentTeamId() : team_id_); roll_attempted_ = R_BLOCK; setRerollAvailability();Index: bb5/common/Field.hh===================================================================--- bb5/common/Field.hh (rvision 1425)+++ bb5/common/Field.hh (copie de travail)@@ -97,6 +97,24 @@ //! @param pos Position in field to look for. int getNbTackleZones(int team_id, const Position& pos) const;+ //! @brief Check if the player can assist a block against another player.+ //! @param pos_assister The position of the player assisting.+ //! @param team_id The team id of the team that tackles. (ie: The team of the target).+ //! @param pos_target The position in field of the target (attacker or defender).+ bool canAssist(const Position& pos_assister, int team_id, const Position& pos_target) const;+ //! @brief Get the number of supporter avaible for a block.+ //! @param pos_assisted Position in field of the player being assisted.+ //! @param team_id The team id of the team assister.+ //! @param pos_target Position in field of the target (attacker or defender).+ int getNbAssister(const Position& pos_assisted, int team_id, const Position& pos_target) const;+ //! @brief Get the number of dices to throz during a block.+ //! @param pos_attacker Position in field of the player attacking.+ //! @param pos_target Position in field of the defender.+ //! @return A positif number is returned if his team attacking choose the result, else it is a negative one+ //! the absolute value determine the number of dice to roll+ int getNbBlockDices(const Position& pos_attacker, const Position& pos_target) const;++ protected: T* tab_[COLS * ROWS]; };Index: bb5/common/Field.hxx===================================================================--- bb5/common/Field.hxx (rvision 1425)+++ bb5/common/Field.hxx (copie de travail)@@ -243,7 +243,58 @@ if (intoField(p) && getPlayer(p) != NULL && getPlayer(p)->getTeamId() == team_id- && getPlayer(p)->getStatus() == STA_STANDING)+ && getPlayer(p)->getStatus() == STA_STANDING+ && getPlayer(p)->hasTackleZone()) res++; return res; }++template <typename T>+inline bool Field<T>::canAssist(const Position& pos_assister, int team_id, const Position& pos_target) const+{+ return (pos_assister.isNear(pos_target)+ // && (getNbTackleZones(team_id, pos_assister)+ // || getPlayer(pos_assister)->hasSkill(SK_GUARD))+ && getNbTackleZones(team_id, pos_assister) == 1+ && getPlayer(pos_assister)->getStatus() == STA_STANDING+ && getPlayer(pos_assister)->hasTackleZone());+}++template <typename T>+inline int Field<T>::getNbAssister(const Position& pos_assisted, int team_id, const Position& pos_target) const+{+ int res = 0;+ Position p;++ for (p.row = pos_target.row - 1; p.row <= pos_target.row + 1; p.row++)+ for (p.col = pos_target.col - 1; p.col <= pos_target.col + 1; p.col++)+ if (intoField(p)+ && getPlayer(p) != NULL+ && p != pos_assisted+ && getPlayer(p)->getTeamId() == team_id+ && canAssist(p, (team_id*-1)+1, pos_target))+ res++;+ return res;+}++template <typename T>+inline int Field<T>::getNbBlockDices(const Position& pos_attacker, const Position& pos_target) const+{+ T* attacker;+ T* target;++ attacker = getPlayer(pos_attacker);+ target = getPlayer(pos_target);+ if (attacker == NULL || target == NULL) {+ return 0;+ }++ // TODO+ // When the extra rules (assiting a block) will be implenting the folowing comments could be removed+ int mod_st_atk = attacker->getSt(); // + getNbAssister(pos_attacker, attacker->getTeamId(), pos_target);+ int mod_st_df = target->getSt(); // + getNbAssister(pos_target, target->getTeamId(), pos_attacker);++ return (mod_st_atk < mod_st_df ? -1 : 1) *+ ((mod_st_atk > 2 * mod_st_df || mod_st_df > 2 * mod_st_atk) ? 3 :+ (mod_st_atk != mod_st_df ? 2 : 1 ));+}Index: bb5/common/Player.hh===================================================================--- bb5/common/Player.hh (rvision 1425)+++ bb5/common/Player.hh (copie de travail)@@ -313,6 +313,14 @@ //! @brief Mark the skill as used for this turn. void useSkill(enum eSkill skill);+ //! @brief Check if this player has a tacle zone.+ bool hasTackleZone() const;+ //! @brief Set the 'has lost his tackle zone' marker+ //! with skills like "Bone-head" or "Really Stupid".+ void lostTackleZone();+ //! @brief Reset the tackle zone marker+ void resetTackleZone();+ //! @brief Called on new turn. void resetTurn();@@ -346,6 +354,8 @@ enum eDeclaredAction action_; bool will_prone_;+ bool has_tackle_zone_;+ private: SkillList skill_list_; ///< List of skills that this player have. SkillList used_skill_list_; ///< List of skills that this player have used this turn.Index: bb5/common/Player.hxx===================================================================--- bb5/common/Player.hxx (rvision 1425)+++ bb5/common/Player.hxx (copie de travail)@@ -26,7 +26,8 @@ has_blocked_(false), has_played_(false), action_(DCL_UNASSIGNED),- will_prone_(false)+ will_prone_(false),+ has_tackle_zone_(true) { name_ = packetToString(m->name);@@ -152,6 +153,7 @@ ma_remain_ = ma_; used_skill_list_.clear(); will_prone_ = (status_ == STA_STUNNED);+ resetTackleZone(); } inline const char* Player::stringify(enum eStatus status)@@ -221,3 +223,18 @@ os << std::endl; return os; }++inline bool Player::hasTackleZone() const+{+ return has_tackle_zone_;+}++inline void Player::lostTackleZone()+{+ has_tackle_zone_=false;+}++inline void Player::resetTackleZone()+{+ has_tackle_zone_=true;+}Index: bb5/client/Api.hxx===================================================================--- bb5/client/Api.hxx (rvision 1425)+++ bb5/client/Api.hxx (copie de travail)@@ -691,20 +691,10 @@ || p->getTeamId() == selected_player_->getTeamId()) return INVALID_ACTION;- // FIXME: Factorize the code to common/ since SPlayer uses the same.- if (selected_player_->getSt() == p->getSt())- return blockDicesNumberPadding() + 1;+ int dices = rules_->field_->getNbBlockDices(selected_player_->getPosition(), to);+ if (dices == 0) { ERR("target undefined or synchronisation error between field and players"); }- if (selected_player_->getSt() > 2 * p->getSt())- return blockDicesNumberPadding() + 3;-- if (selected_player_->getSt() * 2 < p->getSt())- return blockDicesNumberPadding() - 3;-- if (selected_player_->getSt() > p->getSt())- return blockDicesNumberPadding() + 2;- else- return blockDicesNumberPadding() - 2;+ return blockDicesNumberPadding() + dices; } inline int Api::blockDicesNumberPadding() const