From 32503d50d3e1d6265e5322c6d2aecaa8bf64a0f4 Mon Sep 17 00:00:00 2001 From: Florian Wesch Date: Thu, 29 Jun 2006 07:56:36 +0000 Subject: [PATCH] Kompletttrennung Server/Anzeige angefangen git-svn-id: http://infon.googlecode.com/svn/trunk@13 8171fb75-e542-0410-96e4-03d5dd800671 --- Makefile | 21 +- Makefile.client | 19 - common_player.h | 23 ++ gui_player.c | 989 ++++++++++++++++++++++++++++++++++++++++++++++++ gui_player.h | 101 +++++ gui_scroller.c | 92 +++++ gui_scroller.h | 32 ++ gui_world.c | 125 ++++++ gui_world.h | 38 ++ infon.c | 29 +- infond.c | 88 +---- player.c | 170 +-------- player.h | 3 - scroller.c | 83 +--- scroller.h | 8 - world.c | 77 +--- world.h | 6 - 17 files changed, 1431 insertions(+), 473 deletions(-) delete mode 100644 Makefile.client create mode 100644 common_player.h create mode 100644 gui_player.c create mode 100644 gui_player.h create mode 100644 gui_scroller.c create mode 100644 gui_scroller.h create mode 100644 gui_world.c create mode 100644 gui_world.h diff --git a/Makefile b/Makefile index 9327db3..7cd5731 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,3 @@ -#SERVER_GUI=1 - LUADIR=lua-5.0.2 SDLDIR=$(shell sdl-config --prefix) @@ -7,20 +5,19 @@ CFLAGS = -I$(LUADIR)/include/ -I$(SDLDIR)/include/SDL -std=gnu99 -Wall # CFLAGS += -O3 -fexpensive-optimizations -finline-functions -fomit-frame-pointer -DNDEBUG CFLAGS += -ggdb -ifdef SERVER_GUI - LDFLAGS = -L$(LUADIR)/lib -L$(SDLDIR)/lib -levent -llua -llualib -lm -lSDL -lSDL_image -lSGE -lSDL_gfx - GUIFILES=sprite.o video.o - CFLAGS+=-DSERVER_GUI=1 -else - LDFLAGS = -L$(LUADIR)/lib -L$(SDLDIR)/lib -levent -llua -llualib -lm -lSDL -endif +LDFLAGS = -L$(LUADIR)/lib -L$(SDLDIR)/lib -levent -llua -llualib -lm -lSDL +GUI_LDFLAGS = $(LDFLAGS) -lSDL_image -lSGE -lSDL_gfx -all: infond +all: infond infon -infond: infond.o server.o listener.o player.o map.o path.o misc.o world.o path.o map.o creature.o packet.o scroller.o $(GUIFILES) +infond: infond.o server.o listener.o map.o path.o misc.o packet.o player.o world.o creature.o scroller.o $(MAKE) -C $(LUADIR) $(CC) $^ $(LDFLAGS) -o $@ +infon: infon.o client.o packet.o gui_player.o gui_world.o gui_creature.o gui_scroller.o + $(MAKE) -C $(LUADIR) + $(CC) $^ $(GUI_LDFLAGS) -o $@ + clean: $(MAKE) -C $(LUADIR) clean - -rm -f *.o infond tags + -rm -f *.o infond infon tags diff --git a/Makefile.client b/Makefile.client deleted file mode 100644 index ea11814..0000000 --- a/Makefile.client +++ /dev/null @@ -1,19 +0,0 @@ -#XXX: Rotzig - -LUADIR=lua-5.0.2 -SDLDIR=$(shell sdl-config --prefix) - -CFLAGS = -I$(LUADIR)/include/ -I$(SDLDIR)/include/SDL -std=gnu99 -Wall -# CFLAGS += -O3 -fexpensive-optimizations -finline-functions -fomit-frame-pointer -DNDEBUG -CFLAGS += -ggdb - -CFLAGS+=-DCLIENT=1 -DSERVER_GUI=1 -LDFLAGS = -L$(LUADIR)/lib -L$(SDLDIR)/lib -levent -llua -llualib -lm -lSDL -lSDL_image -lSGE -lSDL_gfx - -all: infon - -infon: infon.o client.o server.o listener.o player.o map.o path.o misc.o world.o path.o map.o creature.o packet.o scroller.o sprite.o video.o - $(CC) $^ $(LDFLAGS) -o $@ - -clean: - -rm -f *.o infon tags diff --git a/common_player.h b/common_player.h new file mode 100644 index 0000000..43ad482 --- /dev/null +++ b/common_player.h @@ -0,0 +1,23 @@ +/* + + Copyright (c) 2006 Florian Wesch . All Rights Reserved. + + 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 2 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, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +*/ + +#ifndef COMMON_PLAYER_H +#define COMMON_PLAYER_H + diff --git a/gui_player.c b/gui_player.c new file mode 100644 index 0000000..0ca886e --- /dev/null +++ b/gui_player.c @@ -0,0 +1,989 @@ +/* + + Copyright (c) 2006 Florian Wesch . All Rights Reserved. + + 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 2 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, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +*/ + +#include +#include +#include +#include + +#include +#include + +#include "global.h" +#include "player.h" +#include "server.h" +#include "creature.h" +#include "sprite.h" +#include "world.h" +#include "video.h" +#include "misc.h" +#include "rules.h" +#include "scroller.h" + +#define PLAYER_USED(player) (!!((player)->L)) + +static player_t *king_player = NULL; + +void player_score(player_t *player, int scoredelta, char *reason) { + static char buf[1024]; + snprintf(buf, sizeof(buf), "%s %s %d point%s: %s", + player->name, + scoredelta > 0 ? "gained" : "lost", + abs(scoredelta), + abs(scoredelta) == 1 ? "" : "s", + reason); + + add_to_scroller(buf); + player->score += scoredelta; + player->dirtymask |= PLAYER_DIRTY_SCORE; + + printf("stat: %10d %3d '%10s' %5d: %s\n", game_time, player_num(player), player->name, player->score, reason); +} + +void player_on_creature_spawned(player_t *player, int idx, int points) { + player->num_creatures++; + + lua_pushliteral(player->L, "_spawned_creatures"); + lua_rawget(player->L, LUA_GLOBALSINDEX); + if (!lua_isnil(player->L, -1)) { + lua_pushnumber(player->L, game_round); + lua_rawseti(player->L, -2, idx); + } else { + static char msg[] = "cannot locate _spawned_creatures table. did you delete it?\n"; + player_writeto(player, msg, sizeof(msg) - 1); + } + lua_pop(player->L, 1); + + if (points > 0) + player_score(player, points, "Creature Spawned"); +} + +void player_on_creature_killed(player_t *player, int victim, int killer) { + lua_pushliteral(player->L, "_killed_creatures"); + lua_rawget(player->L, LUA_GLOBALSINDEX); + if (!lua_isnil(player->L, -1)) { + lua_pushnumber(player->L, killer); + lua_rawseti(player->L, -2, victim); + } else { + static char msg[] = "cannot locate _killed_creatures table. did you delete it?\n"; + player_writeto(player, msg, sizeof(msg) - 1); + } + lua_pop(player->L, 1); + + player->num_creatures--; + + if (player->num_creatures == 0) + player->all_dead_time = game_time; + + if (killer == victim) { + player_score(player, CREATURE_SUICIDE_POINTS, "Creature suicides"); + } else if (killer == -1) { + player_score(player, CREATURE_DIED_POINTS, "Creature died"); + } else { + creature_t *victim_creature = creature_by_num(victim); + if (victim_creature->type == 0) { + player_score(player, CREATURE_VICTIM_POINTS_0, "Creature was killed"); + } else { + player_score(player, CREATURE_VICTIM_POINTS_1, "Creature was killed"); + } + creature_t *killer_creature = creature_by_num(killer); + player_score(killer_creature->player, CREATURE_KILLED_POINTS, "Killed a creature"); + } +} + +void player_on_creature_attacked(player_t *player, int victim, int attacker) { + lua_pushliteral(player->L, "_attacked_creatures"); + lua_rawget(player->L, LUA_GLOBALSINDEX); + if (!lua_isnil(player->L, -1)) { + lua_pushnumber(player->L, victim); + lua_rawseti(player->L, -2, attacker); + } else { + static char msg[] = "cannot locate _attacked_creatures table. did you delete it?\n"; + player_writeto(player, msg, sizeof(msg) - 1); + } + lua_pop(player->L, 1); +} + +static int luaPrint(lua_State *L) { + player_t *player = lua_touserdata(L, lua_upvalueindex(1)); + lua_consumecycles(L, 100); + int n=lua_gettop(L); + int i; + for (i=1; i<=n; i++) { + if (i>1) player_writeto(player, "\t", 1); + if (lua_isstring(L,i)) + player_writeto(player, lua_tostring(L,i), lua_strlen(L, i)); + else if (lua_isnil(L,i)) + player_writeto(player, "nil", 3); + else if (lua_isboolean(L,i)) + lua_toboolean(L,i) ? player_writeto(player, "true", 4): + player_writeto(player, "false", 5); + else { + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%s:%p",lua_typename(L,lua_type(L,i)),lua_topointer(L,i)); + player_writeto(player, buffer, strlen(buffer)); + } + } + player_writeto(player, "\n", 1); + return 0; +} + +#define get_player_and_creature() \ + player_t *player = lua_touserdata(L, lua_upvalueindex(1)); \ + (void)player; /* Unused Warning weg */ \ + const int creature_idx = (int)luaL_checklong(L, 1); \ + creature_t *creature = creature_by_num(creature_idx); \ + if (!creature) return luaL_error(L, "%d isn't a valid creature", creature_idx); + +#define assure_is_players_creature() \ + do { if (creature->player != player) \ + return luaL_error(L, "%d isn't your creature", creature_idx); \ + } while(0) + +static int luaCreatureSuicide(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + lua_consumecycles(L, 100); + creature_kill(creature, creature); + return 0; +} + +static int luaCreatureSetPath(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + lua_consumecycles(L, 500); + lua_pushboolean(L, creature_set_path(creature, + luaL_checklong(L, 2), + luaL_checklong(L, 3))); + return 1; +} + +static int luaCreatureSetTarget(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + lua_consumecycles(L, 20); + lua_pushboolean(L, creature_set_target(creature, + luaL_checklong(L, 2))); + return 1; +} + +static int luaCreatureSetConvert(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + lua_consumecycles(L, 20); + lua_pushboolean(L, creature_set_conversion_type(creature, + luaL_checklong(L, 2))); + return 1; +} + +static int luaCreatureSetMessage(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + lua_consumecycles(L, 500); + creature_set_message(creature, luaL_checkstring(L, 2)); + return 0; +} + +static int luaCreatureNearestEnemy(lua_State *L) { + get_player_and_creature(); + if (RESTRICTIVE) assure_is_players_creature(); + lua_consumecycles(L, 500); + int mindist; + const creature_t *nearest = creature_nearest_enemy(creature, &mindist); + if (!nearest) + return 0; + lua_pushnumber(L, creature_num(nearest)); + lua_pushnumber(L, nearest->x); + lua_pushnumber(L, nearest->y); + lua_pushnumber(L, player_num(nearest->player)); + lua_pushnumber(L, mindist); + return 5; +} + +static int luaCreatureGetHealth(lua_State *L) { + get_player_and_creature(); + lua_pushnumber(L, 100 * creature->health / creature_max_health(creature)); + return 1; +} + +static int luaCreatureGetSpeed(lua_State *L) { + get_player_and_creature(); + if (RESTRICTIVE) assure_is_players_creature(); + lua_pushnumber(L, creature_speed(creature)); + return 1; +} + +static int luaCreatureGetType(lua_State *L) { + get_player_and_creature(); + lua_pushnumber(L, creature->type); + return 1; +} + +static int luaCreatureGetFood(lua_State *L) { + get_player_and_creature(); + if (RESTRICTIVE) assure_is_players_creature(); + lua_pushnumber(L, creature->food); + return 1; +} + +static int luaCreatureGetTileFood(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + lua_pushnumber(L, creature_food_on_tile(creature)); + return 1; +} + +static int luaCreatureGetMaxFood(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + lua_pushnumber(L, creature_max_food(creature)); + return 1; +} + +static int luaCreatureGetPos(lua_State *L) { + get_player_and_creature(); + lua_pushnumber(L, creature->x); + lua_pushnumber(L, creature->y); + return 2; +} + +static int luaCreatureGetDistance(lua_State *L) { + get_player_and_creature(); + if (RESTRICTIVE) assure_is_players_creature(); + const creature_t *target = creature_by_num(luaL_checklong(L, 2)); + if (!target) + return 0; + lua_consumecycles(L, 100); + lua_pushnumber(L, creature_dist(creature, target)); + return 1; +} + +static int luaCreatureGetState(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + lua_pushnumber(L, creature->state); + return 1; +} + +static int luaCreatureGetHitpoints(lua_State *L) { + get_player_and_creature(); + if (RESTRICTIVE) assure_is_players_creature(); + lua_pushnumber(L, creature_hitpoints(creature)); + return 1; +} + +static int luaCreatureGetAttackDistance(lua_State *L) { + get_player_and_creature(); + if (RESTRICTIVE) assure_is_players_creature(); + lua_pushnumber(L, creature_attack_distance(creature)); + return 1; +} + +static int luaCreatureSetState(lua_State *L) { + get_player_and_creature(); + assure_is_players_creature(); + int state = luaL_checklong(L, 2); + switch (state) { + case CREATURE_IDLE: + case CREATURE_WALK: + case CREATURE_HEAL: + case CREATURE_EAT: + case CREATURE_ATTACK: + case CREATURE_CONVERT: + case CREATURE_SPAWN: + case CREATURE_FEED: + lua_pushboolean(L, creature_set_state(creature, state)); + break; + default: + luaL_error(L, "invalid state %d", luaL_checklong(L, 2)); + break; + } + return 1; +} + +static int luaAreaSize(lua_State *L) { + lua_pushnumber(L, TILE_X1(1)); + lua_pushnumber(L, TILE_Y1(1)); + lua_pushnumber(L, TILE_X2(world_width() - 2)); + lua_pushnumber(L, TILE_Y1(world_height() - 2)); + return 4; +} + +static int luaGameTime(lua_State *L) { + lua_pushnumber(L, game_time); + return 1; +} + +static int luaGetKothPos(lua_State *L) { + lua_pushnumber(L, TILE_XCENTER(world_koth_x())); + lua_pushnumber(L, TILE_YCENTER(world_koth_y())); + return 2; +} + +static int luaCreatureExists(lua_State *L) { + lua_pushboolean(L, !!creature_by_num(luaL_checklong(L, 1))); + return 1; +} + +static int luaPlayerExists(lua_State *L) { + lua_pushboolean(L, !!player_by_num(luaL_checklong(L, 1))); + return 1; +} + +static int luaPlayerScore(lua_State *L) { + lua_pushnumber(L, player_get_checked_lua(L, luaL_checklong(L, 1))->score); + return 1; +} + +static int luaKingPlayer(lua_State *L) { + player_t *king = player_king(); + if (king) { + lua_pushnumber(L, player_num(king)); + } else { + lua_pushnil(L); + } + return 1; +} + +#define lua_register_player(p,n,f) \ + (lua_pushstring((p)->L, n), \ + lua_pushlightuserdata((p)->L, p), \ + lua_pushcclosure((p)->L, f, 1), \ + lua_settable((p)->L, LUA_GLOBALSINDEX)) + +player_t *player_create(const char *pass) { + int playerno; + + for (playerno = 0; playerno < MAXPLAYERS; playerno++) { + if (!PLAYER_USED(&players[playerno])) + break; + } + + if (playerno == MAXPLAYERS) + return NULL; + + player_t *player = &players[playerno]; + memset(player, 0, sizeof(player_t)); + + snprintf(player->name, sizeof(player->name), "player%d", playerno); + snprintf(player->pass, sizeof(player->pass), "%s", pass); + player->L = lua_open(); + + player->color = playerno % CREATURE_COLORS; + player->all_dead_time = game_time - PLAYER_CREATURE_RESPAWN_DELAY; + player->all_disconnected_time = game_time; + + player->max_cycles = LUA_MAX_CPU; + + lua_baselibopen(player->L); + lua_dblibopen(player->L); + lua_tablibopen(player->L); + lua_strlibopen(player->L); + lua_mathlibopen(player->L); + + lua_register_player(player, "print", luaPrint); + lua_register_player(player, "suicide", luaCreatureSuicide); + lua_register_player(player, "set_path", luaCreatureSetPath); + lua_register_player(player, "get_pos", luaCreatureGetPos); + lua_register_player(player, "get_state", luaCreatureGetState); + lua_register_player(player, "set_state", luaCreatureSetState); + lua_register_player(player, "set_target", luaCreatureSetTarget); + lua_register_player(player, "set_convert", luaCreatureSetConvert); + lua_register_player(player, "nearest_enemy",luaCreatureNearestEnemy); + lua_register_player(player, "get_type", luaCreatureGetType); + lua_register_player(player, "get_food", luaCreatureGetFood); + lua_register_player(player, "get_health", luaCreatureGetHealth); + lua_register_player(player, "get_speed", luaCreatureGetSpeed); + lua_register_player(player, "get_tile_food",luaCreatureGetTileFood); + lua_register_player(player, "get_max_food", luaCreatureGetMaxFood); + lua_register_player(player, "get_distance", luaCreatureGetDistance); + lua_register_player(player, "set_message", luaCreatureSetMessage); + lua_register_player(player, "get_hitpoints", luaCreatureGetHitpoints); + lua_register_player(player, "get_attack_distance",luaCreatureGetAttackDistance); + + lua_register(player->L, "world_size", luaAreaSize); + lua_register(player->L, "game_time", luaGameTime); + lua_register(player->L, "get_koth_pos", luaGetKothPos); + lua_register(player->L, "exists", luaCreatureExists); + lua_register(player->L, "creature_exists", luaCreatureExists); + lua_register(player->L, "player_exists", luaPlayerExists); + lua_register(player->L, "king_player", luaKingPlayer); + lua_register(player->L, "player_score", luaPlayerScore); + + lua_pushliteral(player->L, "CREATURE_IDLE"); + lua_pushnumber(player->L, CREATURE_IDLE); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "CREATURE_WALK"); + lua_pushnumber(player->L, CREATURE_WALK); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "CREATURE_HEAL"); + lua_pushnumber(player->L, CREATURE_HEAL); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "CREATURE_EAT"); + lua_pushnumber(player->L, CREATURE_EAT); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "CREATURE_ATTACK"); + lua_pushnumber(player->L, CREATURE_ATTACK); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "CREATURE_CONVERT"); + lua_pushnumber(player->L, CREATURE_CONVERT); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "CREATURE_SPAWN"); + lua_pushnumber(player->L, CREATURE_SPAWN); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "CREATURE_FEED"); + lua_pushnumber(player->L, CREATURE_FEED); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "player_number"); + lua_pushnumber(player->L, playerno); + lua_settable(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(L, "MAXPLAYERS"); + lua_pushnumber(L, MAXPLAYERS); + lua_settable(L, LUA_GLOBALSINDEX); + + lua_setmaxmem(player->L, LUA_MAX_MEM); + lua_dofile(player->L, "player.lua"); + + player_to_network(player, PLAYER_DIRTY_ALL, PACKET_BROADCAST); + return player; +} + +void player_destroy(player_t *player) { + creature_kill_all_players_creatures(player); + + client_t *client; + while ((client = player->clients)) { + player_detach_client(client, player); + }; + + lua_close(player->L); + player->L = NULL; + + player_to_network(player, PLAYER_DIRTY_ALIVE, PACKET_BROADCAST); +} + +void player_set_name(player_t *player, const char *name) { + snprintf(player->name, sizeof(player->name), "%s", name); + player->dirtymask |= PLAYER_DIRTY_NAME; +} + +void player_mark_for_kill(player_t *player) { + player->kill_me = 1; +} + +int player_num(player_t *player) { + return player - players; +} + +void player_writeto(player_t *player, const void *data, size_t size) { + if (!player->clients) { + assert(player->num_clients == 0); + return; + } + + client_t *client = player->clients; + do { + client_writeto(client, data, size); + client = client->next; + } while (client != player->clients); +} + +player_t *player_by_num(int playerno) { + if (playerno < 0 || playerno >= MAXPLAYERS) + return NULL; + if (!PLAYER_USED(&players[playerno])) + return NULL; + return &players[playerno]; +} + +player_t *player_get_checked_lua(lua_State *L, int playerno) { + if (playerno < 0 || playerno >= MAXPLAYERS) + luaL_error(L, "player number %d out of range", playerno); + + if (!PLAYER_USED(&players[playerno])) + luaL_error(L, "player %d not in use", playerno); + + return &players[playerno]; +} + +int player_attach_client(client_t *client, player_t *player, const char *pass) { + if (!client || !player) + return 0; + + if (!PLAYER_USED(player)) + return 0; + + // Passwort fhslca? + if (strcmp(pass, player->pass)) + return 0; + + if (client->player) { + if (client->player == player) + return 1; + player_detach_client(client, client->player); + } + + client->player = player; + + player->num_clients++; + + if (player->clients) { + client->prev = player->clients; + client->next = player->clients->next; + client->next->prev = client; + client->prev->next = client; + } else { + client->prev = client->next = player->clients = client; + } + assert(client->next->prev == client); + assert(client->prev->next == client); + assert(player->clients->next->prev == player->clients); + assert(player->clients->prev->next == player->clients); + + return 1; +} + +int player_detach_client(client_t *client, player_t *player) { + if (!client || !player) + return 0; + + if (!client->player) + return 0; + + if (client->player != player) + return 0; + + player->num_clients--; + assert(player->num_clients >= 0); + + if (player->num_clients == 0) + player->all_disconnected_time = game_time; + + client->player = NULL; + + if (player->num_clients == 0) { + player->clients = NULL; + } else { + client->next->prev = client->prev; + client->prev->next = client->next; + player->clients = client->next; + assert(client->next->next->prev == client->next); + assert(client->next->prev->next == client->next); + assert(player->clients->next->prev == player->clients); + assert(player->clients->prev->next == player->clients); + } + + client->next = NULL; + client->prev = NULL; + + return 1; +} + +void player_execute_client_lua(player_t *player, const char *source, const char *where) { + int status = luaL_loadbuffer(player->L, source, strlen(source), where); + + if (status == 0) { + int base = lua_gettop(player->L); + lua_pushliteral(player->L, "_TRACEBACK"); + lua_rawget(player->L, LUA_GLOBALSINDEX); + lua_insert(player->L, base); + lua_setcycles(player->L, player->max_cycles); + status = lua_pcall(player->L, 0, 1, base); // Yield() faehig machen? + lua_remove(player->L, base); + } + + const char *msg = lua_tostring(player->L, -1); + + if (status && !msg) + msg = "(error with no message)"; + + if (msg) { + if (strstr(msg, "attempt to yield across C function")) { + player_writeto(player, msg, strlen(msg)); + player_writeto(player, "\n\n", 2); + player_writeto(player, "--------------------------------------------------------------\n", 63); + player_writeto(player, "Long running operations are not allowed from interactive shell\n", 63); + player_writeto(player, "--------------------------------------------------------------\n", 63); + } else { + player_writeto(player, msg, strlen(msg)); + player_writeto(player, "\n", 1); + } + } + lua_pop(player->L, 1); +} + +void player_think() { + static char errorbuf[1000]; + int playerno; + player_t *player = &players[0]; + for (playerno = 0; playerno < MAXPLAYERS; playerno++, player++) { + if (!PLAYER_USED(player)) + continue; + + // Killen? + if (player->kill_me) { + player_writeto(player, "killed\n", 7); + player_destroy(player); + continue; + } + + // Zu wenig Score? + if (player->score <= PLAYER_KICK_SCORE) { + player_writeto(player, "score too low. try harder!\n", 27); + player_destroy(player); + continue; + } + + // Kein Client mehr da? + if (player->num_clients == 0 && + player->all_disconnected_time + NO_PLAYER_DISCONNECT < game_time) + { + player_destroy(player); + continue; + } + + // Alle Viecher tot? neu spawnen. + if (player->num_creatures == 0 && + game_time > player->all_dead_time + PLAYER_CREATURE_RESPAWN_DELAY) + { + int x, y; + world_find_digged(&x, &y); + creature_spawn(player, TILE_XCENTER(x), TILE_YCENTER(y), 0, 0); + world_find_digged(&x, &y); + creature_spawn(player, TILE_XCENTER(x), TILE_YCENTER(y), 0, 0); + //creature_t * first = creature_spawn(player, TILE_XCENTER(world_koth_x()), TILE_YCENTER(world_koth_y()), 1, 0); + // first->food = creature_max_food(first); + } + + // Spiele Luacode aufrufen + lua_pushliteral(player->L, "_TRACEBACK"); + lua_rawget(player->L, LUA_GLOBALSINDEX); + + lua_pushliteral(player->L, "player_think"); + lua_rawget(player->L, LUA_GLOBALSINDEX); + + lua_setcycles(player->L, player->max_cycles); + + switch (lua_pcall(player->L, 0, 0, -2)) { + case LUA_ERRRUN: + snprintf(errorbuf, sizeof(errorbuf), "runtime error: %s", lua_tostring(player->L, -1)); + lua_pop(player->L, 1); + player_writeto(player, errorbuf, strlen(errorbuf)); + break; + case LUA_ERRMEM: + snprintf(errorbuf, sizeof(errorbuf), "mem error: %s", lua_tostring(player->L, -1)); + lua_pop(player->L, 1); + player_writeto(player, errorbuf, strlen(errorbuf)); + break; + case LUA_ERRERR: + snprintf(errorbuf, sizeof(errorbuf), "error calling errorhandler (_TRACEBACK)"); + lua_pop(player->L, 1); + player_writeto(player, errorbuf, strlen(errorbuf)); + break; + default: + break; + } + + int cycles_left = lua_getcycles(player->L); + + if (cycles_left < 0) + cycles_left = 0; + + int newcpu = 100 * (player->max_cycles - cycles_left) / player->max_cycles; + + if (newcpu != player->cpu_usage) { + player->dirtymask |= PLAYER_DIRTY_CPU; + player->cpu_usage = newcpu; + } + + lua_pop(player->L, 1); + + player_to_network(player, player->dirtymask, PACKET_BROADCAST); + player->dirtymask = PLAYER_DIRTY_NONE; + } +} + +#ifdef SERVER_GUI +static int player_sort_by_score(const void *a, const void *b) { + const player_t *pa = *(player_t **)a; + const player_t *pb = *(player_t **)b; + return -(pa->score > pb->score) + (pa->score < pb->score); +} + +void player_draw() { + static int lastturn = 0; + static int page = 0; + + if (SDL_GetTicks() > lastturn + 5000) { + lastturn = SDL_GetTicks(); + page++; + } + + int per_page = video_width() / 128; + if (per_page == 0) per_page = 1; + + int n; + int player_displayed = 0; + + int num_players = 0; + player_t *sorted[MAXPLAYERS]; + + for (n = 0; n < MAXPLAYERS; n++) { + player_t *player = &players[n]; + + if (!PLAYER_USED(player)) + continue; + sorted[num_players++] = player; + } + //printf("%d\n", num_players); + + player_t *king = player_king(); + + if (king) king->score += 1000000; // HACKHACK + qsort(sorted, num_players, sizeof(creature_t*), player_sort_by_score); + if (king) king->score -= 1000000; + + int offset = per_page * page; + if (offset >= num_players) { + page = 0; + offset = 0; + } + + int num = num_players - offset; + if (num > per_page) + num = per_page; + + video_rect(0, video_height() - 32, video_width(), video_height() - 16, 0, 0, 0, 0); + + for (n = offset; n < offset + num; n++) { + player_t *player = sorted[n]; + assert(PLAYER_USED(player)); + + // King in dieser Runde? + if (player == king) { + video_draw(player_displayed * 128 + 10, + video_height() - 86 - 20 * abs(sin(M_PI / 750.0 * (SDL_GetTicks() % 750))), + sprite_get(SPRITE_CROWN)); + } + + // Rotierendes Vieh + video_draw(player_displayed * 128, + video_height() - 32, + sprite_get(CREATURE_SPRITE(player->color, + 0, + (SDL_GetTicks() / 1000) % CREATURE_DIRECTIONS, + (SDL_GetTicks() / 123) % 2))); + // CPU Auslastung Anzeigen + const int cpu = 80 * player->cpu_usage / 100; + video_rect(player_displayed * 128 + 16, + video_height() - 32, + player_displayed * 128 + 16 + cpu, + video_height() - 16, + 2 * cpu, 160 - 2 * cpu , 0x00, 0x00); + + // Name / Punkte + static char buf[18]; + snprintf(buf, sizeof(buf), "%2d. %4d %s", n + 1, player->score, player->name); + video_write(player_displayed * 128 + 16, + video_height() - 30, + buf); + + player_displayed++; + } +} +#else +void player_draw() { +} +#endif + +void player_is_king_of_the_hill(player_t *player, int delta) { + //player_t *old_king = king_player; + + king_player = player; + player->last_koth_time = game_time; + player->koth_time += delta; + while (player->koth_time >= 2000) { + player_score(player, CREATURE_KOTH_POINTS, "King of the Hill!"); + player->koth_time -= 2000; + } + + /* + if (king_player != old_king) { + // Network Sync + packet_t packet; int packet_size; + + packet_size = packet_player_update_king(&packet); + client_writeto_all_gui_clients(&packet, packet_size); + } + */ +} + +void player_there_is_no_king() { + //player_t *old_king = king_player; + king_player = NULL; + + /* + if (old_king) { + // Network Sync + packet_t packet; int packet_size; + + packet_size = packet_player_update_king(&packet); + client_writeto_all_gui_clients(&packet, packet_size); + } + */ +} + +player_t *player_king() { + if (king_player && PLAYER_USED(king_player)) + return king_player; + else + return NULL; +} + +void player_send_initial_update(client_t *client) { + int playerno; + player_t *player = &players[0]; + for (playerno = 0; playerno < MAXPLAYERS; playerno++, player++) { + if (!PLAYER_USED(player)) + continue; + + player_to_network(player, PLAYER_DIRTY_ALL, client); + } +} + +void player_to_network(player_t *player, int dirtymask, client_t *client) { + if (dirtymask == PLAYER_DIRTY_NONE) + return; + + packet_t packet; + packet_reset(&packet); + + packet_write08(&packet, player_num(player)); + packet_write08(&packet, dirtymask); + if (dirtymask & PLAYER_DIRTY_ALIVE) + packet_write08(&packet, PLAYER_USED(player)); + if (dirtymask & PLAYER_DIRTY_NAME) { + packet_write08(&packet, strlen(player->name)); + packet_writeXX(&packet, &player->name, strlen(player->name)); + } + if (dirtymask & PLAYER_DIRTY_COLOR) + packet_write08(&packet, player->color); + if (dirtymask & PLAYER_DIRTY_CPU) + packet_write08(&packet, player->cpu_usage); + if (dirtymask & PLAYER_DIRTY_SCORE) + packet_write16(&packet, player->score - PLAYER_KICK_SCORE); + + packet_send(PACKET_PLAYER_UPDATE, &packet, client); +} + +void player_from_network(packet_t *packet) { + uint8_t playerno = 0; + + if (!packet_read08(packet, &playerno)) goto failed; + if (playerno >= MAXPLAYERS) goto failed; + player_t *player = &players[playerno]; + + uint8_t updatemask; + if (!packet_read08(packet, &updatemask)) goto failed; + + if (updatemask & PLAYER_DIRTY_ALIVE) { + uint8_t alive; + if (!packet_read08(packet, &alive)) goto failed; + player->L = alive ? (void*)0x1 : NULL; + if (!alive) + return; + } + + if (!PLAYER_USED(player)) goto failed; + + if (updatemask & PLAYER_DIRTY_NAME) { + uint8_t len; char buf[256]; + if (!packet_read08(packet, &len)) goto failed; + if (!packet_readXX(packet, buf, len)) goto failed; + buf[len] = '\0'; + snprintf(player->name, sizeof(player->name), "%s", buf); + } + if (updatemask & PLAYER_DIRTY_COLOR) { + uint8_t col; + if (!packet_read08(packet, &col)) goto failed; + if (col >= CREATURE_COLORS) goto failed; + player->color = col; + } + if (updatemask & PLAYER_DIRTY_CPU) { + uint8_t cpu; + if (!packet_read08(packet, &cpu)) goto failed; + if (cpu > 100) goto failed; + player->cpu_usage = cpu; + } + if (updatemask & PLAYER_DIRTY_SCORE) { + uint16_t score; + if (!packet_read16(packet, &score)) goto failed; + player->score = score + PLAYER_KICK_SCORE; + } + return; +failed: + printf("parsing player update packet failed\n"); + return; +} + +/* +int packet_player_update_king(packet_t *packet) { + packet->type = PACKET_PLAYER_KING; + if (player_king()) { + packet->player_update_king.king_player = player_num(player_king()); + } else { + packet->player_update_king.king_player = 0xFF; + } + return sizeof(packet_player_update_king_t); +} + +void packet_handle_player_update_king(packet_t *packet) { + assert(packet->type == PACKET_PLAYER_KING); + if (packet->player_update_king.king_player == 0xFF) { + king_player = NULL; + return; + } + if (packet->player_update_king.king_player >= MAXPLAYERS) + return; + king_player = &players[packet->player_update_king.king_player]; +} +*/ + +void player_init() { + memset(players, 0, sizeof(players)); +} + +void player_shutdown() { + int playerno; + for (playerno = 0; playerno < MAXPLAYERS; playerno++) { + if (PLAYER_USED(&players[playerno]) && + players[playerno].L != (void*)0x1) + player_destroy(&players[playerno]); + } +} diff --git a/gui_player.h b/gui_player.h new file mode 100644 index 0000000..f9d6597 --- /dev/null +++ b/gui_player.h @@ -0,0 +1,101 @@ +/* + + Copyright (c) 2006 Florian Wesch . All Rights Reserved. + + 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 2 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, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +*/ + +#ifndef GUI_PLAYER_H +#define GUI_PLAYER_H + +#include + +#include + +#include "packet.h" + +#define MAXPLAYERS 32 + +typedef struct player_s { + char name[16]; + char pass[16]; + int color; + lua_State *L; + int num_creatures; + + int num_clients; + client_t *clients; + + int score; + int koth_time; + int last_koth_time; + + int all_dead_time; + int all_disconnected_time; + + int max_cycles; + int cpu_usage; + + int kill_me; + + unsigned char dirtymask; +#define PLAYER_DIRTY_ALIVE (1 << 0) +#define PLAYER_DIRTY_NAME (1 << 1) +#define PLAYER_DIRTY_COLOR (1 << 2) +#define PLAYER_DIRTY_CPU (1 << 3) +#define PLAYER_DIRTY_SCORE (1 << 4) + +#define PLAYER_DIRTY_ALL 0x1F +#define PLAYER_DIRTY_NONE 0x00 +} player_t; + +player_t players[MAXPLAYERS]; + +int player_attach_client(client_t *client, player_t *player, const char *pass); +int player_detach_client(client_t *client, player_t *player); + +void player_on_creature_spawned(player_t *player, int idx, int points); +void player_on_creature_killed(player_t *player, int victim, int killer); +void player_on_creature_attacked(player_t *player, int victim, int attacker); + +void player_execute_client_lua(player_t *player, const char *source, const char *where); + +player_t *player_get_checked_lua(lua_State *L, int playerno); +player_t *player_by_num(int playerno); +int player_num(player_t *player); +void player_writeto(player_t *player, const void *data, size_t size); + +void player_set_name(player_t *player, const char *name); +player_t *player_create(const char *pass); +void player_mark_for_kill(player_t *player); + +void player_think(); +void player_draw(); + +void player_is_king_of_the_hill(player_t *player, int delta); +void player_there_is_no_king(); +player_t *player_king(); + +/* Network */ +void player_send_initial_update(client_t *client); +void player_to_network(player_t *player, int dirtymask, client_t *client); +void player_from_network(packet_t *packet); + + +void player_init(); +void player_shutdown(); + +#endif diff --git a/gui_scroller.c b/gui_scroller.c new file mode 100644 index 0000000..d485fb6 --- /dev/null +++ b/gui_scroller.c @@ -0,0 +1,92 @@ +/* + + Copyright (c) 2006 Florian Wesch . All Rights Reserved. + + 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 2 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, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +*/ + +#include +#include + +#include "video.h" +#include "scroller.h" +#include "packet.h" + +static struct evbuffer *scrollbuffer; +static int last_time; +static float x = 0; +static float curspeed = 0; + +static void append(const char *msg) { + // Zuviel insgesamt? + if (EVBUFFER_LENGTH(scrollbuffer) > 10000) + return; + + evbuffer_add(scrollbuffer, (char*)msg, strlen(msg)); + evbuffer_add(scrollbuffer, " - ", 5); +} + +void gui_scroller_draw() { + int chars_per_screen = video_width() / 6 + 1; + + Uint32 now = SDL_GetTicks(); + + float speed = ((float)now- last_time) * + (float)(EVBUFFER_LENGTH(scrollbuffer) - chars_per_screen - 3) / 200.0; + + if (curspeed < speed) curspeed += 0.1; //(speed - curspeed)/30.0; + if (curspeed > speed) curspeed = speed; + if (curspeed < 0.1) curspeed = 0; + + x -= curspeed; + last_time = now; + + while (x < -6) { + evbuffer_drain(scrollbuffer, 1); + x += 6; + } + + while (EVBUFFER_LENGTH(scrollbuffer) <= chars_per_screen + 1) + evbuffer_add(scrollbuffer, " ", 1); + + video_rect(0, video_height() - 15, video_width(), video_height(), 0, 0, 0, 0); + + assert(chars_per_screen < EVBUFFER_LENGTH(scrollbuffer)); + char *end = &EVBUFFER_DATA(scrollbuffer)[chars_per_screen]; + char saved = *end; *end = '\0'; + video_write(x, video_height() - 15, EVBUFFER_DATA(scrollbuffer)); + *end = saved; + + // Bitte drinlassen. Danke + if (now / 1000 % 60 < 5) + video_draw(video_width() - 190, 20, sprite_get(SPRITE_LOGO)); +} + +void scroller_from_network(packet_t *packet) { + char buf[257]; + memcpy(buf, &packet->data, packet->len); + buf[packet->len] = '\0'; + append(buf); +} + +void scroller_init() { + scrollbuffer = evbuffer_new(); + last_time = SDL_GetTicks(); +} + +void scroller_shutdown() { + evbuffer_free(scrollbuffer); +} diff --git a/gui_scroller.h b/gui_scroller.h new file mode 100644 index 0000000..1315500 --- /dev/null +++ b/gui_scroller.h @@ -0,0 +1,32 @@ +/* + + Copyright (c) 2006 Florian Wesch . All Rights Reserved. + + 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 2 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, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +*/ + +#ifndef GUI_SCROLLER_H +#define GUI_SCROLLER_H + +void gui_scroller_draw(); + +/* Network */ +void gui_scroller_from_network(packet_t *packet); + +void gui_scroller_init(); +void gui_scroller_shutdown(); + +#endif diff --git a/gui_world.c b/gui_world.c new file mode 100644 index 0000000..3271692 --- /dev/null +++ b/gui_world.c @@ -0,0 +1,125 @@ +/* + + Copyright (c) 2006 Florian Wesch . All Rights Reserved. + + 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 2 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, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +*/ + +#include +#include +#include + +#include "gui_world.h" + +static int world_w; +static int world_h; + +static int koth_x; +static int koth_y; + +static int *map_sprites; +static int *map_food; +static int displaymode; + +void gui_world_draw() { + for (int y = 0; y < world_h; y++) { + for (int x = 0; x < world_w; x++) { + int val; + switch (displaymode) { + case 0: + video_draw(x * SPRITE_TILE_SIZE, + y * SPRITE_TILE_SIZE, + sprite_get(map_sprites[y * world_w + x])); + break; + case 1: + val = (int)MAP_TILE(map_pathfind, x, y)->area; + video_rect(x * SPRITE_TILE_SIZE, + y * SPRITE_TILE_SIZE, + (x+1) * SPRITE_TILE_SIZE, + (y+1) * SPRITE_TILE_SIZE, + val % 206, -val / 200, val, 0xFF); + break; + case 2: + val = MAP_TILE(map_pathfind, x, y)->region; + video_rect(x * SPRITE_TILE_SIZE, + y * SPRITE_TILE_SIZE, + (x+1) * SPRITE_TILE_SIZE, + (y+1) * SPRITE_TILE_SIZE, + val * 206, -val * 200, val, 0xFF); + break; + } + + int food = map_food[y * world_w + x]; + if (food > 0) { + video_draw(x * SPRITE_TILE_SIZE, + y * SPRITE_TILE_SIZE, + sprite_get(SPRITE_FOOD + food / 1000)); + } + } + } +} + +void gui_world_set_display_mode(int mode) { + if (mode >= 0 && mode <= 2) + displaymode = mode; +} + +void gui_world_from_network(packet_t *packet) { + uint8_t x; uint8_t y; + if (!packet_read08(packet, &x)) goto failed; + if (!packet_read08(packet, &y)) goto failed; + if (x >= world_w) goto failed; + if (y >= world_h) goto failed; + uint8_t spriteno; + if (!packet_read08(packet, &spriteno)) goto failed; + if (!sprite_exists(spriteno)) goto failed; + map_sprites[x + world_w * y] = spriteno; + uint16_t food; + if (!packet_read16(packet, &food)) goto failed; + if (food > MAX_TILE_FOOD) goto failed; + map_food[x + world_w * y] = food; + return; +failed: + printf("parsing world update packet failed\n"); + return; +} + +void gui_world_init(int w, int h) { + world_w = w; + world_h = h; + + koth_x = w / 2; + koth_y = h / 2; + + map_sprites = malloc(w * h * sizeof(int)); + + map_food = malloc(w * h * sizeof(int)); + memset(map_food, 0, w * h * sizeof(int)); + + // Tile Texturen setzen + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + map_sprites[x + w * y] = SPRITE_BORDER; + } + } + +} + +void gui_world_shutdown() { + free(map_sprites); + free(map_food); +} + diff --git a/gui_world.h b/gui_world.h new file mode 100644 index 0000000..dab15b8 --- /dev/null +++ b/gui_world.h @@ -0,0 +1,38 @@ +/* + + Copyright (c) 2006 Florian Wesch . All Rights Reserved. + + 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 2 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, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +*/ + +#ifndef GUI_WORLD_H +#define GUI_WORLD_H + +#include "packet.h" + +// Begrenzt durch die Anzahl vorhandener Food Sprites +#define MAX_TILE_FOOD 9999 + +void gui_world_draw(); +void gui_world_set_display_mode(int mode); + +/* Network */ +void gui_world_from_network(packet_t *packet); + +void gui_world_init(int w, int h); +void gui_world_shutdown(); + +#endif diff --git a/infon.c b/infon.c index b8a4f18..0ecc774 100644 --- a/infon.c +++ b/infon.c @@ -26,13 +26,15 @@ #include "global.h" #include "client.h" -#include "world.h" #include "video.h" #include "sprite.h" -#include "creature.h" -#include "scroller.h" #include "misc.h" +//#include "gui_creature.h" +#include "gui_world.h" +#include "gui_scroller.h" +//#include "gui_player.h" + static int running = 1; void sighandler(int sig) { @@ -72,10 +74,10 @@ int main(int argc, char *argv[]) { video_init(width, height); sprite_init(); - scroller_init(); - world_init(width / SPRITE_TILE_SIZE, height / SPRITE_TILE_SIZE - 2); - player_init(); - creature_init(); + gui_scroller_init(); + gui_world_init(width / SPRITE_TILE_SIZE, height / SPRITE_TILE_SIZE - 2); + //gui_player_init(); + //gui_creature_init(); game_round = 0; game_time = 0; @@ -108,18 +110,19 @@ int main(int argc, char *argv[]) { client_tick(); // Anzeigen - world_draw(); + gui_world_draw(); creature_draw(); - scroller_draw(); + gui_scroller_draw(); player_draw(); video_flip(); } - creature_shutdown(); - player_shutdown(); - world_shutdown(); - scroller_shutdown(); + //gui_creature_shutdown(); + //gui_player_shutdown(); + gui_world_shutdown(); + gui_scroller_shutdown(); + sprite_shutdown(); video_shutdown(); client_shutdown(); diff --git a/infond.c b/infond.c index c207a23..a87e62e 100644 --- a/infond.c +++ b/infond.c @@ -30,8 +30,6 @@ #include "global.h" #include "server.h" #include "world.h" -#include "video.h" -#include "sprite.h" #include "creature.h" #include "scroller.h" @@ -42,25 +40,9 @@ void sighandler(int sig) { running = 0; } -void print_fps() { - static Uint32 frames = 0; - static Uint32 ticks = 0; - frames++; - if(SDL_GetTicks() >= ticks + 1000) { - static int iteration = 0; - if (++iteration % 35 == 0) { - static char buf[16]; - snprintf(buf, sizeof(buf), "%d fps", frames); - add_to_scroller(buf); - } - frames = 0; - ticks = SDL_GetTicks(); - } -} - int main(int argc, char *argv[]) { // const int width = 320, height = 208; - const int width = 640, height = 480; + const int width = 640/16, height = 480/16; // const int width = 800, height = 600; // const int width = 1024, height = 768; // const int width = 1280, height = 1024; @@ -81,12 +63,7 @@ int main(int argc, char *argv[]) { lua_dofile(L, "config.lua"); -#ifdef SERVER_GUI - video_init(width, height); - sprite_init(); -#endif - scroller_init(); - world_init(width / SPRITE_TILE_SIZE, height / SPRITE_TILE_SIZE - 2); + world_init(width, height - 2); server_init(); player_init(); creature_init(); @@ -112,49 +89,6 @@ int main(int argc, char *argv[]) { lastticks = nowticks; -#ifdef SERVER_GUI - SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: - switch (event.key.keysym.sym) { - case SDLK_RETURN: - if (event.key.keysym.mod & KMOD_ALT) - video_fullscreen_toggle(); - break; - case SDLK_ESCAPE: - running = 0; - break; - case SDLK_1: world_set_display_mode(0); break; - case SDLK_2: world_set_display_mode(1); break; - case SDLK_3: world_set_display_mode(2); break; - case SDLK_SPACE: paused = !paused; break; - default: ; - } - break; - case SDL_MOUSEMOTION: - if (event.motion.state == 1) { - world_dig(event.motion.x / SPRITE_TILE_SIZE, event.motion.y / SPRITE_TILE_SIZE, SOLID); - world_dig(event.motion.x / SPRITE_TILE_SIZE + 1, event.motion.y / SPRITE_TILE_SIZE, SOLID); - world_dig(event.motion.x / SPRITE_TILE_SIZE, event.motion.y / SPRITE_TILE_SIZE + 1, SOLID); - world_dig(event.motion.x / SPRITE_TILE_SIZE + 1, event.motion.y / SPRITE_TILE_SIZE + 1, SOLID); - printf("%d %d %d\n", - event.motion.x * TILE_SCALE / SPRITE_TILE_SIZE, - event.motion.y * TILE_SCALE / SPRITE_TILE_SIZE, - world_get_food(event.motion.x / SPRITE_TILE_SIZE, - event.motion.y / SPRITE_TILE_SIZE)); - - } - break; - case SDL_QUIT: - running = 0; - break; - } - } -#endif - - print_fps(); - // Zeit weiterlaufen lassen if (!paused) game_time += delta; @@ -169,30 +103,12 @@ int main(int argc, char *argv[]) { // Viecher bewegen creature_moveall(delta); } - -#ifdef SERVER_GUI - // Anzeigen - world_draw(); - creature_draw(); - scroller_draw(); - player_draw(); - - video_flip(); -#endif - - // GUI Client aktualisieren - // TODO: implement me } creature_shutdown(); player_shutdown(); server_shutdown(); world_shutdown(); - scroller_shutdown(); -#ifdef SERVER_GUI - sprite_shutdown(); - video_shutdown(); -#endif lua_close(L); diff --git a/player.c b/player.c index 0ca886e..bf1be37 100644 --- a/player.c +++ b/player.c @@ -30,9 +30,7 @@ #include "player.h" #include "server.h" #include "creature.h" -#include "sprite.h" #include "world.h" -#include "video.h" #include "misc.h" #include "rules.h" #include "scroller.h" @@ -729,99 +727,6 @@ void player_think() { } } -#ifdef SERVER_GUI -static int player_sort_by_score(const void *a, const void *b) { - const player_t *pa = *(player_t **)a; - const player_t *pb = *(player_t **)b; - return -(pa->score > pb->score) + (pa->score < pb->score); -} - -void player_draw() { - static int lastturn = 0; - static int page = 0; - - if (SDL_GetTicks() > lastturn + 5000) { - lastturn = SDL_GetTicks(); - page++; - } - - int per_page = video_width() / 128; - if (per_page == 0) per_page = 1; - - int n; - int player_displayed = 0; - - int num_players = 0; - player_t *sorted[MAXPLAYERS]; - - for (n = 0; n < MAXPLAYERS; n++) { - player_t *player = &players[n]; - - if (!PLAYER_USED(player)) - continue; - sorted[num_players++] = player; - } - //printf("%d\n", num_players); - - player_t *king = player_king(); - - if (king) king->score += 1000000; // HACKHACK - qsort(sorted, num_players, sizeof(creature_t*), player_sort_by_score); - if (king) king->score -= 1000000; - - int offset = per_page * page; - if (offset >= num_players) { - page = 0; - offset = 0; - } - - int num = num_players - offset; - if (num > per_page) - num = per_page; - - video_rect(0, video_height() - 32, video_width(), video_height() - 16, 0, 0, 0, 0); - - for (n = offset; n < offset + num; n++) { - player_t *player = sorted[n]; - assert(PLAYER_USED(player)); - - // King in dieser Runde? - if (player == king) { - video_draw(player_displayed * 128 + 10, - video_height() - 86 - 20 * abs(sin(M_PI / 750.0 * (SDL_GetTicks() % 750))), - sprite_get(SPRITE_CROWN)); - } - - // Rotierendes Vieh - video_draw(player_displayed * 128, - video_height() - 32, - sprite_get(CREATURE_SPRITE(player->color, - 0, - (SDL_GetTicks() / 1000) % CREATURE_DIRECTIONS, - (SDL_GetTicks() / 123) % 2))); - // CPU Auslastung Anzeigen - const int cpu = 80 * player->cpu_usage / 100; - video_rect(player_displayed * 128 + 16, - video_height() - 32, - player_displayed * 128 + 16 + cpu, - video_height() - 16, - 2 * cpu, 160 - 2 * cpu , 0x00, 0x00); - - // Name / Punkte - static char buf[18]; - snprintf(buf, sizeof(buf), "%2d. %4d %s", n + 1, player->score, player->name); - video_write(player_displayed * 128 + 16, - video_height() - 30, - buf); - - player_displayed++; - } -} -#else -void player_draw() { -} -#endif - void player_is_king_of_the_hill(player_t *player, int delta) { //player_t *old_king = king_player; @@ -902,78 +807,6 @@ void player_to_network(player_t *player, int dirtymask, client_t *client) { packet_send(PACKET_PLAYER_UPDATE, &packet, client); } -void player_from_network(packet_t *packet) { - uint8_t playerno = 0; - - if (!packet_read08(packet, &playerno)) goto failed; - if (playerno >= MAXPLAYERS) goto failed; - player_t *player = &players[playerno]; - - uint8_t updatemask; - if (!packet_read08(packet, &updatemask)) goto failed; - - if (updatemask & PLAYER_DIRTY_ALIVE) { - uint8_t alive; - if (!packet_read08(packet, &alive)) goto failed; - player->L = alive ? (void*)0x1 : NULL; - if (!alive) - return; - } - - if (!PLAYER_USED(player)) goto failed; - - if (updatemask & PLAYER_DIRTY_NAME) { - uint8_t len; char buf[256]; - if (!packet_read08(packet, &len)) goto failed; - if (!packet_readXX(packet, buf, len)) goto failed; - buf[len] = '\0'; - snprintf(player->name, sizeof(player->name), "%s", buf); - } - if (updatemask & PLAYER_DIRTY_COLOR) { - uint8_t col; - if (!packet_read08(packet, &col)) goto failed; - if (col >= CREATURE_COLORS) goto failed; - player->color = col; - } - if (updatemask & PLAYER_DIRTY_CPU) { - uint8_t cpu; - if (!packet_read08(packet, &cpu)) goto failed; - if (cpu > 100) goto failed; - player->cpu_usage = cpu; - } - if (updatemask & PLAYER_DIRTY_SCORE) { - uint16_t score; - if (!packet_read16(packet, &score)) goto failed; - player->score = score + PLAYER_KICK_SCORE; - } - return; -failed: - printf("parsing player update packet failed\n"); - return; -} - -/* -int packet_player_update_king(packet_t *packet) { - packet->type = PACKET_PLAYER_KING; - if (player_king()) { - packet->player_update_king.king_player = player_num(player_king()); - } else { - packet->player_update_king.king_player = 0xFF; - } - return sizeof(packet_player_update_king_t); -} - -void packet_handle_player_update_king(packet_t *packet) { - assert(packet->type == PACKET_PLAYER_KING); - if (packet->player_update_king.king_player == 0xFF) { - king_player = NULL; - return; - } - if (packet->player_update_king.king_player >= MAXPLAYERS) - return; - king_player = &players[packet->player_update_king.king_player]; -} -*/ void player_init() { memset(players, 0, sizeof(players)); @@ -982,8 +815,7 @@ void player_init() { void player_shutdown() { int playerno; for (playerno = 0; playerno < MAXPLAYERS; playerno++) { - if (PLAYER_USED(&players[playerno]) && - players[playerno].L != (void*)0x1) + if (PLAYER_USED(&players[playerno])) player_destroy(&players[playerno]); } } diff --git a/player.h b/player.h index 05217e8..2ba55cd 100644 --- a/player.h +++ b/player.h @@ -84,7 +84,6 @@ player_t *player_create(const char *pass); void player_mark_for_kill(player_t *player); void player_think(); -void player_draw(); void player_is_king_of_the_hill(player_t *player, int delta); void player_there_is_no_king(); @@ -93,8 +92,6 @@ player_t *player_king(); /* Network */ void player_send_initial_update(client_t *client); void player_to_network(player_t *player, int dirtymask, client_t *client); -void player_from_network(packet_t *packet); - void player_init(); void player_shutdown(); diff --git a/scroller.c b/scroller.c index ffa57d8..dfdb35c 100644 --- a/scroller.c +++ b/scroller.c @@ -18,97 +18,16 @@ */ -#include #include +#include -#include "video.h" #include "scroller.h" #include "packet.h" -static struct evbuffer *scrollbuffer; - -static int last_time; - -static void append(const char *msg) { - evbuffer_add(scrollbuffer, (char*)msg, strlen(msg)); - evbuffer_add(scrollbuffer, " - ", 5); -} - void add_to_scroller(const char* msg) { - // Zu lange Einzelnachricht? - if (strlen(msg) > 255) - return; - - // Zuviel insgesamt? - if (EVBUFFER_LENGTH(scrollbuffer) > 10000) - return; - - append(msg); - // Network Sync packet_t packet; packet_reset(&packet); packet_writeXX(&packet, msg, strlen(msg)); packet_send(PACKET_SCROLLER_MSG, &packet, PACKET_BROADCAST); } - -#ifdef SERVER_GUI -static float x = 0; -static float curspeed = 0; - -void scroller_draw() { - int chars_per_screen = video_width() / 6 + 1; - - Uint32 now = SDL_GetTicks(); - - float speed = ((float)now- last_time) * - (float)(EVBUFFER_LENGTH(scrollbuffer) - chars_per_screen - 3) / 200.0; - - if (curspeed < speed) curspeed += 0.1; //(speed - curspeed)/30.0; - if (curspeed > speed) curspeed = speed; - if (curspeed < 0.1) curspeed = 0; - - x -= curspeed; - last_time = now; - - while (x < -6) { - evbuffer_drain(scrollbuffer, 1); - x += 6; - } - - while (EVBUFFER_LENGTH(scrollbuffer) <= chars_per_screen + 1) - evbuffer_add(scrollbuffer, " ", 1); - - video_rect(0, video_height() - 15, video_width(), video_height(), 0, 0, 0, 0); - - assert(chars_per_screen < EVBUFFER_LENGTH(scrollbuffer)); - char *end = &EVBUFFER_DATA(scrollbuffer)[chars_per_screen]; - char saved = *end; *end = '\0'; - video_write(x, video_height() - 15, EVBUFFER_DATA(scrollbuffer)); - *end = saved; - - // Bitte drinlassen. Danke - if (now / 1000 % 60 < 5) - video_draw(video_width() - 190, 20, sprite_get(SPRITE_LOGO)); -} -#else -void scroller_draw() { - evbuffer_drain(scrollbuffer, EVBUFFER_LENGTH(scrollbuffer)); -} -#endif - -void scroller_from_network(packet_t *packet) { - char buf[257]; - memcpy(buf, &packet->data, packet->len); - buf[packet->len] = '\0'; - append(buf); -} - -void scroller_init() { - scrollbuffer = evbuffer_new(); - last_time = SDL_GetTicks(); -} - -void scroller_shutdown() { - evbuffer_free(scrollbuffer); -} diff --git a/scroller.h b/scroller.h index 29a0542..3818272 100644 --- a/scroller.h +++ b/scroller.h @@ -21,14 +21,6 @@ #ifndef SCROLLER_H #define SCROLLER_H -void scroller_draw(); - void add_to_scroller(const char* msg); -/* Network */ -void scroller_from_network(packet_t *packet); - -void scroller_init(); -void scroller_shutdown(); - #endif diff --git a/world.c b/world.c index 1eb6e8f..1cceec8 100644 --- a/world.c +++ b/world.c @@ -19,13 +19,13 @@ */ #include +#include #include #include #include "world.h" -#include "video.h" -#include "path.h" #include "sprite.h" +#include "path.h" static int world_w; static int world_h; @@ -37,52 +37,6 @@ static map_t *map_pathfind; static pathfinder_t finder; static int *map_sprites; static int *map_food; -//static maptype_e *map_type; -static int displaymode; - -#ifdef SERVER_GUI -void world_draw() { - for (int y = 0; y < world_h; y++) { - for (int x = 0; x < world_w; x++) { - int val; - switch (displaymode) { - case 0: - video_draw(x * SPRITE_TILE_SIZE, - y * SPRITE_TILE_SIZE, - sprite_get(map_sprites[y * world_w + x])); - break; - case 1: - val = (int)MAP_TILE(map_pathfind, x, y)->area; - video_rect(x * SPRITE_TILE_SIZE, - y * SPRITE_TILE_SIZE, - (x+1) * SPRITE_TILE_SIZE, - (y+1) * SPRITE_TILE_SIZE, - val % 206, -val / 200, val, 0xFF); - break; - case 2: - val = MAP_TILE(map_pathfind, x, y)->region; - video_rect(x * SPRITE_TILE_SIZE, - y * SPRITE_TILE_SIZE, - (x+1) * SPRITE_TILE_SIZE, - (y+1) * SPRITE_TILE_SIZE, - val * 206, -val * 200, val, 0xFF); - break; - } - - int food = map_food[y * world_w + x]; - if (food > 0) { - video_draw(x * SPRITE_TILE_SIZE, - y * SPRITE_TILE_SIZE, - sprite_get(SPRITE_FOOD + food / 1000)); - } - } - } -} -#else -void world_draw() { -} -#endif - int world_walkable(int x, int y) { return MAP_IS_ON_MAP(map_pathfind, x, y) && @@ -105,11 +59,6 @@ int world_dig(int x, int y, maptype_e type) { return 1; } -void world_set_display_mode(int mode) { - if (mode >= 0 && mode <= 2) - displaymode = mode; -} - pathnode_t *world_findpath(int x1, int y1, int x2, int y2) { return finder_find(&finder, map_pathfind, x1, y1, x2, y2); } @@ -200,28 +149,6 @@ void world_to_network(int x, int y, client_t *client) { packet_send(PACKET_WORLD_UPDATE, &packet, client); } -#ifdef CLIENT -void world_from_network(packet_t *packet) { - uint8_t x; uint8_t y; - if (!packet_read08(packet, &x)) goto failed; - if (!packet_read08(packet, &y)) goto failed; - if (x >= world_w) goto failed; - if (y >= world_h) goto failed; - uint8_t spriteno; - if (!packet_read08(packet, &spriteno)) goto failed; - if (!sprite_exists(spriteno)) goto failed; - map_sprites[x + world_w * y] = spriteno; - uint16_t food; - if (!packet_read16(packet, &food)) goto failed; - if (food > MAX_TILE_FOOD) goto failed; - map_food[x + world_w * y] = food; - return; -failed: - printf("parsing world update packet failed\n"); - return; -} -#endif - void world_init(int w, int h) { world_w = w; world_h = h; diff --git a/world.h b/world.h index d001383..c6e95a2 100644 --- a/world.h +++ b/world.h @@ -50,15 +50,9 @@ int world_koth_y(); pathnode_t *world_findpath(int x1, int y1, int x2, int y2); void world_find_digged(int *x, int *y); -void world_set_display_mode(int mode); - -void world_draw(); - /* Network */ void world_send_initial_update(client_t *client); - void world_to_network(int x, int y, client_t *client); -void world_from_network(packet_t *packet); void world_init(int w, int h); void world_shutdown();