Oops, it wouldn't work if we had just enough exp to go up. 

On Sun, Jun 29, 2008 at 10:46:47AM -0400, Cameron J. Morland wrote:
> Hi,
> 
> It seems to me that if I attack with a unit which is guaranteed to
> level up after one more battle, and likely to survive said battle,
> that this should show in the probability chart.
> 
> See the attached patch, which accomplishes this. 
> Levelling up due to a kill (+8 * enemy level or +4, if zero) is treated.
> 
> Current problems thta I could use help with:
> 
> - I don't calculate how many HP we will have, and simply report that
> we're healed. Not quite sure how to do this.
> 
> - sometimes the experience level of the opponent is not correctly set
> in opp.u_
> 
> - When the defendent can't hit back, both units show as being
> unharmed. I don't understand why this is.
> 
> -- 
> +-----------------------------------------------------------------
> | PGP http://www.cns.bu.edu/~cjmorlan/public-key.pgp
> | Cameron Morland             ----             [EMAIL PROTECTED]
> |
> | The ink of a scholar is more sacred than the blood of the martyr.
> |     --Mohammed
> +-----------------------------------------------------------------

> diff -u -x '*.o' wesnoth-1.5.1.orig/src/actions.cpp 
> wesnoth-1.5.1/src/actions.cpp
> --- wesnoth-1.5.1.orig/src/actions.cpp        2008-06-18 22:16:34.000000000 
> +0200
> +++ wesnoth-1.5.1/src/actions.cpp     2008-06-29 10:54:35.000000000 +0200
> @@ -637,6 +637,9 @@
>               backstab_pos = is_attacker && backstab_check(u_loc, opp_loc, 
> units, teams);
>               rounds = weapon->get_specials("berserk").highest("value", 
> 1).first;
>               firststrike = weapon->get_special_bool("firststrike");
> +             experience = u.experience(); // CJM
> +             max_experience = u.max_experience(); // CJM
> +             level = u.level();
>  
>               // Handle plague.
>               unit_ability_list plague_specials = 
> weapon->get_specials("plague");
> Only in wesnoth-1.5.1/src/: actions.cpp~
> diff -u -x '*.o' wesnoth-1.5.1.orig/src/actions.hpp 
> wesnoth-1.5.1/src/actions.hpp
> --- wesnoth-1.5.1.orig/src/actions.hpp        2008-06-18 22:16:34.000000000 
> +0200
> +++ wesnoth-1.5.1/src/actions.hpp     2008-06-29 10:54:44.000000000 +0200
> @@ -88,6 +88,8 @@
>                                                                */
>               bool swarm;                             /**< Attack has swarm 
> special. */
>               bool firststrike;               /**< Attack has firststrike 
> special. */
> +             unsigned int experience, max_experience; // CJM
> +             unsigned int level;
>  
>               unsigned int rounds;    /**< Berserk special can force us to 
> fight more than one round. */
>               unsigned int hp;                /**< Hitpoints of the unit at 
> the beginning of the battle. */
> Only in wesnoth-1.5.1/src/: actions.hpp~
> diff -u -x '*.o' wesnoth-1.5.1.orig/src/attack_prediction.cpp 
> wesnoth-1.5.1/src/attack_prediction.cpp
> --- wesnoth-1.5.1.orig/src/attack_prediction.cpp      2008-03-19 
> 17:55:39.000000000 +0100
> +++ wesnoth-1.5.1/src/attack_prediction.cpp   2008-06-29 15:51:19.000000000 
> +0200
> @@ -492,10 +492,8 @@
>       }
>  
>       // If this unit drains, HP can increase, so alloc full array.
> -     if (u.drains) {
> -             return u.max_hp + 1;
> -     }
> -     return u.hp+1;
> +     // Do this anyway in case we level up.
> +     return u.max_hp + 1;
>  }
>  
>  combatant::combatant(const battle_context::unit_stats &u, const combatant 
> *prev)
> @@ -718,6 +716,39 @@
>       m.extract_results(summary, opp.summary);
>  }
>  
> +void combatant::consider_levelup(combatant &opp) {
> +     // FIXME: opp.* is not right, sometimes.
> +     printf("<<<%d/%d(%d) : %d/%d(%d)>>>\n", 
> +                              u_.experience, u_.max_experience, u_.level,
> +                              opp.u_.experience, opp.u_.max_experience, 
> opp.u_.level);
> +
> +     if (u_.experience + opp.u_.level >= u_.max_experience) {
> +             // if we survive the combat, we will level up. So the 
> probability
> +             // of death is unchanged, but all other cases get merged into
> +             // the fully healed case.
> +             for (unsigned int i = 1; i < hp_dist.size() - 1; i++) {
> +                     hp_dist[i] = 0;
> +             }
> +             // fully healed unless dead
> +             hp_dist[hp_dist.size() - 1] = 1 - hp_dist[0];
> +     } else if (u_.experience + 
> +                                              ((opp.u_.level == 0) ? 4 : 
> opp.u_.level * 8) > u_.max_experience) {
> +             // if we kill, we will level up
> +             p_kill = opp.hp_dist[0];
> +
> +             // if we could level up, then the damage we had becomes less
> +             // probable since it's now conditional on us not levelling up.
> +             for (unsigned int i = 0; i < hp_dist.size(); i++) {
> +                     hp_dist[i] *= (1 - p_kill);
> +             }
> +
> +             // if we level up, we get fully healed. (FIXME: actually more 
> so; we
> +             // need to calculate how many HP we will gain)
> +             hp_dist[hp_dist.size() - 1] += p_kill;
> +     }
> +
> +}
> +
>  // Two man enter.  One man leave!
>  // ... Or maybe two.  But definitely not three.
>  // Of course, one could be a woman.  Or both.
> @@ -799,6 +830,8 @@
>                       opp.hp_dist[i] = opp.summary[0][i] + opp.summary[1][i];
>       }
>  
> +     consider_levelup(opp);
> +
>       // Make sure we don't try to access the vectors out of bounds,
>       // drain increases HPs so we determine the number of HP here
>       // and make sure it stays within bounds
> Only in wesnoth-1.5.1/src/: attack_prediction.cpp~
> diff -u -x '*.o' wesnoth-1.5.1.orig/src/attack_prediction.hpp 
> wesnoth-1.5.1/src/attack_prediction.hpp
> --- wesnoth-1.5.1.orig/src/attack_prediction.hpp      2008-02-16 
> 09:47:16.000000000 +0100
> +++ wesnoth-1.5.1/src/attack_prediction.hpp   2008-06-29 13:10:58.000000000 
> +0200
> @@ -36,6 +36,8 @@
>       //! Simulate a fight!  Can be called multiple times for cumulative 
> calculations.
>       void fight(combatant &opponent);
>  
> +     void consider_levelup(combatant &opponent);
> +
>       //! Resulting probability distribution (may NOT be as large as max_hp)
>       std::vector<double> hp_dist;
>  
> Only in wesnoth-1.5.1/src/: attack_prediction.hpp~
> Common subdirectories: wesnoth-1.5.1.orig/src/campaign_server and 
> wesnoth-1.5.1/src/campaign_server
> Only in wesnoth-1.5.1/src/: .deps
> Common subdirectories: wesnoth-1.5.1.orig/src/editor and 
> wesnoth-1.5.1/src/editor
> Common subdirectories: wesnoth-1.5.1.orig/src/editor2 and 
> wesnoth-1.5.1/src/editor2
> Common subdirectories: wesnoth-1.5.1.orig/src/gui and wesnoth-1.5.1/src/gui
> Only in wesnoth-1.5.1/src/: libwesnoth.a
> Only in wesnoth-1.5.1/src/: libwesnoth-core.a
> Only in wesnoth-1.5.1/src/: Makefile
> Only in wesnoth-1.5.1/src/: Makefile~
> Only in wesnoth-1.5.1/src/: revision.hpp
> Common subdirectories: wesnoth-1.5.1.orig/src/serialization and 
> wesnoth-1.5.1/src/serialization
> Common subdirectories: wesnoth-1.5.1.orig/src/server and 
> wesnoth-1.5.1/src/server
> Only in wesnoth-1.5.1/src/: TAGS
> Common subdirectories: wesnoth-1.5.1.orig/src/tests and 
> wesnoth-1.5.1/src/tests
> Common subdirectories: wesnoth-1.5.1.orig/src/tools and 
> wesnoth-1.5.1/src/tools
> Only in wesnoth-1.5.1/src/: wesnoth
> Common subdirectories: wesnoth-1.5.1.orig/src/widgets and 
> wesnoth-1.5.1/src/widgets

