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