fix study.c teacher messaging

This commit is contained in:
Enno Rehling 2017-01-26 18:58:29 +01:00
parent 57f6c56e89
commit 23b211d9e4
6 changed files with 90 additions and 59 deletions

2
clibs

@ -1 +1 @@
Subproject commit 1052905e08314de8778750d7585474182723111e
Subproject commit f91ef37f08c5244bf616f1836c0aa9caaf36805c

View File

@ -133,47 +133,59 @@ static void update_faction(sqlite3 *db, const faction *f) {
sqlite3_finalize(stmt);
}
struct cb_data {
const faction *f;
sqlite3 *db;
db_faction *dbf;
};
static bool db_faction_cb(void *el, void *arg) {
db_faction *df = (db_faction *)el;
struct cb_data *cb = (struct cb_data *)arg;
const faction *f = cb->f;
if (f->no == df->no || strcmp(f->email, df->email) == 0 || strcmp(f->name, df->name) == 0) {
cb->dbf = df;
}
if (f->subscription == df->uid) {
cb->dbf = df;
return false;
}
return true;
}
int db_update_factions(sqlite3 * db, bool force, int game_id) {
selist *ql = read_factions(db, game_id);
faction *f;
sqlite3_exec(db, "BEGIN", 0, 0, 0);
for (f = factions; f; f = f->next) {
bool update = force;
db_faction *dbf = 0;
<<<<<<< HEAD
ql_iter it = qli_init(&ql);
=======
#ifdef SELIST_TODO
selist_iter it = qli_init(&ql);
>>>>>>> remove quicklist shim, use selist everywhere
while (qli_more(it)) {
db_faction *df = (db_faction*)qli_next(&it);
if (f->no == df->no || strcmp(f->email, df->email) == 0 || strcmp(f->name, df->name) == 0) {
dbf = df;
if (ql) {
faction *f;
struct cb_data cbdata;
cbdata.db = db;
cbdata.dbf = NULL;
sqlite3_exec(db, "BEGIN", 0, 0, 0);
for (f = factions; f; f = f->next) {
bool update = force;
cbdata.f = f;
selist_foreach_ex(ql, db_faction_cb, &cbdata);
if (cbdata.dbf) {
const db_faction *dbf = cbdata.dbf;
if (dbf->uid != f->subscription) {
log_warning("faction %s(%d) not found in database, but matches %d\n", itoa36(f->no), f->subscription, dbf->uid);
f->subscription = dbf->uid;
}
update = (dbf->no != f->no) || (strcmp(f->email, dbf->email) != 0) || (strcmp(f->name, dbf->name) != 0);
}
if (f->subscription == df->uid) {
dbf = df;
break;
else {
f->subscription = insert_faction(db, game_id, f);
log_warning("faction %s not found in database, created as %d\n", itoa36(f->no), f->subscription);
update = true;
}
if (update) {
update_faction(db, f);
log_debug("faction %s updated\n", itoa36(f->no));
}
}
if (dbf) {
if (dbf->uid != f->subscription) {
log_warning("faction %s(%d) not found in database, but matches %d\n", itoa36(f->no), f->subscription, dbf->uid);
f->subscription = dbf->uid;
}
update = (dbf->no != f->no) || (strcmp(f->email, dbf->email) != 0) || (strcmp(f->name, dbf->name) != 0);
}
else {
f->subscription = insert_faction(db, game_id, f);
log_warning("faction %s not found in database, created as %d\n", itoa36(f->no), f->subscription);
update = true;
}
if (update) {
update_faction(db, f);
log_debug("faction %s updated\n", itoa36(f->no));
}
sqlite3_exec(db, "COMMIT", 0, 0, 0);
}
sqlite3_exec(db, "COMMIT", 0, 0, 0);
return SQLITE_OK;
}

View File

@ -52,8 +52,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/rand.h>
#include <util/rng.h>
#include <util/umlaut.h>
#include <quicklist.h>
#include <selist.h>
/* libc includes */
#include <assert.h>
@ -222,7 +221,7 @@ teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
a = a_add(&student->attribs, a_new(&at_learning));
teach = (teaching_info *)a->data.v;
}
ql_push(&teach->teachers, teacher);
selist_push(&teach->teachers, teacher);
teach->value += n;
if (student->building && teacher->building == student->building) {
@ -531,6 +530,36 @@ static bool ExpensiveMigrants(void)
return rule;
}
struct teach_data {
unit *u;
skill_t sk;
};
static bool cb_msg_teach(void *el, void *arg) {
struct teach_data *td = (struct teach_data *)arg;
unit *ut = (unit *)el;
unit * u = td->u;
skill_t sk = td->sk;
if (ut->faction != u->faction) {
bool feedback = alliedunit(u, ut->faction, HELP_GUARD);
if (feedback) {
ADDMSG(&ut->faction->msgs, msg_message("teach_teacher",
"teacher student skill level", ut, u, sk,
effskill(u, sk, 0)));
}
ADDMSG(&u->faction->msgs, msg_message("teach_student",
"teacher student skill", ut, u, sk));
}
return true;
}
static void msg_teachers(struct selist *teachers, struct unit *u, skill_t sk) {
struct teach_data cbdata;
cbdata.sk = sk;
cbdata.u = u;
selist_foreach_ex(teachers, cb_msg_teach, &cbdata);
}
int study_cmd(unit * u, order * ord)
{
region *r = u->region;
@ -755,19 +784,8 @@ int study_cmd(unit * u, order * ord)
learn_skill(u, sk, days);
if (a != NULL) {
ql_iter qli = qli_init(&teach->teachers);
while (qli_more(qli)) {
unit *teacher = (unit *)qli_next(&qli);
if (teacher->faction != u->faction) {
bool feedback = alliedunit(u, teacher->faction, HELP_GUARD);
if (feedback) {
ADDMSG(&teacher->faction->msgs, msg_message("teach_teacher",
"teacher student skill level", teacher, u, sk,
effskill(u, sk, 0)));
}
ADDMSG(&u->faction->msgs, msg_message("teach_student",
"teacher student skill", teacher, u, sk));
}
if (teach->teachers) {
msg_teachers(teach->teachers, u, sk);
}
a_remove(&u->attribs, a);
a = NULL;

View File

@ -27,7 +27,7 @@ extern "C" {
#endif
struct unit;
struct quicklist;
struct selist;
int teach_cmd(struct unit *u, struct order *ord);
int study_cmd(struct unit *u, struct order *ord);
@ -48,7 +48,7 @@ extern "C" {
#define TEACHNUMBER 10
typedef struct teaching_info {
struct quicklist *teachers;
struct selist *teachers;
int value;
} teaching_info;

View File

@ -19,7 +19,7 @@
#include <tests.h>
#include <CuTest.h>
#include <quicklist.h>
#include <selist.h>
#include <assert.h>
@ -539,9 +539,9 @@ static void test_teach_message(CuTest *tc) {
teach = (teaching_info *)a->data.v;
CuAssertPtrNotNull(tc, teach->teachers);
CuAssertIntEquals(tc, 600, teach->value);
CuAssertIntEquals(tc, 2, ql_length(teach->teachers));
CuAssertPtrEquals(tc, u1, ql_get(teach->teachers, 0));
CuAssertPtrEquals(tc, u2, ql_get(teach->teachers, 1));
CuAssertIntEquals(tc, 2, selist_length(teach->teachers));
CuAssertPtrEquals(tc, u1, selist_get(teach->teachers, 0));
CuAssertPtrEquals(tc, u2, selist_get(teach->teachers, 1));
study_cmd(u, u->thisorder);
CuAssertPtrEquals(tc, NULL, test_find_messagetype(u1->faction->msgs, "teach_teacher"));
CuAssertPtrNotNull(tc, test_find_messagetype(u2->faction->msgs, "teach_teacher"));

View File

@ -105,10 +105,11 @@ struct cb_data {
struct region *r;
};
void cb_map(void *data, void *ex) {
static bool cb_map(void *data, void *ex) {
struct cb_data *cb = (struct cb_data *)ex;
struct unit *u = (struct unit *)data;
cb->call(cb->r, u, cb->data);
return true;
}
void travelthru_map(region * r, void(*cb)(region *, struct unit *, void *), void *data)