1// SuperTux - Switch Trigger
2// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.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 "trigger/switch.hpp"
18
19#include <sstream>
20
21#include "audio/sound_manager.hpp"
22#include "sprite/sprite.hpp"
23#include "sprite/sprite_manager.hpp"
24#include "supertux/sector.hpp"
25#include "util/log.hpp"
26#include "util/reader_mapping.hpp"
27
28namespace {
29const std::string SWITCH_SOUND = "sounds/switch.ogg";
30}
31
32Switch::Switch(const ReaderMapping& reader) :
33 sprite_name(),
34 sprite(),
35 script(),
36 off_script(),
37 state(OFF),
38 bistable()
39{
40 if (!reader.get("x", m_col.m_bbox.get_left())) throw std::runtime_error("no x position set");
41 if (!reader.get("y", m_col.m_bbox.get_top())) throw std::runtime_error("no y position set");
42 if (!reader.get("sprite", sprite_name)) sprite_name = "images/objects/switch/left.sprite";
43 sprite = SpriteManager::current()->create(sprite_name);
44 m_col.m_bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
45
46 reader.get("script", script);
47 bistable = reader.get("off-script", off_script);
48
49 SoundManager::current()->preload( SWITCH_SOUND );
50}
51
52Switch::~Switch()
53{
54}
55
56ObjectSettings
57Switch::get_settings()
58{
59 ObjectSettings result = TriggerBase::get_settings();
60
61 result.add_sprite(_("Sprite"), &sprite_name, "sprite", std::string("images/objects/switch/left.sprite"));
62 result.add_script(_("Turn on script"), &script, "script");
63 result.add_script(_("Turn off script"), &off_script, "off-script");
64
65 result.reorder({"script", "off-script", "sprite", "x", "y"});
66
67 return result;
68}
69
70void
71Switch::after_editor_set() {
72 sprite = SpriteManager::current()->create(sprite_name);
73}
74
75void
76Switch::update(float )
77{
78 switch (state) {
79 case OFF:
80 break;
81 case TURN_ON:
82 if (sprite->animation_done()) {
83 std::ostringstream location;
84 location << "switch" << m_col.m_bbox.p1();
85 Sector::get().run_script(script, location.str());
86
87 sprite->set_action("on", 1);
88 state = ON;
89 }
90 break;
91 case ON:
92 if (sprite->animation_done() && !bistable) {
93 sprite->set_action("turnoff", 1);
94 state = TURN_OFF;
95 }
96 break;
97 case TURN_OFF:
98 if (sprite->animation_done()) {
99 if (bistable) {
100 std::ostringstream location;
101 location << "switch" << m_col.m_bbox.p1();
102 Sector::get().run_script(off_script, location.str());
103 }
104
105 sprite->set_action("off");
106 state = OFF;
107 }
108 break;
109 }
110}
111
112void
113Switch::draw(DrawingContext& context)
114{
115 sprite->draw(context.color(), m_col.m_bbox.p1(), LAYER_TILES);
116}
117
118void
119Switch::event(Player& , EventType type)
120{
121 if (type != EVENT_ACTIVATE) return;
122
123 switch (state) {
124 case OFF:
125 sprite->set_action("turnon", 1);
126 SoundManager::current()->play( SWITCH_SOUND );
127 state = TURN_ON;
128 break;
129 case TURN_ON:
130 break;
131 case ON:
132 if (bistable) {
133 sprite->set_action("turnoff", 1);
134 SoundManager::current()->play( SWITCH_SOUND );
135 state = TURN_OFF;
136 }
137 break;
138 case TURN_OFF:
139 break;
140 }
141}
142
143/* EOF */
144