1// SuperTux
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include "supertux/flip_level_transformer.hpp"
18
19#include "badguy/badguy.hpp"
20#include "object/block.hpp"
21#include "object/camera.hpp"
22#include "object/flower.hpp"
23#include "object/platform.hpp"
24#include "object/player.hpp"
25#include "object/tilemap.hpp"
26#include "supertux/sector.hpp"
27
28void
29FlipLevelTransformer::transform_sector(Sector& sector)
30{
31 float height = sector.get_height();
32
33 for (auto& object : sector.get_objects()) {
34 auto tilemap = dynamic_cast<TileMap*>(object.get());
35 if (tilemap) {
36 transform_tilemap(height, *tilemap);
37 }
38 auto player = dynamic_cast<Player*>(object.get());
39 if (player) {
40 Vector pos = player->get_pos();
41 pos.y = height - pos.y - player->get_bbox().get_height();
42 player->move(pos);
43 continue;
44 }
45 auto badguy = dynamic_cast<BadGuy*>(object.get());
46 if (badguy) {
47 transform_badguy(height, *badguy);
48 }
49 auto flower = dynamic_cast<Flower*>(object.get());
50 if (flower) {
51 transform_flower(*flower);
52 }
53 auto platform = dynamic_cast<Platform*>(object.get());
54 if (platform) {
55 transform_platform(height, *platform);
56 }
57 auto block = dynamic_cast<Block*>(object.get());
58 if (block) {
59 transform_block(height, *block);
60 }
61 auto mobject = dynamic_cast<MovingObject*>(object.get());
62 if (mobject) {
63 transform_moving_object(height, *mobject);
64 }
65 }
66
67 sector.get_camera().reset(sector.get_player().get_pos());
68}
69
70Flip
71FlipLevelTransformer::transform_flip(Flip flip)
72{
73 if (flip & VERTICAL_FLIP) {
74 return flip & ~VERTICAL_FLIP;
75 } else {
76 return flip | VERTICAL_FLIP;
77 }
78}
79
80void
81FlipLevelTransformer::transform_path(float height, float obj_height, Path& path)
82{
83 for (auto& node : path.m_nodes) {
84 Vector& pos = node.position;
85 pos.y = height - pos.y - obj_height;
86 }
87}
88
89void
90FlipLevelTransformer::transform_tilemap(float height, TileMap& tilemap)
91{
92 for (int x = 0; x < tilemap.get_width(); ++x) {
93 for (int y = 0; y < tilemap.get_height()/2; ++y) {
94 // swap tiles
95 int y2 = tilemap.get_height()-1-y;
96 uint32_t t1 = tilemap.get_tile_id(x, y);
97 uint32_t t2 = tilemap.get_tile_id(x, y2);
98 tilemap.change(x, y, t2);
99 tilemap.change(x, y2, t1);
100 }
101 }
102 tilemap.set_flip(transform_flip(tilemap.get_flip()));
103 Vector offset = tilemap.get_offset();
104 offset.y = height - offset.y - tilemap.get_bbox().get_height();
105 tilemap.set_offset(offset);
106 auto path = tilemap.get_path();
107 if (path)
108 transform_path(height, tilemap.get_bbox().get_height(), *path);
109}
110
111void
112FlipLevelTransformer::transform_badguy(float height, BadGuy& badguy)
113{
114 Vector pos = badguy.get_start_position();
115 pos.y = height - pos.y;
116 badguy.set_start_position(pos);
117}
118
119void
120FlipLevelTransformer::transform_moving_object(float height, MovingObject& object)
121{
122 Vector pos = object.get_pos();
123 pos.y = height - pos.y - object.get_bbox().get_height();
124 object.set_pos(pos);
125}
126
127void
128FlipLevelTransformer::transform_flower(Flower& flower)
129{
130 flower.flip = transform_flip(flower.flip);
131}
132
133void
134FlipLevelTransformer::transform_platform(float height, Platform& platform)
135{
136 transform_path(height, platform.get_bbox().get_height(), *(platform.get_path()));
137}
138
139void
140FlipLevelTransformer::transform_block(float height, Block& block)
141{
142 if (block.m_original_y != -1) block.m_original_y = height - block.m_original_y - block.get_bbox().get_height();
143}
144
145/* EOF */
146