pushbutton.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // SuperTux - PushButton running a script
  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. #include "object/pushbutton.hpp"
  17. #include "audio/sound_manager.hpp"
  18. #include "editor/editor.hpp"
  19. #include "object/bigsnowball.hpp"
  20. #include "object/player.hpp"
  21. #include "object/rock.hpp"
  22. #include "sprite/sprite.hpp"
  23. #include "supertux/flip_level_transformer.hpp"
  24. #include "supertux/sector.hpp"
  25. #include "util/reader_mapping.hpp"
  26. namespace {
  27. const std::string BUTTON_SOUND = "sounds/switch.ogg";
  28. //14 -> 8
  29. }
  30. PushButton::PushButton(const ReaderMapping& mapping) :
  31. StickyObject(mapping, "images/objects/pushbutton/pushbutton.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_STATIC),
  32. m_script(),
  33. m_state(OFF),
  34. m_dir(Direction::UP)
  35. {
  36. SoundManager::current()->preload(BUTTON_SOUND);
  37. if (!mapping.get("script", m_script) && !Editor::is_active())
  38. {
  39. log_warning << "No script set for pushbutton." << std::endl;
  40. }
  41. bool old_upside_down;
  42. std::string dir_str;
  43. if (mapping.get("direction", dir_str))
  44. m_dir = string_to_dir(dir_str);
  45. else if (mapping.get("upside-down", old_upside_down) && old_upside_down)
  46. m_dir = Direction::DOWN;
  47. mapping.get("sticky", m_sticky, false);
  48. set_action("off", m_dir, -1);
  49. }
  50. ObjectSettings
  51. PushButton::get_settings()
  52. {
  53. ObjectSettings result = StickyObject::get_settings();
  54. result.add_direction(_("Direction"), &m_dir, { Direction::UP, Direction::DOWN }, "direction");
  55. result.add_script(_("Script"), &m_script, "script");
  56. result.reorder({"direction", "script", "sticky", "x", "y"});
  57. return result;
  58. }
  59. void
  60. PushButton::after_editor_set()
  61. {
  62. MovingSprite::after_editor_set();
  63. set_action("off", m_dir);
  64. }
  65. void
  66. PushButton::update(float dt_sec)
  67. {
  68. if (m_sticky) {
  69. StickyObject::update(dt_sec);
  70. }
  71. }
  72. HitResponse
  73. PushButton::collision(MovingObject& other, const CollisionHit& hit)
  74. {
  75. auto player = dynamic_cast<Player*>(&other);
  76. auto rock = dynamic_cast<Rock*>(&other);
  77. auto bs = dynamic_cast<BigSnowball*>(&other);
  78. if (!player && !rock && !bs)
  79. return FORCE_MOVE;
  80. if (player)
  81. {
  82. float vy = player->get_physic().get_velocity_y();
  83. if (m_dir == Direction::DOWN)
  84. {
  85. if (vy >= 0)
  86. return FORCE_MOVE;
  87. if (hit.bottom)
  88. player->get_physic().set_velocity_y(0);
  89. }
  90. else
  91. {
  92. if (vy <= 0)
  93. return FORCE_MOVE;
  94. if (hit.top)
  95. {
  96. player->get_physic().set_velocity_y(0);
  97. if(!player->is_swimming())
  98. {
  99. player->set_on_ground(true);
  100. }
  101. }
  102. }
  103. }
  104. if (m_state != OFF || !(m_dir == Direction::DOWN ? hit.bottom : hit.top))
  105. return FORCE_MOVE;
  106. // change appearance
  107. m_state = ON;
  108. float old_bbox_height = m_col.m_bbox.get_height();
  109. set_action("on", m_dir, -1);
  110. float new_bbox_height = m_col.m_bbox.get_height();
  111. Vector delta(0, old_bbox_height - new_bbox_height);
  112. set_pos(get_pos() + delta * (m_dir == Direction::DOWN ? 0 : 1.f));
  113. // play sound
  114. SoundManager::current()->play(BUTTON_SOUND, get_pos());
  115. // run script
  116. Sector::get().run_script(m_script, "PushButton");
  117. return FORCE_MOVE;
  118. }
  119. void
  120. PushButton::on_flip(float height)
  121. {
  122. MovingSprite::on_flip(height);
  123. m_dir = m_dir == Direction::UP ? Direction::DOWN : Direction::UP;
  124. set_action(m_state == OFF ? "off" : "on", m_dir);
  125. }
  126. /* EOF */