faction *gm_addfaction(const char *email, plane * p, region * r) { attrib *a; unit *u; faction *f = calloc(1, sizeof(faction)); assert(p != NULL); /* GM faction */ a_add(&f->attribs, make_key(atoi36("quest"))); f->banner = _strdup("quest faction"); f->name = _strdup("quest faction"); f->passw = _strdup(itoa36(rng_int())); if (set_email(&f->email, email) != 0) { log_error("Invalid email address for faction %s: %s\n", itoa36(f->no), email); } f->race = new_race[RC_TEMPLATE]; f->age = 0; f->lastorders = turn; f->alive = true; f->locale = default_locale; f->options = want(O_COMPRESS) | want(O_REPORT) | want(O_COMPUTER) | want(O_ADRESSEN); { faction *xist; int id = atoi36("gm00") - 1; do { xist = findfaction(++id); } while (xist); f->no = id; addlist(&factions, f); fhash(f); } /* generic permissions */ a = a_add(&f->attribs, a_new(&at_permissions)); if (a) { attrib *ap = (attrib *) a->data.v; const char *keys[] = { "gmterf", "gmtele", "gmgive", "gmskil", "gmtake", "gmmsgr", "gmmsgu", "gmgate", 0 }; const char **key_p = keys; while (*key_p) { add_key(&ap, atoi36(*key_p)); ++key_p; } a_add(&ap, make_atgmcreate(resource2item(r_silver))); a->data.v = ap; } /* one initial unit */ u = create_unit(r, f, 1, new_race[RC_TEMPLATE], 1, "quest master", NULL); u->irace = new_race[RC_GNOME]; return f; }
static void test_itoa36(CuTest * tc) { CuAssertStrEquals(tc, itoa36(0), "0"); CuAssertStrEquals(tc, itoa10(INT_MAX), "2147483647"); CuAssertStrEquals(tc, itoab(-1, 5), "-1"); CuAssertStrEquals(tc, itoa36(-1), "-1"); CuAssertStrEquals(tc, itoa36(-10), "-a"); CuAssertStrEquals(tc, itoa36(666), "ii"); }
faction *addfaction(const char *email, const char *password, const struct race * frace, const struct locale * loc) { faction *f = calloc(1, sizeof(faction)); char buf[128]; if (!f) abort(); if (check_email(email) == 0) { faction_setemail(f, email); } else { log_info("Invalid email address for faction %s: %s\n", itoa36(f->no), email?email:""); faction_setemail(f, NULL); } f->alliance_joindate = turn; f->lastorders = 0; f->_alive = true; f->password_id = 0; f->age = 0; f->race = frace; f->magiegebiet = 0; f->locale = loc; f->uid = 0; f->flags = FFL_ISNEW|FFL_PWMSG; if (password) { faction_setpassword(f, password_hash(password, PASSWORD_DEFAULT)); ADDMSG(&f->msgs, msg_message("changepasswd", "value", password)); } f->options = WANT_OPTION(O_REPORT) | WANT_OPTION(O_ZUGVORLAGE) | WANT_OPTION(O_COMPUTER) | WANT_OPTION(O_COMPRESS) | WANT_OPTION(O_ADRESSEN) | WANT_OPTION(O_STATISTICS); f->no = unused_faction_id(); if (rule_region_owners()) { alliance *al = makealliance(f->no, NULL); setalliance(f, al); } addlist(&factions, f); fhash(f); slprintf(buf, sizeof(buf), "%s %s", LOC(loc, "factiondefault"), itoa36(f->no)); f->name = str_strdup(buf); if (!f->race) { log_warning("creating a faction that has no race", itoa36(f->no)); } return f; }
static void test_piracy_cmd(CuTest * tc) { faction *f; region *r; unit *u, *u2; terrain_type *t_ocean; ship_type *st_boat; test_setup(); setup_piracy(); t_ocean = get_or_create_terrain("ocean"); st_boat = st_get_or_create("boat"); u2 = test_create_unit(test_create_faction(NULL), test_create_region(1, 0, t_ocean)); assert(u2); u_set_ship(u2, test_create_ship(u2->region, st_boat)); u = test_create_unit(f = test_create_faction(NULL), r = test_create_region(0, 0, t_ocean)); assert(f && u); set_level(u, SK_SAILING, st_boat->sumskill); u_set_ship(u, test_create_ship(u->region, st_boat)); f->locale = get_or_create_locale("de"); u->thisorder = create_order(K_PIRACY, f->locale, "%s", itoa36(u2->faction->no)); piracy_cmd(u); CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertTrue(tc, u->region != r); CuAssertPtrEquals(tc, u2->region, u->region); CuAssertPtrEquals(tc, u2->region, u->ship->region); CuAssertPtrNotNullMsg(tc, "successful PIRACY sets attribute", r->attribs); /* FIXME: this is testing implementation, not interface */ CuAssertPtrNotNullMsg(tc, "successful PIRACY message", test_find_messagetype(f->msgs, "piratesawvictim")); CuAssertPtrNotNullMsg(tc, "successful PIRACY movement", test_find_messagetype(f->msgs, "shipsail")); test_teardown(); }
static void test_piracy_cmd_land_to_land(CuTest * tc) { unit *u; region *r; faction *f; int target; const terrain_type *t_plain; const ship_type *stype; test_setup(); setup_piracy(); t_plain = get_or_create_terrain("plain"); stype = test_create_shiptype("boat"); /* create a target: */ r = test_create_region(0, 0, t_plain); f = test_create_faction(NULL); u = test_create_unit(f, r); u->ship = test_create_ship(r, stype); target = f->no; /* create a pirate: */ r = test_create_region(1, 0, t_plain); f = test_create_faction(NULL); u = test_create_unit(f, r); u->ship = test_create_ship(r, stype); set_level(u, SK_SAILING, u->ship->type->sumskill); u->thisorder = create_order(K_PIRACY, f->locale, "%s", itoa36(target)); piracy_cmd(u); CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertPtrEquals(tc, r, u->region); test_teardown(); }
ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) { static char buffer[32]; ship *sh = (ship *)calloc(1, sizeof(ship)); const char *sname = 0; if (!sh) abort(); assert(stype); sh->no = newcontainerid(); sh->coast = NODIRECTION; sh->type = stype; sh->region = r; if (lang) { sname = LOC(lang, stype->_name); if (!sname) { sname = LOC(lang, parameters[P_SHIP]); } } if (!sname) { sname = parameters[P_SHIP]; } assert(sname); snprintf(buffer, sizeof(buffer), "%s %s", sname, itoa36(sh->no)); sh->name = str_strdup(buffer); shash(sh); if (r) { addlist(&r->ships, sh); } return sh; }
int change_effect(unit * u, const potion_type * effect, int delta) { if (delta != 0) { attrib *a = a_find(u->attribs, &at_effect); effect_data *data = NULL; while (a && a->type == &at_effect) { data = (effect_data *) a->data.v; if (data->type == effect) { if (data->value + delta == 0) { a_remove(&u->attribs, a); return 0; } else { data->value += delta; return data->value; } } a = a->next; } a = a_add(&u->attribs, a_new(&at_effect)); data = (effect_data *) a->data.v; data->type = effect; data->value = delta; return data->value; } log_error("change effect with delta==0 for unit %s\n", itoa36(u->no)); return 0; }
void name_unit(unit * u) { if (u_race(u)->generate_name) { const char *gen_name = u_race(u)->generate_name(u); if (gen_name) { unit_setname(u, gen_name); } else { unit_setname(u, racename(u->faction->locale, u, u_race(u))); } } else { char name[32]; const char * result; const struct locale * lang = u->faction ? u->faction->locale : default_locale; if (lang) { static const char * prefix[MAXLOCALES]; int i = locale_index(lang); if (!prefix[i]) { prefix[i] = LOC(lang, "unitdefault"); if (!prefix[i]) { prefix[i] = parameters[P_UNIT]; } } result = prefix[i]; } else { result = parameters[P_UNIT]; } strlcpy(name, result, sizeof(name)); strlcat(name, " ", sizeof(name)); strlcat(name, itoa36(u->no), sizeof(name)); unit_setname(u, name); } }
static void test_getunit(CuTest *tc) { unit *u, *u2; order *ord; attrib *a; struct region *r; struct locale *lang; struct terrain_type *t_plain; test_cleanup(); lang = get_or_create_locale("de"); test_translate_param(lang, P_TEMP, "TEMP"); /* note that the english order is FIGHT, not COMBAT, so this is a poor example */ t_plain = test_create_terrain("plain", LAND_REGION); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, t_plain)); a = a_add(&u->attribs, a_new(&at_alias)); a->data.i = atoi36("42"); /* this unit is also TEMP 42 */ r = test_create_region(1, 0, t_plain); ord = create_order(K_GIVE, lang, itoa36(u->no)); init_order(ord); CuAssertIntEquals(tc, GET_UNIT, getunit(u->region, u->faction, &u2)); CuAssertPtrEquals(tc, u, u2); init_order(ord); CuAssertIntEquals(tc, GET_NOTFOUND, getunit(r, u->faction, &u2)); CuAssertPtrEquals(tc, NULL, u2); free_order(ord); ord = create_order(K_GIVE, lang, itoa36(u->no + 1)); init_order(ord); CuAssertIntEquals(tc, GET_NOTFOUND, getunit(u->region, u->faction, &u2)); CuAssertPtrEquals(tc, NULL, u2); free_order(ord); ord = create_order(K_GIVE, lang, "0"); init_order(ord); CuAssertIntEquals(tc, GET_PEASANTS, getunit(u->region, u->faction, &u2)); CuAssertPtrEquals(tc, NULL, u2); free_order(ord); ord = create_order(K_GIVE, lang, "TEMP 42"); init_order(ord); CuAssertIntEquals(tc, GET_UNIT, getunit(u->region, u->faction, &u2)); CuAssertPtrEquals(tc, u, u2); free_order(ord); test_cleanup(); }
int json_export(stream * out, int flags) { cJSON *json, *root = cJSON_CreateObject(); assert(out && out->api); if (regions && (flags & EXPORT_REGIONS)) { char id[32]; region * r; plane * p; cJSON_AddItemToObject(root, "planes", json = cJSON_CreateObject()); for (p = planes; p; p = p->next) { cJSON *data; _snprintf(id, sizeof(id), "%u", p->id); cJSON_AddItemToObject(json, id, data = cJSON_CreateObject()); cJSON_AddNumberToObject(data, "x", p->minx); cJSON_AddNumberToObject(data, "y", p->miny); cJSON_AddNumberToObject(data, "width", p->maxx - p->minx); cJSON_AddNumberToObject(data, "height", p->maxy - p->miny); if (p->name) cJSON_AddStringToObject(data, "name", p->name); } cJSON_AddItemToObject(root, "regions", json = cJSON_CreateObject()); for (r = regions; r; r = r->next) { cJSON *data; _snprintf(id, sizeof(id), "%u", r->uid); cJSON_AddItemToObject(json, id, data = cJSON_CreateObject()); cJSON_AddNumberToObject(data, "x", r->x); cJSON_AddNumberToObject(data, "y", r->y); cJSON_AddStringToObject(data, "type", r->terrain->_name); if (r->land) { cJSON_AddStringToObject(data, "name", r->land->name); } } } if (factions && (flags & EXPORT_FACTIONS)) { faction *f; cJSON_AddItemToObject(root, "factions", json = cJSON_CreateObject()); for (f = factions; f; f = f->next) { cJSON *data; cJSON_AddItemToObject(json, itoa36(f->no), data = cJSON_CreateObject()); cJSON_AddStringToObject(data, "name", f->name); cJSON_AddStringToObject(data, "email", f->email); cJSON_AddNumberToObject(data, "score", f->score); } } if (flags) { char *tok, *output; output = cJSON_Print(root); tok = strtok(output, "\n\r"); while (tok) { if (tok[0]) { out->api->writeln(out->handle, tok); } tok = strtok(NULL, "\n\r"); } free(output); } cJSON_Delete(root); return 0; }
int db_update_factions(sqlite3 * db, bool force, int game_id) { quicklist *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; ql_iter it = qli_init(&ql); 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 (f->subscription == df->uid) { dbf = df; break; } } 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); return SQLITE_OK; }
int update_nmrs(void) { int newplayers = 0; faction *f; int timeout = NMRTimeout(); if (timeout>0) { int i; if (nmrs == NULL) { nmrs = malloc(sizeof(int) * (timeout + 1)); if (!nmrs) abort(); } for (i = 0; i <= timeout; ++i) { nmrs[i] = 0; } } for (f = factions; f; f = f->next) { if (f->age<=1) { ++newplayers; } else if (!fval(f, FFL_NOIDLEOUT|FFL_CURSED)) { int nmr = turn - f->lastorders; if (timeout>0) { if (nmr < 0 || nmr > timeout) { log_error("faction %s has %d NMR", itoa36(f->no), nmr); if (nmr < 0) nmr = 0; if (nmr > timeout) nmr = timeout; } if (nmr > 0) { log_debug("faction %s has %d NMR", itoa36(f->no), nmr); } ++nmrs[nmr]; } } } return newplayers; }
static void test_give_cmd_limit(CuTest * tc) { struct give env = { 0 }; unit *u; test_setup_ex(tc); env.f2 = env.f1 = test_create_faction(NULL); setup_give(&env); u = env.src; scale_number(u, 2); u->thisorder = create_order(K_GIVE, u->faction->locale, "%s 1 PERSON", itoa36(env.dst->no)); give_cmd(u, u->thisorder); CuAssertIntEquals(tc, 2, env.dst->number); CuAssertIntEquals(tc, 1, env.src->number); test_teardown(); }
static void out_faction(FILE * file, const struct faction *f) { if (alliances != NULL) { fprintf(file, "%s (%s/%d) (%.3s/%.3s), %d Einh., %d Pers., $%d, %d NMR\n", f->name, itoa36(f->no), f_get_alliance(f) ? f->alliance->id : 0, LOC(default_locale, rc_name(f->race, NAME_SINGULAR)), magic_school[f->magiegebiet], count_units(f), f->num_total, f->money, turn - f->lastorders); } else { fprintf(file, "%s (%.3s/%.3s), %d Einh., %d Pers., $%d, %d NMR\n", factionname(f), LOC(default_locale, rc_name(f->race, NAME_SINGULAR)), magic_school[f->magiegebiet], count_units(f), f->num_total, f->money, turn - f->lastorders); } }
const char *factionname(const faction * f) { typedef char name[OBJECTIDSIZE + 1]; static name idbuf[8]; static int nextbuf = 0; char *ibuf = idbuf[(++nextbuf) % 8]; if (f && f->name) { slprintf(ibuf, sizeof(idbuf[0]), "%s (%s)", f->name, itoa36(f->no)); } else { strcpy(ibuf, "Unbekannte Partei (?)"); } return ibuf; }
static void guardian_faction(plane * pl, int id) { region *r; faction *f = findfaction(id); if (!f) { f = calloc(1, sizeof(faction)); f->banner = _strdup("Sie dienen dem großen Wyrm"); f->passw = _strdup(itoa36(rng_int())); set_email(&f->email, "*****@*****.**"); f->name = _strdup("Igjarjuks Kundschafter"); f->race = new_race[RC_ILLUSION]; f->age = turn; f->locale = find_locale("de"); f->options = want(O_COMPRESS) | want(O_REPORT) | want(O_COMPUTER) | want(O_ADRESSEN) | want(O_DEBUG); f->no = id; addlist(&factions, f); fhash(f); } if (f->race != new_race[RC_ILLUSION]) { assert(!"guardian id vergeben"); exit(0); } f->lastorders = turn; f->alive = true; for (r = regions; r; r = r->next) if (getplane(r) == pl && rterrain(r) != T_FIREWALL) { unit *u; freset(r, RF_ENCOUNTER); for (u = r->units; u; u = u->next) { if (u->faction == f) break; } if (u) continue; u = createunit(r, f, 1, new_race[RC_GOBLIN]); set_string(&u->name, "Igjarjuks Auge"); set_item(u, I_RING_OF_INVISIBILITY, 1); set_order(&u->thisorder, NULL); fset(u, UFL_ANON_FACTION); set_money(u, 1000); } }
static void update_faction(sqlite3 *db, const faction *f) { char code[5]; const char *sql = "INSERT INTO faction_data (faction_id, code, name, email, lang, turn)" " VALUES (?, ?, ?, ?, ?, ?)"; sqlite3_stmt *stmt = 0; sqlite3_prepare_v2(db, sql, -1, &stmt, 0); sqlite3_bind_int(stmt, 1, f->subscription); strcpy(code, itoa36(f->no)); sqlite3_bind_text(stmt, 2, code, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 3, f->name, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 4, f->email, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 5, f->locale->name, -1, SQLITE_STATIC); sqlite3_bind_int(stmt, 6, turn); sqlite3_step(stmt); sqlite3_finalize(stmt); }
static void test_give_herbs(CuTest * tc) { struct give env = { 0 }; struct order *ord; test_setup_ex(tc); env.f2 = env.f1 = test_create_faction(NULL); setup_give(&env); i_change(&env.src->items, env.itype, 10); ord = create_order(K_GIVE, env.f1->locale, "%s %s", itoa36(env.dst->no), LOC(env.f1->locale, parameters[P_HERBS])); assert(ord); give_cmd(env.src, ord); CuAssertIntEquals(tc, 0, i_get(env.src->items, env.itype)); CuAssertIntEquals(tc, 10, i_get(env.dst->items, env.itype)); free_order(ord); test_teardown(); }
static void starting_region(newfaction ** players, region * r, region * rn[]) { int n; oceans_around(r, rn); freset(r, RF_MARK); for (n = 0; n != MAXDIRECTIONS; ++n) { freset(rn[n], RF_MARK); } terraform_region(r, newterrain(T_PLAIN)); prepare_starting_region(r); if (players && *players) { newfaction *nf = *players; const struct race *rc = nf->race ? nf->race : races; const struct locale *lang = nf->lang ? nf->lang : default_locale; const char * passwd = nf->password ? nf->password : itoa36(rng_int()); addplayer(r, addfaction(nf->email, passwd, rc, lang, 0)); *players = nf->next; free_newfaction(nf); } }
static void setup_pirate(unit **pirate, int p_r_flags, int p_rc_flags, const char *p_shiptype, unit **victim, int v_r_flags, const char *v_shiptype) { terrain_type *vterrain; ship_type *st_boat = NULL; race *rc; faction *f; setup_piracy(); vterrain = get_or_create_terrain("terrain1"); fset(vterrain, v_r_flags); *victim = test_create_unit(test_create_faction(NULL), test_create_region(1, 0, vterrain)); assert(*victim); if (v_shiptype) { st_boat = st_get_or_create(v_shiptype); u_set_ship(*victim, test_create_ship((*victim)->region, st_boat)); free(st_boat->coasts); st_boat->coasts = (struct terrain_type **)calloc(2, sizeof(struct terrain_type *)); st_boat->coasts[0] = vterrain; st_boat->coasts[1] = 0; } *pirate = create_unit(test_create_region(0, 0, get_or_create_terrain("terrain2")), f = test_create_faction(NULL), 1, rc = rc_get_or_create("pirate"), 0, 0, 0); fset(rc, p_rc_flags); assert(f && *pirate); if (p_shiptype) { st_boat = st_get_or_create(p_shiptype); u_set_ship(*pirate, test_create_ship((*pirate)->region, st_boat)); free(st_boat->coasts); st_boat->coasts = (struct terrain_type **)calloc(2, sizeof(struct terrain_type *)); st_boat->coasts[0] = vterrain; st_boat->coasts[1] = 0; } f->locale = get_or_create_locale("de"); (*pirate)->thisorder = create_order(K_PIRACY, f->locale, "%s", itoa36((*victim)->faction->no)); }
static void test_give_men_requires_contact(CuTest * tc) { struct give env = { 0 }; message * msg; order *ord; test_setup_ex(tc); env.f1 = test_create_faction(NULL); env.f2 = test_create_faction(NULL); setup_give(&env); msg = give_men(1, env.src, env.dst, NULL); CuAssertStrEquals(tc, "feedback_no_contact", test_get_messagetype(msg)); CuAssertIntEquals(tc, 1, env.dst->number); CuAssertIntEquals(tc, 1, env.src->number); ord = create_order(K_GIVE, env.f1->locale, "%s ALLES PERSONEN", itoa36(env.dst->no)); test_clear_messages(env.f1); give_cmd(env.src, ord); CuAssertPtrEquals(tc, NULL, test_find_messagetype(env.f1->msgs, "give_person")); CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_no_contact")); msg_release(msg); free_order(ord); test_teardown(); }
int writepasswd(void) { FILE *F; char zText[128]; path_join(basepath(), "passwd", zText, sizeof(zText)); F = fopen(zText, "w"); if (!F) { perror(zText); } else { faction *f; log_info("writing passwords..."); for (f = factions; f; f = f->next) { fprintf(F, "%s:%s:%s:%d\n", itoa36(f->no), faction_getemail(f), faction_getpassword(f), f->uid); } fclose(F); return 0; } return 1; }
const char *write_buildingname(const building * b, char *ibuf, size_t size) { slprintf(ibuf, size, "%s (%s)", b->name, itoa36(b->no)); return ibuf; }
static void xmasgate_write(const trigger * t, struct storage *store) { building *b = (building *)t->data.v; WRITE_TOK(store, itoa36(b->no)); }
int teach_cmd(unit * teacher, struct order *ord) { plane *pl; region *r = teacher->region; skill_t sk_academy = NOSKILL; int teaching, i, j, count, academy_students = 0; if (r->attribs) { if (get_curse(r->attribs, &ct_gbdream)) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "gbdream_noteach", "")); return 0; } } if ((u_race(teacher)->flags & RCF_NOTEACH) || fval(teacher, UFL_WERE)) { cmistake(teacher, ord, 274, MSG_EVENT); return 0; } pl = rplane(r); if (pl && fval(pl, PFL_NOTEACH)) { cmistake(teacher, ord, 273, MSG_EVENT); return 0; } teaching = teacher->number * TEACHNUMBER; if ((i = get_effect(teacher, oldpotiontype[P_FOOL])) > 0) { /* Trank "Dumpfbackenbrot" */ if (i > teaching) i = teaching; /* Trank wirkt pro Schueler, nicht pro Lehrer */ teaching -= i; change_effect(teacher, oldpotiontype[P_FOOL], -i); j = teaching; ADDMSG(&teacher->faction->msgs, msg_message("teachdumb", "teacher amount", teacher, j)); } if (teaching <= 0) return 0; count = 0; init_order_depr(ord); #if TEACH_ALL if (getparam(teacher->faction->locale) == P_ANY) { skill_t sk; unit *scholar; skill_t teachskill[MAXSKILLS]; int t = 0; do { sk = getskill(teacher->faction->locale); teachskill[t] = getskill(teacher->faction->locale); } while (sk != NOSKILL); for (scholar = r->units; teaching > 0 && scholar; scholar = scholar->next) { if (LongHunger(scholar)) { continue; } else if (scholar->faction == teacher->faction) { if (getkeyword(scholar->thisorder) == K_STUDY) { /* Input ist nun von student->thisorder !! */ init_order(scholar->thisorder, scholar->faction->locale); sk = getskill(scholar->faction->locale); if (sk != NOSKILL && teachskill[0] != NOSKILL) { for (t = 0; teachskill[t] != NOSKILL; ++t) { if (sk == teachskill[t]) { break; } } sk = teachskill[t]; } if (sk != NOSKILL && effskill_study(teacher, sk) - TEACHDIFFERENCE > effskill_study(scholar, sk)) { teaching -= teach_unit(teacher, scholar, teaching, sk, true, &academy_students); } } } #ifdef TEACH_FRIENDS else if (alliedunit(teacher, scholar->faction, HELP_GUARD)) { if (getkeyword(scholar->thisorder) == K_STUDY) { /* Input ist nun von student->thisorder !! */ init_order(scholar->thisorder, scholar->faction->locale); sk = getskill(scholar->faction->locale); if (sk != NOSKILL && effskill_study(teacher, sk) - TEACHDIFFERENCE >= effskill(scholar, sk, NULL)) { teaching -= teach_unit(teacher, scholar, teaching, sk, true, &academy_students); } } } #endif } } else #endif { char zOrder[4096]; size_t sz = sizeof(zOrder); order *new_order; zOrder[0] = '\0'; init_order_depr(ord); while (!parser_end()) { skill_t sk; unit *scholar; bool feedback; getunit(r, teacher->faction, &scholar); ++count; /* Falls die Unit nicht gefunden wird, Fehler melden */ if (!scholar) { char tbuf[20]; const char *uid; const char *token; /* Finde den string, der den Fehler verursacht hat */ parser_pushstate(); init_order_depr(ord); for (j = 0; j != count - 1; ++j) { /* skip over the first 'count' units */ getunit(r, teacher->faction, NULL); } token = getstrtoken(); /* Beginne die Fehlermeldung */ if (isparam(token, teacher->faction->locale, P_TEMP)) { token = getstrtoken(); sprintf(tbuf, "%s %s", LOC(teacher->faction->locale, parameters[P_TEMP]), token); uid = tbuf; } else { uid = token; } ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "unitnotfound_id", "id", uid)); parser_popstate(); continue; } feedback = teacher->faction == scholar->faction || alliedunit(scholar, teacher->faction, HELP_GUARD); /* Neuen Befehl zusammenbauen. TEMP-Einheiten werden automatisch in * ihre neuen Nummern uebersetzt. */ if (zOrder[0]) { strncat(zOrder, " ", sz - 1); --sz; } sz -= str_strlcpy(zOrder + 4096 - sz, itoa36(scholar->no), sz); if (getkeyword(scholar->thisorder) != K_STUDY) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_nolearn", "student", scholar)); continue; } /* Input ist nun von student->thisorder !! */ parser_pushstate(); init_order(scholar->thisorder, scholar->faction->locale); sk = getskill(scholar->faction->locale); parser_popstate(); if (sk == NOSKILL) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_nolearn", "student", scholar)); continue; } if (effskill_study(scholar, sk) > effskill_study(teacher, sk) - TEACHDIFFERENCE) { if (feedback) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_asgood", "student", scholar)); } continue; } if (sk == SK_MAGIC) { /* ist der Magier schon spezialisiert, so versteht er nur noch * Lehrer seines Gebietes */ magic_t mage2 = unit_get_magic(scholar); if (mage2 != M_GRAY) { magic_t mage1 = unit_get_magic(teacher); if (mage1 != mage2) { if (feedback) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "error_different_magic", "target", scholar)); } continue; } } } sk_academy = sk; teaching -= teach_unit(teacher, scholar, teaching, sk, false, &academy_students); } new_order = create_order(K_TEACH, teacher->faction->locale, "%s", zOrder); replace_order(&teacher->orders, ord, new_order); free_order(new_order); /* parse_order & set_order have each increased the refcount */ } if (academy_students > 0 && sk_academy!=NOSKILL) { academy_teaching_bonus(teacher, sk_academy, academy_students); } init_order_depr(NULL); return 0; }
newfaction *read_newfactions(const char *filename) { newfaction *newfactions = NULL; FILE *F = fopen(filename, "r"); char buf[1024]; if (F == NULL) return NULL; for (;;) { faction *f; char race[20], email[64], lang[8], password[16]; newfaction *nf, **nfi; int bonus = 0, subscription = 0; int alliance = 0; if (fgets(buf, sizeof(buf), F) == NULL) break; email[0] = '\0'; password[0] = '\0'; if (sscanf(buf, "%54s %20s %8s %d %d %16s %d", email, race, lang, &bonus, &subscription, password, &alliance) < 3) break; if (email[0] == '\0') break; if (password[0] == '\0') { size_t sz; sz = strlcpy(password, itoa36(rng_int()), sizeof(password)); sz += strlcat(password, itoa36(rng_int()), sizeof(password)); } for (f = factions; f; f = f->next) { if (strcmp(f->email, email) == 0 && f->subscription && f->age < MINAGE_MULTI) break; } if (f && f->units) continue; /* skip the ones we've already got */ for (nf = newfactions; nf; nf = nf->next) { if (strcmp(nf->email, email) == 0) break; } if (nf) continue; nf = calloc(sizeof(newfaction), 1); if (set_email(&nf->email, email) != 0) { log_error("Invalid email address for subscription %s: %s\n", itoa36(subscription), email); continue; } nf->password = _strdup(password); nf->race = rc_find(race); nf->subscription = subscription; if (alliances != NULL) { struct alliance *al = findalliance(alliance); if (al == NULL) { char zText[64]; sprintf(zText, "Allianz %d", alliance); al = makealliance(alliance, zText); } nf->allies = al; } else { nf->allies = NULL; } if (nf->race == NULL) { /* if the script didn't supply the race as a token, then it gives us a * race in the default locale (which means that itis a UTF8 string) */ nf->race = findrace(race, default_locale); if (nf->race == NULL) { char buffer[32]; size_t outbytes = sizeof(buffer) - 1; size_t inbytes = strlen(race); unicode_latin1_to_utf8(buffer, &outbytes, race, &inbytes); buffer[outbytes] = 0; nf->race = findrace(buffer, default_locale); if (nf->race == NULL) { log_error("new faction has unknown race '%s'.\n", race); free(nf); continue; } } } nf->lang = get_locale(lang); nf->bonus = bonus; assert(nf->race && nf->email && nf->lang); nfi = &newfactions; while (*nfi) { if ((*nfi)->race == nf->race) break; nfi = &(*nfi)->next; } nf->next = *nfi; *nfi = nf; } fclose(F); return newfactions; }
const char *write_shipname(const ship * sh, char *ibuf, size_t size) { snprintf(ibuf, size, "%s (%s)", sh->name, itoa36(sh->no)); return ibuf; }
void log_dead_factions(void) { if (dead_factions) { const char *logname = config_get("game.deadlog"); if (logname) { FILE *F; char path[PATH_MAX]; join_path(basepath(), logname, path, sizeof(path)); F = fopen(path, "at"); if (F) { faction *f; for (f = dead_factions; f; f = f->next) { fprintf(F, "%d\t%d\t%d\t%s\t%s\t%s\n", turn, f->lastorders, f->age, itoa36(f->no), f->email, f->name); } fclose(F); } } } }
static void removecurse_write(const trigger * t, struct storage *store) { removecurse_data *td = (removecurse_data *) t->data.v; WRITE_TOK(store, td->target ? itoa36(td->target->no) : 0); WRITE_INT(store, td->curse ? td->curse->no : 0); }