diff --git a/src/spells.c b/src/spells.c index 3b8d3ff2c..42da7f32d 100644 --- a/src/spells.c +++ b/src/spells.c @@ -197,7 +197,6 @@ static void magicanalyse_region(region * r, unit * mage, double force) for (a = r->attribs; a; a = a->next) { curse *c = (curse *)a->data.v; double probability; - int mon; if (a->type != &at_curse) continue; @@ -205,8 +204,6 @@ static void magicanalyse_region(region * r, unit * mage, double force) /* ist der curse schwaecher als der Analysezauber, so ergibt sich * mehr als 100% probability und damit immer ein Erfolg. */ probability = curse_chance(c, force); - mon = c->duration + (rng_int() % 10) - 5; - if (mon < 1) mon = 1; found = true; if (chance(probability)) { /* Analyse geglueckt */ @@ -215,6 +212,8 @@ static void magicanalyse_region(region * r, unit * mage, double force) "mage region curse", mage, r, c->type)); } else { + int mon = c->duration + (rng_int() % 10) - 5; + if (mon < 1) mon = 1; ADDMSG(&mage->faction->msgs, msg_message("analyse_region_age", "mage region curse months", mage, r, c->type, mon)); } @@ -238,7 +237,6 @@ static void magicanalyse_unit(unit * u, unit * mage, double force) for (a = u->attribs; a; a = a->next) { curse *c; double probability; - int mon; if (a->type != &at_curse) continue; @@ -246,15 +244,16 @@ static void magicanalyse_unit(unit * u, unit * mage, double force) /* ist der curse schwaecher als der Analysezauber, so ergibt sich * mehr als 100% probability und damit immer ein Erfolg. */ probability = curse_chance(c, force); - mon = c->duration + (rng_int() % 10) - 5; - if (mon < 1) mon = 1; - + found = true; + if (chance(probability)) { /* Analyse geglueckt */ if (c_flags(c) & CURSE_NOAGE) { ADDMSG(&mage->faction->msgs, msg_message("analyse_unit_noage", "mage unit curse", mage, u, c->type)); } else { + int mon = c->duration + (rng_int() % 10) - 5; + if (mon < 1) mon = 1; ADDMSG(&mage->faction->msgs, msg_message("analyse_unit_age", "mage unit curse months", mage, u, c->type, mon)); } @@ -278,24 +277,24 @@ static void magicanalyse_building(building * b, unit * mage, double force) for (a = b->attribs; a; a = a->next) { curse *c; double probability; - int mon; if (a->type != &at_curse) continue; + found = true; c = (curse *)a->data.v; /* ist der curse schwaecher als der Analysezauber, so ergibt sich * mehr als 100% probability und damit immer ein Erfolg. */ probability = curse_chance(c, force); - mon = c->duration + (rng_int() % 10) - 5; - if (mon < 1) mon = 1; if (chance(probability)) { /* Analyse geglueckt */ if (c_flags(c) & CURSE_NOAGE) { - ADDMSG(&mage->faction->msgs, msg_message("analyse_building_age", + ADDMSG(&mage->faction->msgs, msg_message("analyse_building_noage", "mage building curse", mage, b, c->type)); } else { + int mon = c->duration + (rng_int() % 10) - 5; + if (mon < 1) mon = 1; ADDMSG(&mage->faction->msgs, msg_message("analyse_building_age", "mage building curse months", mage, b, c->type, mon)); } @@ -320,16 +319,14 @@ static void magicanalyse_ship(ship * sh, unit * mage, double force) for (a = sh->attribs; a; a = a->next) { curse *c; double probability; - int mon; if (a->type != &at_curse) continue; + found = true; c = (curse *)a->data.v; /* ist der curse schwaecher als der Analysezauber, so ergibt sich * mehr als 100% probability und damit immer ein Erfolg. */ probability = curse_chance(c, force); - mon = c->duration + (rng_int() % 10) - 5; - if (mon < 1) mon = 1; if (chance(probability)) { /* Analyse geglueckt */ if (c_flags(c) & CURSE_NOAGE) { @@ -337,6 +334,8 @@ static void magicanalyse_ship(ship * sh, unit * mage, double force) "mage ship curse", mage, sh, c->type)); } else { + int mon = c->duration + (rng_int() % 10) - 5; + if (mon < 1) mon = 1; ADDMSG(&mage->faction->msgs, msg_message("analyse_ship_age", "mage ship curse months", mage, sh, c->type, mon)); } @@ -4558,7 +4557,7 @@ int sp_analysedream(castorder * co) return 0; u = param->data.u; - magicanalyse_unit(u, mage, cast_level); + magicanalyse_unit(u, mage, co->force); return cast_level; } @@ -4818,7 +4817,7 @@ int sp_analysemagic(castorder * co) case SPP_REGION: { region *tr = param->data.r; - magicanalyse_region(tr, mage, cast_level); + magicanalyse_region(tr, mage, co->force); break; } case SPP_TEMP: @@ -4826,21 +4825,21 @@ int sp_analysemagic(castorder * co) { unit *u; u = param->data.u; - magicanalyse_unit(u, mage, cast_level); + magicanalyse_unit(u, mage, co->force); break; } case SPP_BUILDING: { building *b; b = param->data.b; - magicanalyse_building(b, mage, cast_level); + magicanalyse_building(b, mage, co->force); break; } case SPP_SHIP: { ship *sh; sh = param->data.sh; - magicanalyse_ship(sh, mage, cast_level); + magicanalyse_ship(sh, mage, co->force); break; } default: diff --git a/src/spells.test.c b/src/spells.test.c index 04106d039..f8558f484 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1848,14 +1849,19 @@ static void test_shadowlords(CuTest *tc) { test_teardown(); } -static void test_analysemagic(CuTest *tc) { +static void test_analysemagic_unit(CuTest *tc) +{ struct region *r; struct faction *f; unit *u, *u2; castorder co; spellparameter param, *args = NULL; + message *m; + curse *c; test_setup(); + random_source_inject_constants(0.0, 0); + mt_create_va(mt_new("analyse_unit_age", NULL), "mage:unit", "unit:unit", "curse:curse", "months:int", MT_NEW_END); r = test_create_plain(0, 0); f = test_create_faction(); f->magiegebiet = M_DRAIG; @@ -1866,8 +1872,186 @@ static void test_analysemagic(CuTest *tc) { param.typ = SPP_UNIT; param.data.u = u2; arrput(args, param); - test_create_castorder(&co, u, 3, 10., 0, args); + test_create_castorder(&co, u, 3, 4., 0, args); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertPtrEquals(tc, NULL, test_find_faction_message(f, "analyse_unit_age")); + CuAssertPtrNotNull(tc, test_find_faction_message(f, "analyse_unit_nospell")); + test_clear_messages(f); + + c = create_curse(u, &u2->attribs, &ct_astralblock, 5.0, 20, 5, 0); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + /* curse is too strong, analysis fails */ + CuAssertPtrNotNull(tc, test_find_faction_message(f, "analyse_unit_fail")); + CuAssertPtrEquals(tc, NULL, test_find_faction_message(f, "analyse_unit_nospell")); + test_clear_messages(f); + + c->vigour = co.force; + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertPtrNotNull(tc, m = test_find_faction_message(f, "analyse_unit_age")); + CuAssertPtrEquals(tc, u, m->parameters[0].v); + CuAssertPtrEquals(tc, u2, m->parameters[1].v); + CuAssertPtrEquals(tc, (void *)c->type, m->parameters[2].v); + CuAssertIntEquals(tc, 15, m->parameters[3].i); + CuAssertPtrEquals(tc, NULL, test_find_faction_message(f, "analyse_unit_nospell")); + + test_teardown(); +} + +static void test_analysemagic_ship(CuTest *tc) +{ + struct region *r; + struct faction *f; + unit *u; + castorder co; + spellparameter param, *args = NULL; + message *m; + curse *c; + + test_setup(); + random_source_inject_constants(0.0, 0); + mt_create_va(mt_new("analyse_ship_age", NULL), "mage:unit", "ship:ship", "curse:curse", "months:int", MT_NEW_END); + r = test_create_plain(0, 0); + f = test_create_faction(); + f->magiegebiet = M_DRAIG; + u = test_create_unit(f, r); + u->ship = test_create_ship(r, NULL); + + param.flag = TARGET_OK; + param.typ = SPP_SHIP; + param.data.sh = u->ship; + arrput(args, param); + + test_create_castorder(&co, u, 3, 4., 0, args); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertPtrEquals(tc, NULL, test_find_faction_message(f, "analyse_ship_age")); + CuAssertPtrNotNull(tc, test_find_faction_message(f, "analyse_ship_nospell")); + test_clear_messages(f); + + c = create_curse(u, &u->ship->attribs, &ct_flyingship, 5.0, 20, 5, 0); CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + /* curse is too strong, analysis fails */ + CuAssertPtrNotNull(tc, test_find_faction_message(f, "analyse_ship_fail")); + CuAssertPtrEquals(tc, NULL, test_find_faction_message(f, "analyse_ship_nospell")); + test_clear_messages(f); + + c->vigour = co.force; + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertPtrNotNull(tc, m = test_find_faction_message(f, "analyse_ship_age")); + CuAssertPtrEquals(tc, u, m->parameters[0].v); + CuAssertPtrEquals(tc, u->ship, m->parameters[1].v); + CuAssertPtrEquals(tc, (void *)c->type, m->parameters[2].v); + CuAssertIntEquals(tc, 15, m->parameters[3].i); + CuAssertPtrEquals(tc, NULL, test_find_faction_message(f, "analyse_ship_nospell")); + + test_teardown(); +} + +static void test_analysemagic_building(CuTest *tc) +{ + struct region *r; + struct faction *f; + unit *u; + castorder co; + spellparameter param, *args = NULL; + message *m; + curse *c, *c2; + + test_setup(); + random_source_inject_constants(0.0, 0); + mt_create_va(mt_new("analyse_building_age", NULL), "mage:unit", "building:building", "curse:curse", "months:int", MT_NEW_END); + mt_create_va(mt_new("analyse_building_noage", NULL), "mage:unit", "building:building", "curse:curse", MT_NEW_END); + r = test_create_plain(0, 0); + f = test_create_faction(); + f->magiegebiet = M_DRAIG; + u = test_create_unit(f, r); + u->building = test_create_building(r, NULL); + + param.flag = TARGET_OK; + param.typ = SPP_BUILDING; + param.data.b = u->building; + arrput(args, param); + + test_create_castorder(&co, u, 3, 4., 0, args); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertIntEquals(tc, 1, test_count_messagetype(f->msgs, "analyse_building_nospell")); + CuAssertIntEquals(tc, 0, test_count_messagetype(f->msgs, "analyse_building_age")); + test_clear_messages(f); + + c = create_curse(u, &u->building->attribs, &ct_strongwall, 5.0, 20, 1, 0); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertIntEquals(tc, 0, test_count_messagetype(f->msgs, "analyse_building_nospell")); + /* curse is too strong, analysis fails */ + CuAssertIntEquals(tc, 1, test_count_messagetype(f->msgs, "analyse_building_fail")); + test_clear_messages(f); + + c->vigour = co.force; + c2 = create_curse(u, &u->building->attribs, &ct_magicwalls, co.force, 20, 1, 0); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertIntEquals(tc, 0, test_count_messagetype(f->msgs, "analyse_building_nospell")); + CuAssertPtrNotNull(tc, m = test_find_faction_message(f, "analyse_building_age")); + CuAssertPtrEquals(tc, u, m->parameters[0].v); + CuAssertPtrEquals(tc, u->building, m->parameters[1].v); + CuAssertPtrEquals(tc, (void *)c->type, m->parameters[2].v); + CuAssertIntEquals(tc, 15, m->parameters[3].i); + CuAssertPtrNotNull(tc, m = test_find_faction_message(f, "analyse_building_noage")); + CuAssertPtrEquals(tc, u, m->parameters[0].v); + CuAssertPtrEquals(tc, u->building, m->parameters[1].v); + CuAssertPtrEquals(tc, (void *)c2->type, m->parameters[2].v); + + test_teardown(); +} + +static void test_analysemagic_region(CuTest *tc) +{ + struct region *r; + struct faction *f; + unit *u; + castorder co; + spellparameter param, *args = NULL; + message *m; + curse *c, *c2; + + test_setup(); + random_source_inject_constants(0.0, 0); + mt_create_va(mt_new("analyse_region_age", NULL), "mage:unit", "region:region", "curse:curse", "months:int", MT_NEW_END); + mt_create_va(mt_new("analyse_region_noage", NULL), "mage:unit", "region:region", "curse:curse", MT_NEW_END); + r = test_create_plain(0, 0); + f = test_create_faction(); + f->magiegebiet = M_DRAIG; + u = test_create_unit(f, r); + + param.flag = TARGET_OK; + param.typ = SPP_REGION; + param.data.r = u->region; + arrput(args, param); + + test_create_castorder(&co, u, 3, 4., 0, args); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertIntEquals(tc, 1, test_count_messagetype(f->msgs, "analyse_region_nospell")); + CuAssertIntEquals(tc, 0, test_count_messagetype(f->msgs, "analyse_region_age")); + test_clear_messages(f); + + c = create_curse(u, &u->region->attribs, &ct_peacezone, 5.0, 20, 1, 0); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertIntEquals(tc, 0, test_count_messagetype(f->msgs, "analyse_region_nospell")); + /* curse is too strong, analysis fails */ + CuAssertIntEquals(tc, 1, test_count_messagetype(f->msgs, "analyse_region_fail")); + test_clear_messages(f); + + c->vigour = co.force; + c2 = create_curse(u, &u->region->attribs, &ct_holyground, co.force, 20, 1, 0); + CuAssertIntEquals(tc, co.level, sp_analysemagic(&co)); + CuAssertIntEquals(tc, 0, test_count_messagetype(f->msgs, "analyse_region_nospell")); + CuAssertPtrNotNull(tc, m = test_find_faction_message(f, "analyse_region_age")); + CuAssertPtrEquals(tc, u, m->parameters[0].v); + CuAssertPtrEquals(tc, u->region, m->parameters[1].v); + CuAssertPtrEquals(tc, (void *)c->type, m->parameters[2].v); + CuAssertIntEquals(tc, 15, m->parameters[3].i); + CuAssertPtrNotNull(tc, m = test_find_faction_message(f, "analyse_region_noage")); + CuAssertPtrEquals(tc, u, m->parameters[0].v); + CuAssertPtrEquals(tc, u->region, m->parameters[1].v); + CuAssertPtrEquals(tc, (void *)c2->type, m->parameters[2].v); + test_teardown(); } @@ -1918,7 +2102,11 @@ CuSuite *get_spells_suite(void) SUITE_ADD_TEST(suite, test_summon_familiar); SUITE_ADD_TEST(suite, test_shadowdemons); SUITE_ADD_TEST(suite, test_shadowlords); - SUITE_ADD_TEST(suite, test_analysemagic); + SUITE_ADD_TEST(suite, test_analysemagic_unit); + //SUITE_ADD_TEST(suite, test_analysemagic_temp); + SUITE_ADD_TEST(suite, test_analysemagic_ship); + SUITE_ADD_TEST(suite, test_analysemagic_building); + SUITE_ADD_TEST(suite, test_analysemagic_region); return suite; }