aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2017-10-22 16:45:57 -0400
committerClyne Sullivan <tullivan99@gmail.com>2017-10-22 16:45:57 -0400
commitf785f17cdb286449e8d98be747213740172629c5 (patch)
tree836d9601046f20737d2c27c35c673318adfc2f88
parentb64aa31b4dc0c5e050c4978bae7bd43a040a368b (diff)
removed random gen, indoor changes
-rw-r--r--assets/style/indoors/bg/bg.pngbin0 -> 863 bytes
-rw-r--r--assets/style/indoors/bg/bgFarMountain.pngbin0 -> 36511 bytes
-rw-r--r--assets/style/indoors/bg/bgWoodTile.pngbin0 -> 1050873 bytes
-rw-r--r--assets/style/indoors/bg/carpet.pngbin0 -> 156 bytes
-rw-r--r--assets/style/indoors/bg/dirt.pngbin0 -> 228 bytes
-rw-r--r--assets/style/indoors/bg/forestTileBack.pngbin0 -> 11182 bytes
-rw-r--r--assets/style/indoors/bg/forestTileFar.pngbin0 -> 12789 bytes
-rw-r--r--assets/style/indoors/bg/forestTileFront.pngbin0 -> 9099 bytes
-rw-r--r--assets/style/indoors/bg/forestTileMid.pngbin0 -> 11273 bytes
-rw-r--r--assets/style/indoors/bg/grass.pngbin0 -> 158 bytes
-rw-r--r--assets/style/indoors/bg/insideWoodHouse.pngbin0 -> 8078 bytes
-rw-r--r--assets/style/indoors/bg/star.pngbin0 -> 731 bytes
-rw-r--r--include/world.hpp1
-rw-r--r--src/systems/light.cpp2
-rw-r--r--src/world.cpp276
-rw-r--r--xml/!town.xml12
-rw-r--r--xml/bobshouse.xml22
17 files changed, 120 insertions, 193 deletions
diff --git a/assets/style/indoors/bg/bg.png b/assets/style/indoors/bg/bg.png
new file mode 100644
index 0000000..d3ada5d
--- /dev/null
+++ b/assets/style/indoors/bg/bg.png
Binary files differ
diff --git a/assets/style/indoors/bg/bgFarMountain.png b/assets/style/indoors/bg/bgFarMountain.png
new file mode 100644
index 0000000..f7e2bb9
--- /dev/null
+++ b/assets/style/indoors/bg/bgFarMountain.png
Binary files differ
diff --git a/assets/style/indoors/bg/bgWoodTile.png b/assets/style/indoors/bg/bgWoodTile.png
new file mode 100644
index 0000000..e10dd1f
--- /dev/null
+++ b/assets/style/indoors/bg/bgWoodTile.png
Binary files differ
diff --git a/assets/style/indoors/bg/carpet.png b/assets/style/indoors/bg/carpet.png
new file mode 100644
index 0000000..5585096
--- /dev/null
+++ b/assets/style/indoors/bg/carpet.png
Binary files differ
diff --git a/assets/style/indoors/bg/dirt.png b/assets/style/indoors/bg/dirt.png
new file mode 100644
index 0000000..11252ac
--- /dev/null
+++ b/assets/style/indoors/bg/dirt.png
Binary files differ
diff --git a/assets/style/indoors/bg/forestTileBack.png b/assets/style/indoors/bg/forestTileBack.png
new file mode 100644
index 0000000..d1c621a
--- /dev/null
+++ b/assets/style/indoors/bg/forestTileBack.png
Binary files differ
diff --git a/assets/style/indoors/bg/forestTileFar.png b/assets/style/indoors/bg/forestTileFar.png
new file mode 100644
index 0000000..db2fe8b
--- /dev/null
+++ b/assets/style/indoors/bg/forestTileFar.png
Binary files differ
diff --git a/assets/style/indoors/bg/forestTileFront.png b/assets/style/indoors/bg/forestTileFront.png
new file mode 100644
index 0000000..0dac8e5
--- /dev/null
+++ b/assets/style/indoors/bg/forestTileFront.png
Binary files differ
diff --git a/assets/style/indoors/bg/forestTileMid.png b/assets/style/indoors/bg/forestTileMid.png
new file mode 100644
index 0000000..24b64f7
--- /dev/null
+++ b/assets/style/indoors/bg/forestTileMid.png
Binary files differ
diff --git a/assets/style/indoors/bg/grass.png b/assets/style/indoors/bg/grass.png
new file mode 100644
index 0000000..fc49f0b
--- /dev/null
+++ b/assets/style/indoors/bg/grass.png
Binary files differ
diff --git a/assets/style/indoors/bg/insideWoodHouse.png b/assets/style/indoors/bg/insideWoodHouse.png
new file mode 100644
index 0000000..f926cb2
--- /dev/null
+++ b/assets/style/indoors/bg/insideWoodHouse.png
Binary files differ
diff --git a/assets/style/indoors/bg/star.png b/assets/style/indoors/bg/star.png
new file mode 100644
index 0000000..6360d30
--- /dev/null
+++ b/assets/style/indoors/bg/star.png
Binary files differ
diff --git a/include/world.hpp b/include/world.hpp
index 991990e..0bfe078 100644
--- a/include/world.hpp
+++ b/include/world.hpp
@@ -160,7 +160,6 @@ public:
static void goWorldPortal(Position& p);
static void generate(LuaScript& script);
- static void generate(int width = 0);
static bool save(void);
static void load(const std::string& file);
diff --git a/src/systems/light.cpp b/src/systems/light.cpp
index 361099d..51a6702 100644
--- a/src/systems/light.cpp
+++ b/src/systems/light.cpp
@@ -26,7 +26,7 @@ void LightSystem::render(void) {
unsigned int offset = 0;
for (const auto& l : lights) {
coords[offset] = l.pos.x, coords[offset + 1] = l.pos.y,
- coords[offset + 2] = 0, coords[offset + 3] = l.radius;
+ coords[offset + 2] = -5, coords[offset + 3] = l.radius;
colors[offset] = l.color.red, colors[offset + 1] = l.color.green,
colors[offset + 2] = l.color.blue, colors[offset + 3] = 1.0f;
offset += 4;
diff --git a/src/world.cpp b/src/world.cpp
index f55b39d..e54a7ec 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -45,15 +45,6 @@ static bool waitToSwap = false;
// externally referenced in main.cpp
int worldShade = 0;
-// ground-generating constants
-constexpr const float GROUND_HEIGHT_INITIAL = 80.0f;
-constexpr const float GROUND_HEIGHT_MINIMUM = 60.0f;
-constexpr const float GROUND_HEIGHT_MAXIMUM = 110.0f;
-constexpr const float GROUND_HILLINESS = 10.0f;
-
-// defines grass height in HLINEs
-const unsigned int GRASS_HEIGHT = HLINES(4);
-
WorldSystem::WorldSystem(void)
{
bgmObj = nullptr;
@@ -97,52 +88,6 @@ void WorldSystem::generate(LuaScript& script)
}
}
-void WorldSystem::generate(int width)
-{
- float geninc = 0;
-
- // allocate space for world
- world.data = std::vector<WorldData> (width + GROUND_HILLINESS);
-
- // prepare for generation
- world.data[0].groundHeight = GROUND_HEIGHT_INITIAL;
- auto wditer = std::begin(world.data) + GROUND_HILLINESS;
-
- if (world.indoor) {
- std::fill(world.data.begin(), world.data.end(), WorldData {true, {0, 0}, GROUND_HEIGHT_MINIMUM + 5, 4});
- } else {
- // give every GROUND_HILLINESSth entry a groundHeight value
- for (; wditer < std::end(world.data); wditer += GROUND_HILLINESS)
- wditer[-static_cast<int>(GROUND_HILLINESS)].groundHeight = wditer[0].groundHeight + (randGet() % 8 - 4);
-
- // create slopes from the points that were just defined, populate the rest of the WorldData structure
- for (wditer = std::begin(world.data) + 1; wditer < std::end(world.data); wditer++) {
- auto w = &*(wditer);
-
- if (w->groundHeight != 0)
- geninc = (w[static_cast<int>(GROUND_HILLINESS)].groundHeight - w->groundHeight) / GROUND_HILLINESS;
-
- w->groundHeight = std::clamp(w[-1].groundHeight + geninc, GROUND_HEIGHT_MINIMUM, GROUND_HEIGHT_MAXIMUM);
- w->groundColor = randGet() % 32 / 8;
- w->grassUnpressed = true;
- w->grassHeight[0] = (randGet() % 16) / 3 + HLINES(2);
- w->grassHeight[1] = (randGet() % 16) / 3 + HLINES(2);
- }
- }
-
- // define x-coordinate of world's leftmost 'line'
- world.startX = HLINES(width * -0.5);
-
- // gen. star coordinates
- if (stars.empty()) {
- stars.resize(game::SCREEN_WIDTH / 30);
- for (auto& s : stars) {
- s.x = world.startX + (randGet() % (int)HLINES(width));
- s.y = game::SCREEN_HEIGHT - (randGet() % (int)HLINES(game::SCREEN_HEIGHT / 1.3f));
- }
- }
-}
-
float WorldSystem::isAboveGround(const vec2& p)
{
const auto& gh = world.data[getLineIndex(p.x)].groundHeight;
@@ -307,14 +252,9 @@ void WorldSystem::loader(void)
}
// world generation
- else if (tagName == "generation") {
- auto text = wxml->GetText();
- if (text == nullptr)
- generate(wxml->IntAttribute("width"));
- else {
- LuaScript script (text);
- generate(script);
- }
+ else if (tagName == "generation") {
+ LuaScript script (wxml->GetText());
+ generate(script);
}
// indoor stuff
@@ -591,7 +531,7 @@ void WorldSystem::render(void)
for (int j = 0; j < count; j++) {
GLfloat five[5] = {
- 0, 0, mountainDim.x * j + xcoord, GROUND_HEIGHT_MINIMUM, z
+ 0, 0, mountainDim.x * j + xcoord, 0, z
};
push5(bgItemsFront, five);
@@ -619,12 +559,12 @@ void WorldSystem::render(void)
world.indoorTex.use();
auto dim = world.indoorTex.getDim() * game::HLINE;
GLfloat verts[] = {
- world.startX, GROUND_HEIGHT_MINIMUM, z, 0, 0,
- world.startX + dim.x, GROUND_HEIGHT_MINIMUM, z, 1, 0,
- world.startX + dim.x, GROUND_HEIGHT_MINIMUM + dim.y, z, 1, 1,
- world.startX + dim.x, GROUND_HEIGHT_MINIMUM + dim.y, z, 1, 1,
- world.startX, GROUND_HEIGHT_MINIMUM + dim.y, z, 0, 1,
- world.startX, GROUND_HEIGHT_MINIMUM, z, 0, 0,
+ world.startX, 0, z, 0, 0,
+ world.startX + dim.x, 0, z, 1, 0,
+ world.startX + dim.x, dim.y, z, 1, 1,
+ world.startX + dim.x, dim.y, z, 1, 1,
+ world.startX, dim.y, z, 0, 1,
+ world.startX, 0, z, 0, 0,
};
glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), verts);
@@ -640,10 +580,10 @@ void WorldSystem::render(void)
pOffset = (offset.x - world.startX) / game::HLINE;
// only draw world within player vision
- iStart = std::clamp(static_cast<int>(pOffset - (SCREEN_WIDTH / 2 / game::HLINE) - GROUND_HILLINESS),
+ iStart = std::clamp(static_cast<int>(pOffset - (SCREEN_WIDTH / 2 / game::HLINE)),
0, static_cast<int>(world.data.size()));
iEnd = std::clamp(static_cast<int>(pOffset + (SCREEN_WIDTH / 2 / game::HLINE) + 2),
- 0, static_cast<int>(world.data.size() - GROUND_HILLINESS));
+ 0, static_cast<int>(world.data.size()));
// draw the dirt
waitToSwap = true;
@@ -659,16 +599,9 @@ void WorldSystem::render(void)
GLfloat *dirtp = &dirt[0];
for (int i = iStart; i < iEnd; i++) {
- if (world.data[i].groundHeight <= 0) { // TODO holes (andy)
- world.data[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1;
- //glColor4ub(0, 0, 0, 255);
- } else {
- //safeSetColorA(150, 150, 150, 255);
- }
-
int ty = world.data[i].groundHeight / 64 + world.data[i].groundColor;
GLfloat five[5] = {
- 0, 0, world.startX + HLINES(i), world.data[i].groundHeight - GRASS_HEIGHT, z - 0.1f
+ 0, 0, world.startX + HLINES(i), world.data[i].groundHeight, z - 0.1f
};
push5(dirtp, five);
@@ -679,11 +612,8 @@ void WorldSystem::render(void)
push5(dirtp, five);
five[0]--, five[2] -= game::HLINE;
push5(dirtp, five);
- five[1] = 0, five[3] = world.data[i].groundHeight - GRASS_HEIGHT;
+ five[1] = 0, five[3] = world.data[i].groundHeight;
push5(dirtp, five);
-
- if (world.data[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1)
- world.data[i].groundHeight = 0;
}
glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.45f);
@@ -695,115 +625,105 @@ void WorldSystem::render(void)
Render::worldShader.disable();
Render::worldShader.unuse();
- if (!world.indoor) {
- bgTex++;
- //safeSetColorA(255, 255, 255, 255); TODO
+ bgTex++;
- static std::vector<GLfloat> grass;
- if (grass.size() != world.data.size() * 60) {
- grass.clear();
- grass.resize(world.data.size() * 60);
- }
+ static std::vector<GLfloat> grass;
+ if (grass.size() != world.data.size() * 60) {
+ grass.clear();
+ grass.resize(world.data.size() * 60);
+ }
- GLfloat *grassp = &grass[0];
- for (int i = iStart; i < iEnd; i++) {
- auto wd = world.data[i];
- auto gh = wd.grassHeight;
+ GLfloat *grassp = &grass[0];
+ for (int i = iStart; i < iEnd; i++) {
+ auto wd = world.data[i];
+ auto gh = wd.grassHeight;
- // flatten the grass if the player is standing on it.
- if (!wd.grassUnpressed) {
- gh[0] /= 4;
- gh[1] /= 4;
- }
+ // flatten the grass if the player is standing on it.
+ if (!world.indoor && !wd.grassUnpressed) {
+ gh[0] /= 4;
+ gh[1] /= 4;
+ }
- // actually draw the grass.
- if (wd.groundHeight) {
- float five[5] = {
- 0, 1, world.startX + HLINES(i), wd.groundHeight + gh[0], z - 0.2f
- };
-
- push5(grassp, five);
- five[0]++, five[1]--, five[2] += HLINES(0.5f);
- push5(grassp, five);
- five[1]++, five[3] = wd.groundHeight - GRASS_HEIGHT;
- push5(grassp, five);
- push5(grassp, five);
- five[0]--, five[2] -= HLINES(0.5f);
- push5(grassp, five);
- five[1]--, five[3] = wd.groundHeight + gh[0];
- push5(grassp, five);
- five[1]++;
-
- five[2] = world.startX + HLINES(i + 0.5), five[3] = wd.groundHeight + gh[1];
-
- push5(grassp, five);
- five[0]++, five[1]--, five[2] += HLINES(0.5f) + 1;
- push5(grassp, five);
- five[1]++, five[3] = wd.groundHeight - GRASS_HEIGHT;
- push5(grassp, five);
- push5(grassp, five);
- five[0]--, five[2] -= HLINES(0.5f) + 1;
- push5(grassp, five);
- five[1]--, five[3] = wd.groundHeight + gh[1];
- push5(grassp, five);
- }
+ // actually draw the grass.
+ if (wd.groundHeight) {
+ float five[5] = {
+ 0, 1, world.startX + HLINES(i), wd.groundHeight + gh[0], z - 0.2f
+ };
+
+ push5(grassp, five);
+ five[0]++, five[1]--, five[2] += HLINES(0.5f);
+ push5(grassp, five);
+ five[1]++, five[3] = wd.groundHeight;
+ push5(grassp, five);
+ push5(grassp, five);
+ five[0]--, five[2] -= HLINES(0.5f);
+ push5(grassp, five);
+ five[1]--, five[3] = wd.groundHeight + gh[0];
+ push5(grassp, five);
+ five[1]++;
+
+ five[2] = world.startX + HLINES(i + 0.5), five[3] = wd.groundHeight + gh[1];
+
+ push5(grassp, five);
+ five[0]++, five[1]--, five[2] += HLINES(0.5f) + 1;
+ push5(grassp, five);
+ five[1]++, five[3] = wd.groundHeight;
+ push5(grassp, five);
+ push5(grassp, five);
+ five[0]--, five[2] -= HLINES(0.5f) + 1;
+ push5(grassp, five);
+ five[1]--, five[3] = wd.groundHeight + gh[1];
+ push5(grassp, five);
}
+ }
- Render::worldShader.use();
- glUniform1f(Render::worldShader.uniform[WU_light_impact], 1.0f);
+ Render::worldShader.use();
+ glUniform1f(Render::worldShader.uniform[WU_light_impact], 1.0f);
- Render::worldShader.enable();
+ Render::worldShader.enable();
- glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &grass[2]);
- glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &grass[0]);
- glDrawArrays(GL_TRIANGLES, 0 , grass.size() / 5);
+ glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &grass[2]);
+ glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &grass[0]);
+ glDrawArrays(GL_TRIANGLES, 0 , grass.size() / 5);
- // the starting pixel of the world
- static const float s = -(static_cast<float>(SCREEN_WIDTH) / 2.0f);
- // the ending pixel of the world
- static const float e = static_cast<float>(SCREEN_WIDTH) / 2.0f;
- static const float sheight = static_cast<float>(SCREEN_HEIGHT);
+ // the starting pixel of the world
+ static const float s = -(static_cast<float>(SCREEN_WIDTH) / 2.0f);
+ // the ending pixel of the world
+ static const float e = static_cast<float>(SCREEN_WIDTH) / 2.0f;
+ static const float sheight = static_cast<float>(SCREEN_HEIGHT);
- auto yOffset = offset.y - static_cast<float>(SCREEN_HEIGHT) / 2.0f;
- GLfloat blackBar[] = {
- s, yOffset, z - 0.3f, 0.0f, 0.0f,
- world.startX, yOffset, z - 0.3f, 1.0f, 0.0f,
- world.startX, yOffset + sheight, z - 0.3f, 1.0f, 1.0f,
- world.startX, yOffset + sheight, z - 0.3f, 1.0f, 1.0f,
- s, yOffset + sheight, z - 0.3f, 0.0f, 1.0f,
- s, yOffset, z - 0.3f, 0.0f, 0.0f
- };
+ auto yOffset = offset.y - static_cast<float>(SCREEN_HEIGHT) / 2.0f;
+ GLfloat blackBar[] = {
+ s, yOffset, z - 0.3f, 0.0f, 0.0f,
+ world.startX, yOffset, z - 0.3f, 1.0f, 0.0f,
+ world.startX, yOffset + sheight, z - 0.3f, 1.0f, 1.0f,
+ world.startX, yOffset + sheight, z - 0.3f, 1.0f, 1.0f,
+ s, yOffset + sheight, z - 0.3f, 0.0f, 1.0f,
+ s, yOffset, z - 0.3f, 0.0f, 0.0f
+ };
- if (offset.x + world.startX > s) {
- Colors::black.use();
- glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f);
- glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar);
- glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar + 3);
- glDrawArrays(GL_TRIANGLES, 0, 6);
- }
+ if (offset.x + world.startX > s) {
+ Colors::black.use();
+ glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f);
+ glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar);
+ glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar + 3);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ }
- if (offset.x - world.startX < e) {
- blackBar[0] = blackBar[20] = blackBar[25] = -world.startX;
- blackBar[5] = blackBar[10] = blackBar[15] = e;
+ if (offset.x - world.startX < e) {
+ blackBar[0] = blackBar[20] = blackBar[25] = -world.startX;
+ blackBar[5] = blackBar[10] = blackBar[15] = e;
- Colors::black.use();
- glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f);
- glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar);
- glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar + 3);
- glDrawArrays(GL_TRIANGLES, 0, 6);
- }
-
- Render::worldShader.disable();
- Render::worldShader.unuse();
- } else {
- Render::useShader(&Render::worldShader);
- Render::worldShader.use();
- Colors::red.use();
- vec2 ll = vec2 {world.startX, GROUND_HEIGHT_MINIMUM};
- Render::drawRect(ll, ll + vec2(world.indoorTex.getDim().x, 4), z - 1);
- Render::worldShader.unuse();
+ Colors::black.use();
+ glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f);
+ glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar);
+ glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar + 3);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
}
+ Render::worldShader.disable();
+ Render::worldShader.unuse();
+
waitToSwap = false;
}
diff --git a/xml/!town.xml b/xml/!town.xml
index 26a62a1..b2d96a5 100644
--- a/xml/!town.xml
+++ b/xml/!town.xml
@@ -16,18 +16,10 @@
x = 0
ground = function()
- if (x == 330) then
+ if (x == 320) then
height = -1
else
- if (x &lt; 10) then
- height = 800
- else
- if (x &lt; 30) then
- height = -100 * math.tan(0.08 * (x - 10) + 1.77) + 75
- else
- height = 60
- end
- end
+ height = 1 / math.pow(2, (x - 50) / 2) + 60
end
x = x + 1
end
diff --git a/xml/bobshouse.xml b/xml/bobshouse.xml
index d7c8172..9160ef0 100644
--- a/xml/bobshouse.xml
+++ b/xml/bobshouse.xml
@@ -2,7 +2,7 @@
<include file="entities.xml"/>
<IndoorWorld>
- <style bgm="assets/music/theme_jazz.wav" folder="assets/style/classic/">
+ <style bgm="assets/music/theme_jazz.wav" folder="assets/style/indoors/">
<layer path="bg/bg.png"/>
<layer path="bg/bgFarMountain.png"/>
<layer path="bg/forestTileFar.png"/>
@@ -10,10 +10,26 @@
<layer path="bg/forestTileMid.png"/>
<layer path="bg/forestTileFront.png"/>
<layer path="bg/dirt.png"/>
- <layer path="bg/grass.png"/>
+ <layer path="bg/carpet.png"/>
</style>
<house width="800" texture="assets/style/classic/bg/insideWoodHouse.png"/>
- <generation width="320"/>
+ <generation>
+ x = 0
+
+ ground = function()
+ if (x == 320) then
+ height = -1
+ else
+ height = 60
+ end
+
+ x = x + 1
+ end
+
+ grass = function()
+ height = 2
+ end
+ </generation>
<time>6000</time>
<!--<link outside="town.xml"/>-->
<npc name="Bob" hasDialog="true" spawnx="30"/>