> _______________________________________________
> Wesnoth-dev mailing list
> [email protected]
> https://mail.gna.org/listinfo/wesnoth-dev


-- 
+-----------------------------------------------------------------
| PGP http://www.cns.bu.edu/~cjmorlan/public-key.pgp
| Cameron Morland             ----             [EMAIL PROTECTED]
|
| The ink of a scholar is more sacred than the blood of the martyr.
|     --Mohammed
+-----------------------------------------------------------------
diff -ux '*.o' wesnoth-1.5.1.orig/src/actions.cpp wesnoth-1.5.1/src/actions.cpp
--- wesnoth-1.5.1.orig/src/actions.cpp  2008-06-18 22:16:34.000000000 +0200
+++ wesnoth-1.5.1/src/actions.cpp       2008-06-29 10:54:35.000000000 +0200
@@ -637,6 +637,9 @@
                backstab_pos = is_attacker && backstab_check(u_loc, opp_loc, 
units, teams);
                rounds = weapon->get_specials("berserk").highest("value", 
1).first;
                firststrike = weapon->get_special_bool("firststrike");
+               experience = u.experience(); // CJM
+               max_experience = u.max_experience(); // CJM
+               level = u.level();
 
                // Handle plague.
                unit_ability_list plague_specials = 
weapon->get_specials("plague");
Only in wesnoth-1.5.1/src/: actions.cpp~
diff -ux '*.o' wesnoth-1.5.1.orig/src/actions.hpp wesnoth-1.5.1/src/actions.hpp
--- wesnoth-1.5.1.orig/src/actions.hpp  2008-06-18 22:16:34.000000000 +0200
+++ wesnoth-1.5.1/src/actions.hpp       2008-06-29 10:54:44.000000000 +0200
@@ -88,6 +88,8 @@
                                                                 */
                bool swarm;                             /**< Attack has swarm 
special. */
                bool firststrike;               /**< Attack has firststrike 
special. */
+               unsigned int experience, max_experience; // CJM
+               unsigned int level;
 
                unsigned int rounds;    /**< Berserk special can force us to 
fight more than one round. */
                unsigned int hp;                /**< Hitpoints of the unit at 
the beginning of the battle. */
Only in wesnoth-1.5.1/src/: actions.hpp~
diff -ux '*.o' wesnoth-1.5.1.orig/src/attack_prediction.cpp 
wesnoth-1.5.1/src/attack_prediction.cpp
--- wesnoth-1.5.1.orig/src/attack_prediction.cpp        2008-03-19 
17:55:39.000000000 +0100
+++ wesnoth-1.5.1/src/attack_prediction.cpp     2008-06-29 17:14:25.000000000 
+0200
@@ -492,10 +492,8 @@
        }
 
        // If this unit drains, HP can increase, so alloc full array.
