void CmdMove(CORE_DATA *cd) { USER_DATA *ud = UD(cd); // the game hasnt started if (ud->in_progress == false) { Reply("The game has not yet begun"); return; } // check for correct arg count if (cd->cmd_argc != 2) { ReplyFmt("Usage: !move Coord,Coord"); ReplyFmt("Example: !move e2,e4"); return; } // make sure the player is playing if (IsPlaying(ud, cd->cmd_name) == false) { Reply("You are not playing in this match"); return; } // replies to players in-game are via arena // check whos turn it is if (GetColor(ud, cd->cmd_name) != ud->to_move) { ArenaMessage("It is not your move"); return; } // parse argument char xstr[3]; char ystr[3]; DelimArgs(xstr, 3, cd->cmd_argv[1], 0, ',', false); DelimArgs(ystr, 3, cd->cmd_argv[1], 1, ',', false); int x1, y1, x2, y2; if (ParseCoords(xstr, &x1, &y1) == true && ParseCoords(ystr, &x2, &y2) == true) { char *err = TryMove(ud, ud->to_move, x1, y1, x2, y2); if (err == NULL && ud->in_progress == true) { // successful moves are announced in TryMove() ud->to_move = GetOppositeColor(ud->to_move); LvzToMove(ud->to_move, NULL); ArenaMessageFmt("%s (%s) to Move", GetPlayerName(ud, ud->to_move), GetColorText(ud->to_move)); } else if (ud->in_progress == true) { ArenaMessageFmt("Couldn't move: %s", err); } } else { ArenaMessageFmt("Invalid coordinates"); } }
/* * Each bot's entry point. 'arg' must be a dynamically allocated THREAD_ARG * pointer. The pointer is freed by the new thread. */ void* BotEntryPoint(void *arg) { THREAD_DATA *td = (THREAD_DATA*)arg; /* set the tls key */ pthread_setspecific(g_tls_key, td); init_thread_data(td); db_instance_init(); cmd_instance_init(td); player_instance_init(td); libman_instance_init(td); /* load the core pseudo-plugin */ libman_load_library(td, NULL); /* load the bots libraries */ int num_plugins = DelimCount(td->libstring, ' ') + 1; for (int i = 0; i < num_plugins; ++i) { char libname[64]; DelimArgs(libname, 64, td->libstring, i, ' ', false); if (strlen(libname) > 0) { libman_load_library(td, libname); } } /* mainloop */ mainloop(td); disconnect_from_server(td); libman_instance_shutdown(td); player_instance_shutdown(td); cmd_instance_shutdown(td); db_instance_shutdown(); botman_bot_exiting(td->botman_handle); free_thread_data(td); free(td); return NULL; }
void GameEvent(CORE_DATA *cd) { switch (cd->event) { case EVENT_START: RegisterPlugin(OPENCORE_VERSION, "rabbit", "cycad", "1.0", __DATE__, __TIME__, "A rabbit bot", sizeof(USER_DATA), 0); /* set rabbit pid to nobody */ ud(cd)->rabbit_pid = PID_NONE; /* register rabbit command */ RegisterCommand(COMMAND_RABBIT, "!rabbit", "Rabbit", 2, CMD_PRIVATE, "<name>:<bounty>[:<special>]", "Start the rabbit game", NULL); break; case EVENT_LOGIN: /* set the bot's location to center */ SetPosition(16 * 512, 16 * 512, 0, 0); break; case EVENT_COMMAND: switch (cd->cmd_id) { case COMMAND_RABBIT: { int show_usage = 0; PLAYER_ID rpid = ud(cd)->rabbit_pid; if (rpid == PID_NONE) { /* rabbit game is not runnig */ if (cd->cmd_argc <= 1) { show_usage = 1; } else { char *cmd = cd->cmd_argr[1]; int nargs = ArgCount(cmd, ':'); if (nargs != 2 && nargs != 3) { show_usage = 1; } else { /* args to command are valid */ /* copy name out of command */ char rname[20]; DelimArgs(rname, sizeof(rname), cmd, 0, ':', 0); /* copy bounty out of command */ int bty = AtoiArg(cmd, 1, ':'); /* copy special out of command if it was specified */ int special = 0; if (nargs == 3) special = AtoiArg(cmd, 2, ':'); /* find the player specified on the command line */ PLAYER *rabbit = FindPlayerName(rname, MATCH_HERE | MATCH_PREFIX); if (rabbit) { /* player found, start the game */ start_rabbit_game(cd, rabbit, bty, special); } else { RmtMessageFmt(cd->cmd_name, "Player not found: %s", rname); } } } } else { /* rabbit game is already running */ PLAYER *p = FindPlayerPid(rpid, MATCH_HERE); RmtMessageFmt(cd->cmd_name, "Rabbit is already running (%s is the rabbit)", p ? p->name : "**UNKNOWN**"); } /* display usage if necessary */ if (show_usage) RmtMessageFmt(cd->cmd_name, "Usage: %s <name>:<bounty>[:<special>]", cd->cmd_argv[0]); } default: break; } break; case EVENT_UPDATE: if (ud(cd)->rabbit_pid == cd->p1->pid) { /* if the update is for the rabbit */ if (cd->p1->status & STATUS_SAFE) { /* check if the rabbit is in safe */ /* the rabbit entered safe, end the game */ ArenaMessageFmt("%s has lost the rabbit game by entering safe!", cd->p1->name); ud(cd)->rabbit_pid = PID_NONE; } } break; case EVENT_TIMER: if (ud(cd)->rabbit_pid != PID_NONE) { /* if the rabbit game is running */ /* find the rabbit */ PLAYER *p = FindPlayerPid(ud(cd)->rabbit_pid, MATCH_HERE); if (p) { if (ud(cd)->where_timer == cd->timer_id) { /* a *where timer expired, send the next one and look for response */ PrivMessage(p, "*where"); ud(cd)->expecting_where = 1; } else if (ud(cd)->gameover_timer == cd->timer_id) { /* the game over timer expired, the rabbit didnt die and he won */ ArenaMessageFmt("%s wins the rabbit game by staying alive!", p->name); ud(cd)->rabbit_pid = PID_NONE; } } else { /* rabbit not found, this should never happen! */ } } case EVENT_MESSAGE: /* * Only look for a response of the game is running, the bot is expecting *where, * and the message type is an arena message. */ if (ud(cd)->rabbit_pid != PID_NONE && ud(cd)->expecting_where && cd->msg_type == MSG_ARENA) { /* message is a possible *where response */ /* find the rabbit */ PLAYER *p = FindPlayerPid(ud(cd)->rabbit_pid, MATCH_HERE); if (p) { char where_prefix[32]; snprintf(where_prefix, 32, "%s: ", p->name); where_prefix[32 - 1] = '\0'; /* * Verify that this is *where output by looking for "rabbit: " at the * beginning of the string. */ if (strncasecmp(where_prefix, cd->msg, strlen(where_prefix)) == 0) { /* this must be a *where response, process it */ char loc[4]; snprintf(loc, 4, "%s", &cd->msg[strlen(where_prefix)]); loc[4 - 1] = '\0'; /* announce the rabbits location */ ArenaMessageFmt(">>> Rabbit %s is at %-3s <<<", p->name, loc); /* set the next *where timer */ ud(cd)->where_timer = SetTimer(30 * 1000, 0, 0); /* * The bot wont be looking for *where responses until the * next time it sends the command, so turn parsing off * for now. */ ud(cd)->expecting_where = 0; } } } break; case EVENT_KILL: if (cd->p1->pid == ud(cd)->rabbit_pid) { /* the rabbit died */ ArenaMessageFmt("%s wins the rabbit game by killing Rabbit %s!", cd->p2->name, cd->p1->name); ud(cd)->rabbit_pid = PID_NONE; } break; case EVENT_LEAVE: if (ud(cd)->rabbit_pid == cd->p1->pid) { /* the rabbit left */ ArenaMessageFmt("%s has lost the rabbit game by leaving the arena!", cd->p1->name); ud(cd)->rabbit_pid = PID_NONE; } break; case EVENT_CHANGE: if (ud(cd)->rabbit_pid == cd->p1->pid) { /* the rabbit changed ship */ ArenaMessageFmt("%s has lost the rabbit game by changing ship/freq!", cd->p1->name); ud(cd)->rabbit_pid = PID_NONE; } break; } }