candle.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // SuperTux
  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/candle.hpp"
  17. #include <simplesquirrel/class.hpp>
  18. #include <simplesquirrel/vm.hpp>
  19. #include "math/random.hpp"
  20. #include "object/sprite_particle.hpp"
  21. #include "sprite/sprite.hpp"
  22. #include "sprite/sprite_manager.hpp"
  23. #include "supertux/flip_level_transformer.hpp"
  24. #include "supertux/sector.hpp"
  25. #include "util/reader_mapping.hpp"
  26. Candle::Candle(const ReaderMapping& mapping) :
  27. MovingSprite(mapping, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED),
  28. burning(true),
  29. flicker(true),
  30. lightcolor(1.0f, 1.0f, 1.0f),
  31. candle_light_1(SpriteManager::current()->create("images/objects/candle/candle-light-1.sprite")),
  32. candle_light_2(SpriteManager::current()->create("images/objects/candle/candle-light-2.sprite"))
  33. {
  34. mapping.get("burning", burning, true);
  35. mapping.get("flicker", flicker, true);
  36. std::vector<float> vColor;
  37. if (!mapping.get("color", vColor)) vColor = {1.0f, 1.0f, 1.0f};
  38. mapping.get("layer", m_layer); // Backwards compatibility
  39. // Change the light color if defined.
  40. if (vColor.size() >= 3) {
  41. lightcolor = Color(vColor);
  42. candle_light_1->set_blend(Blend::ADD);
  43. candle_light_2->set_blend(Blend::ADD);
  44. candle_light_1->set_color(lightcolor);
  45. candle_light_2->set_color(lightcolor);
  46. // The following allows the original candle appearance to be preserved.
  47. candle_light_1->set_action("white");
  48. candle_light_2->set_action("white");
  49. }
  50. set_action(burning ? "on" : "off");
  51. }
  52. void
  53. Candle::after_editor_set()
  54. {
  55. MovingSprite::after_editor_set();
  56. candle_light_1->set_color(lightcolor);
  57. candle_light_2->set_color(lightcolor);
  58. set_action(burning ? "on" : "off");
  59. }
  60. ObjectSettings
  61. Candle::get_settings()
  62. {
  63. ObjectSettings result = MovingSprite::get_settings();
  64. result.add_bool(_("Burning"), &burning, "burning", true);
  65. result.add_bool(_("Flicker"), &flicker, "flicker", true);
  66. result.add_color(_("Color"), &lightcolor, "color", Color::WHITE);
  67. result.reorder({"burning", "flicker", "name", "sprite", "color", "z-pos", "x", "y"});
  68. return result;
  69. }
  70. void
  71. Candle::draw(DrawingContext& context)
  72. {
  73. // Draw regular sprite.
  74. MovingSprite::draw(context);
  75. // Draw on lightmap.
  76. if (burning) {
  77. // Vector pos = get_pos() + (bbox.get_size() - candle_light_1->get_size()) / 2;
  78. // draw approx. 1 in 10 frames darker. Makes the candle flicker.
  79. if (graphicsRandom.rand(10) != 0 || !flicker) {
  80. // context.color().draw_surface(candle_light_1, pos, layer);
  81. candle_light_1->draw(context.light(), m_col.m_bbox.get_middle(), m_layer);
  82. } else {
  83. // context.color().draw_surface(candle_light_2, pos, layer);
  84. candle_light_2->draw(context.light(), m_col.m_bbox.get_middle(), m_layer);
  85. }
  86. }
  87. }
  88. HitResponse
  89. Candle::collision(MovingObject&, const CollisionHit& )
  90. {
  91. return FORCE_MOVE;
  92. }
  93. void
  94. Candle::puff_smoke()
  95. {
  96. Vector ppos = m_col.m_bbox.get_middle();
  97. Vector pspeed = Vector(0, -150);
  98. Vector paccel = Vector(0,0);
  99. Sector::get().add<SpriteParticle>("images/particles/smoke.sprite",
  100. "default",
  101. ppos, ANCHOR_MIDDLE,
  102. pspeed, paccel,
  103. LAYER_BACKGROUNDTILES+2);
  104. }
  105. void
  106. Candle::set_burning(bool burning_)
  107. {
  108. if (burning == burning_) return;
  109. burning = burning_;
  110. if (burning_) {
  111. set_action("on");
  112. } else {
  113. set_action("off");
  114. }
  115. // Puff smoke for flickering light sources only.
  116. if (flicker) puff_smoke();
  117. }
  118. void
  119. Candle::on_flip(float height)
  120. {
  121. MovingSprite::on_flip(height);
  122. FlipLevelTransformer::transform_flip(m_flip);
  123. }
  124. void
  125. Candle::register_class(ssq::VM& vm)
  126. {
  127. ssq::Class cls = vm.addAbstractClass<Candle>("Candle", vm.findClass("MovingSprite"));
  128. cls.addFunc("puff_smoke", &Candle::puff_smoke);
  129. cls.addFunc("get_burning", &Candle::get_burning);
  130. cls.addFunc("set_burning", &Candle::set_burning);
  131. cls.addVar("burning", &Candle::get_burning, &Candle::set_burning);
  132. }
  133. /* EOF */