From aec32b2eca58fcbe1a2730d79d500a44cf9043f1 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Wed, 18 May 2005 00:45:26 +0000 Subject: [PATCH] bonusblock can now contain custom MovingObjects, added possibility to execute script with powerups, created a proof of concept red/blue potion level SVN-Revision: 2507 --- data/images/powerups/potions/blue-potion.png | Bin 0 -> 1302 bytes data/images/powerups/potions/red-potion.png | Bin 0 -> 1302 bytes data/images/sprites.strf | 17 +++++ data/levels/test/bonusblock.stl | 95 +++++++++++++++++++-------- data/levels/test/enemy3.stl | 14 ++-- src/badguy/yeti.cpp | 14 +--- src/flip_level_transformer.cpp | 28 ++++++-- src/object/block.cpp | 94 ++++++++++++++++++-------- src/object/block.h | 5 +- src/object/flower.cpp | 3 +- src/object/flower.h | 2 +- src/object/growup.cpp | 3 +- src/object/growup.h | 2 +- src/object/powerup.cpp | 48 ++++++++------ src/object/powerup.h | 4 +- src/object/specialriser.cpp | 3 +- src/object/specialriser.h | 2 +- src/object/tilemap.h | 5 ++ src/scripting/script_interpreter.cpp | 18 +++++ src/scripting/script_interpreter.h | 6 ++ src/scripting/sound.h | 3 + src/scripting/wrapper.cpp | 52 +++++++++++++++ src/scripting/wrapper.interface.h | 2 +- src/sector.cpp | 15 +---- src/trigger/scripttrigger.cpp | 34 +++------- src/worldmap.cpp | 31 ++++++--- 26 files changed, 343 insertions(+), 157 deletions(-) create mode 100644 data/images/powerups/potions/blue-potion.png create mode 100644 data/images/powerups/potions/red-potion.png diff --git a/data/images/powerups/potions/blue-potion.png b/data/images/powerups/potions/blue-potion.png new file mode 100644 index 0000000000000000000000000000000000000000..d68fb706c0dcb957f85520ea5929c8c10c72d3fa GIT binary patch literal 1302 zcmV+x1?l>UP)Y1UJtt<(N=a_8lB4|`@Z`; zpXWQz`#kRh|M4Tb*=&s21vvNFR&ibT;zj|?07D&Yeb{x~N+&jTmx>JyU#Hw-Ebx(9^vs(qO1I_a{2lMA|4u&hN=Yh?}m?vDbh>cQ3?Q9fUR5Y3M-2MX*b5!0-(VX1Omsg>n_D>0T^gy;QF0+4PcBJ z0(y4td<4f?wX_c#W1I&HV2l|x#+(CYve`k=-@gUlmkbODhKFIx7RY1(F#`0x43v#A zU$lYO*NluYCxN4mV|eztLl`qke?O!t+`bLd(=as!i%T#!mk`HgYA3ns^f!6Py2gL=ras_5*VZPXsKTW~f zh-`Kdt*T_RWgsC{h!p2F`8_N=b_ZI0Q)=bhK>*;EG$5?3AGwbPPX0vVblUi zl6Dj_LWme45|nBnWpo!zh$ceBNcA{L@{7}PJ1&>!xpBkbc`b>x1|eENb92yW+#7uz zNYSc>QUOvn5u$;$3Xmj8o-|$Vst}!CUOrE$)H-Iq--@;#z|?drAMQBU+DFO=r9v{9 z+ejG#2|^@Tt4NYOaok4|{|s=ZQw7e{{qeEMNtd8u=*dF4(n>nt2O(mV3hv4+L_|+^ z39YMb01Kp8D@l?~gyHvq&r0_M@h^4Y9Q2J!{Vlm%A887493eyvtv#e{qGTN@8z|L4 zsX9sp2oVFe?L1GtUc#$=3UI=8-Q(Q=IKT`HI>=9e9b_^Uw62lOl+e0{)_yz5l6Jzy z?PCaWyb0f*#P`0#+F;yu-Iuy*M(u*}G!!qAz5(_#zylynvw+0f7QeL;Yc_8C|B?oC3Jf zZbYXa$Y|F7BxAr4V05*)ussodc|XT%nhjUDoZQ>*FLpW){;!@t0gloi8f{%X+5i9m M07*qoM6N<$f|o2p<^TWy literal 0 HcmV?d00001 diff --git a/data/images/powerups/potions/red-potion.png b/data/images/powerups/potions/red-potion.png new file mode 100644 index 0000000000000000000000000000000000000000..2b498d2493b6a7b9b2b4a3fe29170220cfb5e298 GIT binary patch literal 1302 zcmV+x1?l>UP)P8yCg}XpCV+NeD#E3)B#+kOGNq2g(dHOy|9s z_w%~AV`HQZGlfR)=Doag-#Op&J@?-4J@6k7(a&UK%nqRRh-nSa^RBKJfLp+54^yA^ zJg?Dp!Y&S&078Vyt z=jW*>2^X#93u~!B1NhMMywhva0%Ob-VDk9RoqT-c2%~%Uz}Br$EP}PrZbPjGjRrOh zX+{yTwLGU3`>myJZSe+7mdoW*rBXT97l3Z&lV9)K$HajHFh1@AM-eP7!QvuZzYg>B zaQ{A8vq_`fCXkY9K2Mm-u?HB+GJb;B%H{HOrBeC5rxF-rCV=zDckkxlp+oTZo^Q3F zQh{sNU~Uc;799OqMr19E`8-Xnsps>gKrYJ|?sPa6hFs3F1~B&Td%|j3aCp2_;^5xB zuwjFv+V@?+D_0zdAb>k}93w!a6w+F(5Trn$6tUI>Qu3aZT=xAEFbSOQWfx4owQU;+ z;j*sPV0s!ZUUVR`%zbY*mygCsxoW0ervhkcO|?*RFB#>UGTR+b+{20j(V)aqJde zr?VU+P>Kv#(weqX#8T1`0%a`{7)VoUS=QG2Gy#g-}ha%LEsi$wYnVK*P2L5 zLZx_+%MnUR3Zz{C18K@&lJK)*>uj$KoSh1SNpEHb({4kd0QI^niSLsLL0hS1x+5XD zS18cbnovq?R}!VQY)n&r2t)jCVm+UP#+dViF!7y~3>J%St0f6bLeSEhSV{t==txON zDFUTvD@7s%wi|pPO{oR}pS4;5Cq2(Q(GP$UaBBogp8_ueja-f;t*PeoENP9eHF0f2?0>Az$QW}1_y8!qsTA9lVw2X4=5j<*(zcelG-WPL`8AH2jbnh@ zT_HO2L|U_MNhX2Az{F~OVYegt>QRB$)ElmFIr*pFU+uLY{9lc~0OP9|=c(*DW&i*H M07*qoM6N<$g0OB_>;M1& literal 0 HcmV?d00001 diff --git a/data/images/sprites.strf b/data/images/sprites.strf index 7e785de94..bb4fa03f7 100644 --- a/data/images/sprites.strf +++ b/data/images/sprites.strf @@ -1572,4 +1572,21 @@ (mirror-action "right") ) ) + + (sprite + (name "red-potion") + (action + (name "default") + (images "powerups/potions/red-potion.png") + ) + ) + + (sprite + (name "blue-potion") + (action + (name "default") + (images "powerups/potions/blue-potion.png") + ) + ) ) + diff --git a/data/levels/test/bonusblock.stl b/data/levels/test/bonusblock.stl index d719a6075..4b8b60e79 100644 --- a/data/levels/test/bonusblock.stl +++ b/data/levels/test/bonusblock.stl @@ -7,8 +7,6 @@ (name "main") (music "theme.ogg") (gravity 10.000000) - (background (image "arctis.jpg") - (speed 0.5)) (tilemap (layer "background") (solid #f) @@ -56,28 +54,28 @@ (tiles 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 62 0 0 0 0 0 0 0 62 0 0 61 + 61 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 61 0 0 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 0 0 61 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 62 0 0 0 0 61 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 62 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 62 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 62 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 62 0 0 0 0 0 0 0 61 + 61 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 - 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 + 61 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 61 0 0 0 0 0 0 26 0 83 0 0 0 102 0 102 0 0 0 128 0 0 0 103 0 0 0 0 0 61 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 @@ -131,17 +129,58 @@ (image "arctis.jpg") (speed 0.500000) ) - (spawnpoint (name "main") (x 96) (y 160)) - (secretarea (x 133.000015258789) - (y 58.9999771118164) - (width 730.504028320312) - (height 127.476585388184) - (message "This is a Secret Area Test")) + (background + (image "arctis.jpg") + (speed 0.500000) + ) + (spawnpoint (name "main") (x 33) (y 160)) (infoblock (x 128) (y 800) (message (_ "-Info -#This is an info block -#(WOW GREAT) -#This rocks")) +#Beware of these crazy +#red potions. +#Better seek for blue +#potions.")) + ) + (bonusblock (x 96) (y 800) + (contents "custom") + (powerup + (sprite "red-potion") + (script " +function wait(time) { + set_wakeup_time(time); + suspend(); +} + +DisplayEffect.set_black(true); +wait(0.1); +DisplayEffect.set_black(false); +wait(0.07); +DisplayEffect.set_black(true); +wait(0.11); +DisplayEffect.set_black(false); +wait(0.09); +DisplayEffect.set_black(true); +wait(0.6); +Level.flip_vertically(); +DisplayEffect.fade_in(1); +") + ) + ) + (bonusblock (x 470) (y 96) + (contents "custom") + (powerup + (sprite "blue-potion") + (script " +function wait(time) { + set_wakeup_time(time); + suspend(); +} +DisplayEffect.fade_out(1); +wait(1); +Level.flip_vertically(); +DisplayEffect.fade_in(1); +") + ) ) ) ) diff --git a/data/levels/test/enemy3.stl b/data/levels/test/enemy3.stl index 3e2ecccf8..2e08f9049 100644 --- a/data/levels/test/enemy3.stl +++ b/data/levels/test/enemy3.stl @@ -79,10 +79,16 @@ (mriceblock (x 439) (y 159) (stay-on-platform #t)) (mriceblock (x 479) (y 159) (stay-on-platform #f)) (zeekling (x 1000) (y 140)) - (powerup (x 900) (y 140) (type "star")) - (powerup (x 940) (y 140) (type "fireflower")) - (powerup (x 980) (y 140) (type "egg")) - (powerup (x 1020) (y 140) (type "1up")) + (powerup (x 900) (y 140) (sprite "star")) + (powerup (x 940) (y 140) (sprite "fireflower")) + (powerup (x 980) (y 140) (sprite "egg")) + (powerup (x 1020) (y 140) (sprite "1up")) + (powerup (x 1400) (y 140) + (sprite "red-potion") + (contents "custom") + (script "Level.flip_vertically();") + ) + (trampoline (x 250) (y 150) (power 7.5)) (dispenser (x 700) (y 100) (badguy "random") (cycle 1)) ) diff --git a/src/badguy/yeti.cpp b/src/badguy/yeti.cpp index daa9cf677..87faba0b8 100644 --- a/src/badguy/yeti.cpp +++ b/src/badguy/yeti.cpp @@ -21,6 +21,7 @@ #include #include +#include #include "yeti.h" #include "object/camera.h" #include "yeti_stalactite.h" @@ -146,17 +147,8 @@ Yeti::collision_squished(Player& player) // start script if(dead_script != "") { - try { - ScriptInterpreter* interpreter - = new ScriptInterpreter(GameSession::current()->get_working_directory()); - interpreter->register_sector(Sector::current()); - std::istringstream in(dead_script); - interpreter->load_script(in, "Yeti - dead-script"); - interpreter->start_script(); - Sector::current()->add_object(interpreter); - } catch(std::exception& e) { - std::cerr << "Couldn't execute yeti dead script: " << e.what() << "\n"; - } + ScriptInterpreter::add_script_object(Sector::current(), + "Yeti - dead-script", dead_script); } } else { safe_timer.start(SAFE_TIME); diff --git a/src/flip_level_transformer.cpp b/src/flip_level_transformer.cpp index 22f10d4e2..3fafbd5cc 100644 --- a/src/flip_level_transformer.cpp +++ b/src/flip_level_transformer.cpp @@ -21,6 +21,7 @@ #include "flip_level_transformer.h" #include "object/tilemap.h" +#include "object/camera.h" #include "badguy/badguy.h" #include "sector.h" #include "tile_manager.h" @@ -40,20 +41,31 @@ FlipLevelTransformer::transform_sector(Sector* sector) if(tilemap) { transform_tilemap(tilemap); } + Player* player = dynamic_cast (object); + if(player) { + Vector pos = player->get_pos(); + pos.y = height - pos.y; + player->move(pos); + continue; + } BadGuy* badguy = dynamic_cast (object); if(badguy) { transform_badguy(height, badguy); - } else { - MovingObject* mobject = dynamic_cast (object); - if(mobject) { - transform_moving_object(height, mobject); - } + continue; + } + + MovingObject* mobject = dynamic_cast (object); + if(mobject) { + transform_moving_object(height, mobject); } } for(Sector::SpawnPoints::iterator i = sector->spawnpoints.begin(); i != sector->spawnpoints.end(); ++i) { transform_spawnpoint(height, *i); } + + if(sector->camera != 0 && sector->player != 0) + sector->camera->reset(sector->player->get_pos()); } void @@ -69,7 +81,11 @@ FlipLevelTransformer::transform_tilemap(TileMap* tilemap) tilemap->change(x, y2, t1->getID()); } } - tilemap->set_drawing_effect(VERTICAL_FLIP); + if(tilemap->get_drawing_effect() != 0) { + tilemap->set_drawing_effect(0); + } else { + tilemap->set_drawing_effect(VERTICAL_FLIP); + } } void diff --git a/src/object/block.cpp b/src/object/block.cpp index ae016480b..494d718e5 100644 --- a/src/object/block.cpp +++ b/src/object/block.cpp @@ -17,10 +17,12 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. - #include #include "block.h" + +#include + #include "resources.h" #include "player.h" #include "sector.h" @@ -38,6 +40,8 @@ #include "badguy/badguy.h" #include "coin.h" #include "object_factory.h" +#include "lisp/list_iterator.h" +#include "object_factory.h" static const float BOUNCY_BRICK_MAX_OFFSET=8; static const float BOUNCY_BRICK_SPEED=90; @@ -117,7 +121,7 @@ Block::start_bounce() //--------------------------------------------------------------------------- BonusBlock::BonusBlock(const Vector& pos, int data) - : Block(sprite_manager->create("bonusblock")) + : Block(sprite_manager->create("bonusblock")), object(0) { bbox.set_pos(pos); sprite->set_action("normal"); @@ -138,27 +142,55 @@ BonusBlock::BonusBlock(const lisp::Lisp& lisp) : Block(sprite_manager->create("bonusblock")) { Vector pos; - lisp.get("x", pos.x); - lisp.get("y", pos.y); - bbox.set_pos(pos); - std::string contentstring; contents = CONTENT_COIN; - if(lisp.get("contents", contentstring)) { - if(contentstring == "coin") { - contents = CONTENT_COIN; - } else if(contentstring == "firegrow") { - contents = CONTENT_FIREGROW; - } else if(contentstring == "icegrow") { - contents = CONTENT_ICEGROW; - } else if(contentstring == "star") { - contents = CONTENT_STAR; - } else if(contentstring == "1up") { - contents = CONTENT_1UP; + lisp::ListIterator iter(&lisp); + while(iter.next()) { + const std::string& token = iter.item(); + if(token == "x") { + iter.value()->get(pos.x); + } else if(token == "y") { + iter.value()->get(pos.y); + } else if(token == "contents") { + std::string contentstring; + iter.value()->get(contentstring); + if(contentstring == "coin") { + contents = CONTENT_COIN; + } else if(contentstring == "firegrow") { + contents = CONTENT_FIREGROW; + } else if(contentstring == "icegrow") { + contents = CONTENT_ICEGROW; + } else if(contentstring == "star") { + contents = CONTENT_STAR; + } else if(contentstring == "1up") { + contents = CONTENT_1UP; + } else if(contentstring == "custom") { + contents = CONTENT_CUSTOM; + } else { + std::cerr << "Invalid box contents '" << contentstring << "'.\n"; + } } else { - std::cerr << "Invalid box contents '" << contentstring << "'.\n"; - } + if(contents == CONTENT_CUSTOM) { + GameObject* game_object = create_object(token, *(iter.lisp())); + object = dynamic_cast (game_object); + if(object == 0) + throw std::runtime_error( + "Only MovingObjects are allowed inside BonusBlocks"); + } else { + std::cerr << "Invalid element '" << token << "' in bonusblock.\n"; + } + } } + + if(contents == CONTENT_CUSTOM && object == 0) + throw std::runtime_error("Need to specify content object for custom block"); + + bbox.set_pos(pos); +} + +BonusBlock::~BonusBlock() +{ + delete object; } void @@ -185,12 +217,11 @@ BonusBlock::try_open() case CONTENT_FIREGROW: if(player.get_status()->bonus == NO_BONUS) { - SpecialRiser* riser = new SpecialRiser( - new GrowUp(get_pos() + Vector(0, -32))); + SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp()); sector->add_object(riser); } else { SpecialRiser* riser = new SpecialRiser( - new Flower(get_pos() + Vector(0, -32), Flower::FIREFLOWER)); + get_pos(), new Flower(Flower::FIREFLOWER)); sector->add_object(riser); } sound_manager->play_sound("upgrade"); @@ -198,12 +229,11 @@ BonusBlock::try_open() case CONTENT_ICEGROW: if(player.get_status()->bonus == NO_BONUS) { - SpecialRiser* riser = new SpecialRiser( - new GrowUp(get_pos() + Vector(0, -32))); + SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp()); sector->add_object(riser); } else { - SpecialRiser* riser = new SpecialRiser( - new Flower(get_pos() + Vector(0, -32), Flower::ICEFLOWER)); + SpecialRiser* riser = new SpecialRiser( + get_pos(), new Flower(Flower::ICEFLOWER)); sector->add_object(riser); } sound_manager->play_sound("upgrade"); @@ -217,6 +247,13 @@ BonusBlock::try_open() sector->add_object(new OneUp(get_pos())); break; + case CONTENT_CUSTOM: + SpecialRiser* riser = new SpecialRiser(get_pos(), object); + object = 0; + sector->add_object(riser); + sound_manager->play_sound("upgrade"); + break; + default: assert(false); } @@ -225,7 +262,7 @@ BonusBlock::try_open() sprite->set_action("empty"); } -IMPLEMENT_FACTORY(BonusBlock, "bonusblock") +IMPLEMENT_FACTORY(BonusBlock, "bonusblock"); //--------------------------------------------------------------------------- @@ -286,4 +323,5 @@ Brick::try_break(bool playerhit) } } -//IMPLEMENT_FACTORY(Brick, "brick") +//IMPLEMENT_FACTORY(Brick, "brick"); + diff --git a/src/object/block.h b/src/object/block.h index 1650dbd5b..a6f9df111 100644 --- a/src/object/block.h +++ b/src/object/block.h @@ -52,6 +52,7 @@ class BonusBlock : public Block public: BonusBlock(const Vector& pos, int data); BonusBlock(const lisp::Lisp& lisp); + virtual ~BonusBlock(); void try_open(); @@ -64,10 +65,12 @@ private: CONTENT_FIREGROW, CONTENT_ICEGROW, CONTENT_STAR, - CONTENT_1UP + CONTENT_1UP, + CONTENT_CUSTOM }; Contents contents; + MovingObject* object; }; class Brick : public Block diff --git a/src/object/flower.cpp b/src/object/flower.cpp index 9216d4e14..974c27749 100644 --- a/src/object/flower.cpp +++ b/src/object/flower.cpp @@ -27,10 +27,9 @@ #include "player.h" #include "sprite/sprite_manager.h" -Flower::Flower(const Vector& pos, Type _type) +Flower::Flower(Type _type) : type(_type) { - bbox.set_pos(pos); bbox.set_size(32, 32); if(_type == FIREFLOWER) diff --git a/src/object/flower.h b/src/object/flower.h index bfa950bb5..e91f38b17 100644 --- a/src/object/flower.h +++ b/src/object/flower.h @@ -30,7 +30,7 @@ public: enum Type { FIREFLOWER, ICEFLOWER }; - Flower(const Vector& pos, Type type); + Flower(Type type); ~Flower(); virtual void update(float elapsed_time); diff --git a/src/object/growup.cpp b/src/object/growup.cpp index 0499c8572..da9aae1c8 100644 --- a/src/object/growup.cpp +++ b/src/object/growup.cpp @@ -27,9 +27,8 @@ #include "player.h" #include "sprite/sprite_manager.h" -GrowUp::GrowUp(const Vector& pos) +GrowUp::GrowUp() { - bbox.set_pos(pos); bbox.set_size(32, 32); sprite = sprite_manager->create("egg"); diff --git a/src/object/growup.h b/src/object/growup.h index 7976531fb..019d6808c 100644 --- a/src/object/growup.h +++ b/src/object/growup.h @@ -27,7 +27,7 @@ class GrowUp : public MovingObject { public: - GrowUp(const Vector& pos); + GrowUp(); ~GrowUp(); virtual void update(float elapsed_time); diff --git a/src/object/powerup.cpp b/src/object/powerup.cpp index dd6267bdf..3ba31dfa7 100644 --- a/src/object/powerup.cpp +++ b/src/object/powerup.cpp @@ -26,14 +26,17 @@ #include "sprite/sprite_manager.h" #include "object_factory.h" #include "sector.h" +#include "scripting/script_interpreter.h" PowerUp::PowerUp(const lisp::Lisp& lisp) { + std::string sprite_name; lisp.get("x", bbox.p1.x); lisp.get("y", bbox.p1.y); - lisp.get("type", type); + lisp.get("sprite", sprite_name); + lisp.get("script", script); bbox.set_size(32, 32); - sprite = sprite_manager->create(type); + sprite = sprite_manager->create(sprite_name); physic.enable_gravity(true); } @@ -56,27 +59,30 @@ PowerUp::collision(GameObject& other, const CollisionHit& hit) } Player* player = dynamic_cast(&other); - if(player != 0) { - if (type == "egg") { - player->set_bonus(GROWUP_BONUS, true); - sound_manager->play_sound("grow"); - } - else if (type == "fireflower") { - player->set_bonus(FIRE_BONUS, true); - sound_manager->play_sound("fire-flower"); - } - else if (type == "star") { - player->make_invincible(); - } - else if (type == "1up") { - player->get_status()->incLives(); - } - remove_me(); - + if(player == 0) + return FORCE_MOVE; + + remove_me(); + + if (script != "") { + ScriptInterpreter::add_script_object(Sector::current(), "powerup-script", + script); return ABORT_MOVE; } - - return FORCE_MOVE; + + // some defaults if no script has been set + if (sprite->get_name() == "egg") { + player->set_bonus(GROWUP_BONUS, true); + sound_manager->play_sound("grow"); + } else if (sprite->get_name() == "fireflower") { + player->set_bonus(FIRE_BONUS, true); + sound_manager->play_sound("fire-flower"); + } else if (sprite->get_name() == "star") { + player->make_invincible(); + } else if (sprite->get_name() == "1up") { + player->get_status()->incLives(); + } + return ABORT_MOVE; } void diff --git a/src/object/powerup.h b/src/object/powerup.h index a14d3742d..682d8bef7 100644 --- a/src/object/powerup.h +++ b/src/object/powerup.h @@ -1,4 +1,4 @@ -// $Id: growup.h 2458 2005-05-10 11:29:58Z matzebraun $ +// $Id$ // // SuperTux // Copyright (C) 2005 Matthias Braun @@ -39,7 +39,7 @@ public: private: Sprite* sprite; Physic physic; - std::string type; + std::string script; }; #endif diff --git a/src/object/specialriser.cpp b/src/object/specialriser.cpp index ce14ad5c0..efcf59e3d 100644 --- a/src/object/specialriser.cpp +++ b/src/object/specialriser.cpp @@ -26,9 +26,10 @@ #include "sector.h" #include "sprite/sprite_manager.h" -SpecialRiser::SpecialRiser(MovingObject* _child) +SpecialRiser::SpecialRiser(Vector pos, MovingObject* _child) : child(_child) { + _child->set_pos(pos - Vector(0, 32)); offset = 0; } diff --git a/src/object/specialriser.h b/src/object/specialriser.h index fe5a9d4d1..89f9904e6 100644 --- a/src/object/specialriser.h +++ b/src/object/specialriser.h @@ -29,7 +29,7 @@ class SpecialRiser : public GameObject { public: - SpecialRiser(MovingObject* child); + SpecialRiser(Vector pos, MovingObject* child); ~SpecialRiser(); virtual void update(float elapsed_time); diff --git a/src/object/tilemap.h b/src/object/tilemap.h index d647a5ef2..6aa44ad4b 100644 --- a/src/object/tilemap.h +++ b/src/object/tilemap.h @@ -89,6 +89,11 @@ public: drawing_effect = effect; } + int get_drawing_effect() + { + return drawing_effect; + } + private: typedef std::vector Tiles; Tiles tiles; diff --git a/src/scripting/script_interpreter.cpp b/src/scripting/script_interpreter.cpp index 13e9494a0..2d273f232 100644 --- a/src/scripting/script_interpreter.cpp +++ b/src/scripting/script_interpreter.cpp @@ -196,3 +196,21 @@ void ScriptInterpreter::draw(DrawingContext& ) { } + +void +ScriptInterpreter::add_script_object(Sector* sector, const std::string& name, + const std::string& script) +{ + try { + std::auto_ptr interpreter + (new ScriptInterpreter(GameSession::current()->get_working_directory())); + interpreter->register_sector(sector); + std::istringstream in(script); + interpreter->load_script(in, name); + interpreter->start_script(); + sector->add_object(interpreter.release()); + } catch(std::exception& e) { + std::cerr << "Couldn't start '" << name << "' script: " << e.what() << "\n"; + } +} + diff --git a/src/scripting/script_interpreter.h b/src/scripting/script_interpreter.h index c4ecabc31..9cb99c58e 100644 --- a/src/scripting/script_interpreter.h +++ b/src/scripting/script_interpreter.h @@ -29,6 +29,12 @@ public: void set_wakeup_time(float seconds); + /** helper function that parses a script, starts it and adds it to the sector + * specified + */ + static void add_script_object(Sector* sector, const std::string& scriptname, + const std::string& script); + static ScriptInterpreter* current() { return _current; diff --git a/src/scripting/sound.h b/src/scripting/sound.h index 9467c1fbb..348671966 100644 --- a/src/scripting/sound.h +++ b/src/scripting/sound.h @@ -8,6 +8,9 @@ class Sound { public: void play_music(const std::string& musicfile); + /** + * Play a sound effect. The name should be without path or .wav extension + */ void play_sound(const std::string& soundfile); #ifndef SCRIPTING_API diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index ed511ffe4..8c3ff5295 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -364,6 +364,50 @@ static int Text_set_visible_wrapper(HSQUIRRELVM v) return 0; } +static int Player_set_bonus_wrapper(HSQUIRRELVM v) +{ + Scripting::Player* _this; + sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); + const char* arg0; + sq_getstring(v, 2, &arg0); + + _this->set_bonus(arg0); + + return 0; +} + +static int Player_make_invincible_wrapper(HSQUIRRELVM v) +{ + Scripting::Player* _this; + sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); + + _this->make_invincible(); + + return 0; +} + +static int Player_add_life_wrapper(HSQUIRRELVM v) +{ + Scripting::Player* _this; + sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); + + _this->add_life(); + + return 0; +} + +static int Player_add_coins_wrapper(HSQUIRRELVM v) +{ + Scripting::Player* _this; + sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); + int arg0; + sq_getinteger(v, 2, &arg0); + + _this->add_coins(arg0); + + return 0; +} + static int display_text_file_wrapper(HSQUIRRELVM v) { const char* arg0; @@ -449,6 +493,13 @@ static WrappedFunction supertux_Text_methods[] = { { "set_visible", &Text_set_visible_wrapper }, }; +static WrappedFunction supertux_Player_methods[] = { + { "set_bonus", &Player_set_bonus_wrapper }, + { "make_invincible", &Player_make_invincible_wrapper }, + { "add_life", &Player_add_life_wrapper }, + { "add_coins", &Player_add_coins_wrapper }, +}; + WrappedClass supertux_classes[] = { { "DisplayEffect", supertux_DisplayEffect_methods }, { "Camera", supertux_Camera_methods }, @@ -456,6 +507,7 @@ WrappedClass supertux_classes[] = { { "ScriptedObject", supertux_ScriptedObject_methods }, { "Sound", supertux_Sound_methods }, { "Text", supertux_Text_methods }, + { "Player", supertux_Player_methods }, { 0, 0 } }; diff --git a/src/scripting/wrapper.interface.h b/src/scripting/wrapper.interface.h index 761a16605..e9645eca7 100644 --- a/src/scripting/wrapper.interface.h +++ b/src/scripting/wrapper.interface.h @@ -6,4 +6,4 @@ #include "sound.h" #include "text.h" #include "functions.h" - +#include "player.h" diff --git a/src/sector.cpp b/src/sector.cpp index 43743c7c3..1021ff58a 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -422,19 +422,8 @@ Sector::activate(const std::string& spawnpoint) // Run init script if(init_script != "") { - try { - ScriptInterpreter* interpreter - = new ScriptInterpreter(GameSession::current()->get_working_directory()); - interpreter->register_sector(this); - std::string sourcename = std::string("Sector(") + name + ") - init"; - std::istringstream in(init_script); - interpreter->load_script(in, sourcename); - interpreter->start_script(); - add_object(interpreter); - init_script = ""; - } catch(std::exception& e) { - std::cerr << "Couldn't execute init script: " << e.what() << "\n"; - } + ScriptInterpreter::add_script_object(this, + std::string("Sector(") + name + ") - init", init_script); } } diff --git a/src/trigger/scripttrigger.cpp b/src/trigger/scripttrigger.cpp index 5c8ecd70b..8d2a2779d 100644 --- a/src/trigger/scripttrigger.cpp +++ b/src/trigger/scripttrigger.cpp @@ -21,6 +21,8 @@ #include #include +#include +#include #include "scripttrigger.h" #include "game_session.h" @@ -42,6 +44,9 @@ ScriptTrigger::ScriptTrigger(const lisp::Lisp& reader) bbox.set_size(w, h); reader.get("script", script); reader.get("button", must_activate); + if(script == "") { + throw std::runtime_error("Need to specify a script for trigger object"); + } if (must_activate) triggerevent = EVENT_ACTIVATE; @@ -79,30 +84,11 @@ ScriptTrigger::write(lisp::Writer& writer) void ScriptTrigger::event(Player& , EventType type) { - if(type == triggerevent) - { - if (script != "") - { - try - { - ScriptInterpreter* interpreter - = new ScriptInterpreter(GameSession::current()->get_working_directory()); - interpreter->register_sector(Sector::current()); - std::istringstream in(script); - interpreter->load_script(in, "trigger-script"); - interpreter->start_script(); - Sector::current()->add_object(interpreter); - } - catch(std::exception& e) - { - std::cerr << "Couldn't execute trigger script: " << e.what() << "\n"; - } - } - else - { - std::cerr << "Couldn't find trigger script.\n"; - } - } + if(type != triggerevent) + return; + + ScriptInterpreter::add_script_object(Sector::current(), "trigger - scritp", + script); } IMPLEMENT_FACTORY(ScriptTrigger, "scripttrigger"); diff --git a/src/worldmap.cpp b/src/worldmap.cpp index 872c2859a..3649bab51 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -843,11 +843,16 @@ WorldMap::update(float delta) the level (in case there is one), don't show anything */ if(level_finished) { if (level->extro_script != "") { - ScriptInterpreter* interpreter = new ScriptInterpreter(levels_path); - std::istringstream in(level->extro_script); - interpreter->load_script(in, "level-extro-script"); - interpreter->start_script(); - add_object(interpreter); + try { + std::auto_ptr interpreter + (new ScriptInterpreter(levels_path)); + std::istringstream in(level->extro_script); + interpreter->load_script(in, "level-extro-script"); + interpreter->start_script(); + add_object(interpreter.release()); + } catch(std::exception& e) { + std::cerr << "Couldn't run level-extro-script:" << e.what() << "\n"; + } } if (!level->next_worldmap.empty()) @@ -991,11 +996,17 @@ WorldMap::display() sound_manager->play_music(song); if(!intro_displayed && intro_script != "") { - ScriptInterpreter* interpreter = new ScriptInterpreter(levels_path); - std::istringstream in(intro_script); - interpreter->load_script(in, "worldmap-intro-script"); - interpreter->start_script(); - add_object(interpreter); + try { + std::auto_ptr interpreter + (new ScriptInterpreter(levels_path)); + std::istringstream in(intro_script); + interpreter->load_script(in, "worldmap-intro-script"); + interpreter->start_script(); + add_object(interpreter.release()); + } catch(std::exception& e) { + std::cerr << "Couldn't execute worldmap-intro-script: " + << e.what() << "\n"; + } intro_displayed = true; } -- 2.11.0