File: generator_object.cpp

package info (click to toggle)
btanks 0.9.8083-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 43,616 kB
  • sloc: cpp: 46,425; ansic: 12,005; xml: 4,262; python: 313; sh: 13; makefile: 13
file content (127 lines) | stat: -rw-r--r-- 4,275 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdlib.h>
#include <vector>

#include "generator_object.h"
#include "mrt/logger.h"
#include "mrt/exception.h"

#include "generator.h"

using namespace generator;

GeneratorObject::GeneratorObject() : w(0), h(0) {}

class Background : public GeneratorObject {
public: 
	void init(const std::map<const std::string, std::string>& attrs, const std::string &data) {
		GeneratorObject::init(attrs, data);
		tiles.clear();
		
		std::vector<std::string> ts;
		mrt::split(ts, data, ",");
		for(size_t i = 0; i < ts.size(); ++i) {
			mrt::trim(ts[i]);
			tiles.push_back(atoi(ts[i].c_str()));
			//LOG_DEBUG(("tiles[%u] = %d", (unsigned)i, tiles[i]));
		}
		if (tiles.size() != (unsigned)w * h)
			throw_ex(("you must provide exact %d tile ids (%u provided)", w * h, (unsigned)tiles.size()))
	}
	std::vector<int> tiles;

	void render(MapGenerator *gen, const int first_gid, const int x, const int y, const bool full) const {
		//LOG_DEBUG(("render(%d, %d, %d)", first_gid, x, y));
		if (full) {
			for(int dy = 0; dy < h; ++dy) 
				for(int dx = 0; dx < w; ++dx) {
					const int tid = tiles[dy * w + dx];
					if (tid != 0 && gen->get(x + dx, y + dy) == 0)
						gen->set(x + dx, y + dy, first_gid + tid);
				}
		} else {
			int px = x % w, py = y % h;
			int tid = tiles[py * w + px];
			if (tid != 0 && gen->get(x, y) == 0)
				gen->set(x, y, first_gid + tid);
		}
	}

};

void TileBox::init(const std::map<const std::string, std::string>& _attrs, const std::string &data) {
	std::map<const std::string, std::string> attrs = _attrs;
	memset(split_w, 0, sizeof(split_w));
	memset(split_h, 0, sizeof(split_h));
	if (sscanf(attrs["width"].c_str(), "%d,%d,%d", split_w, split_w + 1, split_w + 2) != 3)
		throw_ex(("invalid box(in: %s, out: %s) description: width is missing or invalid", attrs["in"].c_str(), attrs["out"].c_str()));
	if (sscanf(attrs["height"].c_str(), "%d,%d,%d", split_h, split_h + 1, split_h + 2) != 3)
		throw_ex(("invalid box(in: %s, out: %s) description: height is missing or invalid", attrs["in"].c_str(), attrs["out"].c_str()));
	std::vector<std::string> numbers; 
	mrt::split(numbers, data, ",");
		
	this->w = 1;
	this->h = 1;
		
	int w = split_w[0] + split_w[1] + split_w[2];
	int h = split_h[0] + split_h[1] + split_h[2];
		
	if (numbers.size() != (unsigned)w * h)
		throw_ex(("invalid box(in: %s, out: %s) description: got %u numbers, need: %d", attrs["in"].c_str(), attrs["out"].c_str(), (unsigned) numbers.size(), w * h));
	
	//LOG_DEBUG(("parsing numbers: %s", data.c_str()));
	tiles.set_size(w, h, 0);
	for(size_t i = 0; i < numbers.size(); ++i) {
		int y = i / w, x = i % w;
		mrt::trim(numbers[i]);
		int tid = atoi(numbers[i].c_str()) + 1;
		if (tid <= 0)
			throw_ex(("invalid tile %d, box: %s, line %d, tile %d", tid, attrs["id"].c_str(), y, x));
		tiles.set(y, x, tid);
	}
	
	LOG_DEBUG(("box(%dx%d)[%d,%d,%d:%d,%d,%d]", w, h, split_w[0], split_w[1], split_w[2], split_h[0], split_h[1], split_h[1]));
}

void TileBox::render(MapGenerator *gen, const int first_gid, const int x, const int y, const bool full) const {
}

void GeneratorObject::init(const std::map<const std::string, std::string>& attrs, const std::string &data)  {
	int size = atoi(get(attrs, "size").c_str());
	if (size > 0) {
		w = h = size;
		return;
	}

	int w = atoi(get(attrs, "width").c_str());
	if (w > 0) 
		this->w = w;
	int h = atoi(get(attrs, "height").c_str());
	if (h > 0) 
		this->h = h;
	if (w == 0 || h == 0) 
		throw_ex(("you must specify size or width+height of every object"));
}

GeneratorObject *GeneratorObject::create(const std::string &name, const std::map<const std::string, std::string>& attrs, const std::string &data) {
	GeneratorObject *o = create(name);
	o->init(attrs, data);
	return o;
}


GeneratorObject *GeneratorObject::create(const std::string &name) {
	if (name == "background") {
		//create background
		return new Background;
	} else if (name == "box") {
		return new TileBox;
	} else throw_ex(("cannot handle '%s' object", name.c_str()));
}

std::string GeneratorObject::get(const std::map<const std::string, std::string>& attrs, const std::string &name)  {
	static std::string empty;
	const std::map<const std::string, std::string>::const_iterator i = attrs.find(name);
	if (i == attrs.end())
		return empty;
	return i->second;
}