Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

* All creature related parameters are tuneable without recompiling. …

…For example: creature_config.runner_speed = 400. See creature_config.gperf for the full list of variables.

 * 'lio' command renamed to 'bio'
 * The command line options of infond are available in the global variable 'argv'. You can use it in config.lua.
 * 'get_hitpoints' and 'get_attack_distance' deprecated. Use creature_config if you need them.
 * New 'hint' command. If you have other hints you would like to see here, contact me!


git-svn-id: http://infon.googlecode.com/svn/trunk@205 8171fb75-e542-0410-96e4-03d5dd800671
  • Loading branch information...
commit f5b20d72226c2621b5292830b21520c45002edee 1 parent 602d98d
Florian Wesch authored
9 Makefile
View
@@ -153,7 +153,7 @@ dist:
$(MAKE) clean
$(MAKE) linux-server-dist
-source-dist: REVISION
+source-dist: REVISION creature_config.h
tar cvzh -C.. --exclude ".svn" --exclude "infon-source*" --file infon-source-r$(REVISION).tgz infon
win32-client-dist: $(INFON_EXECUTABLE) $(SDL_RENDERER) $(GL_RENDERER)
@@ -199,6 +199,11 @@ $(GL_RENDERER): gl_video.o gl_gui.o gl_mdl.o misc.o
$(LILITH_RENDERER): lilith_gui.o misc.o lilith/lilith/liblilith.a
$(CC) $^ $(LDFLAGS) -shared -o $@
+creature.c: creature_config.h
+
+creature_config.h: creature_config.gperf
+ gperf --output-file=$@ -c -C -t $^
+
infon.res: infon.rc
$(WINDRES) -i $^ -DREVISION="\\\"$(REVISION)\\\"" --input-format=rc -o $@ -O coff
@@ -219,4 +224,4 @@ clean:
distclean: clean
$(MAKE) -C $(LUA) clean
- -rm -f infon*.zip infon*.tgz *.orig *.rej infond-*.demo infond-wrapper REVISION
+ -rm -f infon*.zip infon*.tgz *.orig *.rej infond-*.demo infond-wrapper REVISION creature_config.h
23 config.lua
View
@@ -83,6 +83,16 @@ debugger = false
-- disabled on a public server.
speedchange = false
+-- Use this section to automate competitions. information about
+-- the fight will be written into 'log'. the bots in 'bots' will
+-- automatically join the game. Each of them takes the same
+-- parameters as shown in the autoexec example below.
+-- Set the parameters 'maps', 'time_limit', 'score_limit' as you
+-- wish. 'listenaddr' should be set to nil so nobody can join
+-- this server. the server will terminate once all maps were
+-- played once. The infond command line options are available
+-- in the table 'argv'.
+--
-- competition = {
-- log = "competition.log";
-- bots = {
@@ -101,10 +111,15 @@ speedchange = false
-- Things to do once after the first game started
--
-- function autoexec()
--- start_bot{ source = "contrib/bots/easybot.lua",
--- name = "foo",
--- password = "secret",
--- api = "state" }
+-- -- Change runner speed
+-- creature_config.runner_speed = 1000
+--
+-- -- Join a bot
+-- start_bot{ source = "contrib/bots/queener.lua",
+-- name = "Queener",
+-- password = "topsecret",
+-- log = "queener.log",
+-- api = "oo" }
-- end
-- function checking user/password combinations.
288 creature.c
View
@@ -124,46 +124,26 @@ int creature_eat_from_tile(creature_t *creature, int amount) {
return world_food_eat(X_TO_TILEX(creature->x), Y_TO_TILEY(creature->y), amount);
}
+static int max_health[CREATURE_TYPES] = { 10000, 20000, 5000, 0 };
+
+int creature_type_health(creature_type type) {
+ return max_health[type];
+}
+
int creature_max_health(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 10000;
- case CREATURE_BIG:
- return 20000;
- case CREATURE_FLYER:
- return 5000;
- default:
- assert(0);
- return 0;
- }
+ return creature_type_health(creature->type);
}
+static int max_food[CREATURE_TYPES] = { 10000, 20000, 5000, 0 };
+
int creature_max_food(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 10000;
- case CREATURE_BIG:
- return 20000;
- case CREATURE_FLYER:
- return 5000;
- default:
- assert(0);
- return 0;
- }
+ return max_food[creature->type];
}
+static int aging[CREATURE_TYPES] = { 5, 7, 5, 0 };
+
int creature_aging(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 5;
- case CREATURE_BIG:
- return 7;
- case CREATURE_FLYER:
- return 5;
- default:
- assert(0);
- return 0;
- }
+ return aging[creature->type];
}
creature_t *creature_nearest_enemy(const creature_t *reference, int *distptr) {
@@ -191,18 +171,18 @@ creature_t *creature_nearest_enemy(const creature_t *reference, int *distptr) {
// ------------- Bewegung -------------
+static int base_speed[CREATURE_TYPES] = { 200, 400, 800, 0 };
+static int health_speed[CREATURE_TYPES] = { 625, 0, 0, 0 };
+
int creature_speed(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 200 + creature->health / 16;
- case CREATURE_BIG:
- return 400;
- case CREATURE_FLYER:
- return 800;
- default:
- assert(0);
- return 0;
- }
+ int speed = base_speed[creature->type] +
+ (float)health_speed[creature->type] / creature_max_health(creature) * creature->health;
+
+ // speed limit. needed since (speed / CREATURE_SPEED_RESOLUTION) is synchronized as byte.
+ if (speed > 250 * CREATURE_SPEED_RESOLUTION)
+ speed = 250 * CREATURE_SPEED_RESOLUTION;
+
+ return speed;
}
static int creature_can_walk_path(creature_t *creature) {
@@ -250,18 +230,10 @@ int creature_can_heal(const creature_t *creature) {
creature->food > 0;
}
+static int heal_rate[CREATURE_TYPES] = {500, 300, 600, 0};
+
int creature_heal_rate(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 500;
- case CREATURE_BIG:
- return 300;
- case CREATURE_FLYER:
- return 600;
- default:
- assert(0);
- return 0;
- }
+ return heal_rate[creature->type];
}
void creature_do_heal(creature_t *creature, int delta) {
@@ -291,18 +263,10 @@ int creature_can_eat(const creature_t *creature) {
creature->food < creature_max_food(creature);
}
+static int eat_rate[CREATURE_TYPES] = { 800, 400, 600, 0 };
+
int creature_eat_rate(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 800;
- case CREATURE_BIG:
- return 400;
- case CREATURE_FLYER:
- return 600;
- default:
- assert(0);
- return 0;
- }
+ return eat_rate[creature->type];
}
void creature_do_eat(creature_t *creature, int delta) {
@@ -321,70 +285,49 @@ void creature_do_eat(creature_t *creature, int delta) {
// ------------- Attack -------------
-static const int attack_possible[CREATURE_TYPES][CREATURE_TYPES] =
- // TARGET
- { { 0, 0, 1, 0 },// ATTACKER
- { 1, 1, 1, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 } };
+static int hitpoints[CREATURE_TYPES][CREATURE_TYPES] = {
+ // TARGET ->
+ { 0, 0, 1000, 0 }, // ATTACKER
+ { 1500, 1500, 1500, 0 }, // |
+ { 0, 0, 0, 0 }, // v
+ { 0, 0, 0, 0 },
+};
-int creature_can_attack(const creature_t *creature, const creature_t *target) {
- return attack_possible[creature->type][target->type];
+int creature_hitpoints(const creature_t *creature, const creature_t *target) {
+ return hitpoints[creature->type][target->type];
}
-int creature_hitpoints(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 1000;
- case CREATURE_BIG:
- return 1500;
- case CREATURE_FLYER:
- return 0;
- default:
- assert(0);
- return 0;
- }
-}
+static int attack_distance[CREATURE_TYPES][CREATURE_TYPES] = {
+ // TARGET ->
+ { 0, 0, 768, 0 }, // ATTACKER
+ { 512, 512, 512, 0 }, // |
+ { 0, 0, 0, 0 }, // v
+ { 0, 0, 0, 0 },
+};
-int creature_attack_distance(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 3 * TILE_SCALE;
- case CREATURE_BIG:
- return 2 * TILE_SCALE;
- case CREATURE_FLYER:
- return 0;
- default:
- assert(0);
- return 0;
- }
+int creature_attack_distance(const creature_t *creature, const creature_t *target) {
+ return attack_distance[creature->type][CREATURE_TYPES];
}
void creature_do_attack(creature_t *creature, int delta) {
- const int hitpoints = creature_hitpoints(creature) * delta / 1000;
- if (hitpoints == 0)
- goto finished_attacking;
-
creature_t *target = creature_by_id(creature->target_id);
// Nicht gefunden?
if (!target)
goto finished_attacking;
- // Kann nicht angreifen?
- if (!creature_can_attack(creature, target))
- goto finished_attacking;
-
- // Ziel zu jung?
- // if (target->spawn_time + 500 > game_time)
- // goto finished_attacking;
-
// Eigenes Viech?
if (target->player == creature->player)
goto finished_attacking;
+ const int hitpoints = creature_hitpoints(creature, target) * delta / 1000;
+
+ // Kann nicht angreifen?
+ if (hitpoints == 0)
+ goto finished_attacking;
+
// Zu weit weg?
- if (creature_dist(creature, target) > creature_attack_distance(creature))
+ if (creature_dist(creature, target) > creature_attack_distance(creature, target))
goto finished_attacking;
target->health -= hitpoints;
@@ -404,11 +347,13 @@ void creature_do_attack(creature_t *creature, int delta) {
// ------------- Creature Conversion -------------
-int creature_conversion_speed(creature_t *creature) {
- return 1000;
+static int conversion_speed[CREATURE_TYPES] = { 1000, 1000, 1000, 0 };
+
+int creature_conversion_speed(const creature_t *creature) {
+ return conversion_speed[creature->type];
}
-static const int conversion_food_needed[CREATURE_TYPES][CREATURE_TYPES] =
+static int conversion_food_needed[CREATURE_TYPES][CREATURE_TYPES] =
// TO
{ { 0, 8000, 5000, 0 },// FROM
{ 8000, 0, 0, 0 },
@@ -460,6 +405,9 @@ int creature_set_conversion_type(creature_t *creature, creature_type type) {
if (creature_conversion_food(creature, type) == 0)
return 0;
+ if (creature_type_health(type) == 0)
+ return 0;
+
// Beim Type Wechsel geht Food verloren
if (creature->convert_type != type)
creature->convert_food = 0;
@@ -490,18 +438,30 @@ int creature_set_type(creature_t *creature, creature_type type) {
// ------------- Creature Spawning -------------
// Waehrend des Spawnens verbrauchtes Futter
+static int spawn_food[CREATURE_TYPES] = { 0, 5000, 0, 0 };
+
int creature_spawn_food(const creature_t *creature) {
- return 5000;
+ return spawn_food[creature->type];
}
// Spawngeschwindigkeit (wie schnell wird das obige Futter verbraucht)
+static int spawn_speed[CREATURE_TYPES] = { 0, 2000, 0, 0 };
+
int creature_spawn_speed(const creature_t *creature) {
- return 2000;
+ return spawn_speed[creature->type];
}
// Beim Spawnstart verlorene Lebensenergie
+static int spawn_health[CREATURE_TYPES] = { 0, 4000, 0, 0 };
+
int creature_spawn_health(const creature_t *creature) {
- return 4000;
+ return spawn_health[creature->type];
+}
+
+static int spawn_type[CREATURE_TYPES] = { -1, CREATURE_SMALL, -1, -1 };
+
+int creature_spawn_type(const creature_t *creature) {
+ return spawn_type[creature->type];
}
void creature_do_spawn(creature_t *creature, int delta) {
@@ -531,53 +491,27 @@ void creature_do_spawn(creature_t *creature, int delta) {
}
int creature_can_spawn(const creature_t *creature) {
- return creature->type == 1 &&
- creature->food >= creature_spawn_food(creature) &&
+ return creature_spawn_type(creature) != -1 &&
creature->health > creature_spawn_health(creature);
}
// ---------------- Feeding -----------------
+static int feed_distance[CREATURE_TYPES] = { 256, 0, 256, 0 };
+
int creature_can_feed(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return creature->food > 0;
- case CREATURE_BIG:
- return 0;
- case CREATURE_FLYER:
- return creature->food > 0;
- default:
- assert(0);
- return 0;
- }
+ return feed_distance[creature->type] > 0 &&
+ creature->food > 0;
}
int creature_feed_distance(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return TILE_SCALE;
- case CREATURE_BIG:
- return 0;
- case CREATURE_FLYER:
- return TILE_SCALE;
- default:
- assert(0);
- return 0;
- }
+ return feed_distance[creature->type];
}
+static int feed_speed[CREATURE_TYPES] = { 400, 0, 400, 0 };
+
int creature_feed_speed(const creature_t *creature) {
- switch (creature->type) {
- case CREATURE_SMALL:
- return 400;
- case CREATURE_BIG:
- return 0;
- case CREATURE_FLYER:
- return 400;
- default:
- assert(0);
- return 0;
- }
+ return feed_speed[creature->type];
}
void creature_do_feed(creature_t *creature, int delta) {
@@ -590,10 +524,6 @@ void creature_do_feed(creature_t *creature, int delta) {
if (!target)
goto finished_feeding;
- // Ziel zu jung?
- // if (target->spawn_time + 500 > game_time)
- // goto finished_feeding;
-
// Zu weit weg?
if (creature_dist(creature, target) > creature_feed_distance(creature))
goto finished_feeding;
@@ -898,6 +828,10 @@ creature_t *creature_spawn(player_t *player, creature_t *parent, int x, int y, c
if (!creature)
return NULL;
+ // spawning this type ok?
+ if (creature_type_health(type) == 0)
+ return NULL;
+
num_creatures++;
memset(creature, 0, sizeof(creature_t));
@@ -907,7 +841,7 @@ creature_t *creature_spawn(player_t *player, creature_t *parent, int x, int y, c
creature->y = y;
creature->type = type;
creature->food = 0;
- creature->health = creature_max_health(creature);
+ creature->health = creature_type_health(type);
creature->player = player;
creature->target_id = creature->vm_id; // muesste nicht gesetzt werden
creature->path = NULL;
@@ -1027,6 +961,44 @@ int creature_num_creatures() {
return num_creatures;
}
+static int pure = 1;
+
+struct creature_option {
+ const char *name;
+ const int min;
+ const int max;
+ int *value;
+};
+
+#include "creature_config.h"
+
+int luaCreatureGetConfig(lua_State *L) {
+ size_t namelen; const char *name = luaL_checklstring(L, 1, &namelen);
+ const struct creature_option *opt = in_word_set(name, namelen);
+ if (!opt) luaL_error(L, "option '%s' does not exist", name);
+ lua_pushnumber(L, *opt->value);
+ return 1;
+}
+
+int luaCreatureSetConfig(lua_State *L) {
+ if (num_creatures > 0)
+ luaL_error(L, "cannot change options while there are creatures");
+ size_t namelen; const char *name = luaL_checklstring(L, 1, &namelen);
+ int value = luaL_checklong(L, 2);
+ const struct creature_option *opt = in_word_set(name, namelen);
+ if (!opt) luaL_error(L, "option '%s' does not exist", name);
+ if (value < opt->min || value > opt->max)
+ luaL_error(L, "value for '%s' out of range. (%d - %d)", name, opt->min, opt->max);
+ *opt->value = value;
+ pure = 0;
+ return 0;
+}
+
+int luaCreatureConfigChanged(lua_State *L) {
+ lua_pushboolean(L, pure);
+ return 1;
+}
+
void creature_init() {
for (int i = 0; i < MAXCREATURES; i++) {
creature_t *creature = &creatures[i];
6 creature.h
View
@@ -90,8 +90,6 @@ int creature_dist(const creature_t *a, const creature_t *b);
int creature_food_on_tile(const creature_t *creature);
maptype_e creature_tile_type(const creature_t *creature);
int creature_max_food(const creature_t *creature);
-int creature_hitpoints(const creature_t *creature);
-int creature_attack_distance(const creature_t *creature);
void creature_kill_all_players_creatures(player_t *player);
void creature_moveall(int delta);
@@ -101,6 +99,10 @@ int creature_num_creatures();
void creature_send_initial_update(client_t *client);
void creature_to_network(creature_t *creature, int dirtymask, client_t *client);
+int luaCreatureGetConfig(lua_State *L);
+int luaCreatureSetConfig(lua_State *L);
+int luaCreatureConfigChanged(lua_State *L);
+
void creature_init();
void creature_shutdown();
68 creature_config.gperf
View
@@ -0,0 +1,68 @@
+struct creature_option;
+%%
+runner_aging, 0, 30, &aging[CREATURE_SMALL]
+runner_health, 1000, 100000, &max_health[CREATURE_SMALL]
+runner_food, 0, 100000, &max_food[CREATURE_SMALL]
+runner_speed, 100, 1000, &base_speed[CREATURE_SMALL]
+runner_speed_health, 0, 1000, &health_speed[CREATURE_SMALL]
+runner_heal_rate, 100, 3000, &heal_rate[CREATURE_SMALL]
+runner_eat_rate, 100, 3000, &eat_rate[CREATURE_SMALL]
+runner_attack_runner, 0, 3000, &hitpoints[CREATURE_SMALL][CREATURE_SMALL]
+runner_attack_fatty, 0, 3000, &hitpoints[CREATURE_SMALL][CREATURE_BIG]
+runner_attack_flyer, 0, 3000, &hitpoints[CREATURE_SMALL][CREATURE_FLYER]
+runner_attack_range_runner, 0, 4096, &attack_distance[CREATURE_SMALL][CREATURE_SMALL]
+runner_attack_range_fatty, 0, 4096, &attack_distance[CREATURE_SMALL][CREATURE_BIG]
+runner_attack_range_flyer, 0, 4096, &attack_distance[CREATURE_SMALL][CREATURE_FLYER]
+runner_convert_speed, 500, 3000, &conversion_speed[CREATURE_SMALL]
+runner_convert_fatty, 1000, 20000, &conversion_food_needed[CREATURE_SMALL][CREATURE_BIG]
+runner_convert_flyer, 1000, 20000, &conversion_food_needed[CREATURE_SMALL][CREATURE_FLYER]
+runner_spawn_food, 0, 10000, &spawn_food[CREATURE_SMALL]
+runner_spawn_speed, 500, 10000, &spawn_speed[CREATURE_SMALL]
+runner_spawn_health, 0, 100000, &spawn_health[CREATURE_SMALL]
+runner_spawn_type, -1, 2, &spawn_type[CREATURE_SMALL]
+runner_feed_range, 0, 4096, &feed_distance[CREATURE_SMALL]
+runner_feed_speed, 100, 3000, &feed_speed[CREATURE_SMALL]
+fatty_aging, 0, 30, &aging[CREATURE_BIG]
+fatty_health, 1000, 100000, &max_health[CREATURE_BIG]
+fatty_food, 0, 100000, &max_food[CREATURE_BIG]
+fatty_speed, 100, 1000, &base_speed[CREATURE_BIG]
+fatty_speed_health, 0, 1000, &health_speed[CREATURE_BIG]
+fatty_heal_rate, 100, 3000, &heal_rate[CREATURE_BIG]
+fatty_eat_rate, 100, 3000, &eat_rate[CREATURE_BIG]
+fatty_attack_runner, 0, 3000, &hitpoints[CREATURE_BIG][CREATURE_SMALL]
+fatty_attack_fatty, 0, 3000, &hitpoints[CREATURE_BIG][CREATURE_BIG]
+fatty_attack_flyer, 0, 3000, &hitpoints[CREATURE_BIG][CREATURE_FLYER]
+fatty_attack_range_runner, 0, 4096, &attack_distance[CREATURE_BIG][CREATURE_SMALL]
+fatty_attack_range_fatty, 0, 4096, &attack_distance[CREATURE_BIG][CREATURE_BIG]
+fatty_attack_range_flyer, 0, 4096, &attack_distance[CREATURE_BIG][CREATURE_FLYER]
+fatty_convert_speed, 500, 3000, &conversion_speed[CREATURE_BIG]
+fatty_convert_runner, 1000, 20000, &conversion_food_needed[CREATURE_BIG][CREATURE_SMALL]
+fatty_convert_flyer, 1000, 20000, &conversion_food_needed[CREATURE_BIG][CREATURE_FLYER]
+fatty_spawn_food, 0, 10000, &spawn_food[CREATURE_BIG]
+fatty_spawn_speed, 500, 10000, &spawn_speed[CREATURE_BIG]
+fatty_spawn_health, 0, 100000, &spawn_health[CREATURE_BIG]
+fatty_spawn_type, -1, 2, &spawn_type[CREATURE_BIG]
+fatty_feed_range, 0, 4096, &feed_distance[CREATURE_BIG]
+fatty_feed_speed, 100, 3000, &feed_speed[CREATURE_BIG]
+flyer_aging, 0, 30, &aging[CREATURE_FLYER]
+flyer_health, 1000, 100000, &max_health[CREATURE_FLYER]
+flyer_food, 0, 100000, &max_food[CREATURE_FLYER]
+flyer_speed, 100, 1000, &base_speed[CREATURE_FLYER]
+flyer_speed_health, 0, 1000, &health_speed[CREATURE_FLYER]
+flyer_heal_rate, 100, 3000, &heal_rate[CREATURE_FLYER]
+flyer_eat_rate, 100, 3000, &eat_rate[CREATURE_FLYER]
+flyer_attack_runner, 0, 3000, &hitpoints[CREATURE_FLYER][CREATURE_SMALL]
+flyer_attack_fatty, 0, 3000, &hitpoints[CREATURE_FLYER][CREATURE_BIG]
+flyer_attack_flyer, 0, 3000, &hitpoints[CREATURE_FLYER][CREATURE_FLYER]
+flyer_attack_range_runner, 0, 4096, &attack_distance[CREATURE_FLYER][CREATURE_SMALL]
+flyer_attack_range_fatty, 0, 4096, &attack_distance[CREATURE_FLYER][CREATURE_BIG]
+flyer_attack_range_flyer, 0, 4096, &attack_distance[CREATURE_FLYER][CREATURE_FLYER]
+flyer_convert_speed, 500, 3000, &conversion_speed[CREATURE_FLYER]
+flyer_convert_runner, 1000, 20000, &conversion_food_needed[CREATURE_FLYER][CREATURE_SMALL]
+flyer_convert_fatty, 1000, 20000, &conversion_food_needed[CREATURE_FLYER][CREATURE_BIG]
+flyer_spawn_food, 0, 10000, &spawn_food[CREATURE_FLYER]
+flyer_spawn_speed, 500, 10000, &spawn_speed[CREATURE_FLYER]
+flyer_spawn_health, 0, 100000, &spawn_health[CREATURE_FLYER]
+flyer_spawn_type, -1, 2, &spawn_type[CREATURE_FLYER]
+flyer_feed_range, 0, 4096, &feed_distance[CREATURE_FLYER]
+flyer_feed_speed, 100, 3000, &feed_speed[CREATURE_FLYER]
4 demo-decode.rb
View
@@ -171,6 +171,10 @@ def tick
when 32:
welcome = @file.read(len).delete("\n").strip
when 254:
+ if @file.compress
+ puts "This Demo is compressed twice"
+ exit(1)
+ end
@file.compress = true
when 255:
version = @file.read8
1  game.c
View
@@ -176,6 +176,7 @@ void game_init() {
lua_register(L, "get_realtime", luaGetRealtime);
lua_register(L, "set_paused", luaSetPaused);
lua_register(L, "shutdown", luaShutdown);
+ lua_register(L, "pure_game", luaCreatureConfigChanged);
lua_register_constant (L, MAXPLAYERS);
lua_register_string_constant(L, GAME_NAME);
35 hints.lua
View
@@ -0,0 +1,35 @@
+return {[[
+How can I detect a map change?
+
+Define the global function onGameStart().
+It will be called once after each a new
+map started.
+]]
+,---------------------------------------
+[[
+Did you know you can extend the available
+commands?
+
+You can redefine the global function
+onCommand(line). It will be called with
+any input typed in the client unknown to
+infon.
+]]
+,---------------------------------------
+[[
+Did you know you can load additinal into
+your vm?
+
+You can use dofile(source) to load files
+into you vm. To see a list of available
+file, call dofile_list() within your vm.
+]]
+,---------------------------------------
+[[
+By entering the values 0 upto 9 in the
+command line, you call the functions
+onInput0 upto onInput9. You might use
+them to change the strategy your bot
+uses without much typing.
+]]}
+
13 infond.c
View
@@ -78,8 +78,17 @@ int main(int argc, char *argv[]) {
server_init();
player_init();
- if (luaL_dofile(L, PREFIX "infond.lua"))
- die("cannot execute 'infond.lua': %s", lua_tostring(L, -1));
+ if (luaL_loadfile(L, PREFIX "infond.lua") != 0)
+ die("startup failed: %s", lua_tostring(L, -1));
+
+ if (!lua_checkstack(L, argc))
+ die("too many arguments?");
+
+ for (int i = 1; i < argc; i++)
+ lua_pushstring(L, argv[i]);
+
+ if (lua_pcall(L, argc - 1, 0, 0) != 0)
+ die("startup failed: %s", lua_tostring(L, -1));
// XXX: HACK: stdin client starten
#ifndef NO_CONSOLE_CLIENT
26 infond.lua
View
@@ -22,6 +22,8 @@
-- Konfiguration laden
-----------------------------------------------------------
+argv = {...}
+
config = setmetatable({}, {__index = _G})
setfenv(assert(loadfile(os.getenv("INFOND_CONFIG") or (PREFIX .. "config.lua"))), config)()
@@ -276,7 +278,6 @@ function Client:welcome(msg)
self:write(" \r\n" .. msg .. string.rep(" ", 28 - msglen) .. "\r\n")
end
-
-----------------------------------------------------------
-- Server C Callbacks
-----------------------------------------------------------
@@ -369,6 +370,19 @@ function on_game_ended()
end
end
+------------------------------------------------------------------------
+-- Creature Config Access
+------------------------------------------------------------------------
+
+creature_config = setmetatable({}, {
+ __index = function (t, val)
+ return creature_get_config(val)
+ end,
+ __newindex = function (t, name, val)
+ return creature_set_config(name, val)
+ end
+})
+
-----------------------------------------------------------
-- World Funktionen
-----------------------------------------------------------
@@ -746,15 +760,21 @@ function start_bot(options)
cprint("cannot start log writer: " .. logclient)
end
end
- assert(player_execute(playerno, nil, botsource, options.source), "cannot load bot code")
+ assert(player_execute(playerno, nil, botsource, options.source), "cannot load bot code " .. options.source)
return playerno
end
-----------------------------------------------------------
+-- Load hint file
+-----------------------------------------------------------
+
+hints = dofile(PREFIX .. "hints.lua") or {}
+
+-----------------------------------------------------------
-- Clienthandler laden
-----------------------------------------------------------
-assert(loadfile(PREFIX .. "server.lua"))()
+dofile(PREFIX .. "server.lua")
-- setup listen socket
if config.listenaddr and config.listenport then start_listener() end
21 player.c
View
@@ -481,20 +481,6 @@ static int luaCreatureGetState(lua_State *L) {
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;
-}
-
#ifdef CHEATS
static int luaCreatureCheatGiveAll(lua_State *L) {
get_player_and_creature();
@@ -677,8 +663,6 @@ player_t *player_create(const char *name, const char *pass, const char *highleve
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);
#ifdef CHEATS
lua_register_player(player, "cheat_give_all", luaCreatureCheatGiveAll);
@@ -694,6 +678,7 @@ player_t *player_create(const char *name, const char *pass, const char *highleve
lua_register(player->L, "player_exists", luaPlayerExists);
lua_register(player->L, "king_player", luaKingPlayer);
lua_register(player->L, "player_score", luaPlayerScore);
+ lua_register(player->L, "creature_get_config", luaCreatureGetConfig);
lua_register_constant(player->L, CREATURE_IDLE);
lua_register_constant(player->L, CREATURE_WALK);
@@ -1266,12 +1251,12 @@ void player_init() {
lua_register(L, "creature_get_tile_food", luaCreatureGetTileFood);
lua_register(L, "creature_get_max_food", luaCreatureGetMaxFood);
lua_register(L, "creature_get_distance", luaCreatureGetDistance);
- lua_register(L, "creature_get_hitpoints", luaCreatureGetHitpoints);
- lua_register(L, "creature_get_attack_distance", luaCreatureGetAttackDistance);
lua_register(L, "creature_get_player", luaCreatureGetPlayer);
lua_register(L, "creature_set_food", luaCreatureSetFood);
lua_register(L, "creature_set_type", luaCreatureSetType);
+ lua_register(L, "creature_get_config", luaCreatureGetConfig);
+ lua_register(L, "creature_set_config", luaCreatureSetConfig);
lua_register_constant(L, CREATURE_SMALL);
lua_register_constant(L, CREATURE_BIG);
18 player.lua
View
@@ -175,6 +175,24 @@ function exists(...)
return creature_exists(...)
end
+function get_hitpoints(...)
+ error("'get_hitpoints' is no longer available. use the values of 'creature_config' instead.", 2)
+end
+
+function get_attack_distance(...)
+ error("'get_attack_distance' is no longer available. use the values of 'creature_config' instead.", 2)
+end
+
+------------------------------------------------------------------------
+-- Creature Config Access
+------------------------------------------------------------------------
+
+creature_config = setmetatable({}, {
+ __index = function (t, val)
+ return creature_get_config(val)
+ end
+})
+
------------------------------------------------------------------------
-- Install default onCommand
------------------------------------------------------------------------
26 server.lua
View
@@ -327,6 +327,7 @@ function Client:info()
(get_realtime() and "(realtime)" or "(max speed)"))
self:writeln("time limit | " .. (config.time_limit and string.format("%ds", config.time_limit / 1000) or "none"))
self:writeln("score limit | " .. (config.score_limit or "none"))
+ self:writeln("pure game | " .. (pure_game() and "yes" or "no"))
self:writeln("-------------------------------------------------")
end
@@ -369,6 +370,19 @@ function Client:mainmenu()
end
elseif input == "info" then
self:info()
+ elseif input == "hint" then
+ if not self.hintnum then
+ self.hintnum = math.random(#hints)
+ end
+ self.hintnum = self.hintnum + 1
+ if self.hintnum > #hints then
+ self.hintnum = 1
+ end
+ self:writeln("--------------------------------------------")
+ self:writeln("Hint " .. self.hintnum .. " of " .. #hints)
+ self:writeln("--------------------------------------------")
+ self:write(hints[self.hintnum])
+ self:writeln("--------------------------------------------")
elseif input == "" then
-- nix
elseif self:get_player() then
@@ -394,11 +408,11 @@ function Client:mainmenu()
self:killmenu()
elseif input == "nk" then
self:nokick()
- elseif input == "lio" then
- self:write("limit interactive output to local connection? [Y/n] ")
- self.local_output = self:readln() ~= "n"
+ elseif input == "bio" then
+ self:write("broadcast interactive output to all connections? [y/N] ")
+ self.local_output = self:readln() ~= "y"
elseif input == "lbo" then
- self:write("limit botcode output to this connection? [y/N] ")
+ self:write("limit botcode output to local connection? [y/N] ")
local bot_output_client = self:readln() == "y" and self.fd or nil
player_set_output_client(self:get_player(), bot_output_client)
elseif input == "?" then
@@ -417,7 +431,7 @@ function Client:mainmenu()
elseif input == "??" then
self:menu_header()
self:writeln("lbo - limit bot output")
- self:writeln("lio - limit interactive output")
+ self:writeln("bio - broadcast interactive output")
self:writeln("prompt - change prompt")
if config.nokickpass then
self:writeln("nk - disable no-client kicking")
@@ -425,6 +439,7 @@ function Client:mainmenu()
self:writeln("bb - hex batch (load precompiled code)")
self:writeln("0 - 9 - execute onInputX()")
self:writeln("info - server information")
+ self:writeln("hint - shows a hint")
if self.forward_unknown then
self:writeln("")
self:writeln("Any other input will be passed to the onCommand")
@@ -457,6 +472,7 @@ function Client:mainmenu()
self:menu_header()
self:writeln("hl - choose highlevel api")
self:writeln("info - server information")
+ self:writeln("hint - shows a hint")
self:menu_footer()
else
self:writeln("huh? use '?' for help")
Please sign in to comment.
Something went wrong with that request. Please try again.