void starttourn(void) { int i, j; struct planet *pl; char s[80]; opentlog(); for (i = 0, pl = &planets[i]; i < NUMPLANETS; i++, pl++) { for (j = 0; j < MAXTEAM + 1; j++) { pl->pl_tinfo[j].timestamp = 0; /* doesn't work? */ pl->pl_hinfo = (PL_TYPE(*pl) == PLSTAR) ? ALLTEAM : pl->pl_owner; } } status->clock = 0; explode_everyone(KTOURNSTART, 0); tlog_all(); status2->league++; status2->leagueticksleft = MINUTES(configvals->regulation_minutes); /* version team names configured time date */ pmessage(" ", 0, MALL, UMPIRE); sprintf(s, "Timer started -- %d minutes remaining", status2->leagueticksleft / MINUTES(1)); pmessage(s, 0, MALL, UMPIRE); pmessage(" ", 0, MALL, UMPIRE); }
int getplayer(int from, char *line) { char id; char temp[MSG_LEN]; int what; int numargs; numargs = sscanf(line,"%s %c", temp, &id); id = toupper(id); if (numargs==1) what = from; else if ((id >= '0') && (id <='9')) what = id - '0'; else if ((id >= 'A') && (id <= ('A' + MAXPLAYER - 10))) what = id - 'A' + 10; else { pmessage(from, MINDIV, addr_mess(from, MINDIV), "Invalid player number."); return -1; } if (players[what].p_status == PFREE) { pmessage(from, MINDIV, addr_mess(from, MINDIV), "Player not in the game."); return -1; } return what; }
void udtourny(void) { int trem; char buf[120]; if (!status2->league) return; /* server is configured for league play */ if (status2->league == 1) return; /* we're still prepping */ trem = --status2->leagueticksleft; switch (status2->league) { case 2: /* the 1-minute pre tourney warm up. */ if (trem == SECONDS(5)) pmessage("5 seconds to tournament start", -1, MALL, UMPIRE); else if (trem == SECONDS(2)) pmessage("Hold on to your hats. Everybody dies!", -1, MALL, UMPIRE); else if (trem <= 0) { starttourn(); } break; case 3: /* full-on T-mode */ buf[0] = 0; if (trem % MINUTES(20) == 0 || (trem < MINUTES(20) && 0 == trem % MINUTES(5)) || (trem < MINUTES(5) && 0 == trem % MINUTES(1))) { sprintf(buf, "There are %d minutes remaining in regulation play", trem / MINUTES(1)); } else if (trem < MINUTES(1) && 0 == trem % SECONDS(10)) { sprintf(buf, "There are %d seconds remaining in regulation play", trem / SECONDS(1)); } if (buf[0]) pmessage(buf, -1, MALL, UMPIRE); if (trem <= 0) /* maybe go into overtime */ endtourn(); break; case 4: /* overtime, not implemented */ break; } }
void advertise() { int status; pid_t result; /* do not proceed unless advertising is enabled */ if (!server_advertise_enable) return; /* if forked process jams up, we will simply wait for it to unjam */ if (pid != 0) { result = waitpid(pid, &status, WNOHANG); if (result != pid) return; pid = 0; } /* fork a process to handle the task */ if ((pid = fork()) != 0) return; /* from here on we are executing in the context of the forked process */ alarm_prevent_inheritance(); pmessage(0, MALL, "GOD->ALL", "ad: %s", server_advertise_filter); exit(0); }
void inl_draft_begin() { int h; struct player *j; status->gameup &= ~GU_INL_DRAFTED; context->inl_draft = INL_DRAFT_MOVING_TO_POOL; context->inl_pool = 0; context->inl_home_pick = 0; context->inl_away_pick = 0; for (h = 0, j = &players[0]; h < MAXPLAYER; h++, j++) { if (inl_draft_ignore(j)) continue; j->p_desspeed = 0; bay_release(j); j->p_flags &= ~(PFREPAIR | PFBOMB | PFORBIT | PFBEAMUP | PFBEAMDOWN | PFCLOAK); j->p_flags |= PFSEEN; inl_draft_highlight_off(j); inl_draft_assign_to_pool(j); inl_draft_place(j); } status->gameup |= GU_INL_DRAFTING; pmessage(0, MALL, "GOD->ALL", "The captains have agreed to hold a draft."); }
static void inl_draft_pick(struct player *j, struct player *k) { /* TODO: draw a phaser from captain or selector to pick? */ if (j->p_team != k->p_team) { change_team_quietly(j->p_no, k->p_team, j->p_team); } if (j->p_team == FED) { j->p_inl_pick = context->inl_home_pick++; } if (j->p_team == ROM) { j->p_inl_pick = context->inl_away_pick++; } j->p_inl_draft = INL_DRAFT_MOVING_TO_PICK; pmessage(0, MALL, "GOD->ALL", "Selection #%d: %s (%s) drafts %s (%s).", context->inl_home_pick + context->inl_away_pick, k->p_mapchars, j->p_team == FED ? "HOME" : "AWAY", j->p_mapchars, j->p_name); /* set rank of player depending on pick position */ if (status->gameup & GU_INROBOT) j->p_stats.st_rank = NUMRANKS - (context->inl_home_pick + context->inl_away_pick - 1) / 2 - 2; }
void inl_draft_reject(int n) { struct player *j; if ((n < 0) || (n > MAXPLAYER)) return; j = &players[n]; switch (j->p_inl_draft) { case INL_DRAFT_OFF : /* not involved */ case INL_DRAFT_MOVING_TO_POOL : /* in transit to pool */ case INL_DRAFT_POOLED : /* in pool of players to be chosen */ break; case INL_DRAFT_CAPTAIN_UP : /* captain with right to select */ case INL_DRAFT_CAPTAIN_DOWN : /* captain without right to select */ if (me->p_inl_draft == INL_DRAFT_CAPTAIN_UP || me->p_inl_draft == INL_DRAFT_CAPTAIN_DOWN) { pmessage(0, MALL, "GOD->ALL", "Captain %s slaps captain %s around with a dead trout.", me->p_mapchars, j->p_mapchars); } break; case INL_DRAFT_MOVING_TO_PICK : /* has been chosen, in transit to team */ case INL_DRAFT_PICKED : /* has been chosen by a captain */ if (me->p_inl_draft == INL_DRAFT_CAPTAIN_UP) { /* captain flicks a picked player */ /* meaning: undo pick */ /* TODO: sysdef policy default DRAFT_UNPICK=0 */ /* TODO: verify pick is on same team as captain */ /* TODO: throw the pick back to the pool */ } break; } }
/* ARGSUSED */ int do_help(char *comm, struct message *mess, struct command_handler_2 *cmds, int cmdnum, int prereqs) { int who; int i; char *addr; who = mess->m_from; addr = addr_mess(who,MINDIV); if (cmds[0].command != NULL) { for (i=0; cmds[i].command != NULL; i++) { if ((cmds[i].tag & C_PR_MASK) & ~(prereqs)) /* Dont meet the prereqs */ continue; if (cmds[i].tag & C_DESC) /* Command is just a dummy description */ pmessage(who,MINDIV,addr, cmds[i].command); if (!(cmds[i].desc)) /* Command has no description (its description has a value of NULL, not "") Use this hack to make a command hidden */ continue; if (!(voting) && (cmds[i].tag & C_PR_VOTE)) continue; else if (cmds[i].tag & (C_VC_TEAM | C_VC_ALL)) { char ch; if (cmds[i].tag & C_VC_TEAM) ch = 'T'; else if (cmds[i].tag & C_VC_ALL) ch = 'M'; else ch = '?'; pmessage(who,MINDIV,addr, "|%10s - %c: %s", cmds[i].command, ch, cmds[i].desc); } else pmessage(who,MINDIV,addr, "|%10s - %s", cmds[i].command, cmds[i].desc); } } return 1; }
int main(int argc, char **argv) { int i; char buf[1000]; int seconds = 10, part; int c; while((c = getopt(argc, argv, "n:")) != -1) { switch(c) { case 'n': seconds = atoi(optarg); if(seconds < 0) usage(argv[0]); break; default: usage(argv[0]); break; } } openmem(0, 0); part = seconds % STEP; if (part) sleep(part); for (seconds -= part; seconds > 0; seconds -= STEP) { sprintf(buf, "->ALL ** Attention: The galaxy will be reset in %d seconds.", seconds); pmessage(buf, 0, MALL, SERVNAME); sleep(STEP); } sprintf(buf, "%s->ALL ** Manual galaxy reset **", SERVNAME); pmessage(buf, 0, MALL, SERVNAME); zap(); /* *newgalaxy = 1;*/ status2->newgalaxy = 1; exit(0); }
sendVersion(void) { char client_ver[15]; if (!version_sent) { version_sent = 1; sprintf(client_ver, "@%s.%d", mvers, PATCHLEVEL); pmessage(client_ver, me->p_no, MINDIV | MCONFIG); } }
void sendVersion(void) { static int version_sent = 0; char buf[80]; if (!version_sent) { version_sent = 1; sprintf(buf, "@ Paradise %s", CLIENTVERS); pmessage(buf, me->p_no, MINDIV | MCONFIG); } }
void inl_draft_end() { int h; struct player *j; context->inl_draft = INL_DRAFT_OFF; for (h = 0, j = &players[0]; h < MAXPLAYER; h++, j++) { j->p_inl_draft = INL_DRAFT_OFF; p_heal(j); } pmessage(0, MALL, "GOD->ALL", "The draft has completed."); status->gameup &= ~GU_INL_DRAFTING; }
void endtourn(void) { pmessage(" ", 0, MALL, UMPIRE); pmessage("Time is done", 0, MALL, UMPIRE); pmessage(" ", 0, MALL, UMPIRE); /* print damage assesments */ endgame_effects(1 << status2->home.index, 1 << status2->away.index, -1); scan_for_unexpected_tourny_events(); tlog_all(); closetlog(); /* conquer */ status2->league = 1; /* we should shut the game off here (status->gameup=0) */ }
static void advertise_tourney_queue(void) { char buf[80], addrbuf[10]; int count = 0; int i; if (status->tourn) return; for (i = 0; i < MAXPLAYER; i++) { if (players[i].p_status == PTQUEUE) count++; } sprintf(addrbuf, "%s->YOU ", SERVNAME); sprintf(buf, "There %s %d player%s on the tournament queue", (count == 1) ? "is" : "are", count, (count == 1) ? "" : "s"); pmessage (buf, me->p_no, MINDIV, addrbuf); }
static int inl_draft_next(struct player *k) { int h; struct player *j; for (h = 0, j = &players[0]; h < MAXPLAYER; h++, j++) { if (j == k) continue; if (inl_draft_ignore(j)) continue; if (!j->p_inl_captain) continue; j->p_inl_draft = INL_DRAFT_CAPTAIN_UP; inl_draft_highlight_up(j); k->p_inl_draft = INL_DRAFT_CAPTAIN_DOWN; inl_draft_highlight_down(k); return 1; } /* TODO: test that a captain who leaves and returns can allow draft to continue, test that a replacement captain can take the role */ pmessage(0, MALL, "GOD->ALL", "Draft stalled, no captain of other team."); return 0; }
/* animate alive ships during draft */ void inl_draft_update() { int h; struct player *j; /* tumbling transwarp-like animation for alive ships involved in draft */ for (h = 0, j = &players[0]; h < MAXPLAYER; h++, j++) { int dx, dy; if (inl_draft_ignore(j)) continue; if (j->p_status != PALIVE) continue; /* newly arriving players are forced into the pool */ if (context->inl_draft == INL_DRAFT_MOVING_TO_POOL && j->p_inl_draft == INL_DRAFT_OFF) { pmessage(0, MALL, "GOD->ALL", "%s has joined, and is ready to be drafted", j->p_mapchars); inl_draft_assign_to_pool(j); } inl_draft_place(j); dx = j->p_x - j->p_inl_x; dy = j->p_y - j->p_inl_y; if ((abs(dx) + abs(dy)) > 750) { p_x_y_go(j, j->p_x - (dx / 10), j->p_y - (dy / 10)); j->p_desdir = j->p_dir = (u_char) (j->p_dir + 24); } else { p_x_y_go(j, j->p_inl_x, j->p_inl_y); inl_draft_arrival(j); } } switch (context->inl_draft) { case INL_DRAFT_MOVING_TO_POOL: if (inl_draft_pool_size() == 0) inl_draft_done(); break; case INL_DRAFT_MOVING_TO_HOME: if (inl_draft_count_by_state(INL_DRAFT_MOVING_TO_HOME) == 0) inl_draft_end(); break; } }
dmessage(char *message, unsigned char flags, unsigned char from, unsigned char to) { register int len; W_Color color; char timebuf[10]; LONG curtime; struct tm *tm; char buf[80]; int take, destroy, team, kill, killp, killa, bomb, conq; struct distress dist; take = MTEAM + MTAKE + MVALID; destroy = MTEAM + MDEST + MVALID; kill = MALL + MKILL + MVALID; killp = MALL + MKILLP + MVALID; killa = MALL + MKILLA + MVALID; bomb = MTEAM + MBOMB + MVALID; team = MTEAM + MVALID; conq = MALL + MCONQ + MVALID; time(&curtime); tm = localtime(&curtime); sprintf(timebuf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); len = strlen(message); if (from == 255) { /* From God */ color = textColor; } else { color = playerColor(&(players[from])); } if (censorMessages) if ((flags != kill) && (flags != killp) && (flags != killa) && (flags != bomb) && (flags != take) && (flags != destroy)) censor(message); /* aha! A new type distress/macro call came in. parse it appropriately */ if (flags == (MTEAM | MDISTR | MVALID)) { HandleGenDistr(message, from, to, &dist); len = makedistress(&dist, message, distmacro[dist.distype].macro); #ifdef BEEPLITE if (UseLite) rcdlite(&dist); #endif if (len <= 0) return; flags ^= MDISTR; } if (niftyNewMessages) { if (logmess) { if (logFile != NULL) { fprintf(logFile, "%s: %s\n", timebuf, message); fflush(logFile); } else { printf("%s: %s\n", timebuf, message); } } if (!(logmess && logFile == NULL) && flags == conq) { /* output conquer stuff to stdout in addition to message window */ fprintf(stdout, "%s\n", message); if (instr(message, "kill")) { fprintf(stdout, "NOTE: The server here does not properly set message flags\n"); fprintf(stdout, "You should probably pester the server god to update....\n"); } } if (flags == (MCONFIG + MINDIV + MVALID)) { if (from == 255) CheckFeatures(message); return; } if ((flags == team) || (flags == take) || (flags == destroy)) { W_WriteText(messwt, 0, 0, color, message, len, shipFont(me)); if ((flags == team) && !strncmp(message + 10, " ", 5) && (message[15] == 0)) { printf("dmessage:flags==team PIG call from=%d\n", from); pmessage(cowid, from, MINDIV); } } else if ((flags == kill) || (flags == killp) || (flags == killa) || (flags == bomb)) { W_WriteText(messwk, 0, 0, color, message, len, 0); if (!reportKills) return; /* HW */ } else if (flags & MINDIV) { W_WriteText(messwi, 0, 0, color, message, len, 0); if (!strncmp(message + 10, " ", 5) && (message[15] == 0)) { printf("dmessage:MINDIV PIG call from=%d\n", from); pmessage(cowid, from, MINDIV); } } else { /* if we don't know where * * * the message beLONGs by * * * this time, stick it * in * * the all board... */ W_WriteText(messwa, 0, 0, color, message, len, 0); if (!strncmp(message + 10, " ", 5) && (message[15] == 0)) { pmessage(cowid, from, MINDIV); } } W_WriteText(reviewWin, 0, 0, color, message, len, 0); } else { /* ok, here we have the old kludge nastiness that we can turn on if we * * * HAVE to. yuk, blech, ptooie... */ if ((strncmp(message, "GOD->ALL", 8) == 0 && (instr(message, "was kill") || instr(message, "killed by"))) || (*message != ' ' && instr(message, "We are being attacked"))) { W_WriteText(messwk, 0, 0, color, message, len, 0); if (!reportKills) return; W_WriteText(reviewWin, 0, 0, color, message, len, 0); if (logmess) { if (logFile != NULL) { fprintf(logFile, "%s ", timebuf); fprintf(logFile, "%s\n", message); fflush(logFile); } else { printf("%s ", message); printf("%s\n", timebuf); } } return; } switch (flags & (MTEAM | MINDIV | MALL)) { case MTEAM: W_WriteText(messwt, 0, 0, color, message, len, 0); if (!strncmp(message + 10, " ", 5) && (message[15] == 0)) { pmessage(cowid, from, MINDIV); } if (logmess) { if (logFile != NULL) { fprintf(logFile, "%s ", timebuf); fprintf(logFile, "%s\n", message); fflush(logFile); } else { printf("%s ", message); printf("%s\n", timebuf); } } break; case MINDIV: if (!(flags & MCONFIG)) W_WriteText(messwi, 0, 0, color, message, len, 0); if (!strncmp(message + 10, " ", 5) && (message[15] == 0)) { pmessage(cowid, from, MINDIV); } if (logmess) { if (logFile != NULL) { fprintf(logFile, "%s ", timebuf); fprintf(logFile, "%s\n", message); fflush(logFile); } else { printf("%s ", message); printf("%s\n", timebuf); } } break; default: W_WriteText(messwa, 0, 0, color, message, len, 0); if (!strncmp(message + 10, " ", 5) && (message[15] == 0)) { pmessage(cowid, from, MINDIV); } if (logmess) { if (logFile != NULL) { fprintf(logFile, "%s ", timebuf); fprintf(logFile, "%s\n", message); fflush(logFile); } else { printf("%s", message); printf("%s\n", timebuf); } } break; } W_WriteText(reviewWin, 0, 0, color, message, len, 0); } }
void inl_draft_select(int n) { struct player *j, *k = me; /* j: pick-ee, k: pick-er */ if ((n < 0) || (n > MAXPLAYER)) return; j = &players[n]; switch (j->p_inl_draft) { case INL_DRAFT_OFF : /* not involved */ break; case INL_DRAFT_CAPTAIN_UP : /* captain with right to select */ break; case INL_DRAFT_CAPTAIN_DOWN : /* captain without right to select */ if (k->p_inl_draft == INL_DRAFT_CAPTAIN_UP) { /* captain fingers fellow captain */ /* meaning: pass */ if (inl_draft_next(k)) { pmessage(0, MALL, "GOD->ALL", "%s passes this draft pick.", k->p_mapchars); } /* TODO: this can result in an imbalance */ } break; case INL_DRAFT_MOVING_TO_POOL : /* in transit to pool */ case INL_DRAFT_POOLED : /* in pool of players to be chosen */ if (k->p_inl_draft == INL_DRAFT_CAPTAIN_UP) { /* captain fingers a pool player */ /* meaning: pool player is picked, next captain to pick */ if (!j->p_inl_captain) { if (inl_draft_next(k)) { inl_draft_pick(j, k); } } } else if (k->p_inl_draft == INL_DRAFT_PICKED_SELECTOR) { /* selector fingers a pool player */ /* meaning: pool player is picked, next captain to pick */ k = inl_draft_pick_to_captain(me); if (k == NULL) { pmessage(0, MALL, "GOD->ALL", "Draft error, %s has no captain.", me->p_mapchars); return; } if (k->p_inl_draft != INL_DRAFT_CAPTAIN_UP) { pmessage(0, MALL, "GOD->ALL", "Draft error, pick by %s ignored because captain is not up.", me->p_mapchars); return; } if (!j->p_inl_captain) { if (inl_draft_next(k)) { inl_draft_pick(j, k); } } } else if (k->p_inl_draft == INL_DRAFT_PICKED) { /* non-captain pick fingers a pool player */ /* meaning: team signaling to captain their preference */ /* TODO: distort pool position according to how many fingerings */ } break; case INL_DRAFT_MOVING_TO_PICK : /* has been chosen, in transit to team */ case INL_DRAFT_PICKED : /* has been chosen by a captain */ if (k->p_inl_draft == INL_DRAFT_CAPTAIN_UP || k->p_inl_draft == INL_DRAFT_CAPTAIN_DOWN) { /* captain fingers a picked player */ /* meaning: delegation of pick duty */ if (j->p_team == k->p_team) { j->p_inl_draft = INL_DRAFT_PICKED_SELECTOR; god(j->p_no, "Draft selector, your captain has chosen you to pick."); } } break; case INL_DRAFT_PICKED_SELECTOR: if (k->p_inl_draft == INL_DRAFT_CAPTAIN_UP || k->p_inl_draft == INL_DRAFT_CAPTAIN_DOWN) { /* captain fingers a selector */ /* meaning: cancel delegation of pick duty */ if (j->p_team == k->p_team) { j->p_inl_draft = INL_DRAFT_PICKED; god(j->p_no, "Draft selector, your captain has withdrawn your duty to pick."); } } break; } }
int do_vote(char *comm, struct message *mess, struct command_handler_2 *votes, int num) { int what = 0; int player = -1; register int i; register struct player *j; int pcount=0; /* Total players in game */ int vcount=0; /* Number who've voted recently */ int mflag = 0; int sendto = 0; int who; char nv[PV_TOTAL+1]; who = mess->m_from; if (players[who].p_status == POBSERV) { god(who, "Sorry, observers can't vote"); return 0; } if (votes[num].tag & C_PLAYER) { if ((what = getplayer(who, comm)) < 0) return 0; player = what; } what += votes[num].start; if (what >= PV_TOTAL) return 0; j = &players[who]; if ((j->voting[what] != 0) && (votes[num].frequency != 0)) { if ( (j->voting[what] + votes[num].frequency) > time(NULL) ) { godf(who,"Sorry, you can only use %s every %1.1f minutes", votes[num].command, votes[num].frequency / 60.0); return 0; } } j->voting[what] = time(NULL); /* Enter newest vote */ if (votes[num].tag & C_VC_TEAM) { sendto = players[who].p_team; mflag = MTEAM; } else if (votes[num].tag & C_VC_ALL) { sendto = 0; mflag = MALL; } else { ERROR(1,("Unrecognized message flag in do_vote() for %s\n", comm)); return 0; } if (!strncmp(comm, "EJECT", 5) && (who == player)) { god(who, "Sorry, you can't eject yourself."); return 0; } nv[0] = '\0'; for (i=0, j = &players[i]; i < MAXPLAYER; i++, j++) { /*Skip free slots and robots */ if ( (j->p_status == PFREE) || (j->p_flags & PFROBOT)) continue; /*Also skip players that are not on the same team if team flag is set*/ if ((votes[num].tag & C_VC_TEAM) && (j->p_team != players[who].p_team)) continue; /* Also skip observers */ if (j->p_status == POBSERV) continue; pcount++; /* Did a player vote expire? */ if ((j->voting[what] > 0) && ((votes[num].expiretime == 0) || (j->voting[what] + votes[num].expiretime > time(NULL)))) { vcount++; } else { strcat(nv, j->p_mapchars); strcat(nv, " "); } } pmessage(sendto, mflag, addr_mess(sendto,mflag), "%s has voted to %s. %d player%s (of %d) %s voted.", players[who].p_mapchars, comm, vcount, vcount==1 ? "":"s", pcount, vcount==1 ? "has":"have"); /* The Votes Passes */ if ( (vcount >= votes[num].minpass) && ( ((pcount < (2*vcount)) && (votes[num].tag & C_VC_ALL)) || ((votes[num].tag & C_VC_TEAM) && (pcount/2 + 1 <= vcount)) )) { pmessage(sendto, mflag, addr_mess(sendto,mflag), "The motion %s passes", comm); /* Reset the Votes for this item since it passed */ for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) j->voting[what] = -1; if (votes[num].tag & C_PLAYER) (*votes[num].handler)(who, player, mflag, sendto); else (*votes[num].handler)(who, mflag, sendto); return 1; } else { /* if (votes[num].tag & C_VC_TEAM) i = pcount - vcount - 1; else */ i = pcount/2 + 1 - vcount; if (i < (votes[num].minpass - vcount)) i = votes[num].minpass - vcount; pmessage(sendto, mflag, addr_mess(sendto, mflag), "Still need %d more vote%s, from %s", i, (i==1 ? "":"s"), nv); return 0; } }