/* vi: set ts=2: * * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) * Henning Peters (faroul@beyond.kn-bremen.de) * Enno Rehling (enno@eressea-pbem.de) * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) * * This program may not be used, modified or distributed without * prior permission by the authors of Eressea. */ #define BOOL_DEFINED #include #include #include #include "mapper.h" #include "autoseed.h" /* kernel includes */ #include #include #include #include #include #include #include #include #include #include /* modules */ #include /* util includes */ #include #include /* libc includes */ #include #include #include #ifdef __USE_POSIX #include #include #include #endif const char * orderfile = NULL; void RemovePartei(void) { faction *f, *F; ally *a, *anext; WINDOW *win; char *fac_nr36; int x; unit *u; region *r; win = openwin(SX - 20, 5, "< Partei löschen >"); fac_nr36 = my_input(win, 2, 1, "Partei Nummer: ", NULL); x = atoi36(fac_nr36); if (fac_nr36 && *fac_nr36 && x > 0) { wmove(win, 1, 2); wclrtoeol(win); wrefresh(win); wmove(win, 1, win->_maxx); waddch(win, '|'); wrefresh(win); F = findfaction(x); wmove(win, 1, 2); if (F) { wAddstr(factionname(F)); wrefresh(win); wmove(win, 3, 4); wattron(win, A_BOLD); wAddstr("Alle Einheiten gehen verloren!"); wattroff(win, A_BOLD); wmove(win, 3, 4); beep(); if (yes_no(win, "Diese Partei wirklich löschen?", 'n')) { for (f = factions; f; f = f->next) if (f != F) for (a = f->allies; a; a = anext) { anext = a->next; if (a->faction->no == F->no) removelist(&f->allies, a); } for (r = firstregion(F); r != lastregion(F); r = r->next) for (u = r->units; u; u = u->next) if (u->faction == F) set_number(u, 0); modified = 1; remove_empty_units(); removelist(&factions, F); findfaction(-1); /* static lastfaction auf NULL setzen */ } } else { wprintw(win, (NCURSES_CONST char*)"Partei %d gibt es nicht.", x); wmove(win, 3, 6); wAddstr(""); wrefresh(win); getch(); } } delwin(win); } extern int left, top, breit, hoch; typedef struct island { vmap factions; int maxage; int x; int y; unsigned int land; int age; } island; static int days2level(int days) { int l = 0; while (level_days(l)<=days) ++l; return l-1; } static void change_level(unit * u, skill_t sk, int bylevel) { skill * sv = get_skill(u, sk); assert(bylevel>0); if (sv==0) sv = add_skill(u, sk); sk_set(sv, sv->level+bylevel); } static void give_latestart_bonus(region *r, unit *u, int b) { int bsk = days2level(b*30); change_level(u, SK_OBSERVATION, bsk); change_money(u, 200*b); { unit *u2 = createunit(r, u->faction, 1, u->race); change_level(u2, SK_TACTICS, bsk); u2->irace = u->irace; /* fset(u2, FL_PARTEITARNUNG); */ } { unit *u2 = createunit(r, u->faction, 2*b, u->race); change_level(u2, SK_SPEAR, 3); change_level(u2, SK_TAXING, 3); change_item(u2, I_SPEAR, u2->number); u2->irace = u->irace; /* fset(u2, FL_PARTEITARNUNG); */ } } dropout * dropouts = NULL; int read_orders_file(const char * filename) { faction * f = NULL; char * b; char buffer[16]; FILE * F = fopen(filename, "r"); if (F==NULL) return -1; b = getbuf(F); while (b) { switch (igetparam(b, default_locale)) { case P_GAMENAME: case P_FACTION: strncpy(buffer, getstrtoken(), 16); f = findfaction(atoi36(buffer)); if (f) fset(f, FL_MARK); break; case P_NEXT: f = NULL; break; } b = getbuf(F); } fclose(F); return 0; } void read_orders(const char * filename) { faction *f; boolean loaded = false; #ifdef __USE_POSIX /* if filename points to a directory, read all files it contains. */ struct stat statbuf; if(stat(filename, &statbuf)) { if(S_ISDIR(statbuf.st_mode)) { DIR *dir = opendir(filename); struct dirent *d_ent; if(dir==NULL) return; while((d_ent = readdir(dir)) != NULL) { read_orders_file(d_ent->d_name); } closedir(dir); } else { if (read_orders_file(filename)==0) loaded = true; } } #else /* we do not have this functionality */ if (read_orders_file(filename)==0) loaded=true; #endif if (loaded) for (f=factions;f;f=f->next) { if (!fval(f, FL_MARK) && f->age <=1) { ursprung * ur = f->ursprung; while (ur && ur->id!=0) ur=ur->next; if (ur) { region * r = findregion(ur->x, ur->y); if (r) { dropout * drop = calloc(sizeof(dropout), 1); drop->x = ur->x; drop->y = ur->y; drop->fno = f->no; drop->race = f->race; drop->next = dropouts; dropouts = drop; } } } freset(f, FL_MARK); } } void read_dropouts(const char * filename) { FILE * F = fopen(filename, "r"); if (F==NULL) return; for (;;) { char email[64], race[20]; int age, x, y; if (fscanf(F, "%s %s %d %d %d", email, race, &age, &x, &y)<=0) break; if (age<=2) { region * r = findregion(x, y); if (r) { dropout * drop = calloc(sizeof(dropout), 1); drop->race = rc_find(race); if (drop->race==NULL) drop->race = findrace(race, default_locale); drop->x = x; drop->y = y; drop->fno = -1; drop->next = dropouts; dropouts = drop; } } } fclose(F); } void seed_dropouts(void) { dropout ** dropp = &dropouts; while (*dropp) { dropout *drop = *dropp; region * r = findregion(drop->x, drop->y); if (r) { boolean found = false; newfaction **nfp = &newfactions; unit * u; for (u=r->units;u;u=u->next) if (u->faction->no!=drop->fno) break; if (u==NULL) while (*nfp) { newfaction * nf = *nfp; if (nf->race==drop->race && !nf->bonus) { unit * u = addplayer(r, nf->email, nf->password, nf->race, nf->lang, nf->subscription); #ifdef ALLIANCES u->faction->alliance = nf->allies; #endif ++numnewbies; if (nf->bonus) give_latestart_bonus(r, u, nf->bonus); found=true; *dropp = drop->next; *nfp = nf->next; free(nf); break; } nfp = &nf->next; } if (!found) dropp=&drop->next; } else { *dropp = drop->next; } } } void read_newfactions(const char * filename) { FILE * F = fopen(filename, "r"); if (F==NULL) return; for (;;) { faction * f = factions; char race[20], email[64], lang[8], password[16]; newfaction *nf; int bonus, subscription; #ifdef ALLIANCES int alliance; /* email;race;locale;startbonus;subscription;alliance */ if (fscanf(F, "%s %s %s %d %s %d %d", email, race, lang, &bonus, &subscription, password, &alliance)<=0) break; #else /* email;race;locale;startbonus;subscription */ if (fscanf(F, "%s %s %s %d %d %s", email, race, lang, &bonus, &subscription, password)<=0) break; #endif while (f) { if (strcmp(f->email, email)==0 && f->subscription) { break; } f = f->next; } if (f) 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); nf->email = strdup(email); nf->password = strdup(password); nf->race = rc_find(race); nf->subscription = subscription; #ifdef ALLIANCES { struct alliance * al = findalliance(alliance); if (al==NULL) { char zText[64]; sprintf(zText, "Allianz %d", alliance); al = makealliance(alliance, zText); } nf->allies = al; } #endif if (nf->race==NULL) nf->race = findrace(race, default_locale); nf->lang = find_locale(lang); nf->bonus = bonus; assert(nf->race && nf->email && nf->lang); nf->next = newfactions; newfactions = nf; } fclose(F); } newfaction * select_newfaction(const struct race * rc) { selection *prev, *ilist = NULL, **iinsert; selection *selected = NULL; newfaction *player = newfactions; if (!player) return NULL; insert_selection(&ilist, NULL, strdup("new player"), NULL); iinsert=&ilist->next; prev = ilist; while (player) { if (rc==NULL || player->race==rc) { char str[80]; #ifdef ALLIANCES snprintf(str, 70, "%s %d %s %s", player->bonus?"!":" ", player->allies?player->allies->id:0, locale_string(default_locale, rc_name(player->race, 0)), player->email); #else snprintf(str, 70, "%s %s %s", player->bonus?"!":" ", locale_string(default_locale, rc_name(player->race, 0)), player->email); #endif insert_selection(iinsert, prev, strdup(str), (void*)player); prev = *iinsert; iinsert = &prev->next; } player=player->next; } selected = do_selection(ilist, "Partei", NULL, NULL); if (selected==NULL) return NULL; return (newfaction*)selected->data; } void NeuePartei(region * r) { int i, q, y; char email[INPUT_BUFSIZE+1]; newfaction * nf, **nfp; const struct locale * lang; const struct race * frace; int late, subscription = 0; unit *u; const char * passwd = NULL; int locale_nr; faction * f; if (!r->land) { warnung(0, "Ungeeignete Region! "); return; } nf = select_newfaction(NULL); if (nf!=NULL) { frace = nf->race; subscription = nf->subscription; late = nf->bonus; lang = nf->lang; passwd = nf->password; strcpy(email, nf->email); if (late) { WINDOW *win = openwin(SX - 10, 3, "< Neue Partei einfügen >"); if(r->age >= 5) late = (int) map_input(win, 2, 1, "Startbonus", -1, 99, r->age/2); else late = (int) map_input(win, 2, 1, "Startbonus", -1, 99, 0); delwin(win); } } else { WINDOW *win = openwin(SX - 10, 12, "< Neue Partei einfügen >"); strcpy(buf, my_input(win, 2, 1, "EMail-Adresse (Leer->Ende): ", NULL)); if (!buf[0]) { delwin(win); return; } strcpy(email, buf); for (f=factions;f;f=f->next) { if (strcmp(email, f->email)==0 && f->age==0) { warnung(0, "Neue Partei mit dieser Adresse existiert bereits."); delwin(win); return; } } y = 3; q = 0; wmove(win, y, 4); for (i = 0; i < MAXRACES; i++) if(playerrace(new_race[i])) { sprintf(buf, "%d=%s; ", i, new_race[i]->_name[0]); q += strlen(buf); if (q > SX - 20) { q = strlen(buf); y++; wmove(win, y, 4); } wAddstr(buf); } wrefresh(win); y++; do { int nrace = (char) map_input(win, 2, y, "Rasse", -1, MAXRACES-1, 0); if (nrace == -1) { delwin(win); return; } frace = new_race[nrace]; } while(!playerrace(frace)); y++; late = (int) map_input(win, 2, y, "Startbonus", -1, 99, 0); if(late == -1) { delwin(win); return; } i = 0; q = 0; y++; wmove(win, y, 4); while(localenames[i] != NULL) { sprintf(buf, "%d=%s; ", i, localenames[i]); q += strlen(buf); if (q > SX - 20) { q = strlen(buf); y++; wmove(win, y, 4); } wAddstr(buf); i++; } wrefresh(win); y++; locale_nr = map_input(win, 2, 8, "Locale", -1, i-1, 0); if(locale_nr == -1) { delwin(win); return; } lang = find_locale(localenames[locale_nr]); delwin(win); } /* remove duplicate email addresses */ nfp=&newfactions; while (*nfp) { newfaction * nf = *nfp; if (strcmp(email, nf->email)==0) { *nfp = nf->next; free(nf); } else nfp = &nf->next; } modified = 1; u = addplayer(r, email, passwd, frace, lang, subscription); ++numnewbies; if(late) give_latestart_bonus(r, u, late); #ifndef AMIGA sprintf(buf, "newuser %s", email); system(buf); #endif } static void ModifyPartei(faction * f) { int c, i, q, y; int fmag = count_skill(f, SK_MAGIC); int falch = count_skill(f, SK_ALCHEMY); WINDOW *win; unit *u; sprintf(buf, "<%s >", factionname(f)); win = openwin(SX - 6, 12, buf); wmove(win, 1, 2); wprintw(win, (NCURSES_CONST char*)"Rasse: %s", f->race->_name[1]); wmove(win, 2, 2); wprintw(win, (NCURSES_CONST char*)"Einheiten: %d", f->no_units); wmove(win, 3, 2); wprintw(win, (NCURSES_CONST char*)"Personen: %d", f->num_people); wmove(win, 4, 2); wprintw(win, (NCURSES_CONST char*)"Silber: %d", f->money); wmove(win, 5, 2); wprintw(win, (NCURSES_CONST char*)"Magier: %d", fmag); if (fmag) { region *r; freset(f, FL_DH); waddnstr(win, " (", -1); for (r = firstregion(f); r != lastregion(f); r = r->next) for (u = r->units; u; u = u->next) if (u->faction == f && has_skill(u, SK_MAGIC)) { if (fval(f, FL_DH)) waddnstr(win, ", ", -1); wprintw(win, (NCURSES_CONST char*)"%s(%d): %d", unitid(u), u->number, get_level(u, SK_MAGIC)); fset(f, FL_DH); } waddch(win, ')'); } wmove(win, 6, 2); wprintw(win, (NCURSES_CONST char*)"Alchemisten: %d", falch); if (falch) { region *r; waddnstr(win, " (", -1); freset(f, FL_DH); for (r = firstregion(f); r != lastregion(f); r = r->next) for (u = r->units; u; u = u->next) if (u->faction == f && has_skill(u, SK_ALCHEMY)) { if (fval(f, FL_DH)) waddnstr(win, ", ", -1); wprintw(win, (NCURSES_CONST char*)"%s(%d): %d", unitid(u), u->number, get_level(u, SK_ALCHEMY)); fset(f, FL_DH); } waddch(win, ')'); } wmove(win, 7, 2); wprintw(win, (NCURSES_CONST char*)"Regionen: %d", f->nregions); wmove(win, 8, 2); wprintw(win, (NCURSES_CONST char*)"eMail: %s", f->email); wmove(win, 10, 2); wprintw(win, (NCURSES_CONST char*)"Neue (R)asse oder (e)Mail, (q)uit"); wrefresh(win); for(;;) { c = getch(); switch (tolower(c)) { case 'q': case 27: delwin(win); touchwin(stdscr); return; case 'r': mywin = newwin(5, SX - 20, (SY - 5) / 2, (SX - 20) / 2); wclear(mywin); /*wborder(mywin, '|', '|', '-', '-', '.', '.', '`', '\'');*/ wborder(mywin, 0, 0, 0, 0, 0, 0, 0, 0); Movexy(3, 0); Addstr("< Rasse wählen >"); wrefresh(mywin); y = 2; q = 0; wmove(mywin, y, 4); for (i = 1; i < MAXRACES; i++) { sprintf(buf, "%d=%s; ", i, new_race[i]->_name[0]); q += strlen(buf); if (q > SX - 25) { q = strlen(buf); y++; wmove(mywin, y, 4); } wAddstr(buf); } q = map_input(mywin, 2, 1, "Rasse", 1, MAXRACES-1, old_race(f->race)); delwin(mywin); touchwin(stdscr); touchwin(win); if (new_race[q] != f->race) { modified = 1; f->race = new_race[q]; wmove(win, 1, 2); wprintw(win, (NCURSES_CONST char*)"Rasse: %s", f->race->_name[1]); } refresh(); wrefresh(win); break; case 'e': strcpy(buf, my_input(0, 0, 0, "Neue eMail: ", NULL)); touchwin(stdscr); touchwin(win); if (strlen(buf)) { strcpy(f->email, buf); wmove(win, 8, 2); wprintw(win, (NCURSES_CONST char*)"eMail: %s", f->email); modified = 1; } refresh(); wrefresh(win); break; } } } int ParteiListe(void) { dbllist *P = NULL, *oben, *unten, *tmp; faction *f; char *s; int x; clear(); move(1, 1); addstr("generiere Liste..."); refresh(); /* Momentan unnötig und zeitraubend */ #if 0 for (f = factions; f; f = f->next) { f->num_people = f->nunits = f->nregions = f->money = 0; } x=0; for (r = regions; r; r = r->next) { int q=0; char mark[]="_-¯-"; for (f = factions; f; f = f->next) freset(f, FL_DH); if (++x & 256) { x=0; move(20,1); q++; addch(mark[q&3]); } for (u = r->units; u; u = u->next) { if (u->faction->no != MONSTER_FACTION) { /* Monster nicht */ if (!fval(u->faction, FL_DH)) { fset(u->faction, FL_DH); u->faction->nregions++; } u->faction->nunits++; u->faction->num_people += u->number; u->faction->money += get_money(u); } } } #endif for (f = factions; f; f = f->next) { if (SX > 104) sprintf(buf, "%4s: %-30.30s %-12.12s %-24.24s", factionid(f), f->name, f->race->_name[1], f->email); else sprintf(buf, "%4s: %-30.30s %-12.12s", factionid(f), f->name, f->race->_name[1]); adddbllist(&P, buf); } oben = unten = pointer = P; pline = 0; x = -1; clear(); movexy(0, SY - 1); hline('-', SX + 1); movexy(0, SY); addstr(" Daten; /: suchen; D: Löschen; q,Esc: Ende"); for (;;) { if (x == -1) { clear(); if(oben) { for (unten = oben, x = 0; x < SY - 1 && unten->next; x++) { movexy(3, x); addstr(unten->s); unten = unten->next; } } if (x < SY - 1 && unten) { /* extra, weil sonst * unten=NULL nach for() */ movexy(3, x); addstr(unten->s); } movexy(0, SY - 1); hline('-', SX + 1); movexy(0, SY); addstr(" Daten; /: suchen; D: Löschen; q,Esc: Ende"); } movexy(0, pline); addstr("->"); refresh(); x = getch(); movexy(0, pline); addstr(" "); switch (x) { case 'q': case 27: return 0; case 13: case 10: { char fno[5]; strncpy(fno, pointer->s, 4); fno[4]=0; ModifyPartei(findfaction(atoi36(fno))); } break; case 'D': RemovePartei(); return 1; case KEY_DOWN: if (pointer->next) { pline++; pointer = pointer->next; if (pline == SY - 1) { x = 20; do { oben = oben->next; unten = unten->next; x--; pline--; } while (x && unten /*->next*/ ); x = -1; } } else beep(); break; case KEY_UP: if (pointer->prev) { pline--; pointer = pointer->prev; if (pline < 0) { x = 20; do { oben = oben->prev; unten = unten->prev; x--; pline++; } while (x && oben->prev); x = -1; } } else beep(); break; case KEY_NPAGE: case KEY_RIGHT: for (x = 20; x && unten; x--) { oben = oben->next; pointer = pointer->next; unten = unten->next; } x = -1; break; case KEY_PPAGE: case KEY_LEFT: for (x = 20; x && oben->prev; x--) { oben = oben->prev; pointer = pointer->prev; unten = unten->prev; } x = -1; break; case '/': strcpy(buf, my_input(0, 0, 0, "Partei Nr. oder Name: ", NULL)); touchwin(stdscr); /* redraw erzwingen */ for (tmp = P; tmp; tmp = tmp->next) { s = tmp->s; while (s && strncasecmp(buf, s, strlen(buf))) { s = strchr(s, ' '); if (s) s++; } if (s) break; } if (tmp) { pointer = tmp; pline = 0; if (tmp->prev) { tmp = tmp->prev; pline++; } oben = tmp; x = -1; } else beep(); break; } } }