-       if (u.drains) {
-               return u.max_hp + 1;
-       }
-       return u.hp+1;
+       // Do this anyway in case we level up.
+       return u.max_hp + 1;
 }
 
 combatant::combatant(const battle_context::unit_stats &u, const combatant 
*prev)
@@ -718,6 +716,40 @@
        m.extract_results(summary, opp.summary);
 }
 
+void combatant::consider_levelup(combatant &opp) {
+       // FIXME: opp.* is not right, sometimes.
+       printf("<<<%d/%d(%d) : %d/%d(%d)>>>\n", 
+                                u_.experience, u_.max_experience, u_.level,
+                                opp.u_.experience, opp.u_.max_experience, 
opp.u_.level);
+
+       if (u_.experience + opp.u_.level >= u_.max_experience) {
+               // if we survive the combat, we will level up. So the 
probability
+               // of death is unchanged, but all other cases get merged into
+               // the fully healed case.
+               for (unsigned int i = 1; i < hp_dist.size() - 1; i++) {
+                       hp_dist[i] = 0;
+               }
+               // fully healed unless dead
+               hp_dist[hp_dist.size() - 1] = 1 - hp_dist[0];
+       } else if (u_.experience + ((opp.u_.level == 0) ? 4 : opp.u_.level * 8) 
+                                                >= u_.max_experience) {
+               // if we kill, we will level up
+               float p_kill = opp.hp_dist[0];
+
+               // if we could level up, then the damage we had becomes less
+               // probable since it's now conditional on us not levelling up.
+               // This doesn't apply to the probability of us dying, of course.
+               for (unsigned int i = 1; i < hp_dist.size(); i++) {
+                       hp_dist[i] *= (1 - p_kill);
+               }
+
+               // if we level up, we get fully healed. (FIXME: actually more 
so; we
+               // need to calculate how many HP we will gain)
+               hp_dist[hp_dist.size() - 1] += p_kill;
+       }
+
+}
+
 // Two man enter.  One man leave!
 // ... Or maybe two.  But definitely not three.
 // Of course, one could be a woman.  Or both.
