src/modules/NeonFun.mod/cmd_neonfun_unoplay.c \
src/modules/NeonFun.mod/cmd_neonfun_unotake.c \
src/modules/NeonFun.mod/game_uno.c \
+ src/modules/NeonFun.mod/cmd_neonfun_4wins.c \
+ src/modules/NeonFun.mod/cmd_neonfun_4stone.c \
+ src/modules/NeonFun.mod/cmd_neonfun_4view.c \
+ src/modules/NeonFun.mod/game_4wins.c \
src/modules/NeonFun.mod/module.c
libNeonFun_la_LDFLAGS = -module -rpath /nowhere -avoid-version -no-undefined
libNeonFun_la_LIBADD = $(MYSQL_LIBS)
#include "../../EventLogger.h"
#include "../../bots.h"
#include "game_uno.h"
+#include "game_4wins.h"
#define BOTID NEONFUN_BOTID
#define BOTALIAS "NeonFun"
static void neonfun_parted(struct ChanUser *chanuser, char *reason) {
uno_event_part(chanuser);
+ fourwins_event_part(chanuser);
}
static void neonfun_quitted(struct UserNode *user, char *reason) {
uno_event_quit(user);
+ fourwins_event_quit(user);
}
static int neonfun_freechan(struct ChanNode *chan) {
uno_event_freechan(chan);
+ fourwins_event_freechan(chan);
return 0;
}
write_socket(client, sendBuf, pos+1);
}
+void fourwins_reply(struct fourwins_game *game, const char *text, ...) {
+ struct ClientSocket *client = game->textbot;
+ struct fourwins_guest *guest;
+ int guest_count = 0;
+ for(guest = game->guests; guest; guest = guest->next) {
+ guest_count++;
+ }
+ struct ChanUser *chanusers[guest_count + 2];
+ chanusers[0] = game->player[0];
+ chanusers[1] = game->player[1];
+ guest_count = 0;
+ for(guest = game->guests; guest; guest = guest->next) {
+ chanusers[2 + (guest_count++)] = guest->chanuser;
+ }
+ int i;
+ guest_count += 2;
+ for(i = 0; i < guest_count; i++) {
+ const char *reply_format = get_language_string(chanusers[i]->user, text);
+ if(reply_format == NULL)
+ reply_format = text;
+ char formatBuf[MAXLEN];
+ sprintf(formatBuf, "NOTICE %s :[4WINS] %s", chanusers[i]->user->nick, reply_format);
+ va_list arg_list;
+ char sendBuf[MAXLEN];
+ int pos;
+ if (!(client->flags & SOCKET_FLAG_CONNECTED)) return;
+ sendBuf[0] = '\0';
+ va_start(arg_list, text);
+ pos = vsnprintf(sendBuf, MAXLEN - 2, formatBuf, arg_list);
+ va_end(arg_list);
+ if (pos < 0 || pos > (MAXLEN - 2)) pos = MAXLEN - 2;
+ sendBuf[pos] = '\n';
+ sendBuf[pos+1] = '\0';
+ write_socket(client, sendBuf, pos+1);
+ }
+}
+
#undef BOTID
#undef BOTALIAS
void free_NeonFun(int type);
struct uno_game;
+struct fourwins_game;
struct ChanNode;
struct UserNode;
char* getSetting(struct UserNode *user, struct ChanNode *chan, const char *setting);
void setSetting(struct UserNode *user, struct ChanNode *chan, const char *setting, const char *value);
void uno_reply(struct uno_game *game, struct UserNode *user, const char *text, ...);
+void fourwins_reply(struct fourwins_game *game, const char *text, ...);
#endif
\ No newline at end of file
{"NF_UNO_USER_SKIP", "skipped $b%s$b."}, /* {ARGS: "TestUser"} */
{"NF_UNO_GAME_FINISHED", "The UNO Game has been finished!"},
{"NF_UNO_ADD_CARD", "$b%s$b has to take up %d cards. There is still the possibility that he/she has another card of this type...?"},
+ {"NF_UNO_RANK", "Rank"},
+ {"NF_UNO_NAME", "Name"},
+ {"NF_UNO_WON_GAMES", "Won Games"},
+ {"NF_UNO_TOTAL_WON_GAMES", "Total won Games"},
+
+ {"NF_4WINS_NOT_YOUR_TURN", "Wait your turn!"},
+ {"NF_4WINS_INVALID_COLUMN", "invalid column!"},
+ {"NF_4WINS_COLUMN_FULL", "This column is full!"},
+ {"NF_4WINS_USER_HURRY_UP", "$b%s$b, it's your turn! To put a stone into a column use: 4stone <colomn>"}, /* {ARGS: "TestUser"} */
+ {"NF_4WINS_USER_WON", "$b%s$b won the game!"}, /* {ARGS: "TestUser"} */
+ {"NF_4WINS_ENTER_OPPONENT", "Please enter the nick of the opponent you want to play against as a parameter of 4wins (eg. $b4wins TestUser$b)"},
+ {"NF_4WINS_OPPONENT_NOT_IN_CHAN", "$b%s$b needs to be in this channel to start a game against him/her."}, /* {ARGS: "TestUser"} */
+ {"NF_4WINS_DRAW", "Noone has won this game."},
+ {"NF_4WINS_REQUEST", "$b%s$b wants to play a game against you. use $b4wins$b to start the game."}, /* {ARGS: "TestUser"} */
+ {"NF_4WINS_REQUESTED", "waiting for $b%s$b accepting the game..."}, /* {ARGS: "TestUser"} */
+ {"NF_4WINS_START", "%s accepted the challenge! game starts:"}, /* {ARGS: "TestUser"} */
+ {"NF_4WINS_APPEND_PLAYER", "Please append the nick of a player playing the game you want to view. (eg. $b4view TestUser$b)"},
+ {"NF_4WINS_NO_GAME_FOUND", "Couldn't find a game with this user in this channel."},
+ {"NF_4WINS_VIEWING_ANOTHER_GAME", "You are already viewing another game."},
+ {"NF_4WINS_VIEWING_GAME", "You are now viewing the game."},
+ {"NF_4WINS_GAME_CLOSED", "Game aborted."},
+ {"NF_4WINS_TIMEOUT", "Game aborted (timeout)."},
{NULL, NULL}
};
USER_COMMAND("unotake", neonfun_cmd_unotake, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN);
USER_COMMAND("unoplay", neonfun_cmd_unoplay, 1, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN);
+ USER_COMMAND("4wins", neonfun_cmd_4wins, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN);
+ USER_COMMAND("4stone", neonfun_cmd_4stone, 1, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN);
+ USER_COMMAND("4view", neonfun_cmd_4view, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN);
+
#undef USER_COMMAND
}
CMD_BIND(neonfun_cmd_unotake);
CMD_BIND(neonfun_cmd_unoplay);
+CMD_BIND(neonfun_cmd_4wins);
+CMD_BIND(neonfun_cmd_4stone);
+CMD_BIND(neonfun_cmd_4view);
+
#endif
--- /dev/null
+/* cmd_neonfun_4stone.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonfun.h"
+#include "game_4wins.h"
+
+CMD_BIND(neonfun_cmd_4stone) {
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ if(!chanuser) return;
+ struct fourwins_game *game;
+ for(game = fourwins_active_games; game; game = game->next) {
+ if(chanuser == game->player[0] || chanuser == game->player[1]) {
+ if(game->state == FOURWINS_STATE_WAITING)
+ return;
+ else
+ break;
+ }
+ }
+ if(game) {
+ //check if it's the player's turn
+ if(game->player[game->active_player] != chanuser) {
+ reply(getTextBot(), user, "NF_4WINS_NOT_YOUR_TURN");
+ return;
+ }
+ int x = atoi(argv[0])-1;
+ if(x < 0 || x >= FOURWINS_MATRIX_WIDTH) {
+ reply(getTextBot(), user, "NF_4WINS_INVALID_COLUMN");
+ return;
+ }
+ int y = fourwins_next_free_y(game, x);
+ if(y < 0) {
+ reply(getTextBot(), user, "NF_4WINS_COLUMN_FULL");
+ return;
+ }
+ timeq_del(game->timer);
+ game->timer = NULL;
+ game->matrix[x][y].field = game->active_player+1;
+ fourwins_show_matrix(game);
+ if(fourwins_check_win(game, x, y)) {
+ fourwins_reply(game, "NF_4WINS_USER_WON", game->player[game->active_player]->user->nick);
+ if((game->player[game->active_player]->user->flags & USERFLAG_ISAUTHED)) {
+ char *tmp;
+ int win_count = ((tmp = getSetting(game->player[game->active_player]->user, chan, "4wins_win")) ? atoi(tmp) : 0);
+ int total_win_count = ((tmp = getSetting(game->player[game->active_player]->user, NULL, "4wins_win")) ? atoi(tmp) : 0);
+ win_count++;
+ total_win_count++;
+ char buf[10];
+ sprintf(buf, "%d", win_count);
+ setSetting(game->player[game->active_player]->user, chan, "4wins_win", buf);
+ sprintf(buf, "%d", total_win_count);
+ setSetting(game->player[game->active_player]->user, NULL, "4wins_win", buf);
+ }
+ fourwins_free_game(game);
+ } else {
+ game->total_stones++;
+ if(game->total_stones == FOURWINS_MAX_STONES) {
+ fourwins_reply(game, "NF_4WINS_DRAW");
+ if((game->player[0]->user->flags & USERFLAG_ISAUTHED)) {
+ char *tmp;
+ int win_count = ((tmp = getSetting(game->player[0]->user, chan, "4wins_draw")) ? atoi(tmp) : 0);
+ int total_win_count = ((tmp = getSetting(game->player[0]->user, NULL, "4wins_draw")) ? atoi(tmp) : 0);
+ win_count++;
+ total_win_count++;
+ char buf[10];
+ sprintf(buf, "%d", win_count);
+ setSetting(game->player[0]->user, chan, "4wins_draw", buf);
+ sprintf(buf, "%d", total_win_count);
+ setSetting(game->player[0]->user, NULL, "4wins_draw", buf);
+ }
+ if((game->player[1]->user->flags & USERFLAG_ISAUTHED)) {
+ char *tmp;
+ int win_count = ((tmp = getSetting(game->player[1]->user, chan, "4wins_draw")) ? atoi(tmp) : 0);
+ int total_win_count = ((tmp = getSetting(game->player[1]->user, NULL, "4wins_draw")) ? atoi(tmp) : 0);
+ win_count++;
+ total_win_count++;
+ char buf[10];
+ sprintf(buf, "%d", win_count);
+ setSetting(game->player[1]->user, chan, "4wins_draw", buf);
+ sprintf(buf, "%d", total_win_count);
+ setSetting(game->player[1]->user, NULL, "4wins_draw", buf);
+ }
+ fourwins_free_game(game);
+ return;
+ }
+ if(game->active_player)
+ game->active_player = 0;
+ else
+ game->active_player = 1;
+ fourwins_reply(game, "NF_4WINS_USER_HURRY_UP", game->player[game->active_player]->user->nick);
+ game->timer = timeq_add(120, module_id, fourwins_timeout, game);
+ }
+ }
+}
--- /dev/null
+/* cmd_neonfun_4view.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonfun.h"
+#include "game_4wins.h"
+
+CMD_BIND(neonfun_cmd_4view) {
+ struct UserNode *gameuser;
+ struct ChanUser *chanuser;
+ if(!argc || !(gameuser = getUserByNick(argv[0])) || !(chanuser = getChanUser(gameuser, chan))) {
+ reply(getTextBot(), user, "NF_4WINS_APPEND_PLAYER");
+ return;
+ }
+ struct fourwins_game *game, *fgame = NULL;
+ struct fourwins_guest *guest;
+ for(game = fourwins_active_games; game; game = game->next) {
+ for(guest = game->guests; guest; guest = guest->next) {
+ if(guest->chanuser->user == user) {
+ reply(getTextBot(), user, "NF_4WINS_VIEWING_ANOTHER_GAME");
+ return;
+ }
+ }
+ if(game->player[0]->user == user || game->player[1]->user == user) {
+ reply(getTextBot(), user, "NF_4WINS_VIEWING_ANOTHER_GAME");
+ return;
+ }
+ if(chanuser == game->player[0] || chanuser == game->player[1]) {
+ fgame = game;
+ }
+ }
+ game = fgame;
+ if(game) {
+ guest = malloc(sizeof(*guest));
+ chanuser = getChanUser(user, chan);
+ if(!chanuser) return;
+ guest->chanuser = chanuser;
+ guest->next = game->guests;
+ game->guests = guest;
+ reply(getTextBot(), user, "NF_4WINS_VIEWING_GAME");
+ } else {
+ reply(getTextBot(), user, "NF_4WINS_NO_GAME_FOUND");
+ }
+}
--- /dev/null
+/* cmd_neonfun_4wins.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonfun.h"
+#include "game_4wins.h"
+
+CMD_BIND(neonfun_cmd_4wins) {
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ if(!chanuser) return;
+ struct fourwins_game *game;
+ for(game = fourwins_active_games; game; game = game->next) {
+ if(chanuser == game->player[0]) {
+ return;
+ } else if(chanuser == game->player[1]) {
+ if(game->state == FOURWINS_STATE_WAITING)
+ break;
+ else
+ return;
+ }
+ }
+ if(game) {
+ timeq_del(game->timer);
+ game->timer = NULL;
+ game->state = FOURWINS_STATE_RUNNING;
+ fourwins_reply(game, "NF_4WINS_START", user->nick);
+ if((game->player[0]->user->flags & USERFLAG_ISAUTHED)) {
+ char *tmp;
+ int win_count = ((tmp = getSetting(game->player[0]->user, chan, "4wins_games")) ? atoi(tmp) : 0);
+ int total_win_count = ((tmp = getSetting(game->player[0]->user, NULL, "4wins_games")) ? atoi(tmp) : 0);
+ win_count++;
+ total_win_count++;
+ char buf[10];
+ sprintf(buf, "%d", win_count);
+ setSetting(game->player[0]->user, chan, "4wins_games", buf);
+ sprintf(buf, "%d", total_win_count);
+ setSetting(game->player[0]->user, NULL, "4wins_games", buf);
+ }
+ if((game->player[1]->user->flags & USERFLAG_ISAUTHED)) {
+ char *tmp;
+ int win_count = ((tmp = getSetting(game->player[1]->user, chan, "4wins_games")) ? atoi(tmp) : 0);
+ int total_win_count = ((tmp = getSetting(game->player[1]->user, NULL, "4wins_games")) ? atoi(tmp) : 0);
+ win_count++;
+ total_win_count++;
+ char buf[10];
+ sprintf(buf, "%d", win_count);
+ setSetting(game->player[1]->user, chan, "4wins_games", buf);
+ sprintf(buf, "%d", total_win_count);
+ setSetting(game->player[1]->user, NULL, "4wins_games", buf);
+ }
+ fourwins_show_matrix(game);
+ fourwins_reply(game, "NF_4WINS_USER_HURRY_UP", game->player[game->active_player]->user->nick);
+ game->timer = timeq_add(120, module_id, fourwins_timeout, game);
+ } else {
+ if(!argc) {
+ reply(getTextBot(), user, "NF_4WINS_ENTER_OPPONENT");
+ return;
+ }
+ struct UserNode *opp_user = getUserByNick(argv[0]);
+ if(!opp_user) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ struct ChanUser *opponent = getChanUser(opp_user, chan);
+ if(!opponent) {
+ reply(getTextBot(), user, "NF_4WINS_OPPONENT_NOT_IN_CHAN", opp_user->nick);
+ return;
+ }
+ game = calloc(1,sizeof(*game));
+ game->player[0] = chanuser;
+ game->player[1] = opponent;
+ game->textbot = getTextBot();
+ game->state = FOURWINS_STATE_WAITING;
+ game->timer = timeq_add(120, module_id, fourwins_timeout, game);
+ game->next = fourwins_active_games;
+ fourwins_active_games = game;
+ reply(getTextBot(), user, "NF_4WINS_REQUESTED", opp_user->nick);
+ reply(getTextBot(), opp_user, "NF_4WINS_REQUEST", user->nick);
+ }
+}
--- /dev/null
+/* game_4wins.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "game_4wins.h"
+#include "bot_NeonFun.h"
+#include "../../IRCParser.h"
+#include "../../bots.h"
+#include "../../UserNode.h"
+#include "../../ChanUser.h"
+#include "../../tools.h"
+#include "../botid.h"
+
+struct fourwins_game *fourwins_active_games = NULL;
+
+int fourwins_next_free_y(struct fourwins_game *game, int x) {
+ int y;
+ for(y = 0; y < FOURWINS_MATRIX_HEIGHT; y++) {
+ if(!game->matrix[x][y].field)
+ return y;
+ }
+ return -1;
+}
+
+int fourwins_check_win(struct fourwins_game *game, int x, int y) {
+ int field = game->matrix[x][y].field;
+ if(!field) return 0;
+ //horizontal
+ {
+ int fc = 0;
+ int i;
+ for(i = x; i < FOURWINS_MATRIX_WIDTH; i++) {
+ if(game->matrix[i][y].field == field)
+ fc++;
+ else
+ break;
+ }
+ for(i = x-1; i >= 0; i--) {
+ if(game->matrix[i][y].field == field)
+ fc++;
+ else
+ break;
+ }
+ if(fc >= 4) return 1;
+ }
+ //senkrecht
+ if(y >= 3) {
+ int fc = 0;
+ int i;
+ for(i = y; i >= 0; i--) {
+ if(game->matrix[i][y].field == field)
+ fc++;
+ else
+ break;
+ }
+ if(fc >= 4) return 1;
+ }
+ //diagonal 1
+ {
+ int fc = 0;
+ int ix, iy;
+ for(ix = x, iy = y; ix < FOURWINS_MATRIX_WIDTH && iy < FOURWINS_MATRIX_HEIGHT; ix++, iy++) {
+ if(game->matrix[ix][iy].field == field)
+ fc++;
+ else
+ break;
+ }
+ for(ix = x, iy = y; ix >= 0 && iy >= 0; ix--, iy--) {
+ if(game->matrix[ix][iy].field == field)
+ fc++;
+ else
+ break;
+ }
+ if(fc >= 4) return 1;
+ }
+ //diagonal 2
+ {
+ int fc = 0;
+ int ix, iy;
+ for(ix = x, iy = y; ix < FOURWINS_MATRIX_WIDTH && iy >= 0; ix++, iy--) {
+ if(game->matrix[ix][iy].field == field)
+ fc++;
+ else
+ break;
+ }
+ for(ix = x, iy = y; ix >= 0 && iy < FOURWINS_MATRIX_HEIGHT; ix--, iy++) {
+ if(game->matrix[ix][iy].field == field)
+ fc++;
+ else
+ break;
+ }
+ if(fc >= 4) return 1;
+ }
+ return 0;
+}
+
+void fourwins_show_matrix(struct fourwins_game *game) {
+ int x,y;
+ char lineBuf[MAXLEN];
+ int linePos = 0;
+ for(x = 0; x < FOURWINS_MATRIX_WIDTH; x++) {
+ linePos += sprintf(lineBuf+linePos, (x ? "| %d " : " %d "), x+1);
+ }
+ fourwins_reply(game, lineBuf);
+ for(y = FOURWINS_MATRIX_HEIGHT-1; y >= 0; y--) {
+ linePos = 0;
+ for(x = 0; x < FOURWINS_MATRIX_WIDTH; x++) {
+ char *field = " ";
+ if(game->matrix[x][y].field == 1)
+ field = "\0034o\003";
+ if(game->matrix[x][y].field == 2)
+ field = "\00312o\003";
+ linePos += sprintf(lineBuf+linePos, (x ? " (%s)" : "(%s)"), field);
+ }
+ fourwins_reply(game, lineBuf);
+ }
+}
+
+TIMEQ_CALLBACK(fourwins_timeout) {
+ struct fourwins_game *game = data;
+ game->timer = NULL;
+ fourwins_reply(game, "NF_4WINS_TIMEOUT");
+ fourwins_free_game(game);
+}
+
+void fourwins_free_game(struct fourwins_game *game) {
+ struct fourwins_guest *guest, *next_guest;
+ for(guest = game->guests; guest; guest = next_guest) {
+ next_guest = guest->next;
+ free(guest);
+ }
+ struct fourwins_game *cgame, *prev = NULL;
+ for(cgame = fourwins_active_games; cgame; cgame = cgame->next) {
+ if(cgame == game) {
+ if(prev)
+ prev->next = game->next;
+ else
+ fourwins_active_games->next = game->next;
+ } else
+ prev = cgame;
+ }
+ free(game);
+}
+
+void fourwins_event_part(struct ChanUser *chanuser) {
+ struct fourwins_game *game;
+ for(game = fourwins_active_games; game; game = game->next) {
+ if(game->player[0] == chanuser || game->player[1] == chanuser) {
+ fourwins_reply(game, "NF_4WINS_GAME_CLOSED");
+ fourwins_free_game(game);
+ return;
+ }
+ struct fourwins_guest *guest, *prev_guest = NULL;
+ for(guest = game->guests; guest; guest = guest->next) {
+ if(guest->chanuser == chanuser) {
+ if(prev_guest)
+ prev_guest->next = guest->next;
+ else
+ game->guests = guest->next;
+ free(guest);
+ break;
+ } else
+ prev_guest = guest;
+ }
+ }
+}
+
+void fourwins_event_quit(struct UserNode *user) {
+ struct fourwins_game *game;
+ for(game = fourwins_active_games; game; game = game->next) {
+ if(game->player[0]->user == user || game->player[1]->user == user) {
+ fourwins_reply(game, "NF_4WINS_GAME_CLOSED");
+ fourwins_free_game(game);
+ return;
+ }
+ struct fourwins_guest *guest, *prev_guest = NULL;
+ for(guest = game->guests; guest; guest = guest->next) {
+ if(guest->chanuser->user == user) {
+ if(prev_guest)
+ prev_guest->next = guest->next;
+ else
+ game->guests = guest->next;
+ free(guest);
+ break;
+ } else
+ prev_guest = guest;
+ }
+ }
+}
+
+void fourwins_event_freechan(struct ChanNode *chan) {
+ struct fourwins_game *game;
+ for(game = fourwins_active_games; game; game = game->next) {
+ if(game->player[0]->chan == chan) {
+ fourwins_free_game(game);
+ return;
+ }
+ }
+}
--- /dev/null
+/* game_4wins.h - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _game_4wins_h
+#define _game_4wins_h
+#include "../../timeq.h"
+
+#define FOURWINS_STATE_WAITING 1
+#define FOURWINS_STATE_RUNNING 2
+
+#define FOURWINS_MATRIX_WIDTH 7
+#define FOURWINS_MATRIX_HEIGHT 6
+
+#define FOURWINS_MAX_STONES (FOURWINS_MATRIX_WIDTH * FOURWINS_MATRIX_HEIGHT)
+
+struct UserNode;
+struct ChanNode;
+struct ChanUser;
+struct ClientSocket;
+extern struct fourwins_game *fourwins_active_games;
+
+struct fourwins_guest {
+ struct ChanUser *chanuser;
+ struct fourwins_guest *next;
+};
+
+struct fourwins_game {
+ struct ChanUser *player[2];
+ int active_player;
+ struct fourwins_guest *guests;
+ struct ClientSocket *textbot;
+ int state : 3;
+ struct {
+ unsigned int field:2; /* 0,1,2 */
+ } matrix[FOURWINS_MATRIX_WIDTH][FOURWINS_MATRIX_HEIGHT];
+ int total_stones;
+ struct timeq_entry *timer;
+ struct fourwins_game *next;
+};
+
+int fourwins_next_free_y(struct fourwins_game *game, int x);
+int fourwins_check_win(struct fourwins_game *game, int x, int y);
+void fourwins_show_matrix(struct fourwins_game *game);
+TIMEQ_CALLBACK(fourwins_timeout);
+void fourwins_free_game(struct fourwins_game *game);
+void fourwins_event_part(struct ChanUser *chanuser);
+void fourwins_event_quit(struct UserNode *user);
+void fourwins_event_freechan(struct ChanNode *chan);
+
+#endif
for(game = uno_active_games; game; game = game->next) {
if(game->channel == chan) {
uno_free_game(game);
+ return;
}
}
}