1
// $Id: playfield.cpp 3385 2007-10-30 04:39:26Z grumbel $
3
// Pingus - A free Lemmings clone
4
// Copyright (C) 1999 Ingo Ruhnke <grumbel@gmx.de>
6
// This program is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public License
8
// as published by the Free Software Foundation; either version 2
9
// of the License, or (at your option) any later version.
11
// This program is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
// GNU General Public License for more details.
16
// You should have received a copy of the GNU General Public License
17
// along with this program; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
#include "../globals.hpp"
23
#include "../pingu_holder.hpp"
24
#include "../display/drawing_context.hpp"
25
#include "../display/scene_context.hpp"
26
#include "../world.hpp"
27
#include "../server.hpp"
28
#include "../true_server.hpp"
29
#include "../pingu.hpp"
30
#include "../display/display.hpp"
31
#include "button_panel.hpp"
32
#include "playfield.hpp"
34
Playfield::Playfield (Client* client_, const Rect& rect_)
35
: RectComponent(rect_),
37
buttons(client->get_button_panel()),
39
// We keep the SceneContext has member variable so that we don't
40
// have to reallocate it every frame, which is quite a costly operation
41
scene_context(new SceneContext()),
43
cap(client->get_button_panel())
45
world = client->get_server()->get_world();
46
mouse_scrolling = false;
48
state.set_limit(Rect(Vector2i(0, 0), Size(world->get_width(), world->get_height())));
50
// FIXME: Temporary workaround till start-pos is integrated a bit more properly
51
state.set_pos(world->get_start_pos(0));
54
Playfield::~Playfield()
60
Playfield::draw(DrawingContext& gc)
62
scene_context->clear();
63
scene_context->set_cliprect(rect);
65
//scene_context->light().fill_screen(Color(50, 50, 50));
67
state.push(*scene_context);
69
cap.set_pingu(current_pingu);
70
cap.draw(*scene_context);
72
world->draw(*scene_context);
74
// Draw the scrolling band
75
if (mouse_scrolling && !drag_drop_scrolling)
77
gc.draw_line(mouse_pos.x, mouse_pos.y,
78
scroll_center.x, scroll_center.y-15,
81
gc.draw_line(mouse_pos.x, mouse_pos.y,
82
scroll_center.x, scroll_center.y,
85
gc.draw_line(mouse_pos.x, mouse_pos.y,
86
scroll_center.x, scroll_center.y+15,
89
gc.draw_line(mouse_pos.x, mouse_pos.y,
90
scroll_center.x + 15, scroll_center.y,
93
gc.draw_line(mouse_pos.x, mouse_pos.y,
94
scroll_center.x - 15, scroll_center.y,
98
state.pop(*scene_context);
99
gc.draw(new SceneContextDrawingRequest(scene_context, Vector3f(0,0,-10000)));
103
Playfield::current_pingu_find (const Vector2f& pos)
105
double min_dist = 500.0;
109
for (PinguIter pingu = world->get_pingus()->begin();
110
pingu != world->get_pingus()->end();
113
if ((*pingu)->is_over(static_cast<int>(pos.x), static_cast<int>(pos.y)))
115
dist = (*pingu)->dist(static_cast<int>(pos.x), static_cast<int>(pos.y));
128
Playfield::update(float delta)
130
// FIXME: This should be delta dependant
131
if (!mouse_scrolling)
133
current_pingu = current_pingu_find(state.screen2world(mouse_pos));
134
cap.set_pingu(current_pingu);
138
if (drag_drop_scrolling)
140
state.set_pos(old_state_pos + (scroll_center - mouse_pos));
144
state.set_pos(Vector2f(state.get_pos().x - float(scroll_center.x - mouse_pos.x) * 0.2f,
145
state.get_pos().y - float(scroll_center.y - mouse_pos.y) * 0.2f));
149
if (auto_scrolling && (fullscreen_enabled || SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON))
151
// FIXME: May need to modify this function if it's not gradient enough.
152
scroll_speed = static_cast<int>(800 * delta);
153
//std::cout << "scroll_speed: " << scroll_speed << std::endl;
155
if (mouse_pos.x < 10)
157
state.set_pos(state.get_pos() - Vector2i(scroll_speed, 0));
159
else if (mouse_pos.x > Display::get_width() - 10)
161
state.set_pos(state.get_pos() + Vector2i(scroll_speed, 0));
164
if (mouse_pos.y < 10)
166
state.set_pos(state.get_pos() - Vector2i(0, scroll_speed));
168
else if (mouse_pos.y > Display::get_height() - 10)
170
state.set_pos(state.get_pos() + Vector2i(0, scroll_speed));
176
Playfield::on_primary_button_press(int x, int y)
183
server->send_pingu_action_event(current_pingu, buttons->get_action_name());
188
Playfield::on_secondary_button_press(int x, int y)
190
mouse_scrolling = true;
194
old_state_pos = state.get_pos();
198
Playfield::on_secondary_button_release (int x, int y)
203
mouse_scrolling = false;
207
Playfield::on_pointer_move (int x, int y)
209
// FIXME: useless stuff, but currently the controller doesn't have a state
215
Uint8 *keystate = SDL_GetKeyState(NULL);
216
if (keystate[SDLK_r])
218
CollisionMask mask("other/bash_radius_gfx");
219
Vector2f p = state.screen2world(mouse_pos);
220
server->get_world()->remove(mask,
221
int(p.x - mask.get_width()/2),
222
int(p.y - mask.get_height()/2));
224
else if (keystate[SDLK_g])
226
CollisionMask mask("other/bash_radius_gfx");
227
Vector2f p = state.screen2world(mouse_pos);
228
server->get_world()->put(mask,
229
int(p.x - mask.get_width()/2),
230
int(p.y - mask.get_height()/2),
231
Groundtype::GP_GROUND);
233
else if (keystate[SDLK_b])
235
CollisionMask mask("other/bash_radius_gfx");
236
Vector2f p = state.screen2world(mouse_pos);
237
server->get_world()->put(mask,
238
int(p.x - mask.get_width()/2),
239
int(p.y - mask.get_height()/2),
240
Groundtype::GP_BRIDGE);
246
Playfield::set_server(Server* s)
252
Playfield::get_pos() const
254
return Vector2i(static_cast<int>(state.get_pos().x),
255
static_cast<int>(state.get_pos().y));
259
Playfield::set_viewpoint(int x, int y)
261
state.set_pos(Vector2f((float)x, (float)y));
265
Playfield::scroll (int x, int y)
267
state.set_pos(state.get_pos() + Vector2f((float)x, (float)y));