double dranu (void) /* ------------------------------------------------------------------------- * * Provide a single random number UD on (0, 1). * ------------------------------------------------------------------------- */ { return UD (0.0, 1.0); }
float sranu (void) /* ------------------------------------------------------------------------- * * Provide a single random number UD on (0, 1). * ------------------------------------------------------------------------- */ { return (float) UD (0.0, 1.0); }
/// @brief Looks up member data /// @note upvalue 1: Member descriptor, non-permissions, and lookup data static void Lookup (lua_State * L) { lua_rawgeti(L, lua_upvalueindex(1), eLookup); // object, key[, value], lookup lua_rawgeti(L, -1, eLType); // object, key[, value], lookup, type lua_Integer type = lua_tointeger(L, -1); lua_pop(L, 1); // object, key[, value], lookup switch (type) { case eThis: case eRegistry: lua_pushvalue(L, 1);// object, key[, value], lookup, object if (eRegistry == type) lua_gettable(L, LUA_REGISTRYINDEX); // object, key[, value], lookup, data; break; case ePointerTo: lua_pushlightuserdata(L, *(void**)UD(L, 1));// object, key[, value], lookup, data break; case eKey: lua_rawgeti(L, -2, eLKey); // object, key[, value], lookup, key lua_gettable(L, 1); // object, key[, value], lookup, data break; } lua_replace(L, -2); // object, key[, value], data }
static int WidgetSetDraw (lua_State * L) { Count(L, 2); Widget_SetDraw(U(L, 1), static_cast<void(*)(Uint32,void*)>(UD(L, 2))); return 0; }
static int WidgetSetHitTest (lua_State * L) { Count(L, 2); Widget_SetHitTest(U(L, 1), static_cast<void(*)(Uint32,float,float,void*)>(UD(L, 2))); return 0; }
static int ListboxSetFitBestItem (lua_State * L) { Count(L, 2); Listbox_SetFitBestItem(U(L, 1), static_cast<Uint32(*)(Uint32,float,float,void*)>(UD(L, 2))); return 0; }
static int SliderSetFitBestOffset (lua_State * L) { Count(L, 2); Slider_SetFitBestOffset(U(L, 1), static_cast<float(*)(Uint32,float,float,void*)>(UD(L, 2))); return 0; }
static int TextboxSetFitBestSpot (lua_State * L) { Count(L, 2); Textbox_SetFitBestSpot(U(L, 1), static_cast<Uint32(*)(Uint32,float,float,void*)>(UD(L,2))); return 0; }
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"); } }
/// @brief Assigns to a member /// @note upvalue 1: Member descriptor, non-permissions, and lookup data static void NewIndexMember (lua_State * L) { // Point to the requested member. Uint8 * pData = GetFields(L); // data, key, value, D, D[key], offset, type // Assign the appropriate type. switch (U(L, 7)) { case Member_Reg::ePointer: *(void**)pData = UD(L, 3); break; case Member_Reg::eU8: case Member_Reg::eUChar: *(Uint8*)pData = U8(L, 3); break; case Member_Reg::eS8: case Member_Reg::eSChar: // *(Sint8*)pData = S8(L, 3); break; case Member_Reg::eU16: case Member_Reg::eUShort: *(Uint16*)pData = U16(L, 3); break; case Member_Reg::eS16: case Member_Reg::eSShort: *(Sint16*)pData = S16(L, 3); break; case Member_Reg::eU32: *(Uint32*)pData = U(L, 3); break; case Member_Reg::eS32: *(Sint32*)pData = S32(L, 3); break; case Member_Reg::eULong: break; case Member_Reg::eSLong: *(long*)pData = LI(L, 3); break; case Member_Reg::eUInt: break; case Member_Reg::eSInt: *(Sint32*)pData = S32(L, 3); break; case Member_Reg::eFSingle: *(float*)pData = F(L, 3); break; case Member_Reg::eFDouble: break; case Member_Reg::eString: break; case Member_Reg::eBoolean: *(bool*)pData = B(L, 3); break; } }
void svrandom (integer n, float* x, integer incx) /* ------------------------------------------------------------------------- * * Randomize vector x, UD on (0, 1). * ------------------------------------------------------------------------- */ { register integer i; x += (incx<0) ? (-n+1)*incx : 0; for (i = 0; i < n; i++) x[i*incx] = (float) UD (0.0, 1.0); }
void CmdGameInfo(CORE_DATA *cd) { USER_DATA *ud = UD(cd); if (ud->in_progress == false) { Reply("There is no game going on"); return; } ReplyFmt("%s (White) vs. %s (Black) is In Progress", ud->white, ud->black); char time[32]; TicksToText(time, 32, GetTicksMs() - ud->start_tick); ReplyFmt("The match has been going on for %s", time); ReplyFmt("%s (White) to Move", ud->white); }
void CmdQuit(CORE_DATA *cd) { USER_DATA *ud = UD(cd); if (IsPlaying(ud, cd->cmd_name)) { if (ud->in_progress) { StopGame(ud, "%s cedes victory to %s!", cd->cmd_name, GetOpponentName(ud, cd->cmd_name)); } else { UnsetPlayerName(ud, cd->cmd_name); ArenaMessageFmt("%s is no longer playing", cd->cmd_name); } } else { Reply("You are not playing"); } }
void CmdBlack(CORE_DATA *cd) { USER_DATA *ud = UD(cd); if (IsPlaying(ud, cd->cmd_name) == true) { Reply("You are already playing"); } else if (ud->black[0] != '\0') { ReplyFmt("%s is Black", ud->black); } else { strlcpy(ud->black, cd->cmd_name, 24); if (ud->white[0]) { StartGame(ud); } else { ArenaMessageFmt("%s is Black and awaits a challenger!", ud->black); } } }
/// @brief Validates and returns a Uint8 * argument /// @param L Lua state /// @param index Argument index /// @return u8 * value u8 * PU8 (lua_State * L, int index) { return static_cast<u8*>(UD(L, index)); }
static int PaneSetFitBestXY (lua_State * L) { Count(L, 2); Pane_SetFitBestXY(U(L, 1), static_cast<void(*)(Uint32,float,float,void*,float*,float*)>(UD(L, 2))); return 0; }
void GameEvent(CORE_DATA *cd) { USER_DATA *ud = UD(cd); switch (cd->event) { case EVENT_START: RegisterPlugin(OPENCORE_VERSION, "chess", "cycad", "1.0", __DATE__, __TIME__, "A player-vs-player chess bot", sizeof(USER_DATA), 0); ud = UD(cd); // allocate chess board ud->board = (BOARD)calloc(8, sizeof(PIECE*)); for (int i = 0; i < 8; ++i) { ud->board[i] = (PIECE*)calloc(8, sizeof(PIECE)); } BoardReset(ud, ud->board); // draw the board LvzDrawAll(ud, NULL, true); RegisterCommand(COMMAND_CHESSHELP, "!chesshelp", "Chess", 0, CMD_PUBLIC | CMD_PRIVATE, NULL, "Get basic chessbot information", NULL); RegisterCommand(COMMAND_GAMEINFO, "!gameinfo", "Chess", 0, CMD_PUBLIC | CMD_PRIVATE, NULL, "Get information about the current game", NULL); RegisterCommand(COMMAND_WHITE, "!white", "Chess", 0, CMD_PUBLIC | CMD_PRIVATE, NULL, "Play as White", NULL); RegisterCommand(COMMAND_BLACK, "!black", "Chess", 0, CMD_PUBLIC | CMD_PRIVATE, NULL, "Play as Black", NULL); RegisterCommand(COMMAND_MOVE, "!move", "Chess", 0, CMD_PUBLIC | CMD_PRIVATE, "<coord1>,<coord2>", "Move a chess piece", NULL); RegisterCommand(COMMAND_QUIT, "!quit", "Chess", 0, CMD_PUBLIC | CMD_PRIVATE, NULL, "Stop playing chess", NULL); break; case EVENT_COMMAND: switch (cd->cmd_id) { case COMMAND_CHESSHELP: CmdChessHelp(cd); break; case COMMAND_GAMEINFO: CmdGameInfo(cd); break; case COMMAND_WHITE: CmdWhite(cd); break; case COMMAND_BLACK: CmdBlack(cd); break; case COMMAND_MOVE: CmdMove(cd); break; case COMMAND_QUIT: CmdQuit(cd); break; default: assert(0); break; } break; case EVENT_MESSAGE: #if 0 // eventually handle commands in pubchat, like "b1,c3" if (cd->msg_type == MSG_PUBLIC && ud->in_progress && IsPlaying(cd->msg_name)) { } #endif break; case EVENT_ENTER: LvzActivateBoard(); LvzDrawAll(ud, cd->p1, true); LvzToMove(ud->to_move, cd->p1); if (IsPlaying(ud, cd->p1->name)) { // player rejoined ArenaMessageFmt("%s has returned to the game", cd->p1->name); KillTimer(ud->timer); ud->timer = 0; } break; case EVENT_LEAVE: // check if this player is relevant if (IsPlaying(ud, cd->p1->name)) { if (ud->in_progress && ud->timer) { // timer is only set when one player is already gone StopGame(ud, "Both players left the game"); KillTimer(ud->timer); ud->timer = 0; } else if (ud->in_progress) { // someone left a game in progress ArenaMessageFmt("%s has left the game and has 2 minutes to return", cd->p1->name); ud->timer = SetTimer(2 * 60 * 1000, 0, 0); } else { // no need to wait for someone not playing ArenaMessageFmt("%s is no longer playing", cd->p1->name); UnsetPlayerName(ud, cd->p1->name); } } break; case EVENT_TIMER: // this game needs to be stopped due to timeout if (ud->in_progress && cd->timer_id == ud->timer) { StopGame(ud, "Player did not return to game"); ud->timer = 0; } else if (cd->timer_data1) { uint32_t objid = (uint32_t)(intptr_t)cd->timer_data1; uint32_t on = (uint32_t)(intptr_t)cd->timer_data2; if (on) { PubMessageFmt("*objon %u", objid); } else { PubMessageFmt("*objoff %u", objid); } } break; case EVENT_STOP: // free chess board for (int i = 0; i < 8; ++i) { free(ud->board[i]); } free(ud->board); // free user data free(cd->user_data); break; } }
static int WidgetSetProcessEvent (lua_State * L) { Count(L, 2); Widget_SetProcessEvent(U(L, 1), static_cast<void(*)(Uint32,enum _WidgetEventType,void*)>(UD(L, 2))); return 0; }
/// @brief Validates and returns a void * argument void * UT (lua_State * L, int index) { luaL_checktype(L, index, LUA_TUSERDATA); return *(void**)UD(L, index); }