From 7d4205a3d1465d0220824a4baa27ae8c358aa87c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 27 Feb 2011 12:04:29 -0800 Subject: [PATCH] Fix carts in E3. Store fighters in a quicklist, not a cvector. --- eressea.sln | 12 ++--- res/e3a/resources.xml | 1 + src/spells/combatspells.c | 108 +++++++++++++++++++------------------- 3 files changed, 61 insertions(+), 60 deletions(-) diff --git a/eressea.sln b/eressea.sln index 06627cd40..faa85d728 100644 --- a/eressea.sln +++ b/eressea.sln @@ -1,5 +1,11 @@ Microsoft Visual Studio Solution File, Format Version 11.00 # Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eressea", "src\eressea.vcxproj", "{AD80EB0B-7CB4-42F2-9C95-8CCEF68DB387}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "meropis", "..\meropis\src\meropis.vcxproj", "{52764450-41CA-11E0-B2EC-3136E0D72085}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "..\example\src\example.vcxproj", "{4A17DAEE-2261-4E2C-96F6-BA4132A09551}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kernel", "..\shared\src\kernel.vcxproj", "{6F104C0A-DDF5-A34B-A89C-0DC278DCEF6D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamecode", "..\shared\src\gamecode.vcxproj", "{1E8BFF9E-3044-0742-992F-C5765B80FE65}" @@ -10,12 +16,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua-bindings", "..\shared\s EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "external", "..\external\external.vcxproj", "{F9AE4586-8F65-486B-9666-744839E40A54}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eressea", "src\eressea.vcxproj", "{AD80EB0B-7CB4-42F2-9C95-8CCEF68DB387}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "..\example\src\example.vcxproj", "{4A17DAEE-2261-4E2C-96F6-BA4132A09551}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "atlantis", "..\meropis\src\meropis.vcxproj", "{52764450-41CA-11E0-B2EC-3136E0D72085}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 diff --git a/res/e3a/resources.xml b/res/e3a/resources.xml index b9f14c32c..bd71f8c5d 100644 --- a/res/e3a/resources.xml +++ b/res/e3a/resources.xml @@ -2,6 +2,7 @@ + diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index 9d64d23de..d865b047f 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -34,6 +34,7 @@ /* util includes */ #include #include +#include #include #include @@ -253,20 +254,30 @@ sp_stun(fighter * fi, int level, double power, spell * sp) return level; } -/* ------------------------------------------------------------- */ -/* Für Sprüche 'get_scrambled_list_of_enemys_in_row', so daß man diese - * Liste nur noch einmal durchlaufen muss, um Flächenzauberwirkungen - * abzuarbeiten */ +/** randomly shuffle an array + * for correctness, see Donald E. Knuth, The Art of Computer Programming + */ +static void +scramble_fighters(quicklist * ql) +{ + int qi, qlen = ql_length(ql); + + for (qi=0;qi!=qlen;++qi) { + int qj = qi + (rng_int() % (qlen-qi)); + void * a = ql_get(ql, qi); + void * b = ql_replace(ql, qj, a); + ql_replace(ql, qi, b); + } +} /* Rosthauch */ int sp_combatrosthauch(fighter * fi, int level, double power, spell * sp) { battle *b = fi->side->battle; - cvector *fgs; - void **fig; + quicklist *ql, *fgs; int force = lovar(power * 15); - int k = 0; + int qi, k = 0; /* Immer aus der ersten Reihe nehmen */ unused(sp); @@ -279,10 +290,10 @@ sp_combatrosthauch(fighter * fi, int level, double power, spell * sp) } fgs = fighters(b, fi->side, FIGHT_ROW, BEHIND_ROW-1, FS_ENEMY); - v_scramble(fgs->begin, fgs->end); + scramble_fighters(fgs); - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; + for (qi=0,ql=fgs; ql; ql_advance(&ql, &qi, 1)) { + fighter *df = (fighter *)ql_get(ql, qi); if (df->alive==0) continue; if (force<=0) break; @@ -328,8 +339,7 @@ sp_combatrosthauch(fighter * fi, int level, double power, spell * sp) } } } - cv_kill(fgs); - free(fgs); + ql_free(fgs); if (k == 0) { /* keine Waffen mehr da, die zerstört werden könnten */ @@ -637,11 +647,9 @@ sp_immolation(fighter * fi, int level, double power, spell * sp) { battle *b = fi->side->battle; troop at; - int force; - int killed = 0; + int force, qi, killed = 0; const char *damage; - cvector *fgs; - void **fig; + quicklist *fgs, *ql; message * m; /* 2d4 HP */ @@ -660,8 +668,8 @@ sp_immolation(fighter * fi, int level, double power, spell * sp) at.index = 0; fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY); - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; + for (qi=0,ql=fgs; ql; ql_advance(&ql, &qi, 1)) { + fighter *df = (fighter *)ql_get(ql, qi); int n = df->alive-df->removed; troop dt; @@ -673,8 +681,7 @@ sp_immolation(fighter * fi, int level, double power, spell * sp) } if (force==0) break; } - cv_kill(fgs); - free(fgs); + ql_free(fgs); m = msg_message("battle::combatspell", "mage spell killed", fi->unit, sp, killed); message_all(b, m); @@ -875,11 +882,10 @@ sp_chaosrow(fighter * fi, int level, double power, spell * sp) { battle *b = fi->side->battle; unit *mage = fi->unit; - cvector *fgs; - void **fig; + quicklist *fgs, *ql; message * m; const char * mtype; - int k = 0; + int qi, k = 0; if (!count_enemies(b, fi, FIGHT_ROW, NUMROWS, SELECT_ADVANCE|SELECT_FIND)) { m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); @@ -892,10 +898,10 @@ sp_chaosrow(fighter * fi, int level, double power, spell * sp) else power = get_force(power, 5); fgs = fighters(b, fi->side, FIGHT_ROW, NUMROWS, FS_ENEMY); - v_scramble(fgs->begin, fgs->end); + scramble_fighters(fgs); - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; + for (qi=0,ql=fgs; ql; ql_advance(&ql, &qi, 1)) { + fighter *df = (fighter *)ql_get(ql, qi); int n = df->unit->number; if (df->alive==0) continue; @@ -936,8 +942,7 @@ sp_chaosrow(fighter * fi, int level, double power, spell * sp) } power = MAX(0, power-n); } - cv_kill(fgs); - free(fgs); + ql_free(fgs); if (sp->id==SPL_CHAOSROW) { mtype = (k>0) ? "sp_chaosrow_effect_1" : "sp_chaosrow_effect_0"; @@ -958,9 +963,8 @@ sp_flee(fighter * fi, int level, double power, spell * sp) { battle *b = fi->side->battle; unit *mage = fi->unit; - cvector *fgs; - void **fig; - int force, n; + quicklist *fgs, *ql; + int force, n, qi; int panik = 0; message * msg; @@ -986,10 +990,11 @@ sp_flee(fighter * fi, int level, double power, spell * sp) } fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY); - v_scramble(fgs->begin, fgs->end); + scramble_fighters(fgs); + + for (qi=0,ql=fgs; ql; ql_advance(&ql, &qi, 1)) { + fighter *df = (fighter *)ql_get(ql, qi); - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; for (n=0; n!=df->alive; ++n) { if (force < 0) break; @@ -1009,8 +1014,7 @@ sp_flee(fighter * fi, int level, double power, spell * sp) } } } - cv_kill(fgs); - free(fgs); + ql_free(fgs); msg = msg_message("sp_flee_effect_1", "mage spell amount", mage, sp, panik); message_all(b, msg); @@ -1496,14 +1500,13 @@ sp_keeploot(fighter * fi, int level, double power, spell * sp) } static int -heal_fighters(cvector *fgs, int * power, boolean heal_monsters) +heal_fighters(quicklist *fgs, int * power, boolean heal_monsters) { - int healhp = *power; - int healed = 0; - void **fig; + int healhp = *power, healed = 0, qi; + quicklist *ql; - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; + for (qi=0,ql=fgs; ql; ql_advance(&ql, &qi, 1)) { + fighter *df = (fighter *)ql_get(ql, qi); if (healhp<=0) break; @@ -1542,7 +1545,7 @@ sp_healing(fighter * fi, int level, double power, spell * sp) unit *mage = fi->unit; int j = 0; int healhp = (int)power * 200; - cvector *fgs; + quicklist *fgs; message * msg; boolean use_item = get_item(mage, I_AMULET_OF_HEALING) > 0; @@ -1557,11 +1560,10 @@ sp_healing(fighter * fi, int level, double power, spell * sp) * bis zu verteilende HP aufgebraucht sind */ fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_HELP); - v_scramble(fgs->begin, fgs->end); + scramble_fighters(fgs); j += heal_fighters(fgs, &healhp, false); j += heal_fighters(fgs, &healhp, true); - cv_kill(fgs); - free(fgs); + ql_free(fgs); if (j <= 0) { level = j; @@ -1583,19 +1585,18 @@ sp_undeadhero(fighter * fi, int level, double power, spell * sp) battle *b = fi->side->battle; unit *mage = fi->unit; region *r = b->region; - cvector *fgs; - void **fig; - int n, undead = 0; + quicklist *fgs, *ql; + int qi, n, undead = 0; message * msg; int force = (int)get_force(power,0); double c = 0.50 + 0.02 * power; /* Liste aus allen Kämpfern */ fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY | FS_HELP ); - v_scramble(fgs->begin, fgs->end); + scramble_fighters(fgs); - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; + for (qi=0,ql=fgs; ql; ql_advance(&ql, &qi, 1)) { + fighter *df = (fighter *)ql_get(ql, qi); unit *du = df->unit; if (force<=0) break; @@ -1644,8 +1645,7 @@ sp_undeadhero(fighter * fi, int level, double power, spell * sp) } } } - cv_kill(fgs); - free(fgs); + ql_free(fgs); level = MIN(level, undead); if (undead == 0) {