Crossfire Server, Trunk  1.75.0
main.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <time.h>
23 
24 #include "global.h"
25 #include "maze_gen.h"
26 #include "random_map.h"
27 #include "room_gen.h"
28 #include "rproto.h"
29 #include "sproto.h"
30 
31 #define LO_NEWFILE 2
32 
33 static void generate_map(char *OutFileName) {
34  /* Initialize Crossfire library. */
35  init_globals();
36  settings.debug = llevWarn; // suppress asset loading message
37  init_library();
38  init_readable();
39  init_gods();
40 
41  /* Initialize parameters and set initial settings. */
42  RMParms rp;
43  memset(&rp, 0, sizeof(RMParms));
44  rp.Xsize = -1;
45  rp.Ysize = -1;
46 
47  load_parameters(stdin, LO_NEWFILE, &rp);
48  fclose(stdin);
49 
50  mapstruct *newMap = generate_random_map(OutFileName, &rp, NULL, NULL);
51  FILE *fp;
52  if (strcmp(OutFileName, "-") == 0) {
53  fp = stdout;
54  } else {
55  fp = fopen(OutFileName, "w");
56  if (fp == NULL) {
57  perror("failed to open output file");
58  return;
59  }
60  }
61  save_map_to_stream(newMap, SAVE_MODE_NORMAL, fp, fp);
62  fclose(fp);
63 }
64 
68 static void print_map(char **layout, int width, int height) {
69  int i, j;
70 
71  for (j = 0; j < height; ++j) {
72  for (i = 0; i < width; ++i) {
73  char display_char;
74  display_char = layout[i][j];
75 
76  switch (display_char) {
77  case 0:
78  display_char = '.';
79  break;
80  case 'D':
81  display_char = '+';
82  break;
83  }
84 
85  putchar(display_char);
86  }
87 
88  putchar('\n');
89  }
90 }
91 
92 struct layout {
93  const char *name;
94  char **(*func)(int, int, int, int);
95 };
96 
98  // Most of these need to be cast to silence warnings.
99  // The fourth paramter (and sometimes the third) is ignored in most cases.
100  // xsize,ysize,option,layers
101  { "rogue", &roguelike_layout_gen },
102  { "snake", &make_snake_layout },
103  { "sspiral", &make_square_spiral_layout },
104  { "spiral", &map_gen_spiral },
105  { "maze", &maze_gen },
106  { "onion", &map_gen_onion },
107  { "crawl", &map_gen_crawl }
108 };
109 
122 static void test_layout(int width, int height, char **(*layout_func)(int, int, int, int)) {
123  char **layout;
124  SRANDOM(time(0));
125 
126  // Bail if no layout -- shouldn't occur, but just to be safe
127  if (layout_func == NULL)
128  return;
129 
130  layout = layout_func(width, height, 0, 0);
131 
132  print_map(layout, width, height);
133  free(layout);
134 }
135 
137 static void print_quickhelp(void) {
138  fprintf(stderr, "Type 'random_map -h' for usage instructions.\n");
139 }
140 
142 static void print_usage(void) {
143  printf(
144  "Usage: random_map [options]\n"
145  "\n"
146  "Options:\n"
147  " -h display this help message\n"
148  " -t [-l LAYOUT] [-x WIDTH] [-y HEIGHT]\n"
149  " Test the given map layout\n"
150  " -g FILE Read parameters from stdin and generate random map to FILE.\n"
151  " If FILE is '-' then use stdout.\n"
152  "\n"
153  "Layouts:\n"
154  " rogue -- roguelike map generator\n"
155  " snake -- snake map generator\n"
156  " sspiral -- square spiral map generator\n"
157  " spiral -- spiral map generator\n"
158  " maze -- maze map generator\n"
159  " onion -- onion map generator\n"
160  " crawl -- another maze map generator\n"
161  );
162 }
163 
164 int main(int argc, char *argv[]) {
165  int flag, mode = 0, width = 80, height = 23;
166  char *filename_out=NULL;
167  // Make default behavior be roguelike generation, like old behavior
168  // NOTE: The ugly function pointer cast silences compiler warnings.
169  char **(*func)(int, int, int, int) = (char **(*)(int, int, int, int))&roguelike_layout_gen;
170 
171  /* Parse command-line arguments. */
172  while ((flag = getopt(argc, argv, "g:hl:tx:y:")) != -1) {
173  switch (flag) {
174  case 'g':
175  mode = 2;
176  filename_out = optarg;
177  break;
178  case 'h':
179  print_usage();
180  exit(EXIT_SUCCESS);
181  break;
182  case 'l':
183  for (int i = 0; i < NROFLAYOUTS; ++i)
184  {
185  if (strcmp(optarg, layout_list[i].name) == 0)
186  func = layout_list[i].func;
187  }
188  break;
189  case 't':
190  mode = 1;
191  break;
192  case 'x':
193  width = atoi(optarg);
194  break;
195  case 'y':
196  height = atoi(optarg);
197  break;
198  case '?':
199  print_quickhelp();
200  exit(EXIT_FAILURE);
201  break;
202  }
203  }
204 
205  if (mode == 1) {
206  test_layout(width, height, func);
207  exit(EXIT_SUCCESS);
208  } else if (mode == 2) {
209  generate_map(filename_out);
210  exit(EXIT_SUCCESS);
211  } else {
212  print_quickhelp();
213  exit(EXIT_FAILURE);
214  }
215 }
216 
217 /* some plagarized code from apply.c--I needed just these two functions
218 without all the rest of the junk, so.... */
219 int apply_auto(object *op)
220 {
221  object *tmp = NULL;
222  int i;
223 
224  switch (op->type) {
225  case SHOP_FLOOR:
226  if (!HAS_RANDOM_ITEMS(op)) {
227  return 0;
228  }
229  do {
230  i = 10; /* let's give it 10 tries */
231  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? op->stats.exp : 5)) == NULL && --i)
232  ;
233  if (tmp == NULL) {
234  return 0;
235  }
236  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) {
238  tmp = NULL;
239  }
240  } while (!tmp);
241 
242  SET_FLAG(tmp, FLAG_UNPAID);
243  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
245  tmp = identify(tmp);
246  break;
247 
248  case TREASURE:
249  if (HAS_RANDOM_ITEMS(op))
250  while ((op->stats.hp--) > 0) {
251  create_treasure(op->randomitems, op, GT_ENVIRONMENT, op->stats.exp ? op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
252  }
253  object_remove(op);
255  break;
256  }
257 
258  return tmp ? 1 : 0;
259 }
260 
261 /* apply_auto_fix goes through the entire map (only the first time
262  * when an original map is loaded) and performs special actions for
263  * certain objects (most initialization of chests and creation of
264  * treasures and stuff). Calls apply_auto if appropriate.
265  */
267 {
268  int x, y;
269 
270  for (x = 0; x < MAP_WIDTH(m); x++)
271  for (y = 0; y < MAP_HEIGHT(m); y++)
272  FOR_MAP_PREPARE(m, x, y, tmp) {
273  if (QUERY_FLAG(tmp, FLAG_AUTO_APPLY)) {
274  apply_auto(tmp);
275  } else if (tmp->type == TREASURE) {
276  if (HAS_RANDOM_ITEMS(tmp))
277  while ((tmp->stats.hp--) > 0) {
278  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
279  }
280  }
281  if (tmp && tmp->arch
282  && tmp->type != PLAYER
283  && tmp->type != TREASURE
284  && tmp->randomitems) {
285  if (tmp->type == CONTAINER) {
286  if (HAS_RANDOM_ITEMS(tmp))
287  while ((tmp->stats.hp--) > 0) {
288  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
289  }
290  } else if (HAS_RANDOM_ITEMS(tmp)) {
291  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
292  }
293  }
294  }
295  FOR_MAP_FINISH();
296  for (x = 0; x < MAP_WIDTH(m); x++)
297  for (y = 0; y < MAP_HEIGHT(m); y++)
298  FOR_MAP_PREPARE(m, x, y, tmp) {
299  if (tmp->above
300  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) {
301  check_trigger(tmp, tmp->above);
302  }
303  }
304  FOR_MAP_FINISH();
305 }
306 
307 /*
308  * The following dummy variables are only used to resolve symbols at compile
309  * time. They don't actually do anything useful.
310  */
311 
312 void set_map_timeout(mapstruct *oldmap) {
313  (void)oldmap;
314 }
315 
316 void draw_ext_info(int flags, int pri, const object *pl, uint8_t type,
317  uint8_t subtype, const char *message) {
318  (void)flags;
319  (void)pri;
320  (void)pl;
321  (void)type;
322  (void)subtype;
323  fprintf(logfile, "%s\n", message);
324 }
325 
326 void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type,
327  uint8_t subtype, const char *format, ...) {
328  va_list ap;
329 
330  (void)flags;
331  (void)pri;
332  (void)pl;
333  (void)type;
334  (void)subtype;
335 
336  va_start(ap, format);
337  vfprintf(logfile, format, ap);
338  va_end(ap);
339 }
340 
341 
342 void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype,
343  const char *str1) {
344  (void)color;
345  (void)map;
346  (void)type;
347  (void)subtype;
348  fprintf(logfile, "ext_info_map: %s\n", str1);
349 }
350 
351 void move_firewall(object *ob) {
352  (void)ob;
353 }
354 
355 void emergency_save(int x) {
356  (void)x;
357 }
358 
359 void clean_tmp_files(void) {
360 }
361 
362 void esrv_send_item(object *ob, object *obx) {
363  (void)ob;
364  (void)obx;
365 }
366 
367 void esrv_update_item(int flags, object *pl, object *op) {
368  (void)flags;
369  (void)pl;
370  (void)op;
371 }
372 
373 void dragon_ability_gain(object *ob, int x, int y) {
374  (void)ob;
375  (void)x;
376  (void)y;
377 }
378 
380  (void)m;
381 }
382 
383 int players_on_map(mapstruct *m, int show_all) {
384  (void)m;
385  (void)show_all;
386  return 0;
387 }
388 
389 object *find_skill_by_number(object *who, int skillno) {
390  (void)who;
391  (void)skillno;
392  return NULL;
393 }
394 
395 void esrv_del_item(player *pl, object *ob) {
396  (void)pl;
397  (void)ob;
398 }
399 
401  (void)pl;
402 }
403 
404 void rod_adjust(object *rod) {
405  (void)rod;
406 }
map_gen_onion
char ** map_gen_onion(int xsize, int ysize, int option, int layers)
Generates an onion layout.
Definition: room_gen_onion.cpp:70
init_globals
void init_globals(void)
Initialises all global variables.
Definition: init.cpp:382
living::exp
int64_t exp
Experience.
Definition: living.h:47
HAS_RANDOM_ITEMS
#define HAS_RANDOM_ITEMS(op)
This return TRUE if object has still randomitems which could be expanded.
Definition: define.h:184
PLAYER
@ PLAYER
Definition: object.h:112
players_on_map
int players_on_map(mapstruct *m, int show_all)
Definition: main.cpp:383
layout::func
char **(* func)(int, int, int, int)
Definition: main.cpp:94
global.h
settings
struct Settings settings
Global settings.
Definition: init.cpp:139
apply_auto
int apply_auto(object *op)
Definition: main.cpp:219
random_map.h
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
Definition: define.h:714
roguelike_layout_gen
char ** roguelike_layout_gen(int xsize, int ysize, int options, int _unused_layers)
Actually make the rogue layout.
Definition: rogue_layout.cpp:309
save_map_to_stream
int save_map_to_stream(mapstruct *m, int flag, FILE *fp, FILE *fp2)
Save map to stream.
Definition: map.cpp:1376
layout
Definition: main.cpp:92
mapstruct::difficulty
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:337
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:369
player
One player.
Definition: player.h:107
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:371
TRIGGER_PEDESTAL
@ TRIGGER_PEDESTAL
Definition: object.h:139
print_usage
static void print_usage(void)
Print out usage information.
Definition: main.cpp:142
time
same as sound ncom command like but with extra the client want tick commands so it knows animation timing the client wants to be informed of pickup mode changes Mode will be sent when the player successfully logs and afterward any time the value is but over time
Definition: protocol.txt:416
SHOP_FLOOR
@ SHOP_FLOOR
Definition: object.h:188
object::x
int16_t x
Definition: object.h:335
RMParms::Ysize
int Ysize
Definition: random_map.h:75
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Generate a treasure from a list generating a single item.
Definition: treasure.cpp:322
SRANDOM
#define SRANDOM(seed)
Definition: define.h:629
make_square_spiral_layout
char ** make_square_spiral_layout(int xsize, int ysize, int _unused_options, int _unused_layers)
Generates a square-spiral layout.
Definition: square_spiral.cpp:80
room_gen.h
TREASURE
@ TREASURE
Definition: object.h:115
maze_gen
char ** maze_gen(int xsize, int ysize, int option, int _unused_layers)
This function generates a random blocked maze with the property that there is only one path from one ...
Definition: maze_gen.cpp:59
flags
static const flag_definition flags[]
Flag mapping.
Definition: gridarta-types-convert.cpp:101
llevWarn
@ llevWarn
Warnings or major code issues.
Definition: logger.h:12
generate_random_map
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout, sstring reset_group)
Main random map routine.
Definition: random_map.cpp:75
test_layout
static void test_layout(int width, int height, char **(*layout_func)(int, int, int, int))
Test the map layout produced by the specified generator.
Definition: main.cpp:122
maze_gen.h
TRIGGER_BUTTON
@ TRIGGER_BUTTON
Definition: object.h:137
FLAG_CURSED
#define FLAG_CURSED
The object is cursed.
Definition: define.h:303
map_gen_spiral
char ** map_gen_spiral(int xsize, int ysize, int option, int _unused_layers)
Generates a spiral layout.
Definition: room_gen_spiral.cpp:62
esrv_update_spells
void esrv_update_spells(player *pl)
Definition: main.cpp:400
RMParms
Random map parameters.
Definition: random_map.h:14
set_map_timeout
void set_map_timeout(mapstruct *oldmap)
Definition: main.cpp:312
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
set_darkness_map
void set_darkness_map(mapstruct *m)
Definition: main.cpp:379
esrv_del_item
void esrv_del_item(player *pl, object *ob)
Definition: main.cpp:395
init_gods
void init_gods(void)
This takes a look at all of the archetypes to find the objects which correspond to the GODS (type GOD...
Definition: holy.cpp:59
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
m
static event_registration m
Definition: citylife.cpp:424
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1545
load_parameters
int load_parameters(FILE *fp, int bufstate, RMParms *RP)
Definition: reader.cpp:2492
Settings::debug
LogLevel debug
Default debugging level.
Definition: global.h:248
ext_info_map
void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
Definition: main.cpp:342
LO_NEWFILE
#define LO_NEWFILE
Definition: main.cpp:31
FLAG_UNPAID
#define FLAG_UNPAID
Object hasn't been paid for yet.
Definition: define.h:223
layout_list
static layout layout_list[NROFLAYOUTS]
Definition: main.cpp:97
layout::name
const char * name
Definition: main.cpp:93
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.cpp:326
rod_adjust
void rod_adjust(object *rod)
Definition: main.cpp:404
CONTAINER
@ CONTAINER
Definition: object.h:236
init_readable
void init_readable(void)
Initialize linked lists utilized by message functions in tailor_readable_ob()
Definition: readable.cpp:904
move_firewall
void move_firewall(object *ob)
Definition: main.cpp:351
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
message
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your message
Definition: survival-guide.txt:34
apply_auto_fix
void apply_auto_fix(mapstruct *m)
Definition: main.cpp:266
emergency_save
void emergency_save(int x)
Definition: main.cpp:355
rproto.h
sproto.h
logfile
FILE * logfile
Used by server/daemon.c.
Definition: init.cpp:114
GT_ENVIRONMENT
@ GT_ENVIRONMENT
?
Definition: treasure.h:31
map_gen_crawl
char ** map_gen_crawl(int xsize, int ysize, int iter, int hallway)
Generator of the crawl maze.
Definition: room_gen_crawl.cpp:145
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.cpp:2085
SAVE_MODE_NORMAL
#define SAVE_MODE_NORMAL
No special handling.
Definition: map.h:121
esrv_update_item
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.cpp:367
MAP_WIDTH
#define MAP_WIDTH(m)
Map width.
Definition: map.h:76
esrv_send_item
void esrv_send_item(object *ob, object *obx)
Definition: main.cpp:362
FLAG_DAMNED
#define FLAG_DAMNED
The object is very cursed.
Definition: define.h:304
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
Definition: define.h:707
dragon_ability_gain
void dragon_ability_gain(object *ob, int x, int y)
Definition: main.cpp:373
check_trigger
int check_trigger(object *op, object *cause)
Definition: button.cpp:519
print_map
static void print_map(char **layout, int width, int height)
Print the human-readable layout of a map.
Definition: main.cpp:68
init_library
void init_library(void)
It is vital that init_library() is called by any functions using this library.
Definition: init.cpp:312
find_skill_by_number
object * find_skill_by_number(object *who, int skillno)
Definition: main.cpp:389
main
int main(int argc, char *argv[])
Definition: main.cpp:164
mapstruct
This is a game-map.
Definition: map.h:320
FLAG_AUTO_APPLY
#define FLAG_AUTO_APPLY
Will be applied when created.
Definition: define.h:237
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:370
MAP_HEIGHT
#define MAP_HEIGHT(m)
Map height.
Definition: map.h:78
make_snake_layout
char ** make_snake_layout(int xsize, int ysize, int _unused_options, int _unused_layers)
Generate a snake-like layout.
Definition: snake.cpp:36
object::randomitems
struct treasurelist * randomitems
Items to be generated.
Definition: object.h:395
object_remove
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to.
Definition: object.cpp:1818
clean_tmp_files
void clean_tmp_files(void)
Definition: main.cpp:359
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.cpp:316
object::stats
living stats
Str, Con, Dex, etc.
Definition: object.h:378
NROFLAYOUTS
#define NROFLAYOUTS
Definition: random_map.h:120
generate_map
static void generate_map(char *OutFileName)
Definition: main.cpp:33
RMParms::Xsize
int Xsize
Definition: random_map.h:74
living::hp
int16_t hp
Hit Points.
Definition: living.h:40
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
This calls the appropriate treasure creation function.
Definition: treasure.cpp:290
print_quickhelp
static void print_quickhelp(void)
Print a message stating how to get help.
Definition: main.cpp:137
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
identify
object * identify(object *op)
Identifies an item.
Definition: item.cpp:1443