Lua: remove dgn_comp, use lua instead
This commit is contained in:
143
dat/dungeon.def
143
dat/dungeon.def
@@ -1,143 +0,0 @@
|
||||
# NetHack 3.6 dungeon.def $NHDT-Date: 1462486876 2016/05/05 22:21:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.14 $
|
||||
# Copyright (c) 1990-95 by M. Stephenson
|
||||
# NetHack may be freely redistributed. See license for details.
|
||||
#
|
||||
# The dungeon description file for the "standard" 3.1 NetHack.
|
||||
#
|
||||
# Note: The order of the definition of dungeons in this file
|
||||
# reflects in their order of creation in the real dungeon.
|
||||
# The "Main" branch must *always* be first.
|
||||
# Also note that the order of the dungeons in this file
|
||||
# determines the order in which branch levels are assigned.
|
||||
# If two dungeons have overlapping ranges for their entry
|
||||
# points, then you should list the dungeon with the _least_
|
||||
# number of choices for its branch level _first_.
|
||||
#
|
||||
|
||||
DUNGEON: "The Dungeons of Doom" "D" (25, 5)
|
||||
ALIGNMENT: unaligned
|
||||
BRANCH: "The Gnomish Mines" @ (2, 3)
|
||||
LEVEL: "rogue" "R" @ (15, 4)
|
||||
LEVELDESC: roguelike
|
||||
LEVEL: "oracle" "O" @ (5, 5)
|
||||
LEVALIGN: neutral
|
||||
CHAINBRANCH: "Sokoban" "oracle" + (1, 0) up
|
||||
RNDLEVEL: "bigrm" "B" @ (10, 3) 40 10
|
||||
CHAINBRANCH: "The Quest" "oracle" + (6, 2) portal
|
||||
BRANCH: "Fort Ludios" @ (18, 4) portal
|
||||
RNDLEVEL: "medusa" "none" @ (-5, 4) 4
|
||||
LEVALIGN: chaotic
|
||||
LEVEL: "castle" "none" @ (-1, 0)
|
||||
CHAINBRANCH: "Gehennom" "castle" + (0, 0) no_down
|
||||
BRANCH: "The Elemental Planes" @ (1, 0) no_down up
|
||||
|
||||
#
|
||||
# Gehennom
|
||||
#
|
||||
# Now re-worked for 3.1, hell is hopefully going to be a little
|
||||
# less boring. Also, in 3.1, the tower is not considered as a
|
||||
# part of hell, but is set up as a separate dungeon.
|
||||
#
|
||||
# Gehennom is no longer considered "hellish" as a complete dungeon.
|
||||
# That is, fire resistance is no longer a condition for survival in
|
||||
# it. However, Gehennom, and the special levels in it in particular,
|
||||
# is abundant with fire traps. As a result, fire resistance is still
|
||||
# a prudent survival strategy in Gehennom.
|
||||
#
|
||||
# Note: Gehennom *must* be the second dungeon defined so that
|
||||
# monsters can properly migrate here under certain
|
||||
# circumstances.
|
||||
#
|
||||
DUNGEON: "Gehennom" "G" (20, 5)
|
||||
DESCRIPTION: mazelike
|
||||
DESCRIPTION: hellish
|
||||
ALIGNMENT: noalign
|
||||
BRANCH: "Vlad's Tower" @ (9, 5) up
|
||||
LEVEL: "valley" "V" @ (1, 0)
|
||||
LEVEL: "sanctum" "none" @ (-1, 0)
|
||||
LEVEL: "juiblex" "J" @ (4, 4)
|
||||
LEVEL: "baalz" "B" @ (6, 4)
|
||||
LEVEL: "asmodeus" "A" @ (2, 6)
|
||||
LEVEL: "wizard1" "none" @ (11, 6)
|
||||
CHAINLEVEL: "wizard2" "X" "wizard1" + (1, 0)
|
||||
CHAINLEVEL: "wizard3" "Y" "wizard1" + (2, 0)
|
||||
LEVEL: "orcus" "O" @ (10, 6)
|
||||
LEVEL: "fakewiz1" "F" @ (-6,4)
|
||||
LEVEL: "fakewiz2" "G" @ (-6,4)
|
||||
|
||||
#
|
||||
# The Mines of the Gnomes of Zurich.
|
||||
#
|
||||
DUNGEON: "The Gnomish Mines" "M" (8, 2)
|
||||
ALIGNMENT: lawful
|
||||
DESCRIPTION: mazelike
|
||||
RNDLEVEL: "minetn" "T" @ (3, 2) 7
|
||||
LEVELDESC: town
|
||||
RNDLEVEL: "minend" "E" @ (-1, 0) 3
|
||||
|
||||
#
|
||||
# The Questdungeon
|
||||
#
|
||||
# This is a proto-dungeon. The level file names will be prepended with
|
||||
# three letter role abbreviation during initialization, replacing "x".
|
||||
# A special "x-fill" level must be defined in the levels description
|
||||
# file. It will be used for all levels not defined explicitly below.
|
||||
#
|
||||
DUNGEON: "The Quest" "Q" (5, 2)
|
||||
LEVEL: "x-strt" "none" @ (1, 1)
|
||||
LEVEL: "x-loca" "L" @ (3, 1)
|
||||
LEVEL: "x-goal" "none" @ (-1, 0)
|
||||
|
||||
#
|
||||
# Sokoban
|
||||
#
|
||||
DUNGEON: "Sokoban" "none" (4, 0)
|
||||
DESCRIPTION: mazelike
|
||||
ALIGNMENT: neutral
|
||||
ENTRY: -1
|
||||
RNDLEVEL: "soko1" "none" @ (1, 0) 2
|
||||
RNDLEVEL: "soko2" "none" @ (2, 0) 2
|
||||
RNDLEVEL: "soko3" "none" @ (3, 0) 2
|
||||
RNDLEVEL: "soko4" "none" @ (4, 0) 2
|
||||
|
||||
#
|
||||
# The Central Vault of Croesus.
|
||||
#
|
||||
DUNGEON: "Fort Ludios" "K" (1, 0)
|
||||
DESCRIPTION: mazelike
|
||||
ALIGNMENT: unaligned
|
||||
LEVEL: "knox" "K" @ (-1, 0)
|
||||
#
|
||||
# Vlad's Tower
|
||||
#
|
||||
# It has been removed from Gehennom, and it is surrounded by stone.
|
||||
# Must not allow bones files for its top level.
|
||||
#
|
||||
DUNGEON: "Vlad's Tower" "T" (3, 0)
|
||||
PROTOFILE: "tower"
|
||||
DESCRIPTION: mazelike
|
||||
ALIGNMENT: chaotic
|
||||
ENTRY: -1
|
||||
LEVEL: "tower1" "none" @ (1, 0)
|
||||
# it isn't necessary to list these last two, but doing so makes them
|
||||
# show up in ^O output and in the level teleport menu
|
||||
LEVEL: "tower2" "none" @ (2, 0)
|
||||
LEVEL: "tower3" "none" @ (3, 0)
|
||||
|
||||
#
|
||||
# The Endgame levels
|
||||
#
|
||||
# Enter on 2nd level from bottom; 1st (from bottom) is a
|
||||
# placeholder for surface level, and should be unreachable.
|
||||
# [Note: the name "dummy" is checked for in init_dungeons().]
|
||||
#
|
||||
DUNGEON: "The Elemental Planes" "E" (6, 0)
|
||||
DESCRIPTION: mazelike
|
||||
ALIGNMENT: unaligned
|
||||
ENTRY: -2
|
||||
LEVEL: "astral" "none" @ (1, 0)
|
||||
LEVEL: "water" "none" @ (2, 0)
|
||||
LEVEL: "fire" "none" @ (3, 0)
|
||||
LEVEL: "air" "none" @ (4, 0)
|
||||
LEVEL: "earth" "none" @ (5, 0)
|
||||
LEVEL: "dummy" "none" @ (6, 0)
|
||||
310
dat/dungeon.lua
Normal file
310
dat/dungeon.lua
Normal file
@@ -0,0 +1,310 @@
|
||||
|
||||
dungeon = {
|
||||
{
|
||||
name = "The Dungeons of Doom",
|
||||
bonetag = "D",
|
||||
base = 25,
|
||||
range = 5,
|
||||
alignment = "unaligned",
|
||||
branches = {
|
||||
{
|
||||
name = "The Gnomish Mines",
|
||||
base = 2,
|
||||
range = 3
|
||||
},
|
||||
{
|
||||
name = "Sokoban",
|
||||
chainlevel = "oracle",
|
||||
base = 1,
|
||||
direction = "up"
|
||||
},
|
||||
{
|
||||
name = "The Quest",
|
||||
chainlevel = "oracle",
|
||||
base = 6,
|
||||
range = 2,
|
||||
branchtype = "portal"
|
||||
},
|
||||
{
|
||||
name = "Fort Ludios",
|
||||
base = 18,
|
||||
range = 4,
|
||||
branchtype = "portal"
|
||||
},
|
||||
{
|
||||
name = "Gehennom",
|
||||
chainlevel = "castle",
|
||||
base = 0,
|
||||
branchtype = "no_down"
|
||||
},
|
||||
{
|
||||
name = "The Elemental Planes",
|
||||
base = 1,
|
||||
branchtype = "no_down",
|
||||
direction = "up"
|
||||
}
|
||||
},
|
||||
levels = {
|
||||
{
|
||||
name = "rogue",
|
||||
bonetag = "R",
|
||||
base = 15,
|
||||
range = 4,
|
||||
flags = "roguelike",
|
||||
},
|
||||
{
|
||||
name = "oracle",
|
||||
bonetag = "O",
|
||||
base = 5,
|
||||
range = 5,
|
||||
alignment = "neutral"
|
||||
},
|
||||
{
|
||||
name = "bigrm",
|
||||
bonetag = "B",
|
||||
base = 10,
|
||||
range = 3,
|
||||
chance = 40,
|
||||
nlevels = 10
|
||||
},
|
||||
{
|
||||
name = "medusa",
|
||||
base = -5,
|
||||
range = 4,
|
||||
nlevels = 4,
|
||||
alignment = "chaotic"
|
||||
},
|
||||
{
|
||||
name = "castle",
|
||||
base = -1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "Gehennom",
|
||||
bonetag = "G",
|
||||
base = 20,
|
||||
range = 5,
|
||||
flags = { "mazelike", "hellish" },
|
||||
alignment = "noalign",
|
||||
branches = {
|
||||
{
|
||||
name = "Vlad's Tower",
|
||||
base = 9,
|
||||
range = 5,
|
||||
direction = "up"
|
||||
}
|
||||
},
|
||||
levels = {
|
||||
{
|
||||
name = "valley",
|
||||
bonetag = "V",
|
||||
base = 1
|
||||
},
|
||||
{
|
||||
name = "sanctum",
|
||||
base = -1
|
||||
},
|
||||
{
|
||||
name = "juiblex",
|
||||
bonetag = "J",
|
||||
base = 4,
|
||||
range = 4
|
||||
},
|
||||
{
|
||||
name = "baalz",
|
||||
bonetag = "B",
|
||||
base = 6,
|
||||
range = 4
|
||||
},
|
||||
{
|
||||
name = "asmodeus",
|
||||
bonetag = "A",
|
||||
base = 2,
|
||||
range = 6
|
||||
},
|
||||
{
|
||||
name = "wizard1",
|
||||
base = 11,
|
||||
range = 6
|
||||
},
|
||||
{
|
||||
name = "wizard2",
|
||||
bonetag = "X",
|
||||
chainlevel = "wizard1",
|
||||
base = 1
|
||||
},
|
||||
{
|
||||
name = "wizard3",
|
||||
bonetag = "Y",
|
||||
chainlevel = "wizard1",
|
||||
base = 2
|
||||
},
|
||||
{
|
||||
name = "orcus",
|
||||
bonetag = "O",
|
||||
base = 10,
|
||||
range = 6
|
||||
},
|
||||
{
|
||||
name = "fakewiz1",
|
||||
bonetag = "F",
|
||||
base = -6,
|
||||
range = 4
|
||||
},
|
||||
{
|
||||
name = "fakewiz2",
|
||||
bonetag = "G",
|
||||
base = -6,
|
||||
range = 4
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "The Gnomish Mines",
|
||||
bonetag = "M",
|
||||
base = 8,
|
||||
range = 2,
|
||||
alignment = "lawful",
|
||||
flags = { "mazelike" },
|
||||
levels = {
|
||||
{
|
||||
name = "minetn",
|
||||
bonetag = "T",
|
||||
base = 3,
|
||||
range = 2,
|
||||
nlevels = 7,
|
||||
flags = "town"
|
||||
},
|
||||
{
|
||||
name = "minend",
|
||||
bonetag = "E",
|
||||
base = -1,
|
||||
nlevels = 3
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "The Quest",
|
||||
bonetag = "Q",
|
||||
base = 5,
|
||||
range = 2,
|
||||
levels = {
|
||||
{
|
||||
name = "x-strt",
|
||||
base = 1,
|
||||
range = 1
|
||||
},
|
||||
{
|
||||
name = "x-loca",
|
||||
bonetag = "L",
|
||||
base = 3,
|
||||
range = 1
|
||||
},
|
||||
{
|
||||
name = "x-goal",
|
||||
base = -1
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "Sokoban",
|
||||
base = 4,
|
||||
alignment = "neutral",
|
||||
flags = { "mazelike" },
|
||||
entry = -1,
|
||||
levels = {
|
||||
{
|
||||
name = "soko1",
|
||||
base = 1,
|
||||
nlevels = 2
|
||||
},
|
||||
{
|
||||
name = "soko2",
|
||||
base = 2,
|
||||
nlevels = 2
|
||||
},
|
||||
{
|
||||
name = "soko3",
|
||||
base = 3,
|
||||
nlevels = 2
|
||||
},
|
||||
{
|
||||
name = "soko4",
|
||||
base = 4,
|
||||
nlevels = 2
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "Fort Ludios",
|
||||
base = 1,
|
||||
bonetag = "K",
|
||||
flags = { "mazelike" },
|
||||
alignment = "unaligned",
|
||||
levels = {
|
||||
{
|
||||
name = "knox",
|
||||
bonetag = "K",
|
||||
base = -1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "Vlad's Tower",
|
||||
base = 3,
|
||||
bonetag = "T",
|
||||
protofile = "tower",
|
||||
alignment = "chaotic",
|
||||
flags = { "mazelike" },
|
||||
entry = -1,
|
||||
levels = {
|
||||
{
|
||||
name = "tower1",
|
||||
base = 1
|
||||
},
|
||||
{
|
||||
name = "tower2",
|
||||
base = 2
|
||||
},
|
||||
{
|
||||
name = "tower3",
|
||||
base = 3
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "The Elemental Planes",
|
||||
bonetag = "E",
|
||||
base = 6,
|
||||
alignment = "unaligned",
|
||||
flags = { "mazelike" },
|
||||
entry = -2,
|
||||
levels = {
|
||||
{
|
||||
name = "astral",
|
||||
base = 1
|
||||
},
|
||||
{
|
||||
name = "water",
|
||||
base = 2
|
||||
},
|
||||
{
|
||||
name = "fire",
|
||||
base = 3
|
||||
},
|
||||
{
|
||||
name = "air",
|
||||
base = 4
|
||||
},
|
||||
{
|
||||
name = "earth",
|
||||
base = 5
|
||||
},
|
||||
{
|
||||
name = "dummy",
|
||||
base = 6
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
419
doc/dgn_comp.6
419
doc/dgn_comp.6
@@ -1,419 +0,0 @@
|
||||
.TH DGN_COMP 6 "25 May 2015" NETHACK
|
||||
.de ND
|
||||
.ds Nd \\$3
|
||||
..
|
||||
.de NB
|
||||
.ds Nb \\$2
|
||||
..
|
||||
.de NR
|
||||
.ds Nr \\$2
|
||||
..
|
||||
.ND $NHDT-Date: 1524689548 2018/04/25 20:52:28 $
|
||||
.NB $NHDT-Branch: NetHack-3.6.0 $
|
||||
.NR $NHDT-Revision: 1.6 $
|
||||
.ds Na Kenneth Lorber
|
||||
|
||||
.SH NAME
|
||||
dgn_comp \- NetHack dungeon compiler
|
||||
.SH SYNOPSIS
|
||||
.B dgn_comp
|
||||
[
|
||||
.I file
|
||||
]
|
||||
.PP
|
||||
If no arguments are given, it reads standard input.
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.I Dgn_comp
|
||||
is a dungeon compiler for NetHack version 3.2 and higher. It
|
||||
takes a description file as an argument and produces a dungeon "script"
|
||||
that is to be loaded by NetHack at runtime.
|
||||
.PP
|
||||
The purpose of this tool is to provide NetHack administrators and
|
||||
implementors with a convenient way to create a custom dungeon for the
|
||||
game, without having to recompile the entire world.
|
||||
.SH GRAMMAR
|
||||
.PP
|
||||
DUNGEON:
|
||||
.B name
|
||||
.B bonesmarker
|
||||
(
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) [
|
||||
.B %age
|
||||
]
|
||||
.PP
|
||||
where
|
||||
.B name
|
||||
is the dungeon name,
|
||||
.B bonesmarker
|
||||
is a letter for marking bones files, (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) is the number of levels, and
|
||||
.B %age
|
||||
is its percentage chance of being generated (if absent, 100% chance).
|
||||
|
||||
DESCRIPTION:
|
||||
.B tag
|
||||
.PP
|
||||
where
|
||||
.B tag
|
||||
is currently one of
|
||||
.BR HELLISH ,
|
||||
.BR MAZELIKE ,
|
||||
or
|
||||
.BR ROGUELIKE .
|
||||
|
||||
ALIGNMENT | LEVALIGN: [
|
||||
.B lawful
|
||||
|
|
||||
.B neutral
|
||||
|
|
||||
.B chaotic
|
||||
|
|
||||
.B unaligned
|
||||
]
|
||||
.PP
|
||||
gives the alignment of the dungeon/level (default is unaligned).
|
||||
|
||||
ENTRY:
|
||||
.B level
|
||||
.PP
|
||||
the dungeon entry point. The dungeon connection attaches at this
|
||||
level of the given dungeon.
|
||||
If the value of
|
||||
.B level
|
||||
is negative, the entry level is calculated from the bottom of the
|
||||
dungeon, with -1 being the last level.
|
||||
If this line is not present in a dungeon description, the entry level
|
||||
defaults to 1.
|
||||
|
||||
PROTOFILE:
|
||||
.B name
|
||||
.PP
|
||||
the prototypical name for dungeon level files in this dungeon.
|
||||
For example, the PROTOFILE name for the dungeon
|
||||
.I Vlad's Tower
|
||||
is
|
||||
.IR tower .
|
||||
|
||||
LEVEL:
|
||||
.B name
|
||||
.B bonesmarker
|
||||
@ (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) [
|
||||
.B %age
|
||||
]
|
||||
.PP
|
||||
where
|
||||
.B name
|
||||
is the level name,
|
||||
.B bonesmarker
|
||||
is a letter for marking bones files, (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) is the location and
|
||||
.B %age
|
||||
is the generation percentage, as above.
|
||||
|
||||
RNDLEVEL:
|
||||
.B name
|
||||
.B bonesmarker
|
||||
@ (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
)
|
||||
[
|
||||
.B %age
|
||||
]
|
||||
.B rndlevs
|
||||
.PP
|
||||
where
|
||||
.B name
|
||||
is the level name,
|
||||
.B bonesmarker
|
||||
is a letter for marking bones files, (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) is the location,
|
||||
.B %age
|
||||
is the generation percentage, as above, and
|
||||
.B rndlevs
|
||||
is the number of similar levels available to choose from.
|
||||
|
||||
CHAINLEVEL:
|
||||
.B name
|
||||
.B bonesmarker
|
||||
.B prev_name
|
||||
+ (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) [
|
||||
.B %age
|
||||
]
|
||||
.PP
|
||||
where
|
||||
.B name
|
||||
is the level name,
|
||||
.B bonesmarker
|
||||
is a letter for marking bones files,
|
||||
.B prev_name
|
||||
is the name of a level defined previously, (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) is the
|
||||
.I offset
|
||||
from the level being chained from, and
|
||||
.B %age
|
||||
is the generation percentage.
|
||||
|
||||
RNDCHAINLEVEL:
|
||||
.B name
|
||||
.B bonesmarker
|
||||
.B prev_name
|
||||
+ (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) [
|
||||
.B %age
|
||||
]
|
||||
.B rndlevs
|
||||
.PP
|
||||
where
|
||||
.B name
|
||||
is the level name,
|
||||
.B bonesmarker
|
||||
is a letter for marking bones files,
|
||||
.B prev_name
|
||||
is the name of a level defined previously, (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) is the
|
||||
.I offset
|
||||
from the level being chained from,
|
||||
.B %age
|
||||
is the generation percentage, and
|
||||
.B rndlevs
|
||||
is the number of similar levels available to choose from.
|
||||
|
||||
LEVELDESC:
|
||||
.B type
|
||||
.PP
|
||||
where
|
||||
.B type
|
||||
is the level type, (see DESCRIPTION, above). The
|
||||
.B type
|
||||
is used to override any pre-set value used to describe the entire dungeon,
|
||||
for this level only.
|
||||
|
||||
BRANCH:
|
||||
.B name
|
||||
@ (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) [
|
||||
.B stair
|
||||
|
|
||||
.B no_up
|
||||
|
|
||||
.B no_down
|
||||
|
|
||||
.B portal
|
||||
] [
|
||||
.B up
|
||||
|
|
||||
.B down
|
||||
]
|
||||
.PP
|
||||
where
|
||||
.B name
|
||||
is the name of the dungeon to branch to, and (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) is the location of the branch.
|
||||
The last two optional arguments are
|
||||
the branch type and branch direction.
|
||||
The type of a branch can be a two-way stair connection,
|
||||
a one-way stair connection, or a magic portal.
|
||||
A one-way stair is described by the types
|
||||
.B no_up
|
||||
and
|
||||
.B no_down
|
||||
which specify which stair direction is missing.
|
||||
The default branch type is
|
||||
.BR stair .
|
||||
The direction for a stair can be either up or down; direction is not
|
||||
applicable to portals. The default direction is
|
||||
.BR down .
|
||||
|
||||
CHAINBRANCH:
|
||||
.B name
|
||||
.B prev_name
|
||||
+ (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) [
|
||||
.B stair
|
||||
|
|
||||
.B no_up
|
||||
|
|
||||
.B no_down
|
||||
|
|
||||
.B portal
|
||||
] [
|
||||
.B up
|
||||
|
|
||||
.B down
|
||||
]
|
||||
.PP
|
||||
where
|
||||
.B name
|
||||
is the name of the dungeon to branch to,
|
||||
.B prev_name
|
||||
is the name of a previously defined
|
||||
.B level
|
||||
and (
|
||||
.B base
|
||||
,
|
||||
.B rand
|
||||
) is the
|
||||
.I offset
|
||||
from the level being chained from.
|
||||
The optional branch type and direction are the same as described above.
|
||||
.SH GENERIC RULES
|
||||
.PP
|
||||
Each dungeon must have a unique
|
||||
.B bonesmarker ,
|
||||
and each special level must have a
|
||||
.B bonesmarker
|
||||
unique within its dungeon (letters may be reused in different dungeons).
|
||||
If the
|
||||
.B bonesmarker
|
||||
has the special value "none", no bones files will be created for that
|
||||
level or dungeon.
|
||||
.PP
|
||||
The value
|
||||
.B base
|
||||
may be in the range of 1 to
|
||||
.B MAXLEVEL
|
||||
(as defined in
|
||||
.I global.h
|
||||
).
|
||||
.PP
|
||||
The value
|
||||
.B rand
|
||||
may be in the range of -1 to
|
||||
.BR MAXLEVEL .
|
||||
.PP
|
||||
If
|
||||
.B rand
|
||||
is -1 it will be replaced with the value (num_dunlevs(dungeon) - base)
|
||||
during the load process (ie. from here to the end of the dungeon).
|
||||
.PP
|
||||
If
|
||||
.B rand
|
||||
is 0 the level is located absolutely at
|
||||
.BR base .
|
||||
.PP
|
||||
Branches don't have a probability. Dungeons do. If a dungeon fails
|
||||
to be generated during load, all its levels and branches are skipped.
|
||||
.PP
|
||||
No level or branch may be chained from a level with a percentage generation
|
||||
probability. This is to prevent non-resolution during the load.
|
||||
In addition, no branch may be made from a dungeon with a percentage
|
||||
generation probability for the same reason.
|
||||
.PP
|
||||
As a general rule using the dungeon compiler:
|
||||
.PP
|
||||
If a dungeon has a
|
||||
.B protofile
|
||||
name associated with it
|
||||
.RI ( eg.
|
||||
.BR tower )
|
||||
that file will be used.
|
||||
.PP
|
||||
If a special level is present, it will override the above rule and
|
||||
the appropriate file will be loaded.
|
||||
.PP
|
||||
If neither of the above are present, the standard generator will
|
||||
take over and make a "normal" level.
|
||||
.PP
|
||||
A level alignment, if present, will override
|
||||
the alignment of the dungeon that it exists within.
|
||||
.SH EXAMPLE
|
||||
.PP
|
||||
Here is the current syntax of the dungeon compiler's "language":
|
||||
|
||||
.LP
|
||||
.nf
|
||||
.ta +8n +8n +8n
|
||||
#
|
||||
# The dungeon description file for the "standard" original
|
||||
# 3.0 NetHack.
|
||||
#
|
||||
DUNGEON: "The Dungeons of Doom" "D" (25, 5)
|
||||
LEVEL: "rogue" "none" @ (15, 4)
|
||||
LEVEL: "oracle" "none" @ (5, 7)
|
||||
LEVEL: "bigroom" "B" @ (12, 3) 15
|
||||
LEVEL: "medusa" "none" @ (20, 5)
|
||||
CHAINLEVEL: "castle" "medusa" + (1, 4)
|
||||
CHAINBRANCH: "Hell" "castle" + (0, 0) no_down
|
||||
BRANCH: "The Astral Plane" @ (1, 0) no_down up
|
||||
|
||||
DUNGEON: "Hell" "H" (25, 5)
|
||||
DESCRIPTION: mazelike
|
||||
DESCRIPTION: hellish
|
||||
BRANCH: "Vlad's Tower" @ (13, 5) up
|
||||
LEVEL: "wizard" "none" @ (15, 10)
|
||||
LEVEL: "fakewiz" "A" @ (5, 5)
|
||||
LEVEL: "fakewiz" "B" @ (10, 5)
|
||||
LEVEL: "fakewiz" "C" @ (15, 5)
|
||||
LEVEL: "fakewiz" "D" @ (20, 5)
|
||||
LEVEL: "fakewiz" "E" @ (25, 5)
|
||||
|
||||
DUNGEON: "Vlad's Tower" "T" (3, 0)
|
||||
PROTOFILE: "tower"
|
||||
DESCRIPTION: mazelike
|
||||
ENTRY: -1
|
||||
|
||||
DUNGEON: "The Astral Plane" "A" (1, 0)
|
||||
DESCRIPTION: mazelike
|
||||
PROTOFILE: "endgame"
|
||||
.fi
|
||||
.PP
|
||||
.I NOTES:
|
||||
.br
|
||||
Lines beginning with '#' are considered comments.
|
||||
.br
|
||||
A special level must be explicitly aligned. The alignment of the dungeon
|
||||
it is in only applies to non-special levels within that dungeon.
|
||||
.SH AUTHOR
|
||||
.PP
|
||||
M. Stephenson (from the level compiler by Jean-Christophe Collet).
|
||||
.SH "SEE ALSO"
|
||||
.PP
|
||||
lev_comp(6), nethack(6)
|
||||
.SH BUGS
|
||||
.PP
|
||||
Probably infinite.
|
||||
.SH COPYRIGHT
|
||||
This file is Copyright (C) \*(Na and was last modified \*(Nd (version
|
||||
\*(Nb:\*(Nr).
|
||||
NetHack may be freely redistributed. See license for details.
|
||||
330
doc/dgn_comp.txt
330
doc/dgn_comp.txt
@@ -1,330 +0,0 @@
|
||||
|
||||
|
||||
|
||||
DGN_COMP(6) 1995 DGN_COMP(6)
|
||||
|
||||
|
||||
|
||||
NAME
|
||||
dgn_comp - NetHack dungeon compiler
|
||||
|
||||
SYNOPSIS
|
||||
dgn_comp [ file ]
|
||||
|
||||
If no arguments are given, it reads standard input.
|
||||
|
||||
DESCRIPTION
|
||||
Dgn_comp is a dungeon compiler for NetHack version 3.2 and
|
||||
higher. It takes a description file as an argument and pro-
|
||||
duces a dungeon "script" that is to be loaded by NetHack at
|
||||
runtime.
|
||||
|
||||
The purpose of this tool is to provide NetHack administra-
|
||||
tors and implementors with a convenient way to create a cus-
|
||||
tom dungeon for the game, without having to recompile the
|
||||
entire world.
|
||||
|
||||
GRAMMAR
|
||||
DUNGEON: name bonesmarker ( base , rand ) [ %age ]
|
||||
|
||||
where name is the dungeon name, bonesmarker is a letter for
|
||||
marking bones files, ( base , rand ) is the number of lev-
|
||||
els, and %age is its percentage chance of being generated
|
||||
(if absent, 100% chance).
|
||||
|
||||
DESCRIPTION: tag
|
||||
|
||||
where tag is currently one of HELLISH, MAZELIKE, or ROGUE-
|
||||
LIKE.
|
||||
|
||||
ALIGNMENT | LEVALIGN: [ lawful | neutral | chaotic |
|
||||
unaligned ]
|
||||
|
||||
gives the alignment of the dungeon/level (default is
|
||||
unaligned).
|
||||
|
||||
ENTRY: level
|
||||
|
||||
the dungeon entry point. The dungeon connection attaches at
|
||||
this level of the given dungeon. If the value of level is
|
||||
negative, the entry level is calculated from the bottom of
|
||||
the dungeon, with -1 being the last level. If this line is
|
||||
not present in a dungeon description, the entry level
|
||||
defaults to 1.
|
||||
|
||||
PROTOFILE: name
|
||||
|
||||
the prototypical name for dungeon level files in this
|
||||
dungeon. For example, the PROTOFILE name for the dungeon
|
||||
Vlad's Tower is tower.
|
||||
|
||||
|
||||
|
||||
Dec Last change: 12 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DGN_COMP(6) 1995 DGN_COMP(6)
|
||||
|
||||
|
||||
|
||||
LEVEL: name bonesmarker @ ( base , rand ) [ %age ]
|
||||
|
||||
where name is the level name, bonesmarker is a letter for
|
||||
marking bones files, ( base , rand ) is the location and
|
||||
%age is the generation percentage, as above.
|
||||
|
||||
RNDLEVEL: name bonesmarker @ ( base , rand ) [ %age ]
|
||||
rndlevs
|
||||
|
||||
where name is the level name, bonesmarker is a letter for
|
||||
marking bones files, ( base , rand ) is the location, %age
|
||||
is the generation percentage, as above, and rndlevs is the
|
||||
number of similar levels available to choose from.
|
||||
|
||||
CHAINLEVEL: name bonesmarker prev_name + ( base , rand ) [
|
||||
%age ]
|
||||
|
||||
where name is the level name, bonesmarker is a letter for
|
||||
marking bones files, prev_name is the name of a level
|
||||
defined previously, ( base , rand ) is the offset from the
|
||||
level being chained from, and %age is the generation percen-
|
||||
tage.
|
||||
|
||||
RNDCHAINLEVEL: name bonesmarker prev_name + ( base , rand )
|
||||
[ %age ] rndlevs
|
||||
|
||||
where name is the level name, bonesmarker is a letter for
|
||||
marking bones files, prev_name is the name of a level
|
||||
defined previously, ( base , rand ) is the offset from the
|
||||
level being chained from, %age is the generation percentage,
|
||||
and rndlevs is the number of similar levels available to
|
||||
choose from.
|
||||
|
||||
LEVELDESC: type
|
||||
|
||||
where type is the level type, (see DESCRIPTION, above). The
|
||||
type is used to override any pre-set value used to describe
|
||||
the entire dungeon, for this level only.
|
||||
|
||||
BRANCH: name @ ( base , rand ) [ stair | no_up | no_down |
|
||||
portal ] [ up | down ]
|
||||
|
||||
where name is the name of the dungeon to branch to, and (
|
||||
base , rand ) is the location of the branch. The last two
|
||||
optional arguments are the branch type and branch direction.
|
||||
The type of a branch can be a two-way stair connection, a
|
||||
one-way stair connection, or a magic portal. A one-way
|
||||
stair is described by the types no_up and no_down which
|
||||
specify which stair direction is missing. The default
|
||||
branch type is stair. The direction for a stair can be
|
||||
either up or down; direction is not applicable to portals.
|
||||
The default direction is down.
|
||||
|
||||
|
||||
|
||||
Dec Last change: 12 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DGN_COMP(6) 1995 DGN_COMP(6)
|
||||
|
||||
|
||||
|
||||
CHAINBRANCH: name prev_name + ( base , rand ) [ stair |
|
||||
no_up | no_down | portal ] [ up | down ]
|
||||
|
||||
where name is the name of the dungeon to branch to,
|
||||
prev_name is the name of a previously defined level and (
|
||||
base , rand ) is the offset from the level being chained
|
||||
from. The optional branch type and direction are the same
|
||||
as described above.
|
||||
|
||||
GENERIC RULES
|
||||
Each dungeon must have a unique bonesmarker , and each spe-
|
||||
cial level must have a bonesmarker unique within its dungeon
|
||||
(letters may be reused in different dungeons). If the
|
||||
bonesmarker has the special value "none", no bones files
|
||||
will be created for that level or dungeon.
|
||||
|
||||
The value base may be in the range of 1 to MAXLEVEL (as
|
||||
defined in global.h ).
|
||||
|
||||
The value rand may be in the range of -1 to MAXLEVEL.
|
||||
|
||||
If rand is -1 it will be replaced with the value
|
||||
(num_dunlevs(dungeon) - base) during the load process (ie.
|
||||
from here to the end of the dungeon).
|
||||
|
||||
If rand is 0 the level is located absolutely at base.
|
||||
|
||||
Branches don't have a probability. Dungeons do. If a
|
||||
dungeon fails to be generated during load, all its levels
|
||||
and branches are skipped.
|
||||
|
||||
No level or branch may be chained from a level with a per-
|
||||
centage generation probability. This is to prevent non-
|
||||
resolution during the load. In addition, no branch may be
|
||||
made from a dungeon with a percentage generation probability
|
||||
for the same reason.
|
||||
|
||||
As a general rule using the dungeon compiler:
|
||||
|
||||
If a dungeon has a protofile name associated with it (eg.
|
||||
tower) that file will be used.
|
||||
|
||||
If a special level is present, it will override the above
|
||||
rule and the appropriate file will be loaded.
|
||||
|
||||
If neither of the above are present, the standard generator
|
||||
will take over and make a "normal" level.
|
||||
|
||||
A level alignment, if present, will override the alignment
|
||||
of the dungeon that it exists within.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Dec Last change: 12 3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DGN_COMP(6) 1995 DGN_COMP(6)
|
||||
|
||||
|
||||
|
||||
EXAMPLE
|
||||
Here is the current syntax of the dungeon compiler's
|
||||
"language":
|
||||
|
||||
|
||||
#
|
||||
# The dungeon description file for the "standard" original
|
||||
# 3.0 NetHack.
|
||||
#
|
||||
DUNGEON: "The Dungeons of Doom" "D" (25, 5)
|
||||
LEVEL: "rogue" "none" @ (15, 4)
|
||||
LEVEL: "oracle" "none" @ (5, 7)
|
||||
LEVEL: "bigroom" "B" @ (12, 3) 15
|
||||
LEVEL: "medusa" "none" @ (20, 5)
|
||||
CHAINLEVEL: "castle" "medusa" + (1, 4)
|
||||
CHAINBRANCH: "Hell" "castle" + (0, 0) no_down
|
||||
BRANCH: "The Astral Plane" @ (1, 0) no_down up
|
||||
|
||||
DUNGEON: "Hell" "H" (25, 5)
|
||||
DESCRIPTION: mazelike
|
||||
DESCRIPTION: hellish
|
||||
BRANCH: "Vlad's Tower" @ (13, 5) up
|
||||
LEVEL: "wizard" "none" @ (15, 10)
|
||||
LEVEL: "fakewiz" "A" @ (5, 5)
|
||||
LEVEL: "fakewiz" "B" @ (10, 5)
|
||||
LEVEL: "fakewiz" "C" @ (15, 5)
|
||||
LEVEL: "fakewiz" "D" @ (20, 5)
|
||||
LEVEL: "fakewiz" "E" @ (25, 5)
|
||||
|
||||
DUNGEON: "Vlad's Tower" "T" (3, 0)
|
||||
PROTOFILE: "tower"
|
||||
DESCRIPTION: mazelike
|
||||
ENTRY: -1
|
||||
|
||||
DUNGEON: "The Astral Plane" "A" (1, 0)
|
||||
DESCRIPTION: mazelike
|
||||
PROTOFILE: "endgame"
|
||||
|
||||
NOTES:
|
||||
Lines beginning with '#' are considered comments.
|
||||
A special level must be explicitly aligned. The alignment
|
||||
of the dungeon it is in only applies to non-special levels
|
||||
within that dungeon.
|
||||
|
||||
AUTHOR
|
||||
M. Stephenson (from the level compiler by Jean-Christophe
|
||||
Collet).
|
||||
|
||||
SEE ALSO
|
||||
lev_comp(6), nethack(6)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Dec Last change: 12 4
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DGN_COMP(6) 1995 DGN_COMP(6)
|
||||
|
||||
|
||||
|
||||
BUGS
|
||||
Probably infinite.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Dec Last change: 12 5
|
||||
|
||||
|
||||
|
||||
@@ -18,22 +18,24 @@ struct couple {
|
||||
};
|
||||
|
||||
struct tmpdungeon {
|
||||
char name[24], protoname[24];
|
||||
char *name, *protoname;
|
||||
struct couple lev;
|
||||
int flags, chance, levels, branches,
|
||||
entry_lev; /* entry level for this dungeon */
|
||||
char boneschar;
|
||||
int align;
|
||||
};
|
||||
|
||||
struct tmplevel {
|
||||
char name[24];
|
||||
char *name;
|
||||
char *chainlvl;
|
||||
struct couple lev;
|
||||
int chance, rndlevs, chain, flags;
|
||||
char boneschar;
|
||||
};
|
||||
|
||||
struct tmpbranch {
|
||||
char name[24]; /* destination dungeon name */
|
||||
char *name; /* destination dungeon name */
|
||||
struct couple lev;
|
||||
int chain; /* index into tmplevel array (chained branch)*/
|
||||
int type; /* branch type (see below) */
|
||||
|
||||
@@ -1655,6 +1655,8 @@ E struct selectionvar *FDECL(l_selection_check, (lua_State *, int));
|
||||
E int FDECL(l_selection_register, (lua_State *));
|
||||
|
||||
/* ### nhlua.c ### */
|
||||
E lua_State * NDECL(nhl_init);
|
||||
E boolean FDECL(nhl_loadlua, (lua_State *, const char *));
|
||||
E boolean FDECL(load_lua, (const char *));
|
||||
E void FDECL(nhl_error, (lua_State *, const char *));
|
||||
E void FDECL(lcheck_param_table, (lua_State *));
|
||||
|
||||
288
src/dungeon.c
288
src/dungeon.c
@@ -10,7 +10,7 @@
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
#define DUNGEON_FILE "dungeon"
|
||||
#define DUNGEON_FILE "dungeon.lua"
|
||||
|
||||
#define X_START "x-strt"
|
||||
#define X_LOCATE "x-loca"
|
||||
@@ -765,21 +765,56 @@ struct level_map {
|
||||
{ X_GOAL, &nemesis_level },
|
||||
{ "", (d_level *) 0 } };
|
||||
|
||||
int
|
||||
get_dgn_flags(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int dgn_flags = 0;
|
||||
const char *const flagstrs[] = { "town", "hellish", "mazelike", "roguelike", NULL};
|
||||
const int flagstrs2i[] = { TOWN, HELLISH, MAZELIKE, ROGUELIKE, 0 };
|
||||
|
||||
lua_getfield(L, -1, "flags");
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
int f, nflags;
|
||||
lua_len(L, -1);
|
||||
nflags = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
for (f = 0; f < nflags; f++) {
|
||||
lua_pushinteger(L, f+1);
|
||||
lua_gettable(L, -2);
|
||||
if (lua_type(L, -1) == LUA_TSTRING) {
|
||||
dgn_flags |= flagstrs2i[luaL_checkoption(L, -1, NULL, flagstrs)];
|
||||
lua_pop(L, 1);
|
||||
} else
|
||||
impossible("flags[%i] is not a string", f);
|
||||
}
|
||||
} else if (lua_type(L, -1) == LUA_TSTRING) {
|
||||
dgn_flags |= flagstrs2i[luaL_checkoption(L, -1, NULL, flagstrs)];
|
||||
} else if (lua_type(L, -1) != LUA_TNIL)
|
||||
impossible("flags is not an array or string");
|
||||
lua_pop(L, 1);
|
||||
|
||||
return dgn_flags;
|
||||
}
|
||||
|
||||
/* initialize the "dungeon" structs */
|
||||
void
|
||||
init_dungeons()
|
||||
{
|
||||
dlb *dgn_file;
|
||||
const char *const dgnaligns[] = { "unaligned", "noalign", "lawful", "neutral", "chaotic", NULL};
|
||||
const int dgnaligns2i[] = { D_ALIGN_NONE, D_ALIGN_NONE, D_ALIGN_LAWFUL, D_ALIGN_NEUTRAL, D_ALIGN_CHAOTIC, D_ALIGN_NONE };
|
||||
lua_State *L;
|
||||
register int i, cl = 0, cb = 0;
|
||||
register s_level *x;
|
||||
struct proto_dungeon pd;
|
||||
struct level_map *lev_map;
|
||||
struct version_info vers_info;
|
||||
|
||||
(void) memset(&pd, 0, sizeof(struct proto_dungeon));
|
||||
pd.n_levs = pd.n_brs = 0;
|
||||
|
||||
dgn_file = dlb_fopen(DUNGEON_FILE, RDBMODE);
|
||||
if (!dgn_file) {
|
||||
L = nhl_init();
|
||||
if (!nhl_loadlua(L, DUNGEON_FILE)) {
|
||||
char tbuf[BUFSZ];
|
||||
Sprintf(tbuf, "Cannot open dungeon description - \"%s", DUNGEON_FILE);
|
||||
#ifdef DLBRSRC /* using a resource from the executable */
|
||||
@@ -805,55 +840,186 @@ init_dungeons()
|
||||
panic1(tbuf);
|
||||
}
|
||||
|
||||
/* validate the data's version against the program's version */
|
||||
Fread((genericptr_t) &vers_info, sizeof vers_info, 1, dgn_file);
|
||||
/* we'd better clear the screen now, since when error messages come from
|
||||
* check_version() they will be printed using pline(), which doesn't
|
||||
* mix with the raw messages that might be already on the screen
|
||||
*/
|
||||
if (iflags.window_inited)
|
||||
clear_nhwindow(WIN_MAP);
|
||||
if (!check_version(&vers_info, DUNGEON_FILE, TRUE, UTD_CHECKSIZES))
|
||||
panic("Dungeon description not valid.");
|
||||
|
||||
g.sp_levchn = (s_level *) 0;
|
||||
|
||||
lua_settop(L, 0);
|
||||
|
||||
lua_getglobal(L, "dungeon");
|
||||
if (!lua_istable(L, -1))
|
||||
panic("dungeon is not a lua table");
|
||||
|
||||
lua_len(L, -1);
|
||||
g.n_dgns = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
pd.start = 0;
|
||||
pd.n_levs = 0;
|
||||
pd.n_brs = 0;
|
||||
|
||||
/*
|
||||
* Read in each dungeon and transfer the results to the internal
|
||||
* dungeon arrays.
|
||||
*/
|
||||
g.sp_levchn = (s_level *) 0;
|
||||
Fread((genericptr_t) &g.n_dgns, sizeof(int), 1, dgn_file);
|
||||
|
||||
if (g.n_dgns >= MAXDUNGEON)
|
||||
panic("init_dungeons: too many dungeons");
|
||||
|
||||
for (i = 0; i < g.n_dgns; i++) {
|
||||
Fread((genericptr_t) &pd.tmpdungeon[i], sizeof(struct tmpdungeon), 1,
|
||||
dgn_file);
|
||||
if (!wizard && pd.tmpdungeon[i].chance
|
||||
&& (pd.tmpdungeon[i].chance <= rn2(100))) {
|
||||
int j;
|
||||
int tidx = lua_gettop(L);
|
||||
|
||||
/* skip over any levels or branches */
|
||||
for (j = 0; j < pd.tmpdungeon[i].levels; j++)
|
||||
Fread((genericptr_t) &pd.tmplevel[cl],
|
||||
sizeof(struct tmplevel), 1, dgn_file);
|
||||
lua_pushnil(L); /* first key */
|
||||
i = 0;
|
||||
while (lua_next(L, tidx) != 0) {
|
||||
if (!lua_istable(L, -1))
|
||||
panic("dungeon[%i] is not a lua table", i);
|
||||
|
||||
for (j = 0; j < pd.tmpdungeon[i].branches; j++)
|
||||
Fread((genericptr_t) &pd.tmpbranch[cb],
|
||||
sizeof(struct tmpbranch), 1, dgn_file);
|
||||
char *dgn_name = get_table_str(L, "name");
|
||||
char *dgn_bonetag = get_table_str_opt(L, "bonetag", ""); /* TODO: single char or "none" */
|
||||
char *dgn_protoname = get_table_str_opt(L, "protofile", "");
|
||||
int dgn_base = get_table_int(L, "base");
|
||||
int dgn_range = get_table_int_opt(L, "range", 0);
|
||||
int dgn_align = dgnaligns2i[get_table_option(L, "alignment", "unaligned", dgnaligns)];
|
||||
int dgn_entry = get_table_int_opt(L, "entry", 0);
|
||||
int dgn_chance = get_table_int_opt(L, "chance", 0);
|
||||
int dgn_flags = get_dgn_flags(L);
|
||||
|
||||
debugpline4("DUNGEON[%i]: %s, base=(%i,%i)", i, dgn_name, dgn_base, dgn_range);
|
||||
|
||||
if (!wizard && dgn_chance && (dgn_chance <= rn2(100))) {
|
||||
debugpline1("IGNORING %s", dgn_name);
|
||||
g.n_dgns--;
|
||||
i--;
|
||||
lua_pop(L, 1); /* pop the dungeon table */
|
||||
continue;
|
||||
}
|
||||
|
||||
Strcpy(g.dungeons[i].dname, pd.tmpdungeon[i].name);
|
||||
Strcpy(g.dungeons[i].proto, pd.tmpdungeon[i].protoname);
|
||||
g.dungeons[i].boneid = pd.tmpdungeon[i].boneschar;
|
||||
/* levels begin */
|
||||
lua_getfield(L, -1, "levels");
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
int f, nlevels;
|
||||
lua_len(L, -1);
|
||||
nlevels = lua_tonumber(L, -1);
|
||||
pd.tmpdungeon[i].levels = nlevels;
|
||||
lua_pop(L, 1);
|
||||
for (f = 0; f < nlevels; f++) {
|
||||
lua_pushinteger(L, f+1);
|
||||
lua_gettable(L, -2);
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
int bi;
|
||||
char *lvl_name = get_table_str(L, "name");
|
||||
char *lvl_bonetag = get_table_str_opt(L, "bonetag", "");
|
||||
int lvl_base = get_table_int(L, "base");
|
||||
int lvl_range = get_table_int_opt(L, "range", 0);
|
||||
int lvl_nlevels = get_table_int_opt(L, "nlevels", 0);
|
||||
int lvl_chance = get_table_int_opt(L, "chance", 0);
|
||||
char *lvl_chain = get_table_str_opt(L, "chainlevel", NULL);
|
||||
int lvl_align = dgnaligns2i[get_table_option(L, "alignment", "unaligned", dgnaligns)];
|
||||
int lvl_flags = get_dgn_flags(L);
|
||||
struct tmplevel *tmpl = &pd.tmplevel[pd.n_levs + f];
|
||||
debugpline4("LEVEL[%i]:%s,(%i,%i)", f, lvl_name, lvl_base, lvl_range);
|
||||
tmpl->name = lvl_name;
|
||||
tmpl->chainlvl = lvl_chain;
|
||||
tmpl->lev.base = lvl_base;
|
||||
tmpl->lev.rand = lvl_range;
|
||||
tmpl->chance = lvl_chance;
|
||||
tmpl->rndlevs = lvl_nlevels;
|
||||
tmpl->flags = lvl_flags;
|
||||
tmpl->chain = -1;
|
||||
if (lvl_chain) {
|
||||
debugpline1("CHAINLEVEL: %s", lvl_chain);
|
||||
for (bi = 0; bi < pd.n_levs + f; bi++) {
|
||||
debugpline2("checking(%i):%s", bi, pd.tmplevel[bi].name);
|
||||
if (!strcmp(pd.tmplevel[bi].name, lvl_chain)) {
|
||||
tmpl->chain = bi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmpl->chain == -1)
|
||||
panic("Could not chain level %s to %s", lvl_name, lvl_chain);
|
||||
}
|
||||
} else
|
||||
panic("dungeon[%i].levels[%i] is not a hash", i, f);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
pd.n_levs += nlevels;
|
||||
if (pd.n_levs > LEV_LIMIT)
|
||||
panic("init_dungeon: too many special levels");
|
||||
} else if (lua_type(L, -1) != LUA_TNIL)
|
||||
panic("dungeon[%i].levels is not an array of hashes", i);
|
||||
lua_pop(L, 1);
|
||||
/* levels end */
|
||||
|
||||
if (pd.tmpdungeon[i].lev.rand)
|
||||
g.dungeons[i].num_dunlevs = (xchar) rn1(pd.tmpdungeon[i].lev.rand,
|
||||
pd.tmpdungeon[i].lev.base);
|
||||
/* branches begin */
|
||||
lua_getfield(L, -1, "branches");
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
int f, nbranches;
|
||||
lua_len(L, -1);
|
||||
nbranches = lua_tonumber(L, -1);
|
||||
pd.tmpdungeon[i].branches = nbranches;
|
||||
lua_pop(L, 1);
|
||||
for (f = 0; f < nbranches; f++) {
|
||||
lua_pushinteger(L, f+1);
|
||||
lua_gettable(L, -2);
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
int bi;
|
||||
const char *const brdirstr[] = { "up", "down", NULL };
|
||||
const int brdirstr2i[] = { TRUE, FALSE, FALSE };
|
||||
const char *const brtypes[] = { "stair", "portal", "no_down", "no_up", NULL };
|
||||
const int brtypes2i[] = { TBR_STAIR, TBR_PORTAL, TBR_NO_DOWN, TBR_NO_UP, TBR_STAIR };
|
||||
char *br_name = get_table_str(L, "name");
|
||||
int br_base = get_table_int(L, "base");
|
||||
int br_range = get_table_int_opt(L, "range", 0);
|
||||
int br_type = brtypes2i[get_table_option(L, "branchtype", "stair", brtypes)];
|
||||
int br_up = brdirstr2i[get_table_option(L, "direction", "down", brdirstr)];
|
||||
char *br_chain = get_table_str_opt(L, "chainlevel", NULL);
|
||||
struct tmpbranch *tmpb = &pd.tmpbranch[pd.n_brs + f];
|
||||
|
||||
debugpline4("BRANCH[%i]:%s,(%i,%i)", f, br_name, br_base, br_range);
|
||||
tmpb->name = br_name;
|
||||
tmpb->lev.base = br_base;
|
||||
tmpb->lev.rand = br_range;
|
||||
tmpb->type = br_type;
|
||||
tmpb->up = br_up;
|
||||
tmpb->chain = -1;
|
||||
if (br_chain) {
|
||||
debugpline1("CHAINBRANCH:%s", br_chain);
|
||||
for (bi = 0; bi < pd.n_levs + f - 1; bi++)
|
||||
if (!strcmp(pd.tmplevel[bi].name, br_chain)) {
|
||||
tmpb->chain = bi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
panic("dungeon[%i].branches[%i] is not a hash", i, f);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
pd.n_brs += nbranches;
|
||||
if (pd.n_brs > BRANCH_LIMIT)
|
||||
panic("init_dungeon: too many branches");
|
||||
} else if (lua_type(L, -1) != LUA_TNIL)
|
||||
panic("dungeon[%i].branches is not an array of hashes", i);
|
||||
lua_pop(L, 1);
|
||||
/* branches end */
|
||||
|
||||
pd.tmpdungeon[i].name = dgn_name;
|
||||
pd.tmpdungeon[i].protoname = dgn_protoname;
|
||||
pd.tmpdungeon[i].boneschar = *dgn_bonetag ? *dgn_bonetag : 0;
|
||||
pd.tmpdungeon[i].lev.base = dgn_base;
|
||||
pd.tmpdungeon[i].lev.rand = dgn_range;
|
||||
pd.tmpdungeon[i].flags = dgn_flags;
|
||||
pd.tmpdungeon[i].align = dgn_align;
|
||||
pd.tmpdungeon[i].chance = dgn_chance;
|
||||
pd.tmpdungeon[i].entry_lev = dgn_entry;
|
||||
|
||||
Strcpy(g.dungeons[i].dname, dgn_name); /* FIXME: dname length */
|
||||
Strcpy(g.dungeons[i].proto, dgn_protoname); /* FIXME: proto length */
|
||||
g.dungeons[i].boneid = *dgn_bonetag ? *dgn_bonetag : 0;
|
||||
|
||||
if (dgn_range)
|
||||
g.dungeons[i].num_dunlevs = (xchar) rn1(dgn_range, dgn_base);
|
||||
else
|
||||
g.dungeons[i].num_dunlevs = (xchar) pd.tmpdungeon[i].lev.base;
|
||||
g.dungeons[i].num_dunlevs = (xchar) dgn_base;
|
||||
|
||||
if (!i) {
|
||||
g.dungeons[i].ledger_start = 0;
|
||||
@@ -865,14 +1031,13 @@ init_dungeons()
|
||||
g.dungeons[i].dunlev_ureached = 0;
|
||||
}
|
||||
|
||||
g.dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH);
|
||||
g.dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE);
|
||||
g.dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE);
|
||||
g.dungeons[i].flags.align =
|
||||
((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4);
|
||||
g.dungeons[i].flags.hellish = !!(dgn_flags & HELLISH);
|
||||
g.dungeons[i].flags.maze_like = !!(dgn_flags & MAZELIKE);
|
||||
g.dungeons[i].flags.rogue_like = !!(dgn_flags & ROGUELIKE);
|
||||
g.dungeons[i].flags.align = dgn_align;
|
||||
|
||||
/*
|
||||
* Set the entry level for this dungeon. The pd.tmpdungeon entry
|
||||
* value means:
|
||||
* Set the entry level for this dungeon. The entry value means:
|
||||
* < 0 from bottom (-1 == bottom level)
|
||||
* 0 default (top)
|
||||
* > 0 actual level (1 = top)
|
||||
@@ -880,13 +1045,13 @@ init_dungeons()
|
||||
* Note that the entry_lev field in the dungeon structure is
|
||||
* redundant. It is used only here and in print_dungeon().
|
||||
*/
|
||||
if (pd.tmpdungeon[i].entry_lev < 0) {
|
||||
if (dgn_entry < 0) {
|
||||
g.dungeons[i].entry_lev =
|
||||
g.dungeons[i].num_dunlevs + pd.tmpdungeon[i].entry_lev + 1;
|
||||
g.dungeons[i].num_dunlevs + dgn_entry + 1;
|
||||
if (g.dungeons[i].entry_lev <= 0)
|
||||
g.dungeons[i].entry_lev = 1;
|
||||
} else if (pd.tmpdungeon[i].entry_lev > 0) {
|
||||
g.dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev;
|
||||
} else if (dgn_entry > 0) {
|
||||
g.dungeons[i].entry_lev = dgn_entry;
|
||||
if (g.dungeons[i].entry_lev > g.dungeons[i].num_dunlevs)
|
||||
g.dungeons[i].entry_lev = g.dungeons[i].num_dunlevs;
|
||||
} else { /* default */
|
||||
@@ -928,23 +1093,14 @@ init_dungeons()
|
||||
- (g.dungeons[i].entry_lev - 1);
|
||||
}
|
||||
|
||||
/* this is redundant - it should have been flagged by dgn_comp */
|
||||
if (g.dungeons[i].num_dunlevs > MAXLEVEL)
|
||||
g.dungeons[i].num_dunlevs = MAXLEVEL;
|
||||
|
||||
pd.start = pd.n_levs; /* save starting point */
|
||||
pd.n_levs += pd.tmpdungeon[i].levels;
|
||||
if (pd.n_levs > LEV_LIMIT)
|
||||
panic("init_dungeon: too many special levels");
|
||||
/*
|
||||
* Read in the prototype special levels. Don't add generated
|
||||
* special levels until they are all placed.
|
||||
*/
|
||||
for (; cl < pd.n_levs; cl++) {
|
||||
Fread((genericptr_t) &pd.tmplevel[cl], sizeof(struct tmplevel), 1,
|
||||
dgn_file);
|
||||
|
||||
for (; cl < pd.n_levs; cl++) {
|
||||
init_level(i, cl, &pd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Recursively place the generated levels for this dungeon. This
|
||||
* routine will attempt all possible combinations before giving
|
||||
@@ -957,18 +1113,18 @@ init_dungeons()
|
||||
fflush(stderr);
|
||||
getchar();
|
||||
#endif
|
||||
|
||||
for (; pd.start < pd.n_levs; pd.start++)
|
||||
if (pd.final_lev[pd.start])
|
||||
add_level(pd.final_lev[pd.start]);
|
||||
/* levels handling end */
|
||||
|
||||
pd.n_brs += pd.tmpdungeon[i].branches;
|
||||
if (pd.n_brs > BRANCH_LIMIT)
|
||||
panic("init_dungeon: too many branches");
|
||||
for (; cb < pd.n_brs; cb++)
|
||||
Fread((genericptr_t) &pd.tmpbranch[cb], sizeof(struct tmpbranch),
|
||||
1, dgn_file);
|
||||
lua_pop(L, 1); /* pop the dungeon table */
|
||||
i++;
|
||||
}
|
||||
(void) dlb_fclose(dgn_file);
|
||||
|
||||
lua_pop(L, 1); /* get rid of the dungeon global */
|
||||
debugpline2("init_dungeon lua DONE (n_levs=%i, n_brs=%i)", pd.n_levs, pd.n_brs);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
g.tune[i] = 'A' + rn2(7);
|
||||
@@ -1028,6 +1184,8 @@ init_dungeons()
|
||||
so that it's hidden from '#wizwhere' feedback. */
|
||||
}
|
||||
|
||||
lua_close(L);
|
||||
|
||||
#ifdef DEBUG
|
||||
dumpit();
|
||||
#endif
|
||||
|
||||
39
src/nhlua.c
39
src/nhlua.c
@@ -503,7 +503,7 @@ const char *name;
|
||||
{
|
||||
int ret;
|
||||
|
||||
lua_getfield(L, 1, name);
|
||||
lua_getfield(L, -1, name);
|
||||
ret = (int) luaL_checkinteger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return ret;
|
||||
@@ -518,7 +518,7 @@ int defval;
|
||||
{
|
||||
int ret = defval;
|
||||
|
||||
lua_getfield(L, 1, name);
|
||||
lua_getfield(L, -1, name);
|
||||
if (!lua_isnil(L, -1)) {
|
||||
ret = (int) luaL_checkinteger(L, -1);
|
||||
}
|
||||
@@ -533,7 +533,7 @@ const char *name;
|
||||
{
|
||||
char *ret;
|
||||
|
||||
lua_getfield(L, 1, name);
|
||||
lua_getfield(L, -1, name);
|
||||
ret = dupstr(luaL_checkstring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return ret;
|
||||
@@ -549,10 +549,12 @@ char *defval;
|
||||
{
|
||||
const char *ret;
|
||||
|
||||
lua_getfield(L, 1, name);
|
||||
lua_getfield(L, -1, name);
|
||||
ret = luaL_optstring(L, -1, defval);
|
||||
if (ret)
|
||||
ret = dupstr(ret);
|
||||
lua_pop(L, 1);
|
||||
return ret ? dupstr(ret) : NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -563,7 +565,7 @@ const char *name;
|
||||
int ltyp;
|
||||
int ret = -1;
|
||||
|
||||
lua_getfield(L, 1, name);
|
||||
lua_getfield(L, -1, name);
|
||||
ltyp = lua_type(L, -1);
|
||||
if (ltyp == LUA_TSTRING) {
|
||||
const char *const boolstr[] = { "true", "false", "yes", "no", NULL };
|
||||
@@ -590,7 +592,7 @@ int defval;
|
||||
{
|
||||
int ret = defval;
|
||||
|
||||
lua_getfield(L, 1, name);
|
||||
lua_getfield(L, -1, name);
|
||||
if (lua_type(L, -1) != LUA_TNIL) {
|
||||
lua_pop(L, 1);
|
||||
return get_table_boolean(L, name);
|
||||
@@ -608,7 +610,7 @@ const char *const opts[]; /* NULL-terminated list */
|
||||
{
|
||||
int ret;
|
||||
|
||||
lua_getfield(L, 1, name);
|
||||
lua_getfield(L, -1, name);
|
||||
ret = luaL_checkoption(L, -1, defval, opts);
|
||||
lua_pop(L, 1);
|
||||
return ret;
|
||||
@@ -842,11 +844,9 @@ give_up:
|
||||
return ret;
|
||||
}
|
||||
|
||||
boolean
|
||||
load_lua(name)
|
||||
const char *name;
|
||||
lua_State *
|
||||
nhl_init()
|
||||
{
|
||||
boolean ret = TRUE;
|
||||
lua_State *L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
|
||||
@@ -867,6 +867,21 @@ const char *name;
|
||||
l_register_des(L);
|
||||
|
||||
if (!nhl_loadlua(L, "nhlib.lua")) {
|
||||
lua_close(L);
|
||||
return (lua_State *) 0;
|
||||
}
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
boolean
|
||||
load_lua(name)
|
||||
const char *name;
|
||||
{
|
||||
boolean ret = TRUE;
|
||||
lua_State *L = nhl_init();
|
||||
|
||||
if (!L) {
|
||||
ret = FALSE;
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#define INTEGER 257
|
||||
#define A_DUNGEON 258
|
||||
#define BRANCH 259
|
||||
#define CHBRANCH 260
|
||||
#define LEVEL 261
|
||||
#define RNDLEVEL 262
|
||||
#define CHLEVEL 263
|
||||
#define RNDCHLEVEL 264
|
||||
#define UP_OR_DOWN 265
|
||||
#define PROTOFILE 266
|
||||
#define DESCRIPTION 267
|
||||
#define DESCRIPTOR 268
|
||||
#define LEVELDESC 269
|
||||
#define ALIGNMENT 270
|
||||
#define LEVALIGN 271
|
||||
#define ENTRY 272
|
||||
#define STAIR 273
|
||||
#define NO_UP 274
|
||||
#define NO_DOWN 275
|
||||
#define PORTAL 276
|
||||
#define STRING 277
|
||||
typedef union
|
||||
{
|
||||
int i;
|
||||
char* str;
|
||||
} YYSTYPE;
|
||||
extern YYSTYPE yylval;
|
||||
2000
sys/share/dgn_lex.c
2000
sys/share/dgn_lex.c
File diff suppressed because it is too large
Load Diff
1053
sys/share/dgn_yacc.c
1053
sys/share/dgn_yacc.c
File diff suppressed because it is too large
Load Diff
@@ -11,14 +11,11 @@ NHSROOT=..
|
||||
|
||||
VARDAT = bogusmon data engrave epitaph rumors quest.dat oracles options
|
||||
|
||||
all: $(VARDAT) spec_levs quest_levs dungeon
|
||||
all: $(VARDAT) spec_levs quest_levs
|
||||
|
||||
../util/makedefs:
|
||||
(cd ../util ; $(MAKE) makedefs)
|
||||
|
||||
../util/dgn_comp:
|
||||
(cd ../util ; $(MAKE) dgn_comp)
|
||||
|
||||
../util/tile2x11:
|
||||
(cd ../util ; $(MAKE) tile2x11)
|
||||
|
||||
@@ -129,12 +126,8 @@ spec_levs:
|
||||
quest_levs:
|
||||
touch quest_levs
|
||||
|
||||
dungeon: dungeon.def ../util/makedefs ../util/dgn_comp
|
||||
../util/makedefs -e
|
||||
../util/dgn_comp dungeon.pdf
|
||||
|
||||
spotless:
|
||||
-rm -f spec_levs quest_levs *.lev $(VARDAT) dungeon dungeon.pdf
|
||||
-rm -f spec_levs quest_levs *.lev $(VARDAT)
|
||||
-rm -f nhdat x11tiles beostiles pet_mark.xbm pilemark.xbm rip.xpm mapbg.xpm
|
||||
-rm -f rip.img GEM_RSC.RSC title.img nh16.img NetHack.ad
|
||||
-rm -f nhsplash.xpm nhtiles.bmp
|
||||
|
||||
@@ -67,26 +67,23 @@ MANEXT = 6
|
||||
|
||||
# manual installation for most BSD-style systems
|
||||
GAMEMANCREATE = cat nethack.6 | $(NHGREP) >
|
||||
DGNMANCREATE = cat dgn_comp.6 | $(NHGREP) >
|
||||
RCVRMANCREATE = cat recover.6 | $(NHGREP) >
|
||||
DLBMANCREATE = cat dlb.6 | $(NHGREP) >
|
||||
MDMANCREATE = cat makedefs.6 | $(NHGREP) >
|
||||
# manual installation for most SYSV-style systems
|
||||
# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | nroff -man - >
|
||||
# DGNMANCREATE = cat dgn_comp.6 | $(NHGREP) | nroff -man - >
|
||||
# RCVRMANCREATE = cat recover.6 | $(NHGREP) | nroff -man - >
|
||||
# DLBMANCREATE = cat dlb.6 | $(NHGREP) | nroff -man - >
|
||||
# MDMANCREATE = cat makedefs.6 | $(NHGREP) | nroff -man - >
|
||||
|
||||
manpages:
|
||||
-$(GAMEMANCREATE) $(MANDIR)/$(GAME).$(MANEXT)
|
||||
-$(DGNMANCREATE) $(MANDIR)/dgn_comp.$(MANEXT)
|
||||
-$(RCVRMANCREATE) $(MANDIR)/recover.$(MANEXT)
|
||||
-$(DLBMANCREATE) $(MANDIR)/dlb.$(MANEXT)
|
||||
-$(MDMANCREATE) $(MANDIR)/makedefs.$(MANEXT)
|
||||
|
||||
# manual creation for distribution
|
||||
DISTRIB = Guidebook.txt nethack.txt dgn_comp.txt recover.txt \
|
||||
DISTRIB = Guidebook.txt nethack.txt recover.txt \
|
||||
dlb.txt makedefs.txt
|
||||
|
||||
distrib: $(DISTRIB)
|
||||
@@ -97,8 +94,6 @@ Guidebook.txt : Guidebook.mn tmac.n tmac.nh
|
||||
MAN2TXT = $(NHGREP) | nroff -man - | $(COLCMD)
|
||||
nethack.txt : nethack.6
|
||||
cat nethack.6 | $(MAN2TXT) > nethack.txt
|
||||
dgn_comp.txt : dgn_comp.6
|
||||
cat dgn_comp.6 | $(MAN2TXT) > dgn_comp.txt
|
||||
recover.txt : recover.6
|
||||
cat recover.6 | $(MAN2TXT) > recover.txt
|
||||
dlb.txt : dlb.6
|
||||
|
||||
@@ -491,7 +491,7 @@ CSOURCES = $(HACKCSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC)
|
||||
|
||||
# all .h files except date.h, onames.h, pm.h, and vis_tab.h which would
|
||||
# cause dependency loops if run through "make depend"
|
||||
# and dgn_comp.h, dgn_file.h, special level & dungeon files.
|
||||
# and dgn_file.h, special level & dungeon files.
|
||||
#
|
||||
HACKINCL = align.h amiconf.h artifact.h artilist.h attrib.h beconf.h botl.h \
|
||||
color.h config.h config1.h context.h coord.h decl.h def_os2.h \
|
||||
@@ -505,7 +505,7 @@ HACKINCL = align.h amiconf.h artifact.h artilist.h attrib.h beconf.h botl.h \
|
||||
wincurs.h winX.h winprocs.h wintype.h you.h youprop.h
|
||||
|
||||
HSOURCES = $(HACKINCL) date.h onames.h pm.h vis_tab.h \
|
||||
dgn_comp.h dgn_file.h
|
||||
dgn_file.h
|
||||
|
||||
# the following .o's _must_ be made before any others (for makedefs)
|
||||
FIRSTOBJ = monst.o objects.o
|
||||
|
||||
@@ -88,14 +88,14 @@ SPEC_LEVS = asmodeus.lua baalz.lua bigrm-*.lua castle.lua fakewiz?.lua \
|
||||
QUEST_LEVS = ???-goal.lua ???-fil?.lua ???-loca.lua ???-strt.lua
|
||||
|
||||
DATNODLB = $(VARDATND) license symbols
|
||||
DATDLB = $(DATHELP) dungeon tribute $(SPEC_LEVS) $(QUEST_LEVS) $(VARDATD)
|
||||
DATDLB = $(DATHELP) dungeon.lua tribute $(SPEC_LEVS) $(QUEST_LEVS) $(VARDATD)
|
||||
DAT = $(DATNODLB) $(DATDLB)
|
||||
|
||||
$(GAME):
|
||||
( cd lib/lua-5.3.5/src && make a && cp liblua.a ../../../src/ )
|
||||
( cd src ; $(MAKE) )
|
||||
|
||||
all: $(GAME) recover Guidebook $(VARDAT) dungeon spec_levs check-dlb
|
||||
all: $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb
|
||||
true; $(MOREALL)
|
||||
@echo "Done."
|
||||
|
||||
@@ -133,14 +133,10 @@ options: $(GAME)
|
||||
quest.dat: $(GAME)
|
||||
( cd dat ; $(MAKE) quest.dat )
|
||||
|
||||
spec_levs: dungeon
|
||||
spec_levs:
|
||||
( cd dat ; $(MAKE) spec_levs )
|
||||
( cd dat ; $(MAKE) quest_levs )
|
||||
|
||||
dungeon: $(GAME)
|
||||
( cd util ; $(MAKE) dgn_comp )
|
||||
( cd dat ; $(MAKE) dungeon )
|
||||
|
||||
nhtiles.bmp: $(GAME)
|
||||
( cd dat ; $(MAKE) nhtiles.bmp )
|
||||
|
||||
@@ -237,7 +233,7 @@ dofiles-nodlb:
|
||||
$(CHGRP) $(GAMEGRP) $(DAT) ; \
|
||||
chmod $(FILEPERM) $(DAT) )
|
||||
|
||||
update: $(GAME) recover $(VARDAT) dungeon spec_levs
|
||||
update: $(GAME) recover $(VARDAT) spec_levs
|
||||
# (don't yank the old version out from under people who're playing it)
|
||||
-mv $(INSTDIR)/$(GAME) $(INSTDIR)/$(GAME).old
|
||||
# quest.dat is also kept open and has the same problems over NFS
|
||||
@@ -256,7 +252,7 @@ update: $(GAME) recover $(VARDAT) dungeon spec_levs
|
||||
rootcheck:
|
||||
@true; $(ROOTCHECK)
|
||||
|
||||
install: rootcheck $(GAME) recover $(VARDAT) dungeon spec_levs
|
||||
install: rootcheck $(GAME) recover $(VARDAT) spec_levs
|
||||
true; $(PREINSTALL)
|
||||
# set up the directories
|
||||
# not all mkdirs have -p; those that don't will create a -p directory
|
||||
|
||||
@@ -186,7 +186,6 @@ HACK_H = ../src/hack.h-t
|
||||
|
||||
# utility .c files
|
||||
MAKESRC = makedefs.c
|
||||
DGNCOMPSRC = dgn_yacc.c dgn_lex.c dgn_main.c
|
||||
RECOVSRC = recover.c
|
||||
DLBSRC = dlb_main.c
|
||||
UTILSRCS = $(MAKESRC) panic.c $(DGNCOMPSRC) $(RECOVSRC) $(DLBSRC)
|
||||
@@ -205,9 +204,6 @@ OALLOC = $(OBJDIR)/alloc.o panic.o
|
||||
# object files for makedefs
|
||||
MAKEOBJS = makedefs.o $(OMONOBJ)
|
||||
|
||||
# object files for dungeon compiler
|
||||
DGNCOMPOBJS = dgn_yacc.o dgn_lex.o dgn_main.o $(OALLOC)
|
||||
|
||||
# object files for recovery utility
|
||||
RECOVOBJS = recover.o
|
||||
|
||||
@@ -267,35 +263,6 @@ lintdefs:
|
||||
panic.o: panic.c $(CONFIG_H)
|
||||
|
||||
|
||||
# dependencies for dgn_comp
|
||||
#
|
||||
dgn_comp: $(DGNCOMPOBJS)
|
||||
$(CC) $(LFLAGS) -o dgn_comp $(DGNCOMPOBJS) $(LIBS)
|
||||
|
||||
dgn_yacc.o: dgn_yacc.c $(CONFIG_H) ../include/dgn_file.h ../include/date.h
|
||||
dgn_main.o: dgn_main.c $(CONFIG_H) ../include/dlb.h
|
||||
|
||||
# see dgn_comp.l for WEIRD_LEX discussion
|
||||
dgn_lex.o: dgn_lex.c $(CONFIG_H) ../include/dgn_comp.h ../include/dgn_file.h
|
||||
$(CC) -c $(CFLAGS) -DWEIRD_LEX=`egrep -c _cplusplus dgn_lex.c` dgn_lex.c
|
||||
|
||||
# '$(YACC) -d' generates both $(YTABC) and $(YTABH) in one run
|
||||
../include/dgn_comp.h: dgn_yacc.c
|
||||
|
||||
dgn_yacc.c: dgn_comp.y
|
||||
$(YACC) $(YACCDIST) -d dgn_comp.y
|
||||
sed -e 's#"$(YTABC)"#"$@"#' -e 's#$(YTABC):#$@:#' $(YTABC) > $@ \
|
||||
&& rm $(YTABC)
|
||||
sed -e 's#"$(YTABH)"#"dgn_comp.h"#' $(YTABH) > ../include/dgn_comp.h \
|
||||
&& rm $(YTABH)
|
||||
|
||||
dgn_lex.c: dgn_comp.l
|
||||
$(LEX) $(FLEXDIST) dgn_comp.l
|
||||
sed -e 's#"$(LEXYYC)"#"$@"#' -e 's# *$$##' \
|
||||
-e 's#static void yyunput#void yyunput#' $(LEXYYC) > $@ \
|
||||
&& rm $(LEXYYC)
|
||||
# note: <space><space><star> is basic RE substitute for <space><plus>
|
||||
|
||||
# with all of extern.h's functions to complain about, we drown in
|
||||
# 'defined but not used' without -u
|
||||
lintdgn:
|
||||
@@ -501,17 +468,7 @@ $(HACK_H): $(CONFIG_H)
|
||||
$(CONFIG_H): ../include/config.h
|
||||
@( cd ../src ; $(MAKE) $(CONFIG_H) )
|
||||
|
||||
# 'make dist' => put generated lex and yacc sources into place for distribution
|
||||
SYSSHARE=../sys/share/
|
||||
$(SYSSHARE)dgn_lex.c: dgn_lex.c
|
||||
cp dgn_lex.c $@
|
||||
$(SYSSHARE)dgn_yacc.c: dgn_yacc.c
|
||||
cp dgn_yacc.c $@
|
||||
$(SYSSHARE)dgn_comp.h: ../include/dgn_comp.h
|
||||
cp ../include/dgn_comp.h $@
|
||||
|
||||
dist: $(SYSSHARE)dgn_lex.c $(SYSSHARE)dgn_yacc.c $(SYSSHARE)dgn_comp.h
|
||||
@echo 'pre-generated lex and yacc sources are in place in sys/share'
|
||||
|
||||
tags: $(UTILSRCS)
|
||||
@ctags -tw $(UTILSRCS)
|
||||
@@ -520,9 +477,7 @@ clean:
|
||||
-rm -f *.o
|
||||
|
||||
spotless: clean
|
||||
-rm -f dgn_lex.c dgn_yacc.c
|
||||
-rm -f ../include/dgn_comp.h
|
||||
-rm -f ../include/tile.h tiletxt.c
|
||||
-rm -f makedefs dgn_comp recover dlb
|
||||
-rm -f makedefs recover dlb
|
||||
-rm -f gif2txt txt2ppm tile2x11 tile2img.ttp xpm2img.ttp \
|
||||
tilemap tileedit tile2bmp
|
||||
|
||||
144
util/dgn_comp.l
144
util/dgn_comp.l
@@ -1,144 +0,0 @@
|
||||
%{
|
||||
/* NetHack 3.6 dgn_comp.l $NHDT-Date: 1455415007 2016/02/14 01:56:47 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.13 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* Copyright (c) 1990 by M. Stephenson */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#define DGN_COMP
|
||||
|
||||
#include "config.h"
|
||||
#include "dgn_comp.h"
|
||||
#include "dgn_file.h"
|
||||
|
||||
/*
|
||||
* Most of these don't exist in flex, yywrap is macro and
|
||||
* yyunput is properly declared in flex.skel.
|
||||
*/
|
||||
#if !defined(FLEX_SCANNER) && !defined(FLEXHACK_SCANNER)
|
||||
int FDECL(yyback, (int *,int));
|
||||
int NDECL(yylook);
|
||||
int NDECL(yyinput);
|
||||
int NDECL(yywrap);
|
||||
int NDECL(yylex);
|
||||
/* Traditional lexes let yyunput() and yyoutput() default to int;
|
||||
* newer ones may declare them as void since they don't return
|
||||
* values. For even more fun, the lex supplied as part of the
|
||||
* newer unbundled compiler for SunOS 4.x adds the void declarations
|
||||
* (under __STDC__ or _cplusplus ifdefs -- otherwise they remain
|
||||
* int) while the bundled lex and the one with the older unbundled
|
||||
* compiler do not. To detect this, we need help from outside --
|
||||
* sys/unix/Makefile.utl.
|
||||
*
|
||||
* Digital UNIX is difficult and still has int in spite of all
|
||||
* other signs.
|
||||
*/
|
||||
# if defined(NeXT) || defined(SVR4) || defined(_AIX32)
|
||||
# define VOIDYYPUT
|
||||
# endif
|
||||
# if !defined(VOIDYYPUT) && defined(POSIX_TYPES)
|
||||
# if !defined(BOS) && !defined(HISX) && !defined(_M_UNIX) && !defined(VMS)
|
||||
# define VOIDYYPUT
|
||||
# endif
|
||||
# endif
|
||||
# if !defined(VOIDYYPUT) && defined(WEIRD_LEX)
|
||||
# if defined(SUNOS4) && defined(__STDC__) && (WEIRD_LEX > 1)
|
||||
# define VOIDYYPUT
|
||||
# endif
|
||||
# endif
|
||||
# if defined(VOIDYYPUT) && defined(__osf__)
|
||||
# undef VOIDYYPUT
|
||||
# endif
|
||||
# ifdef VOIDYYPUT
|
||||
void FDECL(yyunput, (int));
|
||||
void FDECL(yyoutput, (int));
|
||||
# else
|
||||
int FDECL(yyunput, (int));
|
||||
int FDECL(yyoutput, (int));
|
||||
# endif
|
||||
|
||||
#else /* !FLEX_SCANNER && !FLEXHACK_SCANNER */
|
||||
/* most recent flex allows suppressing yyunput() altogether when not needed */
|
||||
#define YY_NO_UNPUT
|
||||
#define YY_NO_INPUT
|
||||
#endif
|
||||
|
||||
#if defined(FLEX_SCANNER) || defined(FLEXHACK_SCANNER)
|
||||
/* older flex wants this */
|
||||
#define YY_MALLOC_DECL genericptr_t FDECL(malloc, (size_t)); \
|
||||
genericptr_t FDECL(realloc, (genericptr_t, size_t));
|
||||
/* newer flex assumes <stdlib.h> so needs this in case it's been suppressed */
|
||||
YY_MALLOC_DECL
|
||||
#endif
|
||||
|
||||
void FDECL(init_yyin, (FILE *));
|
||||
void FDECL(init_yyout, (FILE *));
|
||||
|
||||
/* this doesn't always get put in dgn_comp.h
|
||||
* (esp. when using older versions of bison)
|
||||
*/
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
int nh_line_number = 1;
|
||||
|
||||
%}
|
||||
%%
|
||||
DUNGEON return(A_DUNGEON);
|
||||
up { yylval.i=1; return(UP_OR_DOWN); }
|
||||
down { yylval.i=0; return(UP_OR_DOWN); }
|
||||
ENTRY return(ENTRY);
|
||||
stair return(STAIR);
|
||||
no_up return(NO_UP);
|
||||
no_down return(NO_DOWN);
|
||||
portal return(PORTAL);
|
||||
PROTOFILE return(PROTOFILE);
|
||||
DESCRIPTION return(DESCRIPTION);
|
||||
LEVELDESC return(LEVELDESC);
|
||||
ALIGNMENT return(ALIGNMENT);
|
||||
LEVALIGN return(LEVALIGN);
|
||||
town { yylval.i=TOWN ; return(DESCRIPTOR); }
|
||||
hellish { yylval.i=HELLISH ; return(DESCRIPTOR); }
|
||||
mazelike { yylval.i=MAZELIKE ; return(DESCRIPTOR); }
|
||||
roguelike { yylval.i=ROGUELIKE ; return(DESCRIPTOR); }
|
||||
unaligned { yylval.i=D_ALIGN_NONE ; return(DESCRIPTOR); }
|
||||
noalign { yylval.i=D_ALIGN_NONE ; return(DESCRIPTOR); }
|
||||
lawful { yylval.i=D_ALIGN_LAWFUL ; return(DESCRIPTOR); }
|
||||
neutral { yylval.i=D_ALIGN_NEUTRAL ; return(DESCRIPTOR); }
|
||||
chaotic { yylval.i=D_ALIGN_CHAOTIC ; return(DESCRIPTOR); }
|
||||
BRANCH return(BRANCH);
|
||||
CHAINBRANCH return(CHBRANCH);
|
||||
LEVEL return(LEVEL);
|
||||
RNDLEVEL return(RNDLEVEL);
|
||||
CHAINLEVEL return(CHLEVEL);
|
||||
RNDCHLEVEL return(RNDCHLEVEL);
|
||||
[-0-9]+ { yylval.i=atoi(yytext); return(INTEGER); }
|
||||
\"[^"]*\" { yytext[yyleng - 1] = '\0'; /* discard the trailing \" */
|
||||
yylval.str = dupstr(yytext + 1); /* skip the first \" */
|
||||
return STRING; }
|
||||
^#.*\n { nh_line_number++; }
|
||||
\r?\n { nh_line_number++; }
|
||||
[ \t]+ ; /* skip trailing tabs & spaces */
|
||||
. { return yytext[0]; }
|
||||
%%
|
||||
|
||||
/* routine to switch to another input file; needed for flex */
|
||||
void
|
||||
init_yyin( input_f )
|
||||
FILE *input_f;
|
||||
{
|
||||
#if defined(FLEX_SCANNER) || defined(FLEXHACK_SCANNER)
|
||||
if (yyin)
|
||||
yyrestart(input_f);
|
||||
else
|
||||
#endif
|
||||
yyin = input_f;
|
||||
}
|
||||
|
||||
/* analogous routine (for completeness) */
|
||||
void
|
||||
init_yyout( output_f )
|
||||
FILE *output_f;
|
||||
{
|
||||
yyout = output_f;
|
||||
}
|
||||
|
||||
/*dgn_comp.l*/
|
||||
678
util/dgn_comp.y
678
util/dgn_comp.y
@@ -1,678 +0,0 @@
|
||||
%{
|
||||
/* NetHack 3.6 dgn_comp.y $NHDT-Date: 1432512785 2015/05/25 00:13:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* Copyright (c) 1990 by M. Stephenson */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
/*
|
||||
* This file contains the Dungeon Compiler code
|
||||
*/
|
||||
|
||||
/* In case we're using bison in AIX. This definition must be
|
||||
* placed before any other C-language construct in the file
|
||||
* excluding comments and preprocessor directives (thanks IBM
|
||||
* for this wonderful feature...).
|
||||
*
|
||||
* Note: some cpps barf on this 'undefined control' (#pragma).
|
||||
* Addition of the leading space seems to prevent barfage for now,
|
||||
* and AIX will still see the directive in its non-standard locale.
|
||||
*/
|
||||
|
||||
#ifdef _AIX
|
||||
#pragma alloca /* keep leading space! */
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "date.h"
|
||||
#include "dgn_file.h"
|
||||
|
||||
void FDECL(yyerror, (const char *));
|
||||
void FDECL(yywarning, (const char *));
|
||||
int NDECL(yylex);
|
||||
int NDECL(yyparse);
|
||||
int FDECL(getchain, (char *));
|
||||
int NDECL(check_dungeon);
|
||||
int NDECL(check_branch);
|
||||
int NDECL(check_level);
|
||||
void NDECL(init_dungeon);
|
||||
void NDECL(init_branch);
|
||||
void NDECL(init_level);
|
||||
void NDECL(output_dgn);
|
||||
|
||||
#define Free(ptr) free((genericptr_t)ptr)
|
||||
|
||||
#ifdef AMIGA
|
||||
# undef printf
|
||||
#ifndef LATTICE
|
||||
# define memset(addr,val,len) setmem(addr,len,val)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ERR (-1)
|
||||
|
||||
static struct couple couple;
|
||||
static struct tmpdungeon tmpdungeon[MAXDUNGEON];
|
||||
static struct tmplevel tmplevel[LEV_LIMIT];
|
||||
static struct tmpbranch tmpbranch[BRANCH_LIMIT];
|
||||
|
||||
static int in_dungeon = 0, n_dgns = -1, n_levs = -1, n_brs = -1;
|
||||
|
||||
extern int fatal_error;
|
||||
extern const char *fname;
|
||||
extern FILE *yyin, *yyout; /* from dgn_lex.c */
|
||||
|
||||
%}
|
||||
|
||||
%union
|
||||
{
|
||||
int i;
|
||||
char* str;
|
||||
}
|
||||
|
||||
%token <i> INTEGER
|
||||
%token <i> A_DUNGEON BRANCH CHBRANCH LEVEL RNDLEVEL CHLEVEL RNDCHLEVEL
|
||||
%token <i> UP_OR_DOWN PROTOFILE DESCRIPTION DESCRIPTOR LEVELDESC
|
||||
%token <i> ALIGNMENT LEVALIGN ENTRY STAIR NO_UP NO_DOWN PORTAL
|
||||
%token <str> STRING
|
||||
%type <i> optional_int direction branch_type bones_tag
|
||||
%start file
|
||||
|
||||
%%
|
||||
file : /* nothing */
|
||||
| dungeons
|
||||
{
|
||||
output_dgn();
|
||||
}
|
||||
;
|
||||
|
||||
dungeons : dungeon
|
||||
| dungeons dungeon
|
||||
;
|
||||
|
||||
dungeon : dungeonline
|
||||
| dungeondesc
|
||||
| branches
|
||||
| levels
|
||||
;
|
||||
|
||||
dungeonline : A_DUNGEON ':' STRING bones_tag rcouple optional_int
|
||||
{
|
||||
init_dungeon();
|
||||
Strcpy(tmpdungeon[n_dgns].name, $3);
|
||||
tmpdungeon[n_dgns].boneschar = (char)$4;
|
||||
tmpdungeon[n_dgns].lev.base = couple.base;
|
||||
tmpdungeon[n_dgns].lev.rand = couple.rand;
|
||||
tmpdungeon[n_dgns].chance = $6;
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
optional_int : /* nothing */
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
| INTEGER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
dungeondesc : entry
|
||||
| descriptions
|
||||
| prototype
|
||||
;
|
||||
|
||||
entry : ENTRY ':' INTEGER
|
||||
{
|
||||
tmpdungeon[n_dgns].entry_lev = $3;
|
||||
}
|
||||
;
|
||||
|
||||
descriptions : desc
|
||||
;
|
||||
|
||||
desc : DESCRIPTION ':' DESCRIPTOR
|
||||
{
|
||||
if($<i>3 <= TOWN || $<i>3 >= D_ALIGN_CHAOTIC)
|
||||
yyerror("Illegal description - ignoring!");
|
||||
else
|
||||
tmpdungeon[n_dgns].flags |= $<i>3 ;
|
||||
}
|
||||
| ALIGNMENT ':' DESCRIPTOR
|
||||
{
|
||||
if($<i>3 && $<i>3 < D_ALIGN_CHAOTIC)
|
||||
yyerror("Illegal alignment - ignoring!");
|
||||
else
|
||||
tmpdungeon[n_dgns].flags |= $<i>3 ;
|
||||
}
|
||||
;
|
||||
|
||||
prototype : PROTOFILE ':' STRING
|
||||
{
|
||||
Strcpy(tmpdungeon[n_dgns].protoname, $3);
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
levels : level1
|
||||
| level2
|
||||
| levdesc
|
||||
| chlevel1
|
||||
| chlevel2
|
||||
;
|
||||
|
||||
level1 : LEVEL ':' STRING bones_tag '@' acouple
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
}
|
||||
| RNDLEVEL ':' STRING bones_tag '@' acouple INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].rndlevs = $7;
|
||||
tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
level2 : LEVEL ':' STRING bones_tag '@' acouple INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].chance = $7;
|
||||
tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
}
|
||||
| RNDLEVEL ':' STRING bones_tag '@' acouple INTEGER INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].chance = $7;
|
||||
tmplevel[n_levs].rndlevs = $8;
|
||||
tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
levdesc : LEVELDESC ':' DESCRIPTOR
|
||||
{
|
||||
if($<i>3 >= D_ALIGN_CHAOTIC)
|
||||
yyerror("Illegal description - ignoring!");
|
||||
else
|
||||
tmplevel[n_levs].flags |= $<i>3 ;
|
||||
}
|
||||
| LEVALIGN ':' DESCRIPTOR
|
||||
{
|
||||
if($<i>3 && $<i>3 < D_ALIGN_CHAOTIC)
|
||||
yyerror("Illegal alignment - ignoring!");
|
||||
else
|
||||
tmplevel[n_levs].flags |= $<i>3 ;
|
||||
}
|
||||
;
|
||||
|
||||
chlevel1 : CHLEVEL ':' STRING bones_tag STRING '+' rcouple
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].chain = getchain($5);
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
if(!check_level()) n_levs--;
|
||||
else tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
Free($5);
|
||||
}
|
||||
| RNDCHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].chain = getchain($5);
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].rndlevs = $8;
|
||||
if(!check_level()) n_levs--;
|
||||
else tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
Free($5);
|
||||
}
|
||||
;
|
||||
|
||||
chlevel2 : CHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].chain = getchain($5);
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].chance = $8;
|
||||
if(!check_level()) n_levs--;
|
||||
else tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
Free($5);
|
||||
}
|
||||
| RNDCHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].chain = getchain($5);
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].chance = $8;
|
||||
tmplevel[n_levs].rndlevs = $9;
|
||||
if(!check_level()) n_levs--;
|
||||
else tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
Free($5);
|
||||
}
|
||||
;
|
||||
|
||||
branches : branch
|
||||
| chbranch
|
||||
;
|
||||
|
||||
branch : BRANCH ':' STRING '@' acouple branch_type direction
|
||||
{
|
||||
init_branch();
|
||||
Strcpy(tmpbranch[n_brs].name, $3);
|
||||
tmpbranch[n_brs].lev.base = couple.base;
|
||||
tmpbranch[n_brs].lev.rand = couple.rand;
|
||||
tmpbranch[n_brs].type = $6;
|
||||
tmpbranch[n_brs].up = $7;
|
||||
if(!check_branch()) n_brs--;
|
||||
else tmpdungeon[n_dgns].branches++;
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
chbranch : CHBRANCH ':' STRING STRING '+' rcouple branch_type direction
|
||||
{
|
||||
init_branch();
|
||||
Strcpy(tmpbranch[n_brs].name, $3);
|
||||
tmpbranch[n_brs].chain = getchain($4);
|
||||
tmpbranch[n_brs].lev.base = couple.base;
|
||||
tmpbranch[n_brs].lev.rand = couple.rand;
|
||||
tmpbranch[n_brs].type = $7;
|
||||
tmpbranch[n_brs].up = $8;
|
||||
if(!check_branch()) n_brs--;
|
||||
else tmpdungeon[n_dgns].branches++;
|
||||
Free($3);
|
||||
Free($4);
|
||||
}
|
||||
;
|
||||
|
||||
branch_type : /* nothing */
|
||||
{
|
||||
$$ = TBR_STAIR; /* two way stair */
|
||||
}
|
||||
| STAIR
|
||||
{
|
||||
$$ = TBR_STAIR; /* two way stair */
|
||||
}
|
||||
| NO_UP
|
||||
{
|
||||
$$ = TBR_NO_UP; /* no up staircase */
|
||||
}
|
||||
| NO_DOWN
|
||||
{
|
||||
$$ = TBR_NO_DOWN; /* no down staircase */
|
||||
}
|
||||
| PORTAL
|
||||
{
|
||||
$$ = TBR_PORTAL; /* portal connection */
|
||||
}
|
||||
;
|
||||
|
||||
direction : /* nothing */
|
||||
{
|
||||
$$ = 0; /* defaults to down */
|
||||
}
|
||||
| UP_OR_DOWN
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
bones_tag : STRING
|
||||
{
|
||||
char *p = $1;
|
||||
if (strlen(p) != 1) {
|
||||
if (strcmp(p, "none") != 0)
|
||||
yyerror("Bones marker must be a single char, or \"none\"!");
|
||||
*p = '\0';
|
||||
}
|
||||
$$ = *p;
|
||||
Free(p);
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* acouple rules:
|
||||
*
|
||||
* (base, range) where:
|
||||
*
|
||||
* base is either a positive or negative integer with a value
|
||||
* less than or equal to MAXLEVEL.
|
||||
* base > 0 indicates the base level.
|
||||
* base < 0 indicates reverse index (-1 == lowest level)
|
||||
*
|
||||
* range is the random component.
|
||||
* if range is zero, there is no random component.
|
||||
* if range is -1 the dungeon loader will randomize between
|
||||
* the base and the end of the dungeon.
|
||||
* during dungeon load, range is always *added* to the base,
|
||||
* therefore range + base(converted) must not exceed MAXLEVEL.
|
||||
*/
|
||||
acouple : '(' INTEGER ',' INTEGER ')'
|
||||
{
|
||||
if ($2 < -MAXLEVEL || $2 > MAXLEVEL) {
|
||||
yyerror("Abs base out of dlevel range - zeroing!");
|
||||
couple.base = couple.rand = 0;
|
||||
} else if ($4 < -1 ||
|
||||
(($2 < 0) ? (MAXLEVEL + $2 + $4 + 1) > MAXLEVEL :
|
||||
($2 + $4) > MAXLEVEL)) {
|
||||
yyerror("Abs range out of dlevel range - zeroing!");
|
||||
couple.base = couple.rand = 0;
|
||||
} else {
|
||||
couple.base = $2;
|
||||
couple.rand = $4;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* rcouple rules:
|
||||
*
|
||||
* (base, range) where:
|
||||
*
|
||||
* base is either a positive or negative integer with a value
|
||||
* less than or equal to MAXLEVEL.
|
||||
* base > 0 indicates a forward index.
|
||||
* base < 0 indicates a reverse index.
|
||||
* base == 0 indicates on the parent level.
|
||||
*
|
||||
* range is the random component.
|
||||
* if range is zero, there is no random component.
|
||||
* during dungeon load, range is always *added* to the base,
|
||||
* range + base(converted) may be very large. The dungeon
|
||||
* loader will then correct to "between here and the top/bottom".
|
||||
*
|
||||
* There is no practical way of specifying "between here and the
|
||||
* nth / nth last level".
|
||||
*/
|
||||
rcouple : '(' INTEGER ',' INTEGER ')'
|
||||
{
|
||||
if ($2 < -MAXLEVEL || $2 > MAXLEVEL) {
|
||||
yyerror("Rel base out of dlevel range - zeroing!");
|
||||
couple.base = couple.rand = 0;
|
||||
} else {
|
||||
couple.base = $2;
|
||||
couple.rand = $4;
|
||||
}
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
void
|
||||
init_dungeon()
|
||||
{
|
||||
if(++n_dgns > MAXDUNGEON) {
|
||||
(void) fprintf(stderr, "FATAL - Too many dungeons (limit: %d).\n",
|
||||
MAXDUNGEON);
|
||||
(void) fprintf(stderr, "To increase the limit edit MAXDUNGEON in global.h\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
in_dungeon = 1;
|
||||
tmpdungeon[n_dgns].lev.base = 0;
|
||||
tmpdungeon[n_dgns].lev.rand = 0;
|
||||
tmpdungeon[n_dgns].chance = 100;
|
||||
Strcpy(tmpdungeon[n_dgns].name, "");
|
||||
Strcpy(tmpdungeon[n_dgns].protoname, "");
|
||||
tmpdungeon[n_dgns].flags = 0;
|
||||
tmpdungeon[n_dgns].levels = 0;
|
||||
tmpdungeon[n_dgns].branches = 0;
|
||||
tmpdungeon[n_dgns].entry_lev = 0;
|
||||
}
|
||||
|
||||
void
|
||||
init_level()
|
||||
{
|
||||
if(++n_levs > LEV_LIMIT) {
|
||||
|
||||
yyerror("FATAL - Too many special levels defined.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
tmplevel[n_levs].lev.base = 0;
|
||||
tmplevel[n_levs].lev.rand = 0;
|
||||
tmplevel[n_levs].chance = 100;
|
||||
tmplevel[n_levs].rndlevs = 0;
|
||||
tmplevel[n_levs].flags = 0;
|
||||
Strcpy(tmplevel[n_levs].name, "");
|
||||
tmplevel[n_levs].chain = -1;
|
||||
}
|
||||
|
||||
void
|
||||
init_branch()
|
||||
{
|
||||
if(++n_brs > BRANCH_LIMIT) {
|
||||
|
||||
yyerror("FATAL - Too many special levels defined.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
tmpbranch[n_brs].lev.base = 0;
|
||||
tmpbranch[n_brs].lev.rand = 0;
|
||||
Strcpy(tmpbranch[n_brs].name, "");
|
||||
tmpbranch[n_brs].chain = -1;
|
||||
}
|
||||
|
||||
int
|
||||
getchain(s)
|
||||
char *s;
|
||||
{
|
||||
int i;
|
||||
|
||||
if(strlen(s)) {
|
||||
|
||||
for(i = n_levs - tmpdungeon[n_dgns].levels + 1; i <= n_levs; i++)
|
||||
if(!strcmp(tmplevel[i].name, s)) return i;
|
||||
|
||||
yyerror("Can't locate the specified chain level.");
|
||||
return(-2);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Consistancy checking routines:
|
||||
*
|
||||
* - A dungeon must have a unique name.
|
||||
* - A dungeon must have a originating "branch" command
|
||||
* (except, of course, for the first dungeon).
|
||||
* - A dungeon must have a proper depth (at least (1, 0)).
|
||||
*/
|
||||
|
||||
int
|
||||
check_dungeon()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < n_dgns; i++)
|
||||
if(!strcmp(tmpdungeon[i].name, tmpdungeon[n_dgns].name)) {
|
||||
yyerror("Duplicate dungeon name.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(n_dgns)
|
||||
for(i = 0; i < n_brs - tmpdungeon[n_dgns].branches; i++) {
|
||||
if(!strcmp(tmpbranch[i].name, tmpdungeon[n_dgns].name)) break;
|
||||
|
||||
if(i >= n_brs - tmpdungeon[n_dgns].branches) {
|
||||
yyerror("Dungeon cannot be reached.");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
if(tmpdungeon[n_dgns].lev.base <= 0 ||
|
||||
tmpdungeon[n_dgns].lev.rand < 0) {
|
||||
yyerror("Invalid dungeon depth specified.");
|
||||
return(0);
|
||||
}
|
||||
return(1); /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* - A level must have a unique level name.
|
||||
* - If chained, the level used as reference for the chain
|
||||
* must be in this dungeon, must be previously defined, and
|
||||
* the level chained from must be "non-probabilistic" (ie.
|
||||
* have a 100% chance of existing).
|
||||
*/
|
||||
|
||||
int
|
||||
check_level()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!in_dungeon) {
|
||||
yyerror("Level defined outside of dungeon.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
for(i = 0; i < n_levs; i++)
|
||||
if(!strcmp(tmplevel[i].name, tmplevel[n_levs].name)) {
|
||||
yyerror("Duplicate level name.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(tmplevel[i].chain == -2) {
|
||||
yyerror("Invaild level chain reference.");
|
||||
return(0);
|
||||
} else if(tmplevel[i].chain != -1) { /* there is a chain */
|
||||
/* KMH -- tmplevel[tmpbranch[i].chain].chance was in error */
|
||||
if(tmplevel[tmplevel[i].chain].chance != 100) {
|
||||
yyerror("Level cannot chain from a probabilistic level.");
|
||||
return(0);
|
||||
} else if(tmplevel[i].chain == n_levs) {
|
||||
yyerror("A level cannot chain to itself!");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1); /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* - A branch may not branch backwards - to avoid branch loops.
|
||||
* - A branch name must be unique.
|
||||
* (ie. You can only have one entry point to each dungeon).
|
||||
* - If chained, the level used as reference for the chain
|
||||
* must be in this dungeon, must be previously defined, and
|
||||
* the level chained from must be "non-probabilistic" (ie.
|
||||
* have a 100% chance of existing).
|
||||
*/
|
||||
|
||||
int
|
||||
check_branch()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!in_dungeon) {
|
||||
yyerror("Branch defined outside of dungeon.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
for(i = 0; i < n_dgns; i++)
|
||||
if(!strcmp(tmpdungeon[i].name, tmpbranch[n_brs].name)) {
|
||||
|
||||
yyerror("Reverse branching not allowed.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(tmpbranch[i].chain == -2) {
|
||||
|
||||
yyerror("Invaild branch chain reference.");
|
||||
return(0);
|
||||
} else if(tmpbranch[i].chain != -1) { /* it is chained */
|
||||
|
||||
if(tmplevel[tmpbranch[i].chain].chance != 100) {
|
||||
yyerror("Branch cannot chain from a probabilistic level.");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1); /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Output the dungon definition into a file.
|
||||
*
|
||||
* The file will have the following format:
|
||||
*
|
||||
* [ nethack version ID ]
|
||||
* [ number of dungeons ]
|
||||
* [ first dungeon struct ]
|
||||
* [ levels for the first dungeon ]
|
||||
* ...
|
||||
* [ branches for the first dungeon ]
|
||||
* ...
|
||||
* [ second dungeon struct ]
|
||||
* ...
|
||||
*/
|
||||
|
||||
void
|
||||
output_dgn()
|
||||
{
|
||||
int nd, cl = 0, nl = 0,
|
||||
cb = 0, nb = 0;
|
||||
static struct version_info version_data = {
|
||||
VERSION_NUMBER, VERSION_FEATURES,
|
||||
VERSION_SANITY1, VERSION_SANITY2, VERSION_SANITY3
|
||||
};
|
||||
|
||||
if(++n_dgns <= 0) {
|
||||
yyerror("FATAL - no dungeons were defined.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite((char *)&version_data, sizeof version_data, 1, yyout) != 1) {
|
||||
yyerror("FATAL - output failure.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
(void) fwrite((char *)&n_dgns, sizeof(int), 1, yyout);
|
||||
for (nd = 0; nd < n_dgns; nd++) {
|
||||
(void) fwrite((char *)&tmpdungeon[nd], sizeof(struct tmpdungeon),
|
||||
1, yyout);
|
||||
|
||||
nl += tmpdungeon[nd].levels;
|
||||
for(; cl < nl; cl++)
|
||||
(void) fwrite((char *)&tmplevel[cl], sizeof(struct tmplevel),
|
||||
1, yyout);
|
||||
|
||||
nb += tmpdungeon[nd].branches;
|
||||
for(; cb < nb; cb++)
|
||||
(void) fwrite((char *)&tmpbranch[cb], sizeof(struct tmpbranch),
|
||||
1, yyout);
|
||||
}
|
||||
/* apparently necessary for Think C 5.x, otherwise harmless */
|
||||
(void) fflush(yyout);
|
||||
}
|
||||
|
||||
/*dgn_comp.y*/
|
||||
193
util/dgn_main.c
193
util/dgn_main.c
@@ -1,193 +0,0 @@
|
||||
/* NetHack 3.6 dgn_main.c $NHDT-Date: 1432512785 2015/05/25 00:13:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* Copyright (c) 1990 by M. Stephenson */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
/*
|
||||
* This file contains the main function for the parser
|
||||
* and some useful functions needed by yacc
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "dlb.h"
|
||||
|
||||
/* Macintosh-specific code */
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
/* MacOS X has Unix-style files and processes */
|
||||
#undef MAC
|
||||
#endif
|
||||
#ifdef MAC
|
||||
#if defined(__SC__) || defined(__MRC__)
|
||||
#define MPWTOOL
|
||||
#include <CursorCtl.h>
|
||||
#else
|
||||
/* put dungeon file in library location */
|
||||
#define PREFIX ":lib:"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MPWTOOL
|
||||
#define SpinCursor(x)
|
||||
#endif
|
||||
|
||||
#define MAX_ERRORS 25
|
||||
|
||||
extern int NDECL(yyparse);
|
||||
extern int nh_line_number;
|
||||
const char *fname = "(stdin)";
|
||||
int fatal_error = 0;
|
||||
|
||||
int FDECL(main, (int, char **));
|
||||
void FDECL(yyerror, (const char *));
|
||||
void FDECL(yywarning, (const char *));
|
||||
int NDECL(yywrap);
|
||||
void FDECL(init_yyin, (FILE *));
|
||||
void FDECL(init_yyout, (FILE *));
|
||||
|
||||
#ifdef AZTEC_36
|
||||
FILE *FDECL(freopen, (char *, char *, FILE *));
|
||||
#endif
|
||||
#define Fprintf (void) fprintf
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(_WIN32)
|
||||
extern unsigned _stklen = STKSIZ;
|
||||
#endif
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char infile[64], outfile[64], basename[64];
|
||||
FILE *fin, *fout;
|
||||
int i, len;
|
||||
boolean errors_encountered = FALSE;
|
||||
#if defined(MAC) && (defined(THINK_C) || defined(__MWERKS__))
|
||||
char *mark;
|
||||
static char *mac_argv[] = { "dgn_comp", /* dummy argv[0] */
|
||||
":dat:dungeon.pdf" };
|
||||
|
||||
argc = SIZE(mac_argv);
|
||||
argv = mac_argv;
|
||||
#endif
|
||||
|
||||
Strcpy(infile, "(stdin)");
|
||||
fin = stdin;
|
||||
Strcpy(outfile, "(stdout)");
|
||||
fout = stdout;
|
||||
|
||||
if (argc == 1) { /* Read standard input */
|
||||
init_yyin(fin);
|
||||
init_yyout(fout);
|
||||
(void) yyparse();
|
||||
if (fatal_error > 0)
|
||||
errors_encountered = TRUE;
|
||||
} else { /* Otherwise every argument is a filename */
|
||||
for (i = 1; i < argc; i++) {
|
||||
fname = strcpy(infile, argv[i]);
|
||||
/* the input file had better be a .pdf file */
|
||||
len = strlen(fname) - 4; /* length excluding suffix */
|
||||
if (len < 0 || strncmp(".pdf", fname + len, 4)) {
|
||||
Fprintf(stderr, "Error - file name \"%s\" in wrong format.\n",
|
||||
fname);
|
||||
errors_encountered = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* build output file name */
|
||||
#if defined(MAC) && (defined(THINK_C) || defined(__MWERKS__))
|
||||
/* extract basename from path to infile */
|
||||
mark = strrchr(infile, ':');
|
||||
strcpy(basename, mark ? mark + 1 : infile);
|
||||
mark = strchr(basename, '.');
|
||||
if (mark)
|
||||
*mark = '\0';
|
||||
#else
|
||||
/* Use the whole name - strip off the last 3 or 4 chars. */
|
||||
|
||||
#ifdef VMS /* avoid possible interaction with logical name */
|
||||
len++; /* retain "." as trailing punctuation */
|
||||
#endif
|
||||
(void) strncpy(basename, infile, len);
|
||||
basename[len] = '\0';
|
||||
#endif
|
||||
|
||||
outfile[0] = '\0';
|
||||
#ifdef PREFIX
|
||||
(void) strcat(outfile, PREFIX);
|
||||
#endif
|
||||
(void) strcat(outfile, basename);
|
||||
|
||||
fin = freopen(infile, "r", stdin);
|
||||
if (!fin) {
|
||||
Fprintf(stderr, "Can't open %s for input.\n", infile);
|
||||
perror(infile);
|
||||
errors_encountered = TRUE;
|
||||
continue;
|
||||
}
|
||||
fout = freopen(outfile, WRBMODE, stdout);
|
||||
if (!fout) {
|
||||
Fprintf(stderr, "Can't open %s for output.\n", outfile);
|
||||
perror(outfile);
|
||||
errors_encountered = TRUE;
|
||||
continue;
|
||||
}
|
||||
init_yyin(fin);
|
||||
init_yyout(fout);
|
||||
(void) yyparse();
|
||||
nh_line_number = 1;
|
||||
if (fatal_error > 0) {
|
||||
errors_encountered = TRUE;
|
||||
fatal_error = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fout && fclose(fout) < 0) {
|
||||
Fprintf(stderr, "Can't finish output file.");
|
||||
perror(outfile);
|
||||
errors_encountered = TRUE;
|
||||
}
|
||||
exit(errors_encountered ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Each time the parser detects an error, it uses this function.
|
||||
* Here we take count of the errors. To continue farther than
|
||||
* MAX_ERRORS wouldn't be reasonable.
|
||||
*/
|
||||
|
||||
void
|
||||
yyerror(s)
|
||||
const char *s;
|
||||
{
|
||||
(void) fprintf(stderr, "%s : line %d : %s\n", fname, nh_line_number, s);
|
||||
if (++fatal_error > MAX_ERRORS) {
|
||||
(void) fprintf(stderr, "Too many errors, good bye!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Just display a warning (that is : a non fatal error)
|
||||
*/
|
||||
|
||||
void
|
||||
yywarning(s)
|
||||
const char *s;
|
||||
{
|
||||
(void) fprintf(stderr, "%s : line %d : WARNING : %s\n", fname,
|
||||
nh_line_number, s);
|
||||
}
|
||||
|
||||
int
|
||||
yywrap()
|
||||
{
|
||||
SpinCursor(3); /* Don't know if this is a good place to put it ?
|
||||
Is it called for our grammar ?
|
||||
Often enough ?
|
||||
Too often ? -- h+ */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*dgn_main.c*/
|
||||
Reference in New Issue
Block a user