@@ -799,6 +831,9 @@
                        opp.hp_dist[i] = opp.summary[0][i] + opp.summary[1][i];
        }
 
+       consider_levelup(opp);
+       opp.consider_levelup(*this);
+
        // Make sure we don't try to access the vectors out of bounds,
        // drain increases HPs so we determine the number of HP here
        // and make sure it stays within bounds
Only in wesnoth-1.5.1/src/: attack_prediction.cpp~
diff -ux '*.o' wesnoth-1.5.1.orig/src/attack_prediction.hpp 
wesnoth-1.5.1/src/attack_prediction.hpp
--- wesnoth-1.5.1.orig/src/attack_prediction.hpp        2008-02-16 
09:47:16.000000000 +0100
+++ wesnoth-1.5.1/src/attack_prediction.hpp     2008-06-29 13:10:58.000000000 
+0200
@@ -36,6 +36,8 @@
        //! Simulate a fight!  Can be called multiple times for cumulative 
calculations.
        void fight(combatant &opponent);
 
+       void consider_levelup(combatant &opponent);
+
        //! Resulting probability distribution (may NOT be as large as max_hp)
        std::vector<double> hp_dist;
 
Only in wesnoth-1.5.1/src/: attack_prediction.hpp~
Common subdirectories: wesnoth-1.5.1.orig/src/campaign_server and 
wesnoth-1.5.1/src/campaign_server
Only in wesnoth-1.5.1/src/: .deps
Common subdirectories: wesnoth-1.5.1.orig/src/editor and 
wesnoth-1.5.1/src/editor
Common subdirectories: wesnoth-1.5.1.orig/src/editor2 and 
wesnoth-1.5.1/src/editor2
Common subdirectories: wesnoth-1.5.1.orig/src/gui and wesnoth-1.5.1/src/gui
Only in wesnoth-1.5.1/src/: libwesnoth.a
Only in wesnoth-1.5.1/src/: libwesnoth-core.a
Only in wesnoth-1.5.1/src/: Makefile
Only in wesnoth-1.5.1/src/: Makefile~
Only in wesnoth-1.5.1/src/: revision.hpp
Common subdirectories: wesnoth-1.5.1.orig/src/serialization and 
wesnoth-1.5.1/src/serialization
Common subdirectories: wesnoth-1.5.1.orig/src/server and 
wesnoth-1.5.1/src/server
Only in wesnoth-1.5.1/src/: TAGS
Common subdirectories: wesnoth-1.5.1.orig/src/tests and wesnoth-1.5.1/src/tests
Common subdirectories: wesnoth-1.5.1.orig/src/tools and wesnoth-1.5.1/src/tools
Only in wesnoth-1.5.1/src/: wesnoth
Common subdirectories: wesnoth-1.5.1.orig/src/widgets and 
wesnoth-1.5.1/src/widgets
_______________________________________________
Wesnoth-dev mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-dev

Reply